Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 org.eclipse.lsp4e.test/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tests for language server bundle (Incubation)
Bundle-SymbolicName: org.eclipse.lsp4e.test;singleton:=true
Bundle-Version: 0.16.1.qualifier
Bundle-Version: 0.16.2.qualifier
Fragment-Host: org.eclipse.lsp4e
Bundle-Vendor: Eclipse LSP4E
Bundle-RequiredExecutionEnvironment: JavaSE-21
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.lsp4e.test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</parent>
<artifactId>org.eclipse.lsp4e.test</artifactId>
<packaging>eclipse-test-plugin</packaging>
<version>0.16.1-SNAPSHOT</version>
<version>0.16.2-SNAPSHOT</version>

<properties>
<os-jvm-flags /> <!-- for the default case -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.google.gson.Gson;

public class DynamicRegistrationTest extends AbstractTestWithProject {

private static final String WORKSPACE_EXECUTE_COMMAND = "workspace/executeCommand";
Expand Down Expand Up @@ -143,7 +141,7 @@ private UUID registerWatchedFiles() throws Exception {
final var watcher = new org.eclipse.lsp4j.FileSystemWatcher(
org.eclipse.lsp4j.jsonrpc.messages.Either.forLeft("**/*.txt"), null);
options.setWatchers(List.of(watcher));
registration.setRegisterOptions(new Gson().toJsonTree(options));
registration.setRegisterOptions(options);
client.registerCapability(new RegistrationParams(List.of(registration))).get(1, TimeUnit.SECONDS);
return id;
}
Expand All @@ -165,7 +163,7 @@ private UUID registerCommands(String... command) throws Exception {
final var registration = new Registration();
registration.setId(id.toString());
registration.setMethod(WORKSPACE_EXECUTE_COMMAND);
registration.setRegisterOptions(new Gson().toJsonTree(new ExecuteCommandOptions(List.of(command))));
registration.setRegisterOptions(new ExecuteCommandOptions(List.of(command)));
client.registerCapability(new RegistrationParams(List.of(registration))).get(1, TimeUnit.SECONDS);
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.google.gson.Gson;

/**
* Verifies that dynamic registration of completion updates LSP4E server
* capabilities and enables content assist proposals.
Expand Down Expand Up @@ -82,7 +80,7 @@ public void testDynamicCompletionRegistrationProvidesProposalsAndTriggers() thro
registration.setMethod("textDocument/completion");
var opts = new CompletionOptions();
opts.setTriggerCharacters(List.of(".", "/", "#"));
registration.setRegisterOptions(new Gson().toJsonTree(opts));
registration.setRegisterOptions(opts);
client.registerCapability(new RegistrationParams(List.of(registration))).get(2, TimeUnit.SECONDS);

// Compute proposals (manual invocation). Should return the mock item.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2025 Contributors to the Eclipse Foundation.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* See git history
*******************************************************************************/
package org.eclipse.lsp4e.test.internal;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.eclipse.lsp4e.internal.JsonUtil;
import org.eclipse.lsp4j.FileSystemWatcher;
import org.eclipse.lsp4j.WatchKind;
import org.junit.jupiter.api.Test;

public class JsonUtilTest {

@Test
void testRoundtrip() throws Exception {
// Setup an object which uses Either internally.
// This can only be properly de/serialized with Gson instance which knows about LSP4J types.
var original = new FileSystemWatcher();
original.setGlobPattern("**");
original.setKind(WatchKind.Create | WatchKind.Change | WatchKind.Delete);

String json = JsonUtil.LSP4J_GSON.toJson(original);
assertEquals("""
{"globPattern":"**","kind":7}""", json);

FileSystemWatcher copy = JsonUtil.LSP4J_GSON.fromJson(json, FileSystemWatcher.class);
assertEquals(original, copy);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*******************************************************************************/
package org.eclipse.lsp4e;

import static org.eclipse.lsp4e.internal.NullSafetyHelper.*;
import static org.eclipse.lsp4e.internal.NullSafetyHelper.castNonNull;

import java.io.BufferedReader;
import java.io.File;
Expand Down Expand Up @@ -80,6 +80,7 @@
import org.eclipse.lsp4e.internal.ArrayUtil;
import org.eclipse.lsp4e.internal.CancellationUtil;
import org.eclipse.lsp4e.internal.FileBufferListenerAdapter;
import org.eclipse.lsp4e.internal.JsonUtil;
import org.eclipse.lsp4e.internal.SupportedFeatures;
import org.eclipse.lsp4e.internal.files.FileSystemWatcherManager;
import org.eclipse.lsp4e.server.StreamConnectionProvider;
Expand Down Expand Up @@ -129,7 +130,6 @@

import com.google.common.base.Functions;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class LanguageServerWrapper {
Expand Down Expand Up @@ -1173,7 +1173,7 @@ public void registerCapability(RegistrationParams params) {
break;
case "workspace/executeCommand": //$NON-NLS-1$
try {
ExecuteCommandOptions executeCommandOptions = castNonNull(new Gson().fromJson((JsonObject) reg.getRegisterOptions(),
ExecuteCommandOptions executeCommandOptions = castNonNull(JsonUtil.LSP4J_GSON.fromJson((JsonObject) reg.getRegisterOptions(),
ExecuteCommandOptions.class));
List<String> newCommands = executeCommandOptions.getCommands();
if (!newCommands.isEmpty()) {
Expand Down Expand Up @@ -1212,7 +1212,7 @@ public void registerCapability(RegistrationParams params) {
case "textDocument/completion": { //$NON-NLS-1$
CompletionOptions previous = serverCapabilities.getCompletionProvider();
try {
final var completionOpts = new Gson().fromJson((JsonObject) reg.getRegisterOptions(),
final var completionOpts = JsonUtil.LSP4J_GSON.fromJson((JsonObject) reg.getRegisterOptions(),
CompletionOptions.class);
serverCapabilities.setCompletionProvider(completionOpts);
addRegistration(reg, () -> serverCapabilities.setCompletionProvider(previous));
Expand Down Expand Up @@ -1255,8 +1255,9 @@ public void registerCapability(RegistrationParams params) {
return null;
if (registerOptions instanceof DidChangeWatchedFilesRegistrationOptions direct)
return direct;
if (registerOptions instanceof JsonObject jsonObject)
return new Gson().fromJson(jsonObject, DidChangeWatchedFilesRegistrationOptions.class);
if (registerOptions instanceof JsonObject jsonObject) {
return JsonUtil.LSP4J_GSON.fromJson(jsonObject, DidChangeWatchedFilesRegistrationOptions.class);
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
*******************************************************************************/
package org.eclipse.lsp4e.command;

import static org.eclipse.lsp4e.command.LSPCommandHandler.*;
import static org.eclipse.lsp4e.command.LSPCommandHandler.LSP_COMMAND_PARAMETER_ID;
import static org.eclipse.lsp4e.command.LSPCommandHandler.LSP_PATH_PARAMETER_ID;

import java.net.URI;
import java.util.ArrayList;
Expand All @@ -33,6 +34,7 @@
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.lsp4e.command.internal.CommandEventParameter;
import org.eclipse.lsp4e.internal.JsonUtil;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
Expand Down Expand Up @@ -192,7 +194,7 @@ private static WorkspaceEdit createWorkspaceEdit(List<Object> commandArguments,
} else if (arg instanceof TextEdit textEdit) {
currentEntry.value.add(textEdit);
} else if (arg instanceof Map) {
final var gson = new Gson(); // TODO? retrieve the GSon used by LS
Gson gson = JsonUtil.LSP4J_GSON;
TextEdit edit = gson.fromJson(gson.toJson(arg), TextEdit.class);
if (edit != null) {
currentEntry.value.add(edit);
Expand All @@ -210,15 +212,15 @@ private static WorkspaceEdit createWorkspaceEdit(List<Object> commandArguments,
}
}
} else if (arg instanceof JsonArray jsonArray) {
final var gson = new Gson(); // TODO? retrieve the GSon used by LS
Gson gson = JsonUtil.LSP4J_GSON;
jsonArray.forEach(elt -> {
TextEdit edit = gson.fromJson(gson.toJson(elt), TextEdit.class);
if (edit != null) {
currentEntry.value.add(edit);
}
});
} else if (arg instanceof JsonObject jsonObject) {
final var gson = new Gson(); // TODO? retrieve the GSon used by LS
Gson gson = JsonUtil.LSP4J_GSON;
WorkspaceEdit wEdit = gson.fromJson(jsonObject, WorkspaceEdit.class);
if (wEdit != null) {
Map<String, List<TextEdit>> entries = wEdit.getChanges();
Expand Down
28 changes: 28 additions & 0 deletions org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/JsonUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2025 Contributors to the Eclipse Foundation.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* See git history
*******************************************************************************/
package org.eclipse.lsp4e.internal;

import java.util.Map;
import java.util.Objects;

import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;

import com.google.gson.Gson;

/**
* Provides a {@link Gson} instance which can properly serialize and deserialize LSP4J JSON-RPC objects
*/
public class JsonUtil {

public static final Gson LSP4J_GSON = Objects.requireNonNull(new MessageJsonHandler(Map.of()).getGson());

}