Skip to content

Commit

Permalink
feat: Add semantic token highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
famoser committed Mar 3, 2024
1 parent 6a6ca86 commit ca39f7b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 31 deletions.
56 changes: 32 additions & 24 deletions server/src/semantic_token_provider.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
import {integer, SemanticTokensBuilder} from 'vscode-languageserver';
import {SemanticTokensBuilder} from 'vscode-languageserver';
import {DocumentManagerInterface, ParseResult} from './document_manager';
import {collectIdentTerminals, collectMatchingTerminals} from "./parseTree/collect_terminals";
import {definitionSymbolsEqual, getDefinitionSymbolFromMatch} from "./go_to_definition";
import {collectIdentTerminals} from "./parseTree/collect_terminals";
import {getDefinitionSymbolFromMatch} from "./go_to_definition";
import {nonNullable} from "./utils/array";
import {notNull} from "antlr4ts/misc";
import {DeclarationType} from "./tasks/create_symbol_table";

export const tokenModifier = ['declaration', 'deprecated'];
export const tokenTypes = ['function', 'variable', 'parameter', 'event'];
export const tokenModifier = [];
export const tokenTypes = ['function', 'variable', 'parameter'];

export const getSemanticTokens = async (parseResult: ParseResult, documentManager: DocumentManagerInterface) => {
// collect references
const candidateTerminals = collectIdentTerminals(parseResult.parserTree);
const terminalDefinitions = candidateTerminals
.map(async terminal => getDefinitionSymbolFromMatch(parseResult, terminal, documentManager));

const tokensBuilder = new SemanticTokensBuilder();
const tokensBuilder = new SemanticTokensBuilder();
(await Promise.all(terminalDefinitions))
.filter(nonNullable)
.filter(nonNullable)
.forEach(terminalDefinition => {
const tokenType = getTokenType(terminalDefinition.symbol.declaration)
if (tokenType) {
const line = terminalDefinition.origin.match.symbol.line - 1;
const char = terminalDefinition.origin.match.symbol.charPositionInLine;
const length = terminalDefinition.origin.match.symbol.stopIndex - terminalDefinition.origin.match.symbol.startIndex + 1;
tokensBuilder.push(line, char, length, tokenType, [] as any)
}
const tokenType = getTokenType(terminalDefinition.symbol.declaration);
if (tokenType) {
const line = terminalDefinition.origin.match.symbol.line - 1;
const char = terminalDefinition.origin.match.symbol.charPositionInLine;
const length = terminalDefinition.origin.match.symbol.stopIndex - terminalDefinition.origin.match.symbol.startIndex + 1;
tokensBuilder.push(line, char, length, tokenType, [] as any);
}
});

return tokensBuilder.build();
};

const getTokenType = (declarationType: DeclarationType): number|undefined => {
switch (declarationType) {
case DeclarationType.Channel:
case DeclarationType.Free:
case DeclarationType.Const:
return tokenTypes.indexOf('variable')
}
const getTokenType = (declarationType: DeclarationType): number | undefined => {
switch (declarationType) {
case DeclarationType.Channel:
case DeclarationType.Free:
case DeclarationType.Const:
case DeclarationType.Variable:
return tokenTypes.indexOf('variable');
case DeclarationType.Fun:
case DeclarationType.LetFun:
case DeclarationType.Event:
return tokenTypes.indexOf('function');
case DeclarationType.Parameter:
case DeclarationType.DefineParameter:
case DeclarationType.ExpandParameter:
return tokenTypes.indexOf('parameter');
}

return undefined
}
return undefined;
};
2 changes: 0 additions & 2 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ connection.languages.semanticTokens.on(async params => {
return new ResponseError(3, 'Semantic tokens extraction failed', undefined);
}

console.log(semanticTokens)

return semanticTokens;
});

Expand Down
11 changes: 6 additions & 5 deletions server/src/tasks/create_symbol_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const createSymbolTable = (context: ParseTree): CreateSymbolTableResult =

export enum DeclarationType {
Parameter = 'parameter',
Variable = 'variable',

Const = 'const',
Channel = 'channel',
Expand Down Expand Up @@ -135,24 +136,24 @@ class SymbolTableVisitor extends AbstractParseTreeVisitor<ProverifSymbolTable> i
return this.withContext(ctx, () => {
if (ctx.LET() || ctx.IN()) {
collectTPattern(ctx.tpattern()).forEach(typedTerminal => {
this.registerTypedTerminal(typedTerminal, DeclarationType.Parameter);
this.registerTypedTerminal(typedTerminal, DeclarationType.Variable);
});

if (ctx.LET()) {
collectNevartype(ctx.nevartype()).forEach(typedTerminal => {
this.registerTypedTerminal(typedTerminal, DeclarationType.Parameter);
this.registerTypedTerminal(typedTerminal, DeclarationType.Variable);
});
}
} else if (ctx.GET()) {
collectTPatternSeq(ctx.tpatternseq()).forEach(typedTerminal => {
this.registerTypedTerminal(typedTerminal, DeclarationType.Parameter);
this.registerTypedTerminal(typedTerminal, DeclarationType.Variable);
});
} else if (ctx.NEW() || ctx.RANDOM()) {
const type = getType(ctx.typeid());
this.registerTerminal(ctx.IDENT()[0], DeclarationType.Parameter, type);
this.registerTerminal(ctx.IDENT()[0], DeclarationType.Variable, type);
} else if (ctx.LEFTARROW()) {
const typedTerminal = collectBasicpattern(ctx.basicpattern());
this.registerTypedTerminal(typedTerminal, DeclarationType.Parameter);
this.registerTypedTerminal(typedTerminal, DeclarationType.Variable);
}

return this.visitChildren(ctx);
Expand Down
5 changes: 5 additions & 0 deletions syntaxes/pv.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@
"end": "(?=})",
"patterns" : [{ "include": "$self"}]
},
{
"begin" : "\\(",
"end" : "\\)",
"patterns" : [{ "include": "#comments"}]
},
{ "include": "#fun_ident" }
]
},
Expand Down

0 comments on commit ca39f7b

Please sign in to comment.