8278373: JavacTrees.searchMethod finds incorrect match
Reviewed-by: vromero, jjg
This commit is contained in:
parent
d65c665839
commit
642ab34a60
@ -507,10 +507,16 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
|
||||
ClassSymbol sym = (ClassSymbol) types.skipTypeVars(tsym.type, false).tsym;
|
||||
|
||||
Symbol msym = (memberName == sym.name)
|
||||
? findConstructor(sym, paramTypes)
|
||||
: findMethod(sym, memberName, paramTypes);
|
||||
? findConstructor(sym, paramTypes, true)
|
||||
: findMethod(sym, memberName, paramTypes, true);
|
||||
|
||||
if (msym == null) {
|
||||
msym = (memberName == sym.name)
|
||||
? findConstructor(sym, paramTypes, false)
|
||||
: findMethod(sym, memberName, paramTypes, false);
|
||||
}
|
||||
|
||||
if (paramTypes != null) {
|
||||
// explicit (possibly empty) arg list given, so cannot be a field
|
||||
return msym;
|
||||
@ -608,10 +614,10 @@ public class JavacTrees extends DocTrees {
|
||||
return null;
|
||||
}
|
||||
|
||||
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
|
||||
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes, boolean strict) {
|
||||
for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
|
||||
if (sym.kind == MTH) {
|
||||
if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
|
||||
if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) {
|
||||
return (MethodSymbol) sym;
|
||||
}
|
||||
}
|
||||
@ -619,12 +625,13 @@ public class JavacTrees extends DocTrees {
|
||||
return null;
|
||||
}
|
||||
|
||||
private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
|
||||
return searchMethod(tsym, methodName, paramTypes, new HashSet<>());
|
||||
private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes, boolean strict) {
|
||||
return searchMethod(tsym, methodName, paramTypes, strict, new HashSet<>());
|
||||
}
|
||||
|
||||
private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
|
||||
List<Type> paramTypes, Set<ClassSymbol> searched) {
|
||||
List<Type> paramTypes, boolean strict,
|
||||
Set<ClassSymbol> searched) {
|
||||
//### Note that this search is not necessarily what the compiler would do!
|
||||
|
||||
// do not match constructors
|
||||
@ -662,7 +669,7 @@ public class JavacTrees extends DocTrees {
|
||||
for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
|
||||
if (sym != null &&
|
||||
sym.kind == MTH) {
|
||||
if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
|
||||
if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) {
|
||||
return (MethodSymbol) sym;
|
||||
}
|
||||
}
|
||||
@ -675,7 +682,7 @@ public class JavacTrees extends DocTrees {
|
||||
// search superclass
|
||||
Type superclass = tsym.getSuperclass();
|
||||
if (superclass.tsym != null) {
|
||||
MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched);
|
||||
MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, strict, searched);
|
||||
if (msym != null) {
|
||||
return msym;
|
||||
}
|
||||
@ -686,7 +693,7 @@ public class JavacTrees extends DocTrees {
|
||||
for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
|
||||
Type intf = l.head;
|
||||
if (intf.isErroneous()) continue;
|
||||
MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched);
|
||||
MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, strict, searched);
|
||||
if (msym != null) {
|
||||
return msym;
|
||||
}
|
||||
@ -695,7 +702,7 @@ public class JavacTrees extends DocTrees {
|
||||
// search enclosing class
|
||||
ClassSymbol encl = tsym.owner.enclClass();
|
||||
if (encl != null) {
|
||||
MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched);
|
||||
MethodSymbol msym = searchMethod(encl, methodName, paramTypes, strict, searched);
|
||||
if (msym != null) {
|
||||
return msym;
|
||||
}
|
||||
@ -704,7 +711,7 @@ public class JavacTrees extends DocTrees {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
|
||||
private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes, boolean strict) {
|
||||
if (paramTypes == null)
|
||||
return true;
|
||||
|
||||
@ -712,7 +719,7 @@ public class JavacTrees extends DocTrees {
|
||||
return false;
|
||||
|
||||
List<Type> methodParamTypes = method.asType().getParameterTypes();
|
||||
if (!Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) {
|
||||
if (!strict && !Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7021614
|
||||
* @bug 7021614 8278373
|
||||
* @summary extend com.sun.source API to support parsing javadoc comments
|
||||
* @summary check references in at-see and {at-link} tags
|
||||
* @modules jdk.compiler
|
||||
@ -39,19 +39,23 @@ import com.sun.source.doctree.SeeTree;
|
||||
import com.sun.source.doctree.TextTree;
|
||||
import com.sun.source.util.DocTreePath;
|
||||
import com.sun.source.util.DocTreePathScanner;
|
||||
import com.sun.source.util.DocTreeScanner;
|
||||
import com.sun.source.util.DocTrees;
|
||||
import com.sun.source.util.TreePath;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.QualifiedNameable;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
/**
|
||||
@ -174,8 +178,18 @@ public class ReferenceTest extends AbstractProcessor {
|
||||
if (label.size() > 0 && label.get(0) instanceof TextTree)
|
||||
expect = ((TextTree) label.get(0)).getBody();
|
||||
|
||||
if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) {
|
||||
error(tree, "Unexpected value found: " + found +", expected: " + expect);
|
||||
if (expect.startsWith("signature:")) {
|
||||
expect = expect.substring("signature:".length());
|
||||
|
||||
String signature = found.getKind().name() + ":" + elementSignature(found);
|
||||
|
||||
if (!expect.equalsIgnoreCase(signature)) {
|
||||
error(tree, "Unexpected value found: " + signature +", expected: " + expect);
|
||||
}
|
||||
} else {
|
||||
if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) {
|
||||
error(tree, "Unexpected value found: " + found +", expected: " + expect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +197,29 @@ public class ReferenceTest extends AbstractProcessor {
|
||||
trees.printMessage(Kind.ERROR, msg, tree, dc, path.getCompilationUnit());
|
||||
}
|
||||
}
|
||||
|
||||
String elementSignature(Element el) {
|
||||
return switch (el.getKind()) {
|
||||
case METHOD -> elementSignature(el.getEnclosingElement()) + "." + el.getSimpleName() + "(" + executableParamNames((ExecutableElement) el) + ")";
|
||||
case CLASS, INTERFACE -> ((QualifiedNameable) el).getQualifiedName().toString();
|
||||
default -> throw new AssertionError("Unhandled Element kind: " + el.getKind());
|
||||
};
|
||||
}
|
||||
|
||||
String executableParamNames(ExecutableElement ee) {
|
||||
return ee.getParameters()
|
||||
.stream()
|
||||
.map(p -> type2Name(p.asType()))
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
String type2Name(TypeMirror type) {
|
||||
return switch (type.getKind()) {
|
||||
case DECLARED -> elementSignature(((DeclaredType) type).asElement());
|
||||
case INT, LONG -> type.toString();
|
||||
default -> throw new AssertionError("Unhandled type kind: " + type.getKind());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,6 +236,17 @@ public class ReferenceTest extends AbstractProcessor {
|
||||
* @see #varargs(int... args) Method
|
||||
* @see #varargs(int[]) Method
|
||||
* @see #varargs(int[] args) Method
|
||||
*
|
||||
* @see #methodSearch(String) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.String)
|
||||
* @see #methodSearch(StringBuilder) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.CharSequence)
|
||||
* @see #methodSearchPrimitive1(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, int)
|
||||
* @see #methodSearchPrimitive1(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, int)
|
||||
* @see #methodSearchPrimitive1(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, long)
|
||||
* @see #methodSearchPrimitive1(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, long)
|
||||
* @see #methodSearchPrimitive2(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, int)
|
||||
* @see #methodSearchPrimitive2(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, int)
|
||||
* @see #methodSearchPrimitive2(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, long)
|
||||
* @see #methodSearchPrimitive2(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, long)
|
||||
*/
|
||||
class ReferenceTestExtras {
|
||||
int ReferenceTestExtras; // field
|
||||
@ -214,6 +262,20 @@ class ReferenceTestExtras {
|
||||
void m(int i, int j) { }
|
||||
|
||||
void varargs(int... args) { }
|
||||
|
||||
void methodSearch(Object o) {}
|
||||
void methodSearch(String s) {}
|
||||
void methodSearch(CharSequence cs) {}
|
||||
|
||||
void methodSearchPrimitive1(int i, int j) {}
|
||||
void methodSearchPrimitive1(long i, int j) {}
|
||||
void methodSearchPrimitive1(int i, long j) {}
|
||||
void methodSearchPrimitive1(long i, long j) {}
|
||||
|
||||
void methodSearchPrimitive2(long i, long j) {}
|
||||
void methodSearchPrimitive2(int i, long j) {}
|
||||
void methodSearchPrimitive2(long i, int j) {}
|
||||
void methodSearchPrimitive2(int i, int j) {}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user