Skip to content
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

Wrong method name sent for RequestCallHierarchyOutgoing #1303

Open
falko17 opened this issue Jul 26, 2024 · 0 comments
Open

Wrong method name sent for RequestCallHierarchyOutgoing #1303

falko17 opened this issue Jul 26, 2024 · 0 comments

Comments

@falko17
Copy link

falko17 commented Jul 26, 2024

Summary

When calling the LanguageClient.RequestCallHierarchyOutgoing method, the language client uses the method name textDocument/prepareCallHierarchy instead of callHierarchy/outgoingCalls in the JSON-RPC that's sent to the language server. This (apart from just being the wrong method name) causes most language servers to emit an error, since the method's name and parameters don't match.

Workaround

As a workaround, assuming outgoingParams is the CallHierarchyOutgoingCallsParams, client is the LanguageClient, and token is a CancellationToken, one can replace

client.RequestCallHierarchyOutgoing(outgoingParams, t);

with

client.SendRequest("callHierarchy/outgoingCalls", outgoingParams).Returning<IEnumerable<CallHierarchyOutgoingCall>>(token);

Possible cause

I've tried looking into why this happens, but the implementation of this part seems pretty complex, so I'm not sure if the following is correct. What I think happens is that the KnownHandlers in LspHandlerTypeDescriptorProvider—which associate method names with LspHandlerTypeDescriptors—is set up incorrectly. Specifically, the KnownHandlers end up associating the textDocument/prepareCallHierarchy method with the DelegatingCallHierarchyHandler (or rather, its type). When this type is wrapped in the HandlerTypeDescriptor's constructor, the ParamsType is set to CallHierarchyOutgoingCallsParams, while the method is set to textDocument/prepareCallHierarchy, which is where the mismatch originates from. The issue here specifically is how the method name is retrieved: All the interfaces that the given handler implements are checked for method attributes, and then the first of these is chosen. In the case of the DelegatingCallHierarchyHandler, it implements 14 interfaces. The first relevant interface that's returned by type.GetInterfaces() is ICallHierarchyPrepareHandler, whose MethodAttribute specifies textDocument/prepareCallHierarchy as the method name to use.

Something very similar happens with textDocument/prepareTypeHierarchy and typeHierarchy/subtypes. The reason this problem does not occur here is luck: The DelegatingTypeHierarchyHandler also implements 14 analogous interfaces, but the first one returned by type.GetInterfaces() here is ITypeHierarchySubtypesHandler, which happens to match the parameter type and hence causes LanguageClient.RequestTypeHierarchySubtypes to work correctly, despite the same flaw in how the KnownHandlers (or rather the HandlerTypeDescriptors) are being constructed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant