Add semantic token support#114
Draft
trustytrojan wants to merge 7 commits into
Draft
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds LSP semantic tokens (full) support to the Groovy language server, with a new provider that walks the AST to emit tokens for declarations, method calls, and property accesses.
Changes:
- New
SemanticTokensProviderthat emits LSP delta-encoded tokens by inspectingMethodCallExpression,PropertyExpression, and declaration nodes from theASTNodeVisitor. - Wires
semanticTokensFullintoGroovyServices, caching a provider instance. - Advertises semantic tokens capability with a token-type legend in
GroovyLanguageServer.initialize.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 14 comments.
| File | Description |
|---|---|
| src/main/java/net/prominic/groovyls/providers/SemanticTokensProvider.java | New provider that converts AST nodes into LSP semantic tokens. |
| src/main/java/net/prominic/groovyls/GroovyServices.java | Implements semanticTokensFull and lazily creates the provider. |
| src/main/java/net/prominic/groovyls/GroovyLanguageServer.java | Registers semantic tokens capability and legend in server initialization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+371
to
+377
| // Ensure semantic tokens provider is initialized | ||
| if (semanticTokensProvider == null) { | ||
| semanticTokensProvider = new SemanticTokensProvider(fileContentsTracker, astVisitor); | ||
| } | ||
|
|
||
| // Provide semantic tokens - GDSL symbols are injected before LSP transmission | ||
| return CompletableFuture.completedFuture(semanticTokensProvider.provideFull(textDocument)); |
Comment on lines
+162
to
+163
| int startOffset = lineColToOffset(text, range.getStart().getLine(), range.getStart().getCharacter()); | ||
| int endOffset = lineColToOffset(text, range.getEnd().getLine(), range.getEnd().getCharacter()); |
| int found = findExactTokenOffset(text, name, startOffset, endOffset); | ||
| if (found == -1) return; | ||
|
|
||
| Position pos = toLineCol(text, found); |
| int endOffset = lineColToOffset(text, range.getEnd().getLine(), range.getEnd().getCharacter()); | ||
| if (startOffset < 0 || endOffset <= startOffset) return; | ||
|
|
||
| int found = findExactTokenOffset(text, name, startOffset, endOffset); |
Comment on lines
+183
to
+184
| int endOffsetCtor = lineColToOffset(text, range.getEnd().getLine(), range.getEnd().getCharacter()); | ||
|
|
Comment on lines
+222
to
+229
| private SemanticTokens encodeDeltaTokens(List<Token> tokens) { | ||
| List<Integer> data = new ArrayList<>(); | ||
| int prevLine = 0; | ||
| int prevChar = 0; | ||
| boolean first = true; | ||
| for (Token t : tokens) { | ||
| int deltaLine = first ? t.line : t.line - prevLine; | ||
| int deltaStart = first ? t.startChar : (deltaLine == 0 ? t.startChar - prevChar : t.startChar); |
Comment on lines
+101
to
+105
| SemanticTokensWithRegistrationOptions semanticTokensOptions = new SemanticTokensWithRegistrationOptions(); | ||
| semanticTokensOptions.setLegend(new SemanticTokensLegend( | ||
| SemanticTokensProvider.TOKEN_TYPES, | ||
| Collections.emptyList())); | ||
| semanticTokensOptions.setFull(true); |
| * or comments. Tokens are encoded using the LSP delta format. | ||
| */ | ||
| public class SemanticTokensProvider { | ||
| private final FileContentsTracker fileContentsTracker; |
| "macro","keyword","modifier","comment","string","number","regexp","operator" | ||
| )); | ||
|
|
||
| private final ASTNodeVisitor astVisitor; |
Comment on lines
+243
to
+253
| private int lineColToOffset(String text, int line, int col) { | ||
| if (line < 0) return -1; | ||
| int curLine = 0; | ||
| int offset = 0; | ||
| int len = text.length(); | ||
| while (offset < len && curLine < line) { | ||
| if (text.charAt(offset) == '\n') { | ||
| curLine++; | ||
| } | ||
| offset++; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before
After