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

Missing reference in Call Hierarchy (probably due to the use of generics) #402

Closed
mauromol opened this issue Dec 19, 2017 · 5 comments
Closed
Assignees

Comments

@mauromol
Copy link

Consider the following Groovy class:

package test13
abstract class Test13 {
	String foo(Number number, Date date) {
		'Hello'
	}
}

and the following Java class:

package test13;
import java.util.Date;

public class Test13J<T extends Test13> {

	private T test;
	
	void bar() {
		test.foo(1, new Date());
	}
}

If you hit Ctrl+Alt+H (Call Hierarchy) on Test13.foo(Number, Date), the call from Test13J.bar() is not shown.

@eric-milles
Copy link
Member

If I add import java.util.Date to the Test13 comp unit, the match is found. In MethodLocator.resolveLevel, there is a different path if the import is present or not.

protected int resolveLevel(MessageSend messageSend) {
	MethodBinding method = messageSend.binding;
	...
	if (messageSend.resolvedType == null) {
		// Closest match may have different argument numbers when ProblemReason is NotFound
		// see MessageSend#resolveType(BlockScope)
		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=97322
		int argLength = messageSend.arguments == null ? 0 : messageSend.arguments.length;
		if (this.pattern.parameterSimpleNames == null || argLength == this.pattern.parameterSimpleNames.length) {
			return INACCURATE_MATCH; // EXIT HERE as issue is stated
		}
		return IMPOSSIBLE_MATCH;
	}
	...
	int declaringLevel;
	if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) {
		ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
		declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.selector, method.parameters, methodReceiverType.qualifiedPackageName(), method.isDefault());
		if (declaringLevel == IMPOSSIBLE_MATCH) {
			...
		}
		if ((declaringLevel & FLAVORS_MASK) != 0) {
			// level got some flavors => return it
			return declaringLevel; // EXIT HERE if import is added (return value 3075)
		}
	} else ...
}

@mauromol
Copy link
Author

This test case was extracted from a project where there are other types rather than Number and Date. Perhaps in my actual project, import statements may be missing because the parameter types are defined in the same package of the equivalent of Test13 class. Tomorrow I will try and see.

@eric-milles
Copy link
Member

eric-milles commented Dec 19, 2017

I believe the root cause lies in MatchLocator. When the Groovy source is being parsed for search results, there is a case where it triggers this method. Without my edits, the parser treats the source as Java, so the Groovy rules for type lookup are not applied.

protected Parser basicParser() {
	if (this.basicParser == null) {
		ProblemReporter problemReporter =
			new ProblemReporter(
				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
				this.options,
				new DefaultProblemFactory());
		// GROOVY edit
		//this.basicParser = new Parser(problemReporter, false);
		this.basicParser = LanguageSupportFactory.getParser(this, this.options, problemReporter, false, 1);
		// GROOVY end
		this.basicParser.reportOnlyOneSyntaxError = true;
	}
	return this.basicParser;
}

This is a common pattern throughout the JDT Core patch. A Groovy-aware parser is woven in using LanguageSupportFactory.

@eric-milles
Copy link
Member

ready to test

@mauromol
Copy link
Author

Seems to work now with 2.9.2.xx-201712192218-e47, both with this use case and in our main application code. Thank you! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants