handle semantic token delta & range request

This commit is contained in:
全卓 2022-12-02 13:57:38 +08:00
parent 28098c9c12
commit 8a519d8dc4
2 changed files with 66 additions and 24 deletions

View File

@ -56,6 +56,16 @@ enum TokenTypes {
export const tokenBuilders: Map<string, SemanticTokensBuilder> = new Map(); export const tokenBuilders: Map<string, SemanticTokensBuilder> = new Map();
export function getTokenBuilder(uri: string): SemanticTokensBuilder {
let builder = tokenBuilders.get(uri);
if (builder !== undefined) {
return builder;
}
builder = new SemanticTokensBuilder();
tokenBuilders.set(uri, builder);
return builder;
}
export function getTokenTypes(): string[] { export function getTokenTypes(): string[] {
tokenTypes = tokenTypes.filter((value, index, arr) => { tokenTypes = tokenTypes.filter((value, index, arr) => {
return initParams.capabilities.textDocument.semanticTokens.tokenTypes.includes(value); return initParams.capabilities.textDocument.semanticTokens.tokenTypes.includes(value);
@ -71,7 +81,7 @@ export function getTokenModifiers(): string[] {
} }
export class SemanticListener extends CMakeListener { export class SemanticListener extends CMakeListener {
private _data: number[] = []; // private _data: number[] = [];
private _builder: SemanticTokensBuilder; private _builder: SemanticTokensBuilder;
private _uri: URI; private _uri: URI;
@ -87,7 +97,7 @@ export class SemanticListener extends CMakeListener {
constructor(uri: URI) { constructor(uri: URI) {
super(); super();
this._uri = uri; this._uri = uri;
this._builder = this.getTokenBuilder(uri.toString()); this._builder = getTokenBuilder(uri.toString());
} }
private isOperator(token: string): boolean { private isOperator(token: string): boolean {
@ -107,16 +117,20 @@ export class SemanticListener extends CMakeListener {
return result; return result;
} }
private getTokenBuilder(uri: string): SemanticTokensBuilder { public buildEdits() {
let result = tokenBuilders.get(uri); return this._builder.buildEdits();
if (result !== undefined) {
return result;
} }
result = new SemanticTokensBuilder(); // private getTokenBuilder(uri: string): SemanticTokensBuilder {
tokenBuilders.set(uri, result); // let result = tokenBuilders.get(uri);
return result; // if (result !== undefined) {
} // return result;
// }
// result = new SemanticTokensBuilder();
// tokenBuilders.set(uri, result);
// return result;
// }
private getCmdKeyWords(sigs: string[]): string[] { private getCmdKeyWords(sigs: string[]): string[] {
let result: string[] = []; let result: string[] = [];

View File

@ -1,7 +1,8 @@
import { import {
createConnection, DidChangeConfigurationNotification, HoverParams, InitializeParams, InitializeResult, createConnection, DidChangeConfigurationNotification, DidChangeConfigurationParams,
LSPAny, HoverParams, InitializedParams, InitializeParams, InitializeResult, ProposedFeatures,
ProposedFeatures, SemanticTokensParams, SignatureHelpParams, TextDocuments, TextDocumentSyncKind SemanticTokensDeltaParams, SemanticTokensParams, SemanticTokensRangeParams,
SignatureHelpParams, TextDocumentChangeEvent, TextDocuments, TextDocumentSyncKind
} from 'vscode-languageserver/node'; } from 'vscode-languageserver/node';
import { import {
@ -17,17 +18,17 @@ import { exec } from 'child_process';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
import { URI, Utils } from 'vscode-uri'; import { URI, Utils } from 'vscode-uri';
import * as builtinCmds from './builtin-cmds.json'; import * as builtinCmds from './builtin-cmds.json';
import { cmakeInfo } from './cmakeInfo';
import CMakeErrorListener from './diagnostics';
import { SymbolListener } from './docSymbols'; import { SymbolListener } from './docSymbols';
import { FormatListener } from './format'; import { FormatListener } from './format';
import antlr4 from './parser/antlr4/index.js'; import antlr4 from './parser/antlr4/index.js';
import CMakeLexer from './parser/CMakeLexer.js'; import CMakeLexer from './parser/CMakeLexer.js';
import CMakeParser from './parser/CMakeParser.js'; import CMakeParser from './parser/CMakeParser.js';
import { getTokenModifiers, getTokenTypes, SemanticListener, tokenBuilders } from './semanticTokens'; import { getTokenBuilder, getTokenModifiers, getTokenTypes, SemanticListener, tokenBuilders } from './semanticTokens';
import { extSettings } from './settings';
import { DefinationListener, incToBaseDir, refToDef, topScope } from './symbolTable/goToDefination'; import { DefinationListener, incToBaseDir, refToDef, topScope } from './symbolTable/goToDefination';
import { getFileContext } from './utils'; import { getFileContext } from './utils';
import ExtensionSettings, { extSettings } from './settings';
import { cmakeInfo } from './cmakeInfo';
import CMakeErrorListener from './diagnostics';
type Word = { type Word = {
text: string, text: string,
@ -67,7 +68,9 @@ connection.onInitialize(async (params: InitializeParams) => {
tokenModifiers: getTokenModifiers() tokenModifiers: getTokenModifiers()
}, },
range: false, range: false,
full: true full: {
delta: true
}
} }
}, },
serverInfo: { serverInfo: {
@ -79,7 +82,7 @@ connection.onInitialize(async (params: InitializeParams) => {
return result; return result;
}); });
connection.onInitialized(async () => { connection.onInitialized(async (params: InitializedParams) => {
console.log("Initialized"); console.log("Initialized");
connection.client.register(DidChangeConfigurationNotification.type, undefined); connection.client.register(DidChangeConfigurationNotification.type, undefined);
await extSettings.getSettings(); await extSettings.getSettings();
@ -330,6 +333,31 @@ connection.languages.semanticTokens.on(async (params: SemanticTokensParams) => {
return semanticListener.getSemanticTokens(); return semanticListener.getSemanticTokens();
}); });
connection.languages.semanticTokens.onDelta((params: SemanticTokensDeltaParams) => {
const document = documents.get(params.textDocument.uri);
if (document === undefined) {
return {
edits: []
};
}
const builder = getTokenBuilder(document.uri);
builder.previousResult(params.previousResultId);
const docuUri: URI = URI.parse(document.uri);
const tree = getFileContext(docuUri);
const semanticListener = new SemanticListener(docuUri);
antlr4.tree.ParseTreeWalker.DEFAULT.walk(semanticListener, tree);
return semanticListener.buildEdits();
});
connection.languages.semanticTokens.onRange((params: SemanticTokensRangeParams) => {
return {
data: []
};
});
/** /**
* @param params This argument is null when configuration changed * @param params This argument is null when configuration changed
* *
@ -346,13 +374,13 @@ connection.languages.semanticTokens.on(async (params: SemanticTokensParams) => {
* https://github.com/microsoft/vscode/issues/54821 * https://github.com/microsoft/vscode/issues/54821
* https://github.com/microsoft/vscode-languageserver-node/issues/380 * https://github.com/microsoft/vscode-languageserver-node/issues/380
*/ */
connection.onDidChangeConfiguration(params => { connection.onDidChangeConfiguration((params: DidChangeConfigurationParams) => {
extSettings.getSettings(); extSettings.getSettings();
}); });
// The content of a text document has changed. This event is emitted // The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed. // when the text document first opened or when its content has changed.
documents.onDidChangeContent(change => { documents.onDidChangeContent((change: TextDocumentChangeEvent<TextDocument>) => {
contentChanged = true; contentChanged = true;
// const document = documents.get(change.document.uri); // const document = documents.get(change.document.uri);
@ -372,7 +400,7 @@ documents.onDidChangeContent(change => {
}); });
}); });
documents.onDidClose(event => { documents.onDidClose((event: TextDocumentChangeEvent<TextDocument>) => {
tokenBuilders.delete(event.document.uri); tokenBuilders.delete(event.document.uri);
}); });