Skip to content

Commit

Permalink
Merge pull request #10 from lfortran/dylon/preview
Browse files Browse the repository at this point in the history
Adds hover previews that show symbol definitions
  • Loading branch information
dylon authored Nov 19, 2024
2 parents fd56bcf + 50764e2 commit 6a48b73
Show file tree
Hide file tree
Showing 7 changed files with 471 additions and 104 deletions.
404 changes: 310 additions & 94 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@
"sinon": "^19.0.2",
"ts-sinon": "^2.0.2",
"tsx": "^4.19.2",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"vsce": "^2.15.0"
},
"dependencies": {
"tmp": "^0.2.1",
"vsce": "^2.15.0"
"tmp": "^0.2.1"
}
}
35 changes: 30 additions & 5 deletions server/src/lfortran-language-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import {
CompletionItem,
CompletionItemKind,
CompletionList,
Position,
_Connection,
DefinitionLink,
DefinitionParams,
Diagnostic,
DidChangeConfigurationNotification,
DidChangeConfigurationParams,
DidChangeWatchedFilesParams,
DidChangeTextDocumentParams,
// DidChangeTextDocumentParams,
// DidChangeWatchedFilesParams,
DocumentSymbolParams,
Hover,
HoverParams,
InitializedParams,
InitializeParams,
InitializeResult,
Expand Down Expand Up @@ -99,6 +100,7 @@ export class LFortranLanguageServer {
},
definitionProvider: true,
documentSymbolProvider: true,
hoverProvider: true,
textDocumentSync: TextDocumentSyncKind.Incremental,
}
};
Expand Down Expand Up @@ -302,7 +304,6 @@ export class LFortranLanguageServer {
// }

extractQuery(text: string, line: number, column: number): string | null {
let isIdentifiable = this.isIdentifiable;
let currLine = 0;
let currCol = 0;

Expand Down Expand Up @@ -342,7 +343,7 @@ export class LFortranLanguageServer {
return null;
}

async onCompletion(documentPosition: TextDocumentPositionParams): Promise<CompletionItem[] | CompletionList | undefined> {
onCompletion(documentPosition: TextDocumentPositionParams): CompletionItem[] | CompletionList | undefined {
let uri: string = documentPosition.textDocument.uri;
let document = this.documents.get(uri);
let dictionary = this.dictionaries.get(uri);
Expand All @@ -359,4 +360,28 @@ export class LFortranLanguageServer {
onCompletionResolve(item: CompletionItem): CompletionItem {
return item;
}

onHover(params: HoverParams): Hover | undefined {
let uri: string = params.textDocument.uri;
let document = this.documents.get(uri);
let dictionary = this.dictionaries.get(uri);
if ((document !== undefined) && (dictionary !== undefined)) {
let text: string = document.getText();
let pos: Position = params.position;
let query: string | null = this.extractQuery(text, pos.line, pos.character);
if (query !== null) {
let completion: CompletionItem | undefined =
dictionary.exactLookup(query) as CompletionItem;
let definition: string | undefined = completion?.detail;
if (definition !== undefined) {
return {
contents: {
language: "fortran",
value: definition,
},
};
}
}
}
}
}
1 change: 1 addition & 0 deletions server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ connection.onDidChangeConfiguration(server.onDidChangeConfiguration.bind(server)
// connection.onDidChangeWatchedFiles(server.onDidChangeWatchedFiles.bind(server));
connection.onCompletion(server.onCompletion.bind(server));
connection.onCompletionResolve(server.onCompletionResolve.bind(server));
connection.onHover(server.onHover.bind(server));

documents.onDidClose(server.onDidClose.bind(server));
documents.onDidChangeContent(server.onDidChangeContent.bind(server));
Expand Down
14 changes: 14 additions & 0 deletions server/src/prefix-trie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,20 @@ export class PrefixTrie {
return true;
}

exactLookup(term: string): object | string | undefined {
term = term.toLowerCase();
let curr: PrefixNode | undefined = this.root;
for (let i = 0, k = term.length;
(i < k) && (curr !== undefined);
i++) {
let label: string = term[i];
curr = curr.transition(label);
}
if (curr !== undefined) {
return curr.value;
}
}

lookup(term: string): PrefixIterator {
term = term.toLowerCase();
let curr: PrefixNode | undefined = this.root;
Expand Down
85 changes: 83 additions & 2 deletions server/test/spec/lfortran-language-server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import {
DiagnosticSeverity,
DidChangeConfigurationParams,
DocumentSymbolParams,
Hover,
HoverParams,
InitializeParams,
Location,
MarkedString,
Position,
Range,
RemoteWorkspace,
Expand Down Expand Up @@ -510,7 +513,7 @@ describe("LFortranLanguageServer", () => {
});

describe("onCompletion", () => {
it("completes queries based on indexed terms", async () => {
it("completes queries based on indexed terms", () => {
let text: string = "def foo; def bar; def baz; def qux; def quo; ba";
document.getText.returns(text);

Expand Down Expand Up @@ -581,7 +584,7 @@ describe("LFortranLanguageServer", () => {
};

let actual: CompletionItem[] | CompletionList =
await server.onCompletion(documentPosition);
server.onCompletion(documentPosition);

if (!Array.isArray(actual)) {
actual = (actual as CompletionList).items;
Expand All @@ -603,4 +606,82 @@ describe("LFortranLanguageServer", () => {
assert.deepEqual(actual, expected);
});
});

describe("onHover", () => {
it("displays a symbol's definition", async () => {
let text: string = "def foo; def bar; def baz; def qux; def quo; ba";
document.getText.returns(text);

let symbols: SymbolInformation[] = [
{
name: "foo",
kind: SymbolKind.Function,
location: {
uri: uri,
range: {
start: {
line: 0,
character: 0,
},
end: {
line: 0,
character: 7,
},
},
},
},
{
name: "bar",
kind: SymbolKind.Function,
location: {
uri: uri,
range: {
start: {
line: 0,
character: 9,
},
end: {
line: 0,
character: 16,
},
},
},
},
{
name: "baz",
kind: SymbolKind.Function,
location: {
uri: uri,
range: {
start: {
line: 0,
character: 18,
},
end: {
line: 0,
character: 25,
},
},
},
},
];

server.index(uri, symbols);

let hoverParams: HoverParams = {
textDocument: {
uri: uri,
},
position: {
line: 0,
character: 5,
}
};

let response: Hover = server.onHover(hoverParams);
let contents: MarkedString = response.contents as MarkedString;
assert.equal(contents.language, "fortran");
assert.equal(contents.value, "def foo;");
});
});
});
30 changes: 30 additions & 0 deletions server/test/spec/prefix-trie.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,34 @@ describe("PrefixTrie", () => {
)
);
});

it("can match terms exactly", () => {
fc.assert(
fc.property(
fc.gen(),
fc.uniqueArray(fc.string()),
fc.string(),
(gen, terms: string[], randomQuery: string) => {
let dict: PrefixTrie = PrefixTrie.from(terms);

if (terms.length > 0) {
let exactIndex: number = gen(fc.nat, { max: terms.length - 1 });
let exactQuery: string = terms[exactIndex];
let exactMatch: string = dict.exactLookup(exactQuery) as string;
assert.isDefined(exactMatch);
assert.equal(exactQuery.toLowerCase(), exactMatch.toLowerCase());
}

if (dict.contains(randomQuery)) {
let exactMatch: string | undefined = dict.exactLookup(randomQuery) as string;
assert.isDefined(exactMatch);
assert.equal(randomQuery.toLowerCase(), exactMatch.toLowerCase());
} else {
let exactMatch: string | undefined = dict.exactLookup(randomQuery) as string;
assert.isUndefined(exactMatch);
}
}
)
);
});
});

0 comments on commit 6a48b73

Please sign in to comment.