Skip to content

Commit

Permalink
Ability to switch back to original Java LS semantic tokens via setting
Browse files Browse the repository at this point in the history
  • Loading branch information
BoykoAlex committed Jun 6, 2024
1 parent 64dc2d0 commit d2373fb
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.Registration;
import org.eclipse.lsp4j.RegistrationParams;
import org.eclipse.lsp4j.SemanticTokensCapabilities;
import org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.SetTraceParams;
Expand Down Expand Up @@ -546,8 +547,12 @@ protected final ServerCapabilities getServerCapabilities() {
c.setWorkspaceSymbolProvider(true);
}
// TODO: Check if server supports all token types from the legend
SemanticTokensWithRegistrationOptions semanticTokensCapability = getTextDocumentService().getSemanticTokensWithRegistrationOptions();
c.setSemanticTokensProvider(semanticTokensCapability);
// Eclipse LSP4E client gives `null` semantic tokens client capability yet it works up to dynamic registration
SemanticTokensCapabilities clientSemanticTokensCapability = getTextDocumentService().clientCapabilities.getSemanticTokens();
if (clientSemanticTokensCapability == null || clientSemanticTokensCapability.getDynamicRegistration() == null || !clientSemanticTokensCapability.getDynamicRegistration().booleanValue()) {
SemanticTokensWithRegistrationOptions semanticTokensCapability = getTextDocumentService().getSemanticTokensWithRegistrationOptions();
c.setSemanticTokensProvider(semanticTokensCapability);
}

WorkspaceFoldersOptions workspaceFoldersOptions = new WorkspaceFoldersOptions();
workspaceFoldersOptions.setSupported(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ public boolean hasCodeLensResolveProvider() {
return this.codeLensResolveHandler != null;
}

final SemanticTokensWithRegistrationOptions getSemanticTokensWithRegistrationOptions() {
public final SemanticTokensWithRegistrationOptions getSemanticTokensWithRegistrationOptions() {
return semanticTokensHandler == null ? null : semanticTokensHandler.getCapability();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public boolean isJpqlEnabled() {
return isEnabled != null && isEnabled.booleanValue();
}

public boolean isJavaEmbeddedLanguagesSyntaxHighlighting() {
Boolean isEnabled = settings.getBoolean("boot-java", "embedded-syntax-highlighting");
return isEnabled != null && isEnabled.booleanValue();
}

public String[] xmlBeansFoldersToScan() {
String foldersStr = settings.getString("boot-java", "support-spring-xml-config", "scan-folders");
if (foldersStr != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.springframework.ide.vscode.boot.java.reconcilers.ServerHttpSecurityLambdaDslReconciler;
import org.springframework.ide.vscode.boot.java.reconcilers.UnnecessarySpringExtensionReconciler;
import org.springframework.ide.vscode.boot.java.reconcilers.WebSecurityConfigurerAdapterReconciler;
import org.springframework.ide.vscode.boot.java.semantictokens.EmbeddedLanguagesSemanticTokensSupport;
import org.springframework.ide.vscode.boot.java.semantictokens.JavaSemanticTokensProvider;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;

Expand Down Expand Up @@ -128,5 +129,9 @@ public class JdtConfig {
@Bean QueryJdtAstReconciler dataQueryReconciler(HqlReconciler hqlReconciler, JpqlReconciler jpqlReconciler, SqlReconciler sqlReconciler) {
return new QueryJdtAstReconciler(hqlReconciler, jpqlReconciler, sqlReconciler);
}

@Bean EmbeddedLanguagesSemanticTokensSupport embbededLanguagesSyntaxHighlighting(SimpleLanguageServer server, BootJavaConfig config) {
return new EmbeddedLanguagesSemanticTokensSupport(server, config);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.semantictokens;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import org.eclipse.lsp4j.DocumentFilter;
import org.eclipse.lsp4j.Registration;
import org.eclipse.lsp4j.RegistrationParams;
import org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions;
import org.eclipse.lsp4j.Unregistration;
import org.eclipse.lsp4j.UnregistrationParams;
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.util.text.LanguageId;

public class EmbeddedLanguagesSemanticTokensSupport {

private static final String CAPABILITY = "textDocument/semanticTokens";

private final SimpleLanguageServer server;
private boolean enabled;

private String registrationId;
private boolean initialized;

public EmbeddedLanguagesSemanticTokensSupport(SimpleLanguageServer server, BootJavaConfig config) {
this.server = server;
this.enabled = false;
this.initialized = false;
this.registrationId = null;
config.addListener(v -> setEnabled(config.isJavaEmbeddedLanguagesSyntaxHighlighting()));
}

public synchronized boolean isEnabled() {
return enabled;
}

private synchronized void setEnabled(boolean enabled) {
if (!initialized || this.enabled != enabled) {
this.initialized = true;
this.enabled = enabled;
SemanticTokensWithRegistrationOptions semanticTokensCapability = server.getTextDocumentService()
.getSemanticTokensWithRegistrationOptions();
if (semanticTokensCapability != null) {
List<DocumentFilter> newDocSelectors = semanticTokensCapability.getDocumentSelector().stream()
.filter(s -> !LanguageId.JAVA.getId().equals(s.getLanguage())).toList();
if (newDocSelectors.size() != semanticTokensCapability.getDocumentSelector().size()) {
if (!enabled) {
semanticTokensCapability.setDocumentSelector(newDocSelectors);
}
CompletableFuture<?> unregisterFuture = CompletableFuture.completedFuture(null);
if (this.registrationId != null) {
UnregistrationParams unregisterParams = new UnregistrationParams(
List.of(new Unregistration(this.registrationId, CAPABILITY)));
unregisterFuture = server.getClient().unregisterCapability(unregisterParams)
.thenAccept(v -> this.registrationId = null);
}

unregisterFuture.thenCompose(res -> {
final String registrationId = UUID.randomUUID().toString();
RegistrationParams registerParams = new RegistrationParams(
List.of(new Registration(registrationId, CAPABILITY, semanticTokensCapability)));
return server.getClient().registerCapability(registerParams)
.thenAccept(v -> this.registrationId = registrationId);
});
}

}
}
}

}
5 changes: 5 additions & 0 deletions vscode-extensions/vscode-spring-boot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@
"title": "Features",
"order": 100,
"properties": {
"boot-java.embedded-syntax-highlighting": {
"type": "boolean",
"default": true,
"description": "Syntax Hyghlighting for Languages embedded into Java source code"
},
"boot-java.validation.java.reconcilers": {
"type": "boolean",
"default": true,
Expand Down

0 comments on commit d2373fb

Please sign in to comment.