Skip to content

Commit

Permalink
'Open Call Hierarchy' does not jump to reference where it is invoked at
Browse files Browse the repository at this point in the history
Signed-off-by: Snjezana Peco <snjezana.peco@redhat.com>
  • Loading branch information
snjeza committed Sep 8, 2021
1 parent 00b8336 commit 38a131c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -95,7 +96,17 @@ public List<CallHierarchyIncomingCall> callHierarchyIncomingCalls(CallHierarchyI

CallHierarchyItem item = params.getItem();
Assert.isNotNull(item, "call item");
Position position = item.getSelectionRange().getStart();
Position position;
switch (item.getKind()) {
case Class:
case Enum:
case Interface:
position = item.getSelectionRange().getStart();
break;
default:
position = item.getRange().getStart();
break;
}
int line = position.getLine();
int character = position.getCharacter();

Expand All @@ -115,7 +126,7 @@ public List<CallHierarchyOutgoingCall> callHierarchyOutgoingCalls(CallHierarchyO

CallHierarchyItem item = params.getItem();
Assert.isNotNull(item, "call item");
Position position = item.getSelectionRange().getStart();
Position position = item.getRange().getStart();
int line = position.getLine();
int character = position.getCharacter();

Expand Down Expand Up @@ -177,29 +188,46 @@ private List<CallHierarchyIncomingCall> getIncomingCallItemsAt(String uri, int l

MethodWrapper wrapper = incomingMethodWrapperCache.containsKey(candidate) ?
incomingMethodWrapperCache.get(candidate) : getCallRoot(candidate, true);
if (wrapper == null) {
if (wrapper == null || !wrapper.canHaveChildren()) {
return null;
}

MethodWrapper[] calls = wrapper.getCalls(sub.split(1));
if (calls == null) {
return null;
}

List<CallHierarchyIncomingCall> result = new ArrayList<>();
for (MethodWrapper call : calls) {
Collection<CallLocation> callLocations = call.getMethodCall().getCallLocations();
if (callLocations != null) {
for (CallLocation location : callLocations) {
IOpenable openable = getOpenable(location);
Range callRange = getRange(openable, location);
CallHierarchyItem symbol = toCallHierarchyItem(call.getMember());
symbol.setSelectionRange(callRange);
List<Range> ranges = toCallRanges(callLocations);
result.add(new CallHierarchyIncomingCall(symbol, ranges));
}
}
IMember member = call.getMember();
if (member != null) {
incomingMethodWrapperCache.put(member, call);
}
CallHierarchyItem symbol = toCallHierarchyItem(call.getMember());
List<Range> ranges = toCallRanges(call.getMethodCall().getCallLocations());
result.add(new CallHierarchyIncomingCall(symbol, ranges));
}

return result;
}

private Range getRange(IOpenable openable, CallLocation location) {
int[] start = JsonRpcHelpers.toLine(openable, location.getStart());
int[] end = JsonRpcHelpers.toLine(openable, location.getEnd());
Assert.isNotNull(start, "start");
Assert.isNotNull(end, "end");
// Assert.isLegal(start[0] == end[0], "Expected equal start and end lines. Start was: " + Arrays.toString(start) + " End was:" + Arrays.toString(end));
Range callRange = new Range(new Position(start[0], start[1]), new Position(end[0], end[1]));
return callRange;
}

private List<CallHierarchyOutgoingCall> getOutgoingCallItemsAt(String uri, int line, int character, IProgressMonitor monitor) throws JavaModelException {
SubMonitor sub = SubMonitor.convert(monitor, 2);
IMember candidate = getCallHierarchyElement(uri, line, character, sub.split(1));
Expand All @@ -221,13 +249,20 @@ private List<CallHierarchyOutgoingCall> getOutgoingCallItemsAt(String uri, int l

List<CallHierarchyOutgoingCall> result = new ArrayList<>();
for (MethodWrapper call : calls) {
Collection<CallLocation> callLocations = call.getMethodCall().getCallLocations();
if (callLocations != null) {
List<Range> ranges = toCallRanges(callLocations);
Iterator<CallLocation> iter = callLocations.iterator();
while (iter.hasNext()) {
iter.next();
CallHierarchyItem symbol = toCallHierarchyItem(call.getMember());
result.add(new CallHierarchyOutgoingCall(symbol, ranges));
}
}
IMember member = call.getMember();
if (member != null) {
outgoingMethodWrapperCache.put(member, call);
}
CallHierarchyItem symbol = toCallHierarchyItem(call.getMember());
List<Range> ranges = toCallRanges(call.getMethodCall().getCallLocations());
result.add(new CallHierarchyOutgoingCall(symbol, ranges));
}

return result;
Expand Down Expand Up @@ -280,23 +315,23 @@ private List<Range> toCallRanges(Collection<CallLocation> callLocations) {
List<Range> ranges = new ArrayList<>();
if (callLocations != null) {
for (CallLocation location : callLocations) {
IOpenable openable = location.getMember().getCompilationUnit();
if (openable == null) {
openable = location.getMember().getTypeRoot();
}
int[] start = JsonRpcHelpers.toLine(openable, location.getStart());
int[] end = JsonRpcHelpers.toLine(openable, location.getEnd());
Assert.isNotNull(start, "start");
Assert.isNotNull(end, "end");
// Assert.isLegal(start[0] == end[0], "Expected equal start and end lines. Start was: " + Arrays.toString(start) + " End was:" + Arrays.toString(end));
Range callRange = new Range(new Position(start[0], start[1]), new Position(end[0], end[1]));
IOpenable openable = getOpenable(location);
Range callRange = getRange(openable, location);
ranges.add(callRange);
}
}

return ranges;
}

private IOpenable getOpenable(CallLocation location) {
IOpenable openable = location.getMember().getCompilationUnit();
if (openable == null) {
openable = location.getMember().getTypeRoot();
}
return openable;
}

/**
* Throws an {@link OperationCanceledException} if the argument is canceled.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sample;

public class Call {
public static void main(String[] args) {
System.out.println("skip");
System.out.println("skip");
System.out.println("skip");
new Foo().someMethod();
System.out.println("skip");
System.out.println("skip");
new Foo().someMethod();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.lsp4j.CallHierarchyOutgoingCallsParams;
import org.eclipse.lsp4j.CallHierarchyPrepareParams;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.SymbolKind;
import org.eclipse.lsp4j.SymbolTag;
import org.eclipse.lsp4j.TextDocumentIdentifier;
Expand Down Expand Up @@ -96,9 +97,30 @@ public void incomingCalls_src() throws Exception {
List<CallHierarchyIncomingCall> calls = getIncomingCalls(items.get(0));
assertNotNull(calls);
assertEquals(3, calls.size());
assertItem(calls.get(0).getFrom(), "Child()", Constructor, "org.sample.CallHierarchy$Child", false, 42);
assertItem(calls.get(1).getFrom(), "main(String[])" + JavaElementLabels.DECL_STRING + "void", Method, "org.sample.CallHierarchy", true, 5);
assertItem(calls.get(2).getFrom(), "method_1()" + JavaElementLabels.DECL_STRING + "void", Method, "org.sample.CallHierarchy$Base", false, 33);
assertItem(calls.get(0).getFrom(), "Child()", Constructor, "org.sample.CallHierarchy$Child", false, 45);
assertItem(calls.get(1).getFrom(), "main(String[])" + JavaElementLabels.DECL_STRING + "void", Method, "org.sample.CallHierarchy", true, 7);
assertItem(calls.get(2).getFrom(), "method_1()" + JavaElementLabels.DECL_STRING + "void", Method, "org.sample.CallHierarchy$Base", false, 35);
}

@Test
public void testSelectionRange() throws Exception {
// Line from `org.sample.Foo`
// public void <|>someMethod() {}
String uri = getUriFromSrcProject("org.sample.Foo");
List<CallHierarchyItem> items = prepareCallHierarchy(uri, 8, 13);
assertNotNull(items);
assertEquals(1, items.size());
assertItem(items.get(0), "someMethod()" + JavaElementLabels.DECL_STRING + "void", Method, "org.sample.Foo", false, 8);

List<CallHierarchyIncomingCall> calls = getIncomingCalls(items.get(0));
assertNotNull(calls);
assertEquals(4, calls.size());
assertItem(calls.get(2).getFrom(), "main(String[]) : void", Method, "org.sample.Call", false, 7);
assertItem(calls.get(3).getFrom(), "main(String[]) : void", Method, "org.sample.Call", false, 10);
Range selectionRange = calls.get(2).getFrom().getSelectionRange();
assertEquals(new Range(new Position(7, 18), new Position(7, 30)), selectionRange);
selectionRange = calls.get(3).getFrom().getSelectionRange();
assertEquals(new Range(new Position(10, 18), new Position(10, 30)), selectionRange);
}

@Test
Expand All @@ -119,9 +141,9 @@ public void outgoingCalls_src() throws Exception {

List<CallHierarchyOutgoingCall> call1Calls = getOutgoings(calls.get(1).getTo());
assertNotNull(call1Calls);
assertEquals(2, call1Calls.size());
assertEquals(4, call1Calls.size());
assertItem(call1Calls.get(0).getTo(), "Child()", Constructor, "org.sample.CallHierarchy$Child", false, 42);
assertItem(call1Calls.get(1).getTo(), "currentThread()" + JavaElementLabels.DECL_STRING + "Thread", Method, "java.lang.Thread", false, 0);
assertItem(call1Calls.get(2).getTo(), "currentThread()" + JavaElementLabels.DECL_STRING + "Thread", Method, "java.lang.Thread", false, 0);
}

@Test
Expand All @@ -137,12 +159,12 @@ public void incomingCalls_maven() throws Exception {
List<CallHierarchyIncomingCall> calls = getIncomingCalls(items.get(0));
assertNotNull(calls);
assertEquals(1, calls.size());
assertItem(calls.get(0).getFrom(), "FooBuilder()", Constructor, "org.sample.CallHierarchy$FooBuilder", false, 9);
assertItem(calls.get(0).getFrom(), "FooBuilder()", Constructor, "org.sample.CallHierarchy$FooBuilder", false, 10);

List<CallHierarchyIncomingCall> call0Calls = getIncomingCalls(calls.get(0).getFrom());
assertNotNull(call0Calls);
assertEquals(1, call0Calls.size());
assertItem(call0Calls.get(0).getFrom(), "{...}", Constructor, "org.sample.CallHierarchyOther", false, 4);
assertEquals(3, call0Calls.size());
assertItem(call0Calls.get(0).getFrom(), "{...}", Constructor, "org.sample.CallHierarchyOther", false, 5);
}

@Test
Expand All @@ -157,7 +179,7 @@ public void outgoing_jar() throws Exception {

List<CallHierarchyOutgoingCall> calls = getOutgoings(items.get(0));
assertNotNull(calls);
assertEquals(1, calls.size());
assertEquals(2, calls.size());
assertItem(calls.get(0).getTo(), "capitalize(String)" + JavaElementLabels.DECL_STRING + "String", Method, "org.apache.commons.lang3.text.WordUtils", false, 368);

List<CallHierarchyOutgoingCall> call0Calls = getOutgoings(calls.get(0).getTo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void testEmptyNames() throws Exception {
}

@Test
public void testSearchSourcMethodDeclarations() {
public void testSearchSourceMethodDeclarations() {
preferences.setIncludeSourceMethodDeclarations(true);
List<SymbolInformation> results = WorkspaceSymbolHandler.search("deleteSomething", "hello", true, monitor);
assertNotNull(results);
Expand All @@ -177,7 +177,7 @@ public void testSearchSourcMethodDeclarations() {

results = WorkspaceSymbolHandler.search("main", "hello", true, monitor);
assertNotNull(results);
assertEquals("Found " + results.size() + " result", 10, results.size());
assertEquals("Found " + results.size() + " result", 11, results.size());
boolean allMethods = results.stream().allMatch(s -> s.getKind() == SymbolKind.Method);
assertTrue("Found a non-method symbol", allMethods);
preferences.setIncludeSourceMethodDeclarations(false);
Expand Down

0 comments on commit 38a131c

Please sign in to comment.