Skip to content

Commit 74e8804

Browse files
committed
#126: Parse Object into a JsonElement
1 parent b4659be commit 74e8804

File tree

16 files changed

+574
-9
lines changed

16 files changed

+574
-9
lines changed

Diff for: org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/adapters/CollectionTypeAdapter.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,14 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
4545
Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Collection.class);
4646
if (elementTypes.length != 1)
4747
return null;
48-
TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementTypes[0]));
48+
Type elementType = elementTypes[0];
49+
TypeAdapter<?> elementTypeAdapter;
50+
if (elementType == Object.class)
51+
elementTypeAdapter = new JsonElementTypeAdapter(gson);
52+
else
53+
elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
4954
Supplier<Collection<Object>> constructor = getConstructor((Class<Collection<Object>>) typeToken.getRawType());
50-
return (TypeAdapter<T>) create(gson, elementTypes[0], elementTypeAdapter, constructor);
55+
return (TypeAdapter<T>) create(gson, elementType, elementTypeAdapter, constructor);
5156
}
5257

5358
@SuppressWarnings({ "unchecked", "rawtypes" })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 TypeFox GmbH (http://www.typefox.io) and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*******************************************************************************/
8+
package org.eclipse.lsp4j.jsonrpc.json.adapters;
9+
10+
import java.io.IOException;
11+
12+
import com.google.gson.Gson;
13+
import com.google.gson.JsonElement;
14+
import com.google.gson.TypeAdapter;
15+
import com.google.gson.TypeAdapterFactory;
16+
import com.google.gson.internal.bind.TypeAdapters;
17+
import com.google.gson.reflect.TypeToken;
18+
import com.google.gson.stream.JsonReader;
19+
import com.google.gson.stream.JsonWriter;
20+
21+
/**
22+
* A type adapter that reads every input into a tree of {@link JsonElement}s.
23+
*/
24+
public class JsonElementTypeAdapter extends TypeAdapter<Object> {
25+
26+
/**
27+
* This factory should not be registered with a GsonBuilder because it always matches.
28+
* Use it as argument to a {@link com.google.gson.annotations.JsonAdapter} annotation like this:
29+
* {@code @JsonAdapter(JsonElementTypeAdapter.Factory.class)}
30+
*/
31+
public static class Factory implements TypeAdapterFactory {
32+
33+
@SuppressWarnings("unchecked")
34+
@Override
35+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
36+
return (TypeAdapter<T>) new JsonElementTypeAdapter(gson);
37+
}
38+
39+
}
40+
41+
private final Gson gson;
42+
43+
public JsonElementTypeAdapter(Gson gson) {
44+
this.gson = gson;
45+
}
46+
47+
@Override
48+
public JsonElement read(JsonReader in) throws IOException {
49+
return TypeAdapters.JSON_ELEMENT.read(in);
50+
}
51+
52+
@Override
53+
public void write(JsonWriter out, Object value) throws IOException {
54+
if (value == null) {
55+
out.nullValue();
56+
} else if (value instanceof JsonElement) {
57+
TypeAdapters.JSON_ELEMENT.write(out, (JsonElement) value);
58+
} else {
59+
gson.toJson(value, value.getClass(), out);;
60+
}
61+
}
62+
63+
}

Diff for: org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java

+4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
package org.eclipse.lsp4j.jsonrpc.messages;
99

1010
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
11+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1112
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
1213

14+
import com.google.gson.annotations.JsonAdapter;
15+
1316
public class ResponseError {
1417

1518
/**
@@ -48,6 +51,7 @@ public void setMessage(String message) {
4851
* A Primitive or Structured value that contains additional information
4952
* about the error. Can be omitted.
5053
*/
54+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
5155
private Object data;
5256

5357
public Object getData() {

Diff for: org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/json/MessageJsonHandlerTest.java

+24-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
package org.eclipse.lsp4j.jsonrpc.test.json;
99

1010
import java.util.Arrays;
11-
import java.util.HashMap;
11+
import java.util.Collections;
1212
import java.util.HashSet;
1313
import java.util.LinkedHashMap;
1414
import java.util.List;
@@ -22,6 +22,7 @@
2222
import org.eclipse.lsp4j.jsonrpc.messages.Message;
2323
import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
2424
import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
25+
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
2526
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
2627
import org.junit.Assert;
2728
import org.junit.Test;
@@ -522,6 +523,26 @@ public void testEnumParam() {
522523
parameters);
523524
}
524525

526+
@Test
527+
public void testResponseErrorData() {
528+
MessageJsonHandler handler = new MessageJsonHandler(Collections.emptyMap());
529+
ResponseMessage message = (ResponseMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
530+
+ "\"id\":\"2\",\n"
531+
+ "\"error\": { \"code\": -32001, \"message\": \"foo\",\n"
532+
+ " \"data\": { \"uri\": \"file:/foo\", \"version\": 5, \"list\": [\"a\", \"b\", \"c\"] }\n"
533+
+ " }\n"
534+
+ "}");
535+
ResponseError error = message.getError();
536+
Assert.assertTrue("Expected a JsonObject in error.data", error.getData() instanceof JsonObject);
537+
JsonObject data = (JsonObject) error.getData();
538+
Assert.assertEquals("file:/foo", data.get("uri").getAsString());
539+
Assert.assertEquals(5, data.get("version").getAsInt());
540+
JsonArray list = data.get("list").getAsJsonArray();
541+
Assert.assertEquals("a", list.get(0).getAsString());
542+
Assert.assertEquals("b", list.get(1).getAsString());
543+
Assert.assertEquals("c", list.get(2).getAsString());
544+
}
545+
525546
public static final <T> void swap(T[] a, int i, int j) {
526547
T t = a[i];
527548
a[i] = a[j];
@@ -652,8 +673,8 @@ public void testErrorResponse_AllOrders() {
652673
ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
653674
Assert.assertEquals("failed", message.getError().getMessage());
654675
Object data = message.getError().getData();
655-
Map<String, String> expected = new HashMap<>();
656-
expected.put("uri", "failed");
676+
JsonObject expected = new JsonObject();
677+
expected.addProperty("uri", "failed");
657678
Assert.assertEquals(expected, data);
658679
Assert.assertNull(message.getResult());
659680
});

Diff for: org.eclipse.lsp4j/src/main/java/org/eclipse/lsp4j/Protocol.xtend

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
*******************************************************************************/
88
package org.eclipse.lsp4j
99

10+
import com.google.common.annotations.Beta
11+
import com.google.gson.annotations.JsonAdapter
1012
import java.util.ArrayList
1113
import java.util.LinkedHashMap
1214
import java.util.List
1315
import java.util.Map
1416
import org.eclipse.lsp4j.generator.JsonRpcData
17+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter
1518
import org.eclipse.lsp4j.jsonrpc.messages.Either
1619
import org.eclipse.lsp4j.jsonrpc.messages.Either3
1720
import org.eclipse.lsp4j.jsonrpc.validation.NonNull
18-
import com.google.common.annotations.Beta
1921

2022
@JsonRpcData
2123
class DynamicRegistrationCapabilities {
@@ -444,6 +446,7 @@ class ClientCapabilities {
444446
/**
445447
* Experimental client capabilities.
446448
*/
449+
@JsonAdapter(JsonElementTypeAdapter.Factory)
447450
Object experimental
448451

449452
new() {
@@ -534,6 +537,7 @@ class CodeLens {
534537
/**
535538
* An data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
536539
*/
540+
@JsonAdapter(JsonElementTypeAdapter.Factory)
537541
Object data
538542

539543
new() {
@@ -700,6 +704,7 @@ class CompletionItem {
700704
/**
701705
* An data entry field that is preserved on a completion item between a completion and a completion resolve request.
702706
*/
707+
@JsonAdapter(JsonElementTypeAdapter.Factory)
703708
Object data
704709

705710
new() {
@@ -822,7 +827,11 @@ class Diagnostic {
822827
*/
823828
@JsonRpcData
824829
class DidChangeConfigurationParams {
830+
/**
831+
* The actual changed settings.
832+
*/
825833
@NonNull
834+
@JsonAdapter(JsonElementTypeAdapter.Factory)
826835
Object settings
827836

828837
new() {
@@ -1528,6 +1537,7 @@ class InitializeParams {
15281537
/**
15291538
* User provided initialization options.
15301539
*/
1540+
@JsonAdapter(JsonElementTypeAdapter.Factory)
15311541
Object initializationOptions
15321542

15331543
/**
@@ -1908,6 +1918,7 @@ class ServerCapabilities {
19081918
/**
19091919
* Experimental server capabilities.
19101920
*/
1921+
@JsonAdapter(JsonElementTypeAdapter.Factory)
19111922
Object experimental
19121923

19131924
/**
@@ -2387,6 +2398,7 @@ class Registration {
23872398
/**
23882399
* Options necessary for the registration.
23892400
*/
2401+
@JsonAdapter(JsonElementTypeAdapter.Factory)
23902402
Object registerOptions
23912403

23922404
new() {

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/ClientCapabilities.java

+3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
1011
import org.eclipse.lsp4j.TextDocumentClientCapabilities;
1112
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
13+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1214
import org.eclipse.xtext.xbase.lib.Pure;
1315
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
1416

@@ -40,6 +42,7 @@ public class ClientCapabilities {
4042
/**
4143
* Experimental client capabilities.
4244
*/
45+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
4346
private Object experimental;
4447

4548
public ClientCapabilities() {

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/CodeLens.java

+3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
1011
import org.eclipse.lsp4j.Command;
1112
import org.eclipse.lsp4j.Range;
13+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1214
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
1315
import org.eclipse.xtext.xbase.lib.Pure;
1416
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
@@ -36,6 +38,7 @@ public class CodeLens {
3638
/**
3739
* An data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
3840
*/
41+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
3942
private Object data;
4043

4144
public CodeLens() {

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/CompletionItem.java

+3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
1011
import java.util.List;
1112
import org.eclipse.lsp4j.Command;
1213
import org.eclipse.lsp4j.CompletionItemKind;
1314
import org.eclipse.lsp4j.InsertTextFormat;
1415
import org.eclipse.lsp4j.TextEdit;
16+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1517
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
1618
import org.eclipse.xtext.xbase.lib.Pure;
1719
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
@@ -92,6 +94,7 @@ public class CompletionItem {
9294
/**
9395
* An data entry field that is preserved on a completion item between a completion and a completion resolve request.
9496
*/
97+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
9598
private Object data;
9699

97100
public CompletionItem() {

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/DidChangeConfigurationParams.java

+12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
11+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1012
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
1113
import org.eclipse.xtext.xbase.lib.Pure;
1214
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
@@ -16,7 +18,11 @@
1618
*/
1719
@SuppressWarnings("all")
1820
public class DidChangeConfigurationParams {
21+
/**
22+
* The actual changed settings.
23+
*/
1924
@NonNull
25+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
2026
private Object settings;
2127

2228
public DidChangeConfigurationParams() {
@@ -26,12 +32,18 @@ public DidChangeConfigurationParams(@NonNull final Object settings) {
2632
this.settings = settings;
2733
}
2834

35+
/**
36+
* The actual changed settings.
37+
*/
2938
@Pure
3039
@NonNull
3140
public Object getSettings() {
3241
return this.settings;
3342
}
3443

44+
/**
45+
* The actual changed settings.
46+
*/
3547
public void setSettings(@NonNull final Object settings) {
3648
this.settings = settings;
3749
}

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/InitializeParams.java

+3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
1011
import org.eclipse.lsp4j.ClientCapabilities;
12+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1113
import org.eclipse.xtext.xbase.lib.Pure;
1214
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
1315

@@ -37,6 +39,7 @@ public class InitializeParams {
3739
/**
3840
* User provided initialization options.
3941
*/
42+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
4043
private Object initializationOptions;
4144

4245
/**

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/Registration.java

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88
package org.eclipse.lsp4j;
99

10+
import com.google.gson.annotations.JsonAdapter;
11+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
1012
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
1113
import org.eclipse.xtext.xbase.lib.Pure;
1214
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
@@ -32,6 +34,7 @@ public class Registration {
3234
/**
3335
* Options necessary for the registration.
3436
*/
37+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
3538
private Object registerOptions;
3639

3740
public Registration() {

Diff for: org.eclipse.lsp4j/src/main/xtend-gen/org/eclipse/lsp4j/ServerCapabilities.java

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package org.eclipse.lsp4j;
99

1010
import com.google.common.annotations.Beta;
11+
import com.google.gson.annotations.JsonAdapter;
1112
import org.eclipse.lsp4j.CodeLensOptions;
1213
import org.eclipse.lsp4j.CompletionOptions;
1314
import org.eclipse.lsp4j.DocumentLinkOptions;
@@ -17,6 +18,7 @@
1718
import org.eclipse.lsp4j.TextDocumentSyncKind;
1819
import org.eclipse.lsp4j.TextDocumentSyncOptions;
1920
import org.eclipse.lsp4j.WorkspaceServerCapabilities;
21+
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
2022
import org.eclipse.lsp4j.jsonrpc.messages.Either;
2123
import org.eclipse.xtext.xbase.lib.Pure;
2224
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
@@ -112,6 +114,7 @@ public class ServerCapabilities {
112114
/**
113115
* Experimental server capabilities.
114116
*/
117+
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
115118
private Object experimental;
116119

117120
/**

0 commit comments

Comments
 (0)