Skip to content

Commit fb19719

Browse files
committed
Initial commit of CodeLens integration (work in progress)
1 parent 8605870 commit fb19719

File tree

5 files changed

+106
-18
lines changed

5 files changed

+106
-18
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @fileoverview Handles all CodeLens logic for Apache Dispatcher Config files.
3+
* @author Darian Benam <[email protected]>
4+
*/
5+
6+
import { ApacheDispatcherConfigToken } from "@language-server/core/tree-sitter";
7+
import { removeOuterQuotes } from "@language-server/utils/string";
8+
import { CodeLens, Command, Range } from "vscode-languageserver";
9+
import Parser = require("web-tree-sitter");
10+
11+
function containsEnvironmentVariable(value: string): boolean {
12+
return /\$\{.*?\}/.test(value);
13+
}
14+
15+
export function getCodeLensDefinitions(syntaxTree: Parser.Tree | undefined): CodeLens[] {
16+
if (syntaxTree === undefined) {
17+
return [];
18+
}
19+
20+
const codeLensDefinitions: CodeLens[] = [];
21+
const syntaxNodeStack: Parser.SyntaxNode[] = [ syntaxTree.rootNode ];
22+
23+
while (syntaxNodeStack.length > 0) {
24+
const syntaxNode: Parser.SyntaxNode | undefined = syntaxNodeStack.pop();
25+
26+
if (syntaxNode === undefined || syntaxNode.hasError()) {
27+
continue;
28+
}
29+
30+
const syntaxNodeValue: string = removeOuterQuotes(syntaxNode.text);
31+
32+
if (
33+
syntaxNode.type === ApacheDispatcherConfigToken.String &&
34+
containsEnvironmentVariable(syntaxNodeValue)
35+
) {
36+
const range: Range = {
37+
start: {
38+
line: syntaxNode.startPosition.row,
39+
character: syntaxNode.startPosition.column
40+
},
41+
end: {
42+
line: syntaxNode.endPosition.row,
43+
character: syntaxNode.endPosition.column
44+
}
45+
};
46+
47+
// TODO: Look into creating a lookup table for environment variables under the /conf.d/variables folder
48+
codeLensDefinitions.push({
49+
range: range,
50+
command: Command.create(`"${syntaxNodeValue}" resolves to ""`, "")
51+
});
52+
}
53+
54+
for (const childNode of syntaxNode.children) {
55+
syntaxNodeStack.push(childNode);
56+
}
57+
}
58+
59+
return codeLensDefinitions;
60+
}

server/src/core/definition-provider.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { INCLUDE_FUNCTION_NAME } from "@language-server/constants/function";
77
import { DocumentParserTreeManager } from "@language-server/core/document-parser-tree-manager";
88
import { ApacheDispatcherConfigToken, getCurrentSyntaxNode } from "@language-server/core/tree-sitter";
99
import { FileExistenceContext, getFileExistenceContext } from "@language-server/utils/file-system";
10+
import { removeOuterQuotes } from "@language-server/utils/string";
1011
import {
1112
DefinitionLink,
1213
DefinitionParams,
@@ -19,22 +20,6 @@ import Parser = require("web-tree-sitter");
1920
const START_POSITION: Position = Position.create(0, 0);
2021
const START_POSITION_RANGE: Range = Range.create(START_POSITION, START_POSITION);
2122

22-
function isSingleQuoteString(text: string): boolean {
23-
return text.startsWith("'") && text.endsWith("'");
24-
}
25-
26-
function isDoubleQuoteString(text: string): boolean {
27-
return text.startsWith("\"") && text.endsWith("\"");
28-
}
29-
30-
function removeOuterQuotes(text: string): string {
31-
if (isSingleQuoteString(text) || isDoubleQuoteString(text)) {
32-
return text.substring(1, text.length - 1);
33-
}
34-
35-
return text;
36-
}
37-
3823
export async function getDefinition(
3924
documentParserTreeManager: DocumentParserTreeManager,
4025
definitionParams: DefinitionParams

server/src/core/document-parser-tree-manager.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
* @author Darian Benam <[email protected]>
44
*/
55

6+
import { getCodeLensDefinitions } from "@language-server/core/codelens-provider";
67
import {
78
ApacheDispatcherConfigToken,
89
loadApacheDispatcherConfigTreeSitterLanguage,
910
tokenizeTextDocument
1011
} from "@language-server/core/tree-sitter";
11-
import { DocumentSymbol, SymbolKind, TextDocuments } from "vscode-languageserver";
12+
import { CodeLens, DocumentSymbol, SymbolKind, TextDocuments } from "vscode-languageserver";
1213
import { Range, TextDocument } from "vscode-languageserver-textdocument";
1314
import Parser = require("web-tree-sitter");
1415

@@ -98,7 +99,6 @@ export class DocumentParserTreeManager {
9899
};
99100
}
100101

101-
102102
private getApacheDispatcherConfigTokenSymbolKind(tokenType: ApacheDispatcherConfigToken): SymbolKind {
103103
switch (tokenType) {
104104
case ApacheDispatcherConfigToken.Function:
@@ -194,6 +194,10 @@ export class DocumentParserTreeManager {
194194
return rootSymbols;
195195
}
196196

197+
public getDocumentCodeLensDefinitions(documentUri: string): CodeLens[] {
198+
return getCodeLensDefinitions(this.documentParseTree.get(documentUri))
199+
}
200+
197201
public updateParseTree(document: TextDocument): void {
198202
if (this.treeSitterParser === undefined) {
199203
throw new Error("Tree-sitter parser has not been initialized!");

server/src/server.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import * as path from "path";
1212
import { TextDocument } from "vscode-languageserver-textdocument";
1313
import {
1414
ClientCapabilities,
15+
CodeLens,
16+
CodeLensParams,
1517
CompletionItem,
1618
Connection,
1719
DefinitionLink,
@@ -50,6 +52,9 @@ CONNECTION.onInitialize(async function(initializeParams: InitializeParams): Prom
5052

5153
const result: InitializeResult = {
5254
capabilities: {
55+
codeLensProvider: {
56+
resolveProvider: true
57+
},
5358
completionProvider: {
5459
triggerCharacters: AUTOCOMPLETION_TRIGGER_CHARACTERS
5560
},
@@ -85,6 +90,20 @@ CONNECTION.onInitialized(async function(): Promise<void> {
8590
console.info("Language server initialized.");
8691
});
8792

93+
CONNECTION.onCodeLens(async function(params: CodeLensParams): Promise<CodeLens[]> {
94+
if (documentParserTreeManager === undefined) {
95+
await waitForDocumentParserTreeManagerInitialization(documentParserTreeManager);
96+
}
97+
98+
const document: TextDocument | undefined = DOCUMENT_MANAGER.get(params.textDocument.uri);
99+
100+
if (document === undefined) {
101+
return [];
102+
}
103+
104+
return documentParserTreeManager.getDocumentCodeLensDefinitions(document.uri);
105+
});
106+
88107
CONNECTION.onCompletion(
89108
async (textDocumentPositionParams: TextDocumentPositionParams): Promise<CompletionItem[]> => {
90109
return await handleAutoCompletion(

server/src/utils/string.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @fileoverview Miscellaneous utility functions for dealing with strings.
3+
* @author Darian Benam <[email protected]>
4+
*/
5+
6+
function isSingleQuoteString(text: string): boolean {
7+
return text.startsWith("'") && text.endsWith("'");
8+
}
9+
10+
function isDoubleQuoteString(text: string): boolean {
11+
return text.startsWith("\"") && text.endsWith("\"");
12+
}
13+
14+
export function removeOuterQuotes(text: string): string {
15+
if (isSingleQuoteString(text) || isDoubleQuoteString(text)) {
16+
return text.substring(1, text.length - 1);
17+
}
18+
19+
return text;
20+
}

0 commit comments

Comments
 (0)