eclipse.jdt.ls icon indicating copy to clipboard operation
eclipse.jdt.ls copied to clipboard

Incoming call's hierarchy item's selectionRange behaves differently to all other (tested) servers

Open bstaletic opened this issue 1 year ago • 2 comments

I am implementing call hierarchies in ycmd and ended up facing a situation where jdt.ls behaves differently than the other servers I have tested.

The response to the incomingCallHierarchy request looks something like this (irrelevant properties intentionally omitted):

{
    "from": {
        "range": spans_the_whole_function,
        "selectionRange": here_jdt_behaves_differently
    },
    "fromRanges": list_of_call_sites
}

Let's say function foo() is calling bar() and only once. With jdt.ls, selectionRange spans the call site. With other servers, selectionRange spans the name of foo().

This is important to me, because I want the ability to take the data from the incomingCallHierarchy and send a new prepareCallHierarchy request from the calling function (foo()).

I can also think of two other reasons why the current JDT behaviour is bad:

  1. It seems useless to have selectionRange == fromRanges[0], as it does not provide any additional information about the hierarchy item.
  2. The documentation for from seems to imply that the data should be about the calling function, not the called function.

Granted, I can achieve my goal with some JDT specific hacks, as JDT can do what I want if I switch to using range instead of selectionRange. However, that seems counterintuitive and would require server specific hacks for some other servers.

bstaletic avatar Jun 11 '24 17:06 bstaletic

For reference, here's a related discussion between myself and a rust-analyzer maintainer:

https://github.com/rust-lang/rust-analyzer/issues/17388

bstaletic avatar Jun 13 '24 10:06 bstaletic

I am experiencing the same issue. Typescript and pyright seem to provide the selectionRange of the caller, not the callsite, in this field.

The specification also suggests this, which seems to imply everything in from should refer to the caller, and callsite stuff should go in fromRanges:

export interface CallHierarchyIncomingCall {
	/**
	 * The item that makes the call.
	 */
	from: CallHierarchyItem;

	/**
	 * The ranges at which the calls appear. This is relative to the caller
	 * denoted by `this.from`.
	 */
	fromRanges: Range[];
}

TomKrcmar2 avatar Oct 09 '24 00:10 TomKrcmar2