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

api to support call hierarchy view #70231

Closed
jrieken opened this issue Mar 11, 2019 · 16 comments
Closed

api to support call hierarchy view #70231

jrieken opened this issue Mar 11, 2019 · 16 comments
Assignees
Labels
api-finalization callhierarchy editor-symbols definitions, declarations, references feature-request Request for new features or functionality verification-needed Verification of issue is requested verified Verification succeeded
Milestone

Comments

@jrieken
Copy link
Member

jrieken commented Mar 11, 2019

This is for #16110, ideas already exist in microsoft/vscode-languageserver-node#420

@jrieken jrieken self-assigned this Mar 11, 2019
@jrieken jrieken added api-proposal editor-symbols definitions, declarations, references feature-request Request for new features or functionality labels Mar 11, 2019
@jrieken jrieken added this to the March 2019 milestone Mar 11, 2019
@jrieken

This comment has been minimized.

jrieken added a commit that referenced this issue Mar 25, 2019
@jrieken jrieken modified the milestones: March 2019, April 2019 Mar 25, 2019
@aeschli

This comment has been minimized.

@jrieken
Copy link
Member Author

jrieken commented Jun 6, 2019

For June we plan to change the API to @aeschli's proposal: #70231 (comment)

@testforstephen
Copy link

@jrieken When will the new API be ready? I'd like to try the call hierarchy feature in Java language server.

@testforstephen
Copy link

i have tried the api in Java language server, here is the feedback:

  • The client api lags behind the protocol.callHierarchy.proposed.md definition.
  • Peek Call Hierarchy shows the callee hierarchy by default, but i prefer to show the caller hierarchy by default. Other IDEs, such as Intellij IDEA and Eclipse, show the Caller Method Hierarchy by default.
  • For the callee hierarchy, when clicking the callee method at the right panel, the left panel will refresh the code region, but it doesn't select the callee method name. The caller hierarchy works.

@jrieken
Copy link
Member Author

jrieken commented Aug 30, 2019

An updated proposal (based on @aeschli's feedback) can be found here: #80112

@jrieken jrieken added this to the September 2019 milestone Sep 10, 2019
@jrieken

This comment has been minimized.

@jrieken jrieken modified the milestones: September 2019, October 2019 Sep 30, 2019
@jrieken
Copy link
Member Author

jrieken commented Sep 30, 2019

Moving to October for finalisation

@jrieken
Copy link
Member Author

jrieken commented Oct 25, 2019

The final and revised proposal featuring a prepare function to get started and two provide functions that work on call hierarchy items.

/**
* Represents programming constructs like functions or constructors in the context
* of call hierarchy.
*/
export class CallHierarchyItem {
    /**
    * The name of this item.
    */
    name: string;

    /**
    * The kind of this item.
    */
    kind: SymbolKind;

    /**
    * Tags for this item.
    */
    tags?: ReadonlyArray<SymbolTag>;

    /**
    * More detail for this item, e.g. the signature of a function.
    */
    detail?: string;

    /**
    * The resource identifier of this item.
    */
    uri: Uri;

    /**
    * The range enclosing this symbol not including leading/trailing whitespace but everything else, e.g. comments and code.
    */
    range: Range;

    /**
    * The range that should be selected and revealed when this symbol is being picked, e.g. the name of a function.
    * Must be contained by the [`range`](#CallHierarchyItem.range).
    */
    selectionRange: Range;

    constructor(kind: SymbolKind, name: string, detail: string, uri: Uri, range: Range, selectionRange: Range);
}

/**
* Represents an incoming call, e.g. a caller of a method or constructor.
*/
export class CallHierarchyIncomingCall {

    /**
    * The item that makes the call.
    */
    from: CallHierarchyItem;

    /**
    * The range at which at which the calls appears. This is relative to the caller
    * denoted by [`this.from`](#CallHierarchyIncomingCall.from).
    */
    fromRanges: Range[];

    /**
    * Create a new call object.
    *
    * @param item The item making the call.
    * @param fromRanges The ranges at which the calls appear.
    */
    constructor(item: CallHierarchyItem, fromRanges: Range[]);
}

/**
* Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc.
*/
export class CallHierarchyOutgoingCall {

    /**
    * The item that is called.
    */
    to: CallHierarchyItem;

    /**
    * The range at which this item is called. This is the range relative to the caller, e.g the item
    * passed to [`provideCallHierarchyOutgoingCalls`](#CallHierarchyItemProvider.provideCallHierarchyOutgoingCalls)
    * and not [`this.to`](#CallHierarchyOutgoingCall.to).
    */
    fromRanges: Range[];

    /**
    * Create a new call object.
    *
    * @param item The item being called
    * @param fromRanges The ranges at which the calls appear.
    */
    constructor(item: CallHierarchyItem, fromRanges: Range[]);
}

/**
* The call hierarchy provider interface describes the constract between extensions
* and the call hierarchy feature which allows to browse calls and caller of function,
* methods, constructor etc.
*/
export interface CallHierarchyProvider {

    /**
    * Bootstraps call hierarchy by returning the item that is denoted by the given document
    * and position. This item will be used as entry into the call graph. Providers should
    * return `undefined` or `null` when there is no item at the given location.
    *
    * @param document The document in which the command was invoked.
    * @param position The position at which the command was invoked.
    * @param token A cancellation token.
    * @returns A call hierarchy item or a thenable that resolves to such. The lack of a result can be
    * signaled by returning `undefined` or `null`.
    */
    prepareCallHierarchy(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<CallHierarchyItem>;

    /**
    * Provide all incoming calls for an item, e.g all callers for a method. In graph terms this descibes directed
    * and annotated edges inside the call graph, e.g the given item is the starting node and the result is the nodes
    * that can be reached.
    *
    * @param item The hierarchy item for which incoming calls should be computed.
    * @param token A cancellation token.
    * @returns A set of incoming calls or a thenable that resolves to such. The lack of a result can be
    * signaled by returning `undefined` or `null`.
    */
    provideCallHierarchyIncomingCalls(item: CallHierarchyItem, token: CancellationToken): ProviderResult<CallHierarchyIncomingCall[]>;

    /**
    * Provide all outgoing calls for an item, e.g call calls to functions, methods, or constructors from the given item. In
    * graph terms this descibes directed and annotated edges inside the call graph, e.g the given item is the starting
    * node and the result is the nodes that can be reached.
    *
    * @param item The hierarchy item for which outgoing calls should be computed.
    * @param token A cancellation token.
    * @returns A set of outgoing calls or a thenable that resolves to such. The lack of a result can be
    * signaled by returning `undefined` or `null`.
    */
    provideCallHierarchyOutgoingCalls(item: CallHierarchyItem, token: CancellationToken): ProviderResult<CallHierarchyOutgoingCall[]>;
}

export namespace languages {

    /**
    * Register a call hierarchy provider.
    *
    * @param selector A selector that defines the documents this provider is applicable to.
    * @param provider A call hierarchy provider.
    * @return A [disposable](#Disposable) that unregisters this provider when being disposed.
    */
    export function registerCallHierarchyProvider(selector: DocumentSelector, provider: CallHierarchyProvider): Disposable;
}

@aeschli
Copy link
Contributor

aeschli commented Oct 25, 2019

LGTM!
Typo descibes -> describes

jrieken added a commit that referenced this issue Oct 25, 2019
@mjbvz
Copy link
Collaborator

mjbvz commented Oct 26, 2019

@rbuckton You were looking into this on the TS side; does this API look ok to you? Also did you determine if we need a new TS server api for this. My current thinking is that while we could implement call hierarchy using the existing TSServer apis such as find all references, that may require a lot of calls. And there would be false positives too, such as cases where functions are passed into other higher order functions

@rbuckton
Copy link
Member

If we're not planning to use find-all-references for this, then we'd definitely need a new API in tsserver. In general the API looks good to me.

@jrieken
Copy link
Member Author

jrieken commented Oct 28, 2019

@rbuckton I don't that out going calls can be implemented without extra API in ts-server

@jrieken jrieken closed this as completed Oct 28, 2019
@jrieken jrieken added the verification-needed Verification of issue is requested label Oct 28, 2019
@testforstephen
Copy link

@jrieken As i understand, this api is for the client to register call hierarchy provider. For the Java language, we want to make the jdt language server to provide call hierarchy provider directly. Looks like there is some small difference between protocol.callHierarchy.proposed.md definition and the client api. So are there any changes required for call hierarchy LSP? Any issue to track it? thanks.

@jrieken
Copy link
Member Author

jrieken commented Oct 29, 2019

@dbaeumer will follow up with the LSP once we have shipped this version

@jrieken
Copy link
Member Author

jrieken commented Oct 29, 2019

I believe it's this issue: microsoft/vscode-languageserver-node#520 (comment)

@roblourens roblourens added the verified Verification succeeded label Oct 30, 2019
@vscodebot vscodebot bot locked and limited conversation to collaborators Dec 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-finalization callhierarchy editor-symbols definitions, declarations, references feature-request Request for new features or functionality verification-needed Verification of issue is requested verified Verification succeeded
Projects
None yet
Development

No branches or pull requests

6 participants