Skip to content

Wrong method name sent for RequestCallHierarchyOutgoing #1303

Open
@falko17

Description

@falko17

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions