-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
T#<method declared in java.lang.Object>, where T is a Type Parameter, cannot be resolved. #2044
Comments
@ftomassetti and friends? |
How are you doing getting the resolved type? Something similar came up as a problem for me recently where NB: This comes with the disclaimer that I've not fully investigated/confirmed the difference, but it might be related to the above. |
I'm still using the old API, so I get the Additional Info: This is the stacktrace:
|
Been doing some digging and the issue above is easy to demonstrate using these test cases. Resolving The stack trace and the exception thrown varies depending on how the resolution happens. The "solution" seems simple in that where there are no bounds then the equivalent of @Test
public void issue2044_typeVariableExtendsObject() {
String x = "public class X <K extends Object> {\n" +
" private int getPartition(final K key) {\n" +
" int x = (new Object()).hashCode();\n" +
" return key.hashCode() / getHashes().length;\n" +
" }\n" +
"}";
doTestSimple(x); // passes
}
@Test
public void issue2044_simpleTypeVariable() {
String x = "public class X <K> {\n" +
" private int getPartition(final K key) {\n" +
" int x = (new Object()).hashCode();\n" +
" return key.hashCode() / getHashes().length;\n" +
" }\n" +
"}";
doTestSimple(x); // fails
}
private void doTestSimple(String x) {
TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver());
ParserConfiguration configuration = new ParserConfiguration().setSymbolResolver(new JavaSymbolSolver(typeSolver));
JavaParser javaParser = new JavaParser(configuration);
ParseResult<CompilationUnit> result = javaParser.parse(ParseStart.COMPILATION_UNIT, provider(x));
assumeTrue(result.isSuccessful());
result.ifSuccessful(compilationUnit -> {
List<MethodCallExpr> methodCallExprs = compilationUnit.findAll(MethodCallExpr.class);
assertEquals(3, methodCallExprs.size());
MethodCallExpr methodCallExpr = methodCallExprs.get(1);
//// Exception-triggering method calls
// throws RuntimeException - stack trace below
methodCallExpr.calculateResolvedType();
/*
java.lang.RuntimeException: Method 'hashCode' cannot be resolved in context key.hashCode() (line: 3) MethodCallExprContext{wrapped=key.hashCode()}. Parameter types: []
at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(JavaParserFacade.java:586)
at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:267)
at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:44)
at com.github.javaparser.ast.expr.MethodCallExpr.accept(MethodCallExpr.java:115)
at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(JavaParserFacade.java:447)
at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(JavaParserFacade.java:310)
at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(JavaParserFacade.java:292)
at com.github.javaparser.symbolsolver.JavaSymbolSolver.calculateType(JavaSymbolSolver.java:250)
at com.github.javaparser.ast.expr.Expression.calculateResolvedType(Expression.java:564)
at com.github.javaparser.symbolsolver.Issue2044.lambda$null$0(Issue2044.java:81)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at com.github.javaparser.symbolsolver.Issue2044.lambda$issue2044$1(Issue2044.java:49)
*/
// throws UnsolvedSymbolException - stack trace below
methodCallExpr.resolve();
/*
Unsolved symbol : We are unable to find the method declaration corresponding to key.hashCode()
UnsolvedSymbolException{context='null', name='We are unable to find the method declaration corresponding to key.hashCode()', cause='null'}
at com.github.javaparser.symbolsolver.JavaSymbolSolver.resolveDeclaration(JavaSymbolSolver.java:146)
at com.github.javaparser.ast.expr.MethodCallExpr.resolve(MethodCallExpr.java:313)
at com.github.javaparser.symbolsolver.Issue2044.lambda$null$0(Issue2044.java:101)
*/
});
} Note that this is where the bound-checking takes place - Lines 385 to 393 in 770059b
|
Note that this is sufficient to make the tests above pass, but has wider implications re: generating code etc. public TypeParameter(TokenRange tokenRange, SimpleName name, NodeList<ClassOrInterfaceType> typeBound, NodeList<AnnotationExpr> annotations) {
super(tokenRange, annotations);
setName(name);
if(typeBound.isEmpty()) {
ClassOrInterfaceType object = new ClassOrInterfaceType();
object.setName("Object");
typeBound.add(object);
}
setTypeBound(typeBound);
customInitialization();
} javaparser/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java Lines 92 to 98 in 770059b
|
I agree that the symbol solver should figure out that K is at least an Object. I am surprised this is not the case already |
…ct" when resolving TypeVariables with an empty bounds list
Let's look at this sample method I have:
Based on what I've seen so far, the symbol solver cannot find a
ResolvedMethodDeclaration
from theMethodCallExpr
key.hashCode()
becausekey
is of typeK
a type parameter. However,key.hashCode()
is a validMethodCallExpr
, because K implicitly extendsObject
.I may be way off here, and I may have not set up my resolver correctly (though I am using
ReflectionTypeSolver
). But is this what is happening, and if so, does this sound like a bug or intended behavior? I can get around it either way.The text was updated successfully, but these errors were encountered: