perlnavigator-server
Version:
Perl language server
131 lines • 5.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHover = void 0;
const node_1 = require("vscode-languageserver/node");
const types_1 = require("./types");
const utils_1 = require("./utils");
const refinement_1 = require("./refinement");
const pod_1 = require("./pod");
const vscode_uri_1 = require("vscode-uri");
async function getHover(params, perlDoc, txtDoc, modMap) {
let position = params.position;
const symbol = (0, utils_1.getSymbol)(position, txtDoc);
let elem = perlDoc.canonicalElems.get(symbol);
if (!elem) {
const elems = (0, utils_1.lookupSymbol)(perlDoc, modMap, symbol, position.line);
// Nothing or too many things.
if (elems.length != 1)
return;
elem = elems[0];
}
const refined = await (0, refinement_1.refineElementIfSub)(elem, params, perlDoc);
let title = buildHoverDoc(symbol, elem, refined);
// Sometimes, there's nothing worth showing.
// I'm assuming we won't get any useful POD if we can't get a useful title. Could be wrong
if (!title)
return;
let merged = title;
let docs = await (0, pod_1.getPod)(elem, perlDoc, modMap);
if (docs) {
if (!docs.startsWith("\n"))
docs = "\n" + docs; // Markdown requires two newlines to make one
merged += `\n${docs}`;
}
const hoverContent = {
kind: node_1.MarkupKind.Markdown,
value: merged
};
const documentation = { contents: hoverContent };
return documentation;
}
exports.getHover = getHover;
function buildHoverDoc(symbol, elem, refined) {
let sig = "";
let name = elem.name;
// Early return.
if ([types_1.PerlSymbolKind.LocalVar, types_1.PerlSymbolKind.ImportedVar, types_1.PerlSymbolKind.Canonical].includes(elem.type)) {
if (elem.typeDetail.length > 0)
return `(object) ${elem.typeDetail}`;
else if (symbol.startsWith("$self"))
// We either know the object type, or it's $self
return `(object) ${elem.package}`;
}
if (refined && refined.signature) {
let signature = refined.signature;
signature = [...signature];
if (symbol.indexOf("->") != -1 && refined.type != types_1.PerlSymbolKind.LocalMethod) {
signature.shift();
name = name.replace(/::(\w+)$/, "->$1");
}
if (signature.length > 0)
sig = "(" + signature.join(", ") + ")";
}
let desc;
switch (elem.type) {
case types_1.PerlSymbolKind.ImportedSub: // inherited methods can still be subs (e.g. new from a parent)
case types_1.PerlSymbolKind.Inherited:
desc = `(subroutine) ${name}${sig}`;
if (elem.typeDetail && elem.typeDetail != elem.name)
desc += ` [${elem.typeDetail}]`;
break;
case types_1.PerlSymbolKind.LocalSub:
desc = `(subroutine) ${name}${sig}`;
break;
case types_1.PerlSymbolKind.LocalMethod:
case types_1.PerlSymbolKind.Method:
desc = `(method) ${name}${sig}`;
break;
case types_1.PerlSymbolKind.LocalVar:
// Not very interesting info
// desc = `(variable) ${symbol}`;
break;
case types_1.PerlSymbolKind.Constant:
desc = `(constant) ${symbol}`;
break;
case types_1.PerlSymbolKind.ImportedVar:
desc = `${name}: ${elem.value}`;
if (elem.package)
desc += ` [${elem.package}]`; // Is this ever known?
break;
case types_1.PerlSymbolKind.ImportedHash:
desc = `${elem.name} [${elem.package}]`;
break;
case types_1.PerlSymbolKind.Package:
desc = `(package) ${elem.name}`;
break;
case types_1.PerlSymbolKind.Module: {
let file = vscode_uri_1.default.parse(elem.uri).fsPath;
desc = `(module) ${elem.name}: ${file}`;
break;
}
case types_1.PerlSymbolKind.Label:
desc = `(label) ${symbol}`;
break;
case types_1.PerlSymbolKind.Class:
desc = `(class) ${symbol}`;
break;
case types_1.PerlSymbolKind.Role:
desc = `(role) ${symbol}`;
break;
case types_1.PerlSymbolKind.Field:
case types_1.PerlSymbolKind.PathedField:
desc = `(attribute) ${elem.name}`;
break;
case types_1.PerlSymbolKind.Phaser:
desc = `(phase) ${symbol}`;
break;
case types_1.PerlSymbolKind.HttpRoute:
case types_1.PerlSymbolKind.OutlineOnlySub:
// You cant go-to or hover on a route or outline only sub.
break;
case types_1.PerlSymbolKind.AutoLoadVar:
desc = `(autoloaded) ${symbol}`;
break;
default:
// We should never get here
desc = `Unknown: ${elem.name}`;
break;
}
return desc;
}
//# sourceMappingURL=hover.js.map