61 lines
3.0 KiB
JavaScript
61 lines
3.0 KiB
JavaScript
const vscode = require('vscode');
|
||
const { relations } = require('./graph.cjs');
|
||
const { uri } = require('./inspection.cjs');
|
||
|
||
function command(name, args) {
|
||
return `command:${name}?${encodeURIComponent(JSON.stringify(args))}`;
|
||
}
|
||
|
||
async function description(inspection, index, symbol, root) {
|
||
const value = index.documentation.find(item => item.symbol === symbol.name);
|
||
if (!value) return undefined;
|
||
const documentIndex = { files: [index.documentation_files[value.file]] };
|
||
await inspection.verify(documentIndex, 0, root);
|
||
return { ...value, uri: uri(documentIndex, 0, root) };
|
||
}
|
||
|
||
function registerHover(context, selector, inspection, lookup) {
|
||
context.subscriptions.push(vscode.languages.registerHoverProvider(selector, {
|
||
async provideHover(document, position) {
|
||
const state = await lookup(document, position);
|
||
if (!state?.symbols.length) return undefined;
|
||
const contents = [];
|
||
for (const symbol of state.symbols) {
|
||
const page = new vscode.MarkdownString();
|
||
page.isTrusted = { enabledCommands: ['dever.showCalls', 'dever.openDomainLinks', 'dever.previewDocumentation'] };
|
||
page.appendMarkdown(`**${symbol.name}**\n\n`);
|
||
if (state.index.documentation_errors.length) {
|
||
page.appendMarkdown('**说明校验未通过。** 失效或重复的标题详见“Dever”输出;签名和调用关系仍来自源码。\n\n');
|
||
}
|
||
for (const signature of symbol.signatures) page.appendCodeblock(signature, 'dever');
|
||
const detail = await description(inspection, state.index, symbol, state.root);
|
||
if (detail) {
|
||
page.baseUri = detail.uri;
|
||
page.appendMarkdown(`${detail.markdown}\n\n`);
|
||
} else {
|
||
page.appendMarkdown('尚未提供领域说明;签名和关系来自已保存源码。\n\n');
|
||
}
|
||
for (const incoming of [true, false]) {
|
||
const related = relations(state.index, symbol.id, incoming);
|
||
const label = incoming ? '调用方' : '调用目标';
|
||
const names = related.slice(0, 4).map(item => `\`${item.symbol.name}\``).join('、');
|
||
page.appendMarkdown(`${label}:${names || '当前静态索引中无记录'}${related.length > 4 ? `,共 ${related.length} 个` : ''}。\n\n`);
|
||
}
|
||
const links = [];
|
||
for (const site of symbol.declarations.slice(0, 1)) {
|
||
const target = uri(state.index, site.file, state.root).with({ fragment: `L${site.start.line + 1},${site.start.character + 1}` });
|
||
links.push(`[源码](${target.toString()})`);
|
||
}
|
||
if (detail) links.push(`[说明](${command('dever.previewDocumentation', [state.root, symbol.name])})`);
|
||
links.push(`[调用详情](${command('dever.showCalls', [state.root, symbol.name])})`);
|
||
links.push(`[领域流程](${command('dever.openDomainLinks', [state.root, symbol.name])})`);
|
||
page.appendMarkdown(links.join(' · '));
|
||
contents.push(page);
|
||
}
|
||
return new vscode.Hover(contents);
|
||
}
|
||
}));
|
||
}
|
||
|
||
module.exports = { registerHover, description, command };
|