Skip to content

Commit

Permalink
Fix call hierarchy position resolution eclipse-jdtls#2771
Browse files Browse the repository at this point in the history
  • Loading branch information
gayanper authored and rgrunber committed Jul 26, 2023
1 parent e49a751 commit da3292f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public List<CallHierarchyItem> prepareCallHierarchy(CallHierarchyPrepareParams p
int character = params.getPosition().getCharacter();

try {
IMember candidate = getCallHierarchyElement(uri, line, character, monitor);
IMember candidate = getCallHierarchyElement(uri, line, character, true, monitor);
if (candidate == null) {
return null;
}
Expand Down Expand Up @@ -140,7 +140,7 @@ public List<CallHierarchyOutgoingCall> callHierarchyOutgoingCalls(CallHierarchyO
return null;
}

private IMember getCallHierarchyElement(String uri, int line, int character, IProgressMonitor monitor) throws JavaModelException {
private IMember getCallHierarchyElement(String uri, int line, int character, boolean prepare, IProgressMonitor monitor) throws JavaModelException {
Assert.isNotNull(uri, "uri");

ITypeRoot root = JDTUtils.resolveTypeRoot(uri);
Expand All @@ -162,7 +162,12 @@ private IMember getCallHierarchyElement(String uri, int line, int character, IPr
int offset = JsonRpcHelpers.toOffset(root, line, character);
List<IJavaElement> selectedElements = codeResolve(root, offset);
Stream<IJavaElement> possibleElements = selectedElements.stream().filter(CallHierarchyCore::isPossibleInputElement);
Optional<IJavaElement> firstElement = possibleElements.findFirst();
Optional<IJavaElement> firstElement = possibleElements.findFirst().flatMap(element -> {
if (!prepare && element instanceof IType) {
return Optional.ofNullable(getEnclosingMember(root, offset)).map(IJavaElement.class::cast).filter(e -> !element.equals(e)).or(() -> Optional.of(element));
}
return Optional.of(element);
});
if (firstElement.isPresent() && firstElement.get() instanceof IMember member) {
candidate = member;
}
Expand All @@ -177,7 +182,7 @@ private IMember getCallHierarchyElement(String uri, int line, int character, IPr

private List<CallHierarchyIncomingCall> getIncomingCallItemsAt(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));
IMember candidate = getCallHierarchyElement(uri, line, character, false, sub.split(1));
if (candidate == null) {
return null;
}
Expand Down Expand Up @@ -228,7 +233,7 @@ private Range getRange(IOpenable openable, CallLocation location) {

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));
IMember candidate = getCallHierarchyElement(uri, line, character, false, sub.split(1));
if (candidate == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.sample;

public interface CallHierarchyGH2771 {
Opt<String> name();

public static class Opt<T> {
public static <T> Opt<T> of(T t) {
return new Opt();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,35 @@ public void outgoing_jar() throws Exception {
assertTrue(jarUri.contains("WordUtils.class"));
}

@Test
public void incomingCalls_OnInterfaceMethod() throws Exception {
// Line 27 from `CallHierarchy`
// public void <|>bar() {
String uri = getUriFromSrcProject("org.sample.CallHierarchyGH2771");
List<CallHierarchyItem> items = prepareCallHierarchy(uri, 3, 17);
assertNotNull(items);
assertEquals(1, items.size());
assertItem(items.get(0), "name()" + JavaElementLabels.DECL_STRING + "Opt<String>", Method, "org.sample.CallHierarchyGH2771", false, 3);

List<CallHierarchyIncomingCall> calls = getIncomingCalls(items.get(0));
assertNotNull(calls);
assertEquals(0, calls.size());
}

@Test
public void incomingCalls_OnInterfaceMethodReturnType() throws Exception {
// Line 27 from `CallHierarchy`
// public void <|>bar() {
String uri = getUriFromSrcProject("org.sample.CallHierarchyGH2771");
List<CallHierarchyItem> items = prepareCallHierarchy(uri, 3, 6);
assertNotNull(items);
assertEquals(1, items.size());
assertItem(items.get(0), "Opt<T>", Class, "org.sample.CallHierarchyGH2771", false, 5);

List<CallHierarchyIncomingCall> calls = getIncomingCalls(items.get(0));
assertNotNull(calls);
assertEquals(1, calls.size());
}
// @Test
// public void outgoing_recursive() throws Exception {
// // Line 60 from `CallHierarchy`
Expand Down

0 comments on commit da3292f

Please sign in to comment.