-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug #130: Support for JSON-RPC-like Debug Server Protocol's RPC #131
Conversation
Issue tracker reference: |
@svenefftinge @spoenemann @akosyakov Is there anything I can do to help on this topic? I'm eager to see progress there and can allocate most of my time. |
@jonahkichwacoders thanks for the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this proposal! The code seems to me of very high quality. I would support your nomination as a committer :-)
Are you planning to also implement service interfaces with corresponding data structures in the style of org.eclipse.lsp4j.services.LanguageServer
? Or have you already done that?
ide/build.gradle
Outdated
@@ -30,6 +38,7 @@ oomphIde { | |||
addProjectFolder('../org.eclipse.lsp4j') | |||
addProjectFolder('../org.eclipse.lsp4j.generator') | |||
addProjectFolder('../org.eclipse.lsp4j.jsonrpc') | |||
addProjectFolder('../org.eclipse.dsp4j.jsonrpc') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the namespace org.eclipse.dsp4j
, since theoretically that could cause name clashes with other Eclipse projects. On the other hand, I like the symmetry with org.eclipse.lsp4j
. What do others think about this?
An alternative project name could be org.eclipse.lsp4j.jsonrpc.debug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, depending on decision here will affect name of the interfaces containing plug-in. I was originally planning on org.eclipse.dsp4j, but perhaps org.eclipse.lsp4j.debug makes more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, IIRC there even is some rule at eclipse for java packages to use the project name as prefix.
return result; | ||
} | ||
|
||
protected Object parseParams(JsonReader in, String method) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make MessageTypeAdapterFactory
extensible in order to avoid duplicating code here. I'll prepare a PR for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, there is certainly some duplication between the two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merged #135.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the debug code to to use this new code. I also slightly refactored the MessageTypeAdapterFactory
to access some of its logic from the subclass.
super(supportedMethods, configureGson); | ||
} | ||
|
||
public GsonBuilder getDefaultGsonBuilder() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This additional class could be avoided by passing a Consumer<GsonBuilder>
to the default MessageJsonHandler
. When multiple type adapter factories are configured for the same type, the last one should win.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, the advantage of your approach too is that the other type factories don't need to be duplicated. A lot of the tests instantiate DebugMessageJsonHandler
directly, so I'll probably want a method somewhere that constructs a MessageJsonHandler
correctly for the tests in the same way as it is constructed for by the DebugLauncher
. Perhaps a method in the DebugLauncher
itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am having trouble writing a sensible method in DebugLauncher, at the moment it looks like the sample below, which seems uglier than having the extra class, ideas welcome.
The reason for the complication is the circular dependency between the MessageJsonHandler
and the DebugMessageTypeAdapterFactory
.
My next update will have the DebugMessageJsonHandler
still, but rather than repeating everything in getDefaultGsonBuilder
I'll call super's one and then add on the DebugMessageTypeAdapterFactory
.
If you have a thought on something I overlooked, I would be pleased for the feedback.
static MessageJsonHandler createMessageHandler(Map<String, JsonRpcMethod> supportedMethods,
Consumer<GsonBuilder> configureGson) {
DebugMessageTypeAdapterFactory adapterFactory[] = new DebugMessageTypeAdapterFactory[] {null};
Consumer<GsonBuilder> consumer = (builder) -> {
builder.registerTypeAdapterFactory(adapterFactory[0]);
configureGson.accept(builder);
};
MessageJsonHandler messageJsonHandler = new MessageJsonHandler(supportedMethods, consumer);
adapterFactory[0] = new DebugMessageTypeAdapterFactory(messageJsonHandler);
return messageJsonHandler;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, we could change the configureGson
parameter in MessageJsonHandler to BiConsumer<GsonBuilder, MessageJsonHandler>
, but that's a breaking change. @akosyakov, @svenefftinge do you think this is worth it? Would help for cases when someone wants to customize parsing / serialization of messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also add an additional constructor and deprecate the existing one. That would prevent it being a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, we don't even need to deprecate the old one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not made this change yet. The current version, and the new constructor we discussed suffers from a problem. It passes a reference to this
from the constructor when the object is not fully created, so creating new API that required and actually enforced passing around an incompletely constructed object seems like a bad idea. If you would like me to pursue this further (e.g. add an initialize()
method for example) I can raise and issue and work on that separately?
} | ||
|
||
@Test | ||
public void testParamsParsing_AllOrders() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parsing test that tries all iterations would also be nice for the MessageJsonHandlerTest
in org.eclipse.lsp4j.jsonrpc
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will contribute it back to both places. I also realised on revisiting that the idea was to remove the _02/_03/etc versions of the methods, so I will do that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the _AllOrders
method to MessageJsonHandlerTest
and extended it to do all the types of messages.
That makes no sense. Has probably been triggered by Jonahs mention of |
Yes. |
Thanks.
I am planning to create a PR in the coming days with the equivalent for the debug protocol. It is generated from the debug protocol json schema. Originally I was going to put it in a plug-in called org.eclipse.dsp4j, but based on your other comments, perhaps org.eclipse.lsp4j.debug would make more sense. |
OK. |
It seems like the word "bug" is not necessary for triggering the Bugzilla bot, see eclipse/kapua#131 |
…ng of JSON The DSP implementation created some new tests for checking every order of fields in a JSON message. This commit adapts the same test for LSP messages. Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
3c90c26
to
e374cf0
Compare
@spoenemann I have updated the code with all your feedback and it is again ready for review. This update has the next part too, the service protocol files. As the DSP has a Json Schema that defines it, the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent!
As long as the main source for the DSP is a JSON schema, it totally makes sense to generate the Java code from it. Ideally, the generator would be in this project (org.eclipse.lsp4j.generator
), but probably we cannot just copy the code from Microsoft/vscode-debugadapter-node or a derived version of it. We can leave that problem for later and first make this PR ready for merge.
org.eclipse.lsp4j.debug/README.md
Outdated
``` | ||
$ git clone git@github.com:jonahkichwacoders/vscode-debugadapter-node.git | ||
$ git checkout dsp | ||
$ npm install -g typescript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typescript
is already in the devDependencies
of the package.json, so it's not necessary to install it globally. The line tsc -p ./src/ # convert typescript
should be added as a script in the package.json
/** | ||
* <p> | ||
* Version of debugProtocol.json this class was derived from. | ||
* </p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these <p>...</p>
create quite a lot of noise. I would prefer to omit them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add some additional logic to the generator to only add the <p>
between paragraphs and omit them on single paragraph comments.
* completed, by executing a debugger statement etc. | ||
* </p> | ||
*/ | ||
public static class StoppedEventArguments { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class structure should not be nested, but flat, in order to be consistent with the LSP implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably it would be better to generate a DebugProtocol.xtend
with @JsonRpcData
tags and that gets us even closer. It would be a 2 stage generation process (first the typescript one then the o.e.lsp4j.generator one), but then the DebugProtocol.xtend
would be much readable (and shorter). WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two-stage generation sounds a bit scary at first. But a nice side effect is that all the derived members (getters, setters, equals, hashCode) are consistent in both protocols. And I like the idea to have a more readable version of the Java data structures.
* Possible values include - but not limited to those defined in {@link Reason} | ||
* </p> | ||
*/ | ||
public String reason; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fields should not be public, but accessible via getters, in order to be consistent with the LSP implementation.
* </ul> | ||
*/ | ||
@JsonNotification | ||
default void initialized() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these default implementations? I'd remove them.
These are warnings always seen when running gradle build Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
This provides the supporting RPC implementation for VSCode's Debug Protocol as defined https://github.com/Microsoft/vscode-debugadapter-node/blob/master/debugProtocol.json See the class comment on DebugMessageTypeAdapter for details on mapping between Debug Server Protocol and JSON-RPC 2.0. See DebugProtocol/IDebugProtocolClient/IDebugProtocolServer for the Java Service Interfaces and supporting types. Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
…dler Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
7670fce
to
33fe5de
Compare
@spoenemann Its ready, I have hopefully addressed all your concerns adequately. With the generation of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks again!
A further improvement would be to generate @NonNull
annotations from the required
properties in the schema, but I'll create a separate issue for that.
* <p> | ||
* Auto-generated from debugProtocol.json schema version 1.24.0. Do not edit manually. | ||
*/ | ||
class DebugProtcol { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this class could be removed now.
is deprecated and going to be removed soon. Fixes eclipse-lsp4j#131 Signed-off-by: azerr <azerr@redhat.com>
This provides the supporting RPC implementation for VSCode's Debug Protocol
as defined https://github.com/Microsoft/vscode-debugadapter-node/blob/master/debugProtocol.json
See the class comment on DebugMessageTypeAdapterFactory for details on
mapping between Debug Server Protocol and JSON-RPC 2.0.
Signed-off-by: Jonah Graham jonah@kichwacoders.com