eclipse-lsp4j / lsp4j

A Java implementation of the language server protocol intended to be consumed by tools and language servers implemented in Java.
https://eclipse.org/lsp4j
Other
613 stars 145 forks source link

An asymmetry in processing delegate methods #688

Open pisv opened 1 year ago

pisv commented 1 year ago

Looking at the call sites of AnnotationUtil.findDelegateSegments, there are two different ways in which the found delegate methods are processed:

  1. by using the formal return type of the method, as in ServiceEndpoints.getSupportedMethods and EndpointProxy.EndpointProxy

  2. by calling the method and using the actual type of the resulting delegate object, as in GenericEndpoint.recursiveFindRpcMethods

This seems to create a certain asymmetry, where some JSON-RPC methods (annotated with either @JsonRequest or @JsonNotification) can be found by the second way of processing delegate methods and cannot be found by the first way. This asymmetry is the root of the problem described in #686.

In particular, if GenericEndpoint.recursiveFindRpcMethods used the formal return type of the delegate method instead of the actual type of the delegate object, the use case initially described in #686 would fail with ResponseErrorCode.MethodNotFound at https://github.com/eclipse/lsp4j/blob/b17a5f1c6f2f0a05901fcfc47f11f98d2b303f5f/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/services/GenericEndpoint.java#L142 rather than by throwing the mysterious java.lang.IllegalArgumentException: argument type mismatch.

If, on the other hand, ServiceEndpoints.getSupportedMethods could call a delegate method and use the actual type of the resulting delegate object instead of using the formal return type of the delegate method, the use case in #686 would just work.

Note, however, that calling delegate methods to determine the actual type of the delegate object is possible only for local services -- it is not possible for remote interfaces -- which means that an asymmetry of a certain kind would still remain. My concern is that this asymmetry might sometimes reveal itself when attempting to use the same service interfaces both on the server and on the client.

Now the question is: Should the actual type of delegate objects be always used for local services to support use cases similar to #686 or, for the sake of consistency, would it be better to use the formal return type of delegate methods in all cases (for both remote interfaces and local services)? WDYT?