Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d2c340c
Initial plan
Copilot Dec 21, 2025
5558f86
Add support for textDocument/semanticTokens/full/delta
Copilot Dec 21, 2025
ca23cbc
Clear semantic tokens cache when document is closed
Copilot Dec 21, 2025
bcfca7a
Add ServerContextDocumentClosedEvent for document close notification
Copilot Dec 21, 2025
dd1767d
Add given/when/then comments to delta tokens tests
Copilot Dec 21, 2025
326065c
Add delta size optimization: return full tokens when delta is larger
Copilot Dec 21, 2025
a348e8a
Remove redundant delta size optimization - algorithm already computes…
Copilot Dec 21, 2025
e24445a
Add debug logging for delta computation to diagnose large deleteCount…
Copilot Dec 22, 2025
c573c50
Merge branch 'develop' into copilot/support-semantic-tokens-delta
nixel2007 Dec 26, 2025
bc7b28d
Merge branch 'develop' into copilot/support-semantic-tokens-delta
nixel2007 Dec 26, 2025
05dbd20
Параллельное вычисление сапплаеров семантических токенов + оптимизаци…
nixel2007 Dec 27, 2025
d32ed49
Убран лишний вызов Absolute где возможно
nixel2007 Dec 27, 2025
bffa3e7
Рефакторинг
nixel2007 Dec 27, 2025
ab6b235
Исправлены тесты: нормализация URI через Absolute.uri()
Copilot Dec 27, 2025
a973c76
Документация: semanticTokens/full/delta теперь поддерживается
Copilot Dec 27, 2025
2c48c95
Удалён отладочный вывод из SemanticTokensProvider
Copilot Dec 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Perfomance measurement - [SSL 3.1](../bench/index.html)
| [callHierarchy/incomingCalls](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_incomingCalls) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [callHierarchy/outgoingCalls](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_outgoingCalls) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [semanticTokens/full](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | multilineTokenSupport = true | |
| [semanticTokens/full/delta](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [semanticTokens/full/delta](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [semanticTokens/range](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [linkedEditingRange](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_linkedEditingRange) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [moniker](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_moniker) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
| [callHierarchy/incomingCalls](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_incomingCalls) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [callHierarchy/outgoingCalls](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_outgoingCalls) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [semanticTokens/full](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | multilineTokenSupport = true | |
| [semanticTokens/full/delta](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [semanticTokens/full/delta](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/checkmark.svg" alt="yes" width="20"> | | |
| [semanticTokens/range](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [linkedEditingRange](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_linkedEditingRange) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
| [moniker](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_moniker) | <img src="./assets/images/cross.svg" alt="no" width="20"> | | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.eclipse.lsp4j.SaveOptions;
import org.eclipse.lsp4j.SelectionRangeRegistrationOptions;
import org.eclipse.lsp4j.SemanticTokensLegend;
import org.eclipse.lsp4j.SemanticTokensServerFull;
import org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.ServerInfo;
Expand Down Expand Up @@ -379,7 +380,11 @@ private ExecuteCommandOptions getExecuteCommandProvider() {

private SemanticTokensWithRegistrationOptions getSemanticTokensProvider() {
var semanticTokensProvider = new SemanticTokensWithRegistrationOptions(legend);
semanticTokensProvider.setFull(Boolean.TRUE);

var fullOptions = new SemanticTokensServerFull();
fullOptions.setDelta(Boolean.TRUE);
semanticTokensProvider.setFull(fullOptions);

semanticTokensProvider.setRange(Boolean.FALSE);
return semanticTokensProvider;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
import org.eclipse.lsp4j.SelectionRange;
import org.eclipse.lsp4j.SelectionRangeParams;
import org.eclipse.lsp4j.SemanticTokens;
import org.eclipse.lsp4j.SemanticTokensDelta;
import org.eclipse.lsp4j.SemanticTokensDeltaParams;
import org.eclipse.lsp4j.SemanticTokensParams;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.TextDocumentClientCapabilities;
Expand Down Expand Up @@ -176,7 +178,7 @@ private void onDestroy() {

@Override
public CompletableFuture<@Nullable Hover> hover(HoverParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -191,7 +193,7 @@ private void onDestroy() {
public CompletableFuture<Either<List<? extends Location>, List<? extends LocationLink>>> definition(
DefinitionParams params
) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Either.forRight(Collections.emptyList()));
}
Expand All @@ -211,7 +213,7 @@ public CompletableFuture<Either<List<? extends Location>, List<? extends Locatio

@Override
public CompletableFuture<List<? extends Location>> references(ReferenceParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -226,7 +228,7 @@ public CompletableFuture<List<? extends Location>> references(ReferenceParams pa
public CompletableFuture<List<Either<SymbolInformation, DocumentSymbol>>> documentSymbol(
DocumentSymbolParams params
) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -241,7 +243,7 @@ public CompletableFuture<List<Either<SymbolInformation, DocumentSymbol>>> docume

@Override
public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -254,7 +256,7 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio

@Override
public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -268,7 +270,7 @@ public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams param
@Override
public CompletableFuture<CodeLens> resolveCodeLens(CodeLens unresolved) {
var data = codeLensProvider.extractData(unresolved);
var documentContext = context.getDocument(data.getUri());
var documentContext = context.getDocumentUnsafe(data.getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(unresolved);
}
Expand All @@ -280,7 +282,7 @@ public CompletableFuture<CodeLens> resolveCodeLens(CodeLens unresolved) {

@Override
public CompletableFuture<List<? extends TextEdit>> formatting(DocumentFormattingParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -293,7 +295,7 @@ public CompletableFuture<List<? extends TextEdit>> formatting(DocumentFormatting

@Override
public CompletableFuture<List<? extends TextEdit>> rangeFormatting(DocumentRangeFormattingParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -306,7 +308,7 @@ public CompletableFuture<List<? extends TextEdit>> rangeFormatting(DocumentRange

@Override
public CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -320,7 +322,7 @@ public CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestPar
@Override
public CompletableFuture<@Nullable List<CallHierarchyItem>> prepareCallHierarchy(CallHierarchyPrepareParams params) {
// При возврате пустого списка VSCode падает. По протоколу разрешен возврат null.
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -339,7 +341,7 @@ public CompletableFuture<List<FoldingRange>> foldingRange(FoldingRangeRequestPar

@Override
public CompletableFuture<SemanticTokens> semanticTokensFull(SemanticTokensParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -350,13 +352,26 @@ public CompletableFuture<SemanticTokens> semanticTokensFull(SemanticTokensParams
);
}

@Override
public CompletableFuture<Either<SemanticTokens, SemanticTokensDelta>> semanticTokensFullDelta(
SemanticTokensDeltaParams params
) {
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}

return withFreshDocumentContext(
documentContext,
() -> semanticTokensProvider.getSemanticTokensFullDelta(documentContext, params)
);
}

@Override
public CompletableFuture<List<CallHierarchyIncomingCall>> callHierarchyIncomingCalls(
CallHierarchyIncomingCallsParams params
) {
var documentContext = context.getDocument(params.getItem().getUri());
var documentContext = context.getDocumentUnsafe(params.getItem().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -371,7 +386,7 @@ public CompletableFuture<List<CallHierarchyIncomingCall>> callHierarchyIncomingC
public CompletableFuture<List<CallHierarchyOutgoingCall>> callHierarchyOutgoingCalls(
CallHierarchyOutgoingCallsParams params
) {
var documentContext = context.getDocument(params.getItem().getUri());
var documentContext = context.getDocumentUnsafe(params.getItem().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -384,7 +399,7 @@ public CompletableFuture<List<CallHierarchyOutgoingCall>> callHierarchyOutgoingC

@Override
public CompletableFuture<List<@Nullable SelectionRange>> selectionRange(SelectionRangeParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -397,7 +412,7 @@ public CompletableFuture<List<CallHierarchyOutgoingCall>> callHierarchyOutgoingC

@Override
public CompletableFuture<List<ColorInformation>> documentColor(DocumentColorParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -410,7 +425,7 @@ public CompletableFuture<List<ColorInformation>> documentColor(DocumentColorPara

@Override
public CompletableFuture<List<ColorPresentation>> colorPresentation(ColorPresentationParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand All @@ -423,7 +438,7 @@ public CompletableFuture<List<ColorPresentation>> colorPresentation(ColorPresent

@Override
public CompletableFuture<List<InlayHint>> inlayHint(InlayHintParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
Expand Down Expand Up @@ -459,7 +474,7 @@ public void didOpen(DidOpenTextDocumentParams params) {

@Override
public void didChange(DidChangeTextDocumentParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return;
}
Expand All @@ -486,7 +501,7 @@ public void didChange(DidChangeTextDocumentParams params) {

@Override
public void didClose(DidCloseTextDocumentParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return;
}
Expand Down Expand Up @@ -515,7 +530,7 @@ public void didClose(DidCloseTextDocumentParams params) {

@Override
public void didSave(DidSaveTextDocumentParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return;
}
Expand All @@ -527,7 +542,7 @@ public void didSave(DidSaveTextDocumentParams params) {

@Override
public CompletableFuture<List<DocumentLink>> documentLink(DocumentLinkParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -540,7 +555,7 @@ public CompletableFuture<List<DocumentLink>> documentLink(DocumentLinkParams par

@Override
public CompletableFuture<Diagnostics> diagnostics(DiagnosticParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(Diagnostics.EMPTY);
}
Expand All @@ -563,7 +578,7 @@ public CompletableFuture<Diagnostics> diagnostics(DiagnosticParams params) {

@Override
public CompletableFuture<DocumentDiagnosticReport> diagnostic(DocumentDiagnosticParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(
new DocumentDiagnosticReport(new RelatedFullDocumentDiagnosticReport(Collections.emptyList()))
Expand All @@ -578,7 +593,7 @@ public CompletableFuture<DocumentDiagnosticReport> diagnostic(DocumentDiagnostic

@Override
public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaultBehavior>> prepareRename(PrepareRenameParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand All @@ -591,7 +606,7 @@ public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaul

@Override
public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
var documentContext = context.getDocument(params.getTextDocument().getUri());
var documentContext = context.getDocumentUnsafe(params.getTextDocument().getUri());
if (documentContext == null) {
return CompletableFuture.completedFuture(null);
}
Expand Down
Loading