Skip to content

Commit 21ae8ed

Browse files
authored
Merge pull request #419 from codefori/worksofliam/issue417
Improve hover provider to utilize existing documentation
2 parents 4065868 + f75ae55 commit 21ae8ed

File tree

2 files changed

+84
-81
lines changed

2 files changed

+84
-81
lines changed

extension/server/src/providers/hover.ts

Lines changed: 83 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Parser from "../../../../language/parser";
44
import { URI } from 'vscode-uri';
55
import { Keywords } from '../../../../language/parserTypes';
66

7-
export default async function hoverProvider(params: HoverParams): Promise<Hover|undefined> {
7+
export default async function hoverProvider(params: HoverParams): Promise<Hover | undefined> {
88
const currentPath = params.textDocument.uri;
99
const currentLine = params.position.line;
1010
const document = documents.get(currentPath);
@@ -15,74 +15,81 @@ export default async function hoverProvider(params: HoverParams): Promise<Hover|
1515
const word = getWordRangeAtPosition(document, params.position);
1616
if (!word) return;
1717

18-
const procedure = doc.procedures.find(proc => proc.name.toUpperCase() === word.toUpperCase());
18+
let symbol = doc.findDefinition(currentLine, word);
1919

20-
if (procedure) {
21-
let markdown = ``;
22-
let returnValue = `void`
20+
if (symbol) {
21+
if (symbol.type === `procedure`) {
2322

24-
let returnKeywords: Keywords = {
25-
...procedure.keyword,
26-
};
27-
delete returnKeywords[`EXTPROC`];
23+
// If a symbol is found, but there are no docs,
24+
// maybe the docs exist on a matching prototype?
25+
if (symbol.tags.length === 0) {
26+
const withDocs = doc.findAll(word).find(p => p.type === `procedure` && p.tags.length > 0);
27+
if (withDocs) {
28+
symbol = withDocs;
29+
}
30+
}
2831

29-
if (Object.keys(returnKeywords).length > 0) returnValue = prettyKeywords(returnKeywords);
32+
let markdown = ``;
33+
let returnValue = `void`
3034

31-
const returnTag = procedure.tags.find(tag => tag.tag === `return`);
32-
const deprecatedTag = procedure.tags.find(tag => tag.tag === `deprecated`);
35+
let returnKeywords: Keywords = {
36+
...symbol.keyword,
37+
};
38+
delete returnKeywords[`EXTPROC`];
3339

34-
// Deprecated notice
35-
if (deprecatedTag) {
36-
markdown += `**Deprecated:** ${deprecatedTag.content}\n\n`;
37-
}
40+
if (Object.keys(returnKeywords).length > 0) returnValue = prettyKeywords(returnKeywords);
3841

39-
// Formatted code
40-
markdown += `\`\`\`vb\n${procedure.name}(`;
42+
const returnTag = symbol.tags.find(tag => tag.tag === `return`);
43+
const deprecatedTag = symbol.tags.find(tag => tag.tag === `deprecated`);
4144

42-
if (procedure.subItems.length > 0) {
43-
markdown += `\n ${procedure.subItems.map(parm => `${parm.name}: ${prettyKeywords(parm.keyword)}`).join(`,\n `)}\n`;
44-
}
45+
// Deprecated notice
46+
if (deprecatedTag) {
47+
markdown += `**Deprecated:** ${deprecatedTag.content}\n\n`;
48+
}
4549

46-
markdown += `): ${returnValue}\n\`\`\` \n`;
50+
// Formatted code
51+
markdown += `\`\`\`vb\n${symbol.name}(`;
4752

48-
const titleTag = procedure.tags.find(tag => tag.tag === `title`);
49-
const descriptionTag = procedure.tags.find(tag => tag.tag === `description`);
53+
if (symbol.subItems.length > 0) {
54+
markdown += `\n ${symbol.subItems.map(parm => `${parm.name}: ${prettyKeywords(parm.keyword)}`).join(`,\n `)}\n`;
55+
}
5056

51-
const header = [titleTag ? titleTag.content : undefined, descriptionTag ? descriptionTag.content : undefined].filter(x => x).join(` — `);
57+
markdown += `): ${returnValue}\n\`\`\` \n`;
5258

53-
// Header
54-
markdown += `${header}\n\n`;
59+
const titleTag = symbol.tags.find(tag => tag.tag === `title`);
60+
const descriptionTag = symbol.tags.find(tag => tag.tag === `description`);
5561

56-
// Params
57-
markdown += procedure.subItems.map((parm) => `*@param* \`${parm.name.replace(new RegExp(`\\*`, `g`), `\\*`)}\` ${parm.tags.find(t => t.tag === `description`)?.content || ``}`).join(`\n\n`);
62+
const header = [titleTag ? titleTag.content : undefined, descriptionTag ? descriptionTag.content : undefined].filter(x => x).join(` — `);
5863

59-
// Return value
60-
if (returnTag) {
61-
markdown += `\n\n*@returns* ${returnTag.content}`;
62-
}
64+
// Header
65+
markdown += `${header}\n\n`;
6366

64-
if (procedure.position && currentPath !== procedure.position.path) {
65-
markdown += `\n\n*@file* \`${procedure.position.path}:${procedure.position.range.line+1}\``;
66-
}
67-
68-
return {
69-
contents: {
70-
kind: MarkupKind.Markdown,
71-
value: markdown
67+
// Params
68+
markdown += symbol.subItems.map((parm) => `*@param* \`${parm.name.replace(new RegExp(`\\*`, `g`), `\\*`)}\` ${parm.tags.find(t => t.tag === `description`)?.content || ``}`).join(`\n\n`);
69+
70+
// Return value
71+
if (returnTag) {
72+
markdown += `\n\n*@returns* ${returnTag.content}`;
7273
}
73-
};
74-
} else {
75-
// If they're inside of a procedure, let's get the stuff from there too
76-
let theVariable = doc.findDefinition(currentLine, word);
7774

78-
if (theVariable) {
75+
if (symbol.position && currentPath !== symbol.position.path) {
76+
markdown += `\n\n*@file* \`${symbol.position.path}:${symbol.position.range.line + 1}\``;
77+
}
78+
79+
return {
80+
contents: {
81+
kind: MarkupKind.Markdown,
82+
value: markdown
83+
}
84+
};
85+
} else {
7986
// Variable definition found
80-
const refs = theVariable.references.length;
81-
82-
let markdown = `\`${theVariable.name} ${prettyKeywords(theVariable.keyword)}\` (${refs} reference${refs === 1 ? `` : `s`})`;
87+
const refs = symbol.references.length;
88+
89+
let markdown = `\`${symbol.name} ${prettyKeywords(symbol.keyword)}\` (${refs} reference${refs === 1 ? `` : `s`})`;
8390

84-
if (theVariable.position && currentPath !== theVariable.position.path) {
85-
markdown += `\n\n*@file* \`${theVariable.position.path}:${theVariable.position.range.line+1}\``;
91+
if (symbol.position && currentPath !== symbol.position.path) {
92+
markdown += `\n\n*@file* \`${symbol.position.path}:${symbol.position.range.line + 1}\``;
8693
}
8794

8895
return {
@@ -91,41 +98,41 @@ export default async function hoverProvider(params: HoverParams): Promise<Hover|
9198
value: markdown
9299
}
93100
};
101+
}
94102

95-
} else {
96-
const lineContent = document.getText(Range.create(currentLine, 0, currentLine, 200));
97-
98-
const includeDirective = Parser.getIncludeFromDirective(lineContent);
99-
100-
if (includeDirective && parser.includeFileFetch) {
101-
const include = await parser.includeFileFetch(currentPath, includeDirective);
102-
let displayName = includeDirective;
103+
} else {
104+
const lineContent = document.getText(Range.create(currentLine, 0, currentLine, 200));
103105

104-
if (include.found && include.uri) {
105-
const foundUri = URI.parse(include.uri);
106+
const includeDirective = Parser.getIncludeFromDirective(lineContent);
106107

107-
if (foundUri.scheme === `member`) {
108-
const lastIndex = foundUri.path.lastIndexOf(`.`);
109-
if (lastIndex >= 0) {
110-
displayName = foundUri.path.substring(0, lastIndex);
111-
} else {
112-
displayName = foundUri.path;
113-
}
108+
if (includeDirective && parser.includeFileFetch) {
109+
const include = await parser.includeFileFetch(currentPath, includeDirective);
110+
let displayName = includeDirective;
114111

115-
if (displayName.startsWith(`/`)) displayName = displayName.substring(1);
112+
if (include.found && include.uri) {
113+
const foundUri = URI.parse(include.uri);
116114

115+
if (foundUri.scheme === `member`) {
116+
const lastIndex = foundUri.path.lastIndexOf(`.`);
117+
if (lastIndex >= 0) {
118+
displayName = foundUri.path.substring(0, lastIndex);
117119
} else {
118120
displayName = foundUri.path;
119121
}
120-
}
121122

122-
return {
123-
contents: {
124-
kind: MarkupKind.Markdown,
125-
value: (include.found ? `\`${displayName}\`` : includeDirective) + ` (${include.found ? `found` : `not found`})`
126-
}
127-
};
123+
if (displayName.startsWith(`/`)) displayName = displayName.substring(1);
124+
125+
} else {
126+
displayName = foundUri.path;
127+
}
128128
}
129+
130+
return {
131+
contents: {
132+
kind: MarkupKind.Markdown,
133+
value: (include.found ? `\`${displayName}\`` : includeDirective) + ` (${include.found ? `found` : `not found`})`
134+
}
135+
};
129136
}
130137
}
131138
}

language/models/cache.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,7 @@ export default class Cache {
177177
findAll(name: string): Declaration[] {
178178
name = name.toUpperCase();
179179
const symbols = this.symbolRegister.get(name);
180-
if (symbols) {
181-
return Array.isArray(symbols) ? symbols : [symbols];
182-
}
183-
184-
return [];
180+
return symbols || [];
185181
}
186182

187183
public findProcedurebyLine(lineNumber: number): Declaration | undefined {

0 commit comments

Comments
 (0)