Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit 642ab34

Browse files
committed
8278373: JavacTrees.searchMethod finds incorrect match
Reviewed-by: vromero, jjg
1 parent d65c665 commit 642ab34

File tree

2 files changed

+87
-18
lines changed

2 files changed

+87
-18
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,16 @@ private Symbol attributeDocReference(TreePath path, DCReference ref) {
507507
}
508508

509509
ClassSymbol sym = (ClassSymbol) types.skipTypeVars(tsym.type, false).tsym;
510-
511510
Symbol msym = (memberName == sym.name)
512-
? findConstructor(sym, paramTypes)
513-
: findMethod(sym, memberName, paramTypes);
511+
? findConstructor(sym, paramTypes, true)
512+
: findMethod(sym, memberName, paramTypes, true);
513+
514+
if (msym == null) {
515+
msym = (memberName == sym.name)
516+
? findConstructor(sym, paramTypes, false)
517+
: findMethod(sym, memberName, paramTypes, false);
518+
}
519+
514520
if (paramTypes != null) {
515521
// explicit (possibly empty) arg list given, so cannot be a field
516522
return msym;
@@ -608,23 +614,24 @@ private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set<ClassSymbol>
608614
return null;
609615
}
610616

611-
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
617+
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes, boolean strict) {
612618
for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
613619
if (sym.kind == MTH) {
614-
if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
620+
if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) {
615621
return (MethodSymbol) sym;
616622
}
617623
}
618624
}
619625
return null;
620626
}
621627

622-
private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
623-
return searchMethod(tsym, methodName, paramTypes, new HashSet<>());
628+
private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes, boolean strict) {
629+
return searchMethod(tsym, methodName, paramTypes, strict, new HashSet<>());
624630
}
625631

626632
private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
627-
List<Type> paramTypes, Set<ClassSymbol> searched) {
633+
List<Type> paramTypes, boolean strict,
634+
Set<ClassSymbol> searched) {
628635
//### Note that this search is not necessarily what the compiler would do!
629636

630637
// do not match constructors
@@ -662,7 +669,7 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
662669
for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
663670
if (sym != null &&
664671
sym.kind == MTH) {
665-
if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
672+
if (hasParameterTypes((MethodSymbol) sym, paramTypes, strict)) {
666673
return (MethodSymbol) sym;
667674
}
668675
}
@@ -675,7 +682,7 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
675682
// search superclass
676683
Type superclass = tsym.getSuperclass();
677684
if (superclass.tsym != null) {
678-
MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched);
685+
MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, strict, searched);
679686
if (msym != null) {
680687
return msym;
681688
}
@@ -686,7 +693,7 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
686693
for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
687694
Type intf = l.head;
688695
if (intf.isErroneous()) continue;
689-
MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched);
696+
MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, strict, searched);
690697
if (msym != null) {
691698
return msym;
692699
}
@@ -695,7 +702,7 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
695702
// search enclosing class
696703
ClassSymbol encl = tsym.owner.enclClass();
697704
if (encl != null) {
698-
MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched);
705+
MethodSymbol msym = searchMethod(encl, methodName, paramTypes, strict, searched);
699706
if (msym != null) {
700707
return msym;
701708
}
@@ -704,15 +711,15 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
704711
return null;
705712
}
706713

707-
private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
714+
private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes, boolean strict) {
708715
if (paramTypes == null)
709716
return true;
710717

711718
if (method.params().size() != paramTypes.size())
712719
return false;
713720

714721
List<Type> methodParamTypes = method.asType().getParameterTypes();
715-
if (!Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) {
722+
if (!strict && !Type.isErroneous(paramTypes) && types.isSubtypes(paramTypes, methodParamTypes)) {
716723
return true;
717724
}
718725

test/langtools/tools/javac/doctree/ReferenceTest.java

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 7021614
26+
* @bug 7021614 8278373
2727
* @summary extend com.sun.source API to support parsing javadoc comments
2828
* @summary check references in at-see and {at-link} tags
2929
* @modules jdk.compiler
@@ -39,19 +39,23 @@
3939
import com.sun.source.doctree.TextTree;
4040
import com.sun.source.util.DocTreePath;
4141
import com.sun.source.util.DocTreePathScanner;
42-
import com.sun.source.util.DocTreeScanner;
4342
import com.sun.source.util.DocTrees;
4443
import com.sun.source.util.TreePath;
4544

4645
import java.util.List;
4746
import java.util.Set;
47+
import java.util.stream.Collectors;
4848
import javax.annotation.processing.AbstractProcessor;
4949
import javax.annotation.processing.ProcessingEnvironment;
5050
import javax.annotation.processing.RoundEnvironment;
5151
import javax.annotation.processing.SupportedAnnotationTypes;
5252
import javax.lang.model.SourceVersion;
5353
import javax.lang.model.element.Element;
54+
import javax.lang.model.element.ExecutableElement;
55+
import javax.lang.model.element.QualifiedNameable;
5456
import javax.lang.model.element.TypeElement;
57+
import javax.lang.model.type.DeclaredType;
58+
import javax.lang.model.type.TypeMirror;
5559
import javax.tools.Diagnostic.Kind;
5660

5761
/**
@@ -174,15 +178,48 @@ void checkReference(ReferenceTree tree, List<? extends DocTree> label) {
174178
if (label.size() > 0 && label.get(0) instanceof TextTree)
175179
expect = ((TextTree) label.get(0)).getBody();
176180

177-
if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) {
178-
error(tree, "Unexpected value found: " + found +", expected: " + expect);
181+
if (expect.startsWith("signature:")) {
182+
expect = expect.substring("signature:".length());
183+
184+
String signature = found.getKind().name() + ":" + elementSignature(found);
185+
186+
if (!expect.equalsIgnoreCase(signature)) {
187+
error(tree, "Unexpected value found: " + signature +", expected: " + expect);
188+
}
189+
} else {
190+
if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) {
191+
error(tree, "Unexpected value found: " + found +", expected: " + expect);
192+
}
179193
}
180194
}
181195

182196
void error(DocTree tree, String msg) {
183197
trees.printMessage(Kind.ERROR, msg, tree, dc, path.getCompilationUnit());
184198
}
185199
}
200+
201+
String elementSignature(Element el) {
202+
return switch (el.getKind()) {
203+
case METHOD -> elementSignature(el.getEnclosingElement()) + "." + el.getSimpleName() + "(" + executableParamNames((ExecutableElement) el) + ")";
204+
case CLASS, INTERFACE -> ((QualifiedNameable) el).getQualifiedName().toString();
205+
default -> throw new AssertionError("Unhandled Element kind: " + el.getKind());
206+
};
207+
}
208+
209+
String executableParamNames(ExecutableElement ee) {
210+
return ee.getParameters()
211+
.stream()
212+
.map(p -> type2Name(p.asType()))
213+
.collect(Collectors.joining(", "));
214+
}
215+
216+
String type2Name(TypeMirror type) {
217+
return switch (type.getKind()) {
218+
case DECLARED -> elementSignature(((DeclaredType) type).asElement());
219+
case INT, LONG -> type.toString();
220+
default -> throw new AssertionError("Unhandled type kind: " + type.getKind());
221+
};
222+
}
186223
}
187224

188225
/**
@@ -199,6 +236,17 @@ void error(DocTree tree, String msg) {
199236
* @see #varargs(int... args) Method
200237
* @see #varargs(int[]) Method
201238
* @see #varargs(int[] args) Method
239+
*
240+
* @see #methodSearch(String) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.String)
241+
* @see #methodSearch(StringBuilder) signature:METHOD:ReferenceTestExtras.methodSearch(java.lang.CharSequence)
242+
* @see #methodSearchPrimitive1(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, int)
243+
* @see #methodSearchPrimitive1(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, int)
244+
* @see #methodSearchPrimitive1(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(int, long)
245+
* @see #methodSearchPrimitive1(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive1(long, long)
246+
* @see #methodSearchPrimitive2(int, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, int)
247+
* @see #methodSearchPrimitive2(long, int) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, int)
248+
* @see #methodSearchPrimitive2(int, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(int, long)
249+
* @see #methodSearchPrimitive2(long, long) signature:METHOD:ReferenceTestExtras.methodSearchPrimitive2(long, long)
202250
*/
203251
class ReferenceTestExtras {
204252
int ReferenceTestExtras; // field
@@ -214,6 +262,20 @@ void m(int i) { }
214262
void m(int i, int j) { }
215263

216264
void varargs(int... args) { }
265+
266+
void methodSearch(Object o) {}
267+
void methodSearch(String s) {}
268+
void methodSearch(CharSequence cs) {}
269+
270+
void methodSearchPrimitive1(int i, int j) {}
271+
void methodSearchPrimitive1(long i, int j) {}
272+
void methodSearchPrimitive1(int i, long j) {}
273+
void methodSearchPrimitive1(long i, long j) {}
274+
275+
void methodSearchPrimitive2(long i, long j) {}
276+
void methodSearchPrimitive2(int i, long j) {}
277+
void methodSearchPrimitive2(long i, int j) {}
278+
void methodSearchPrimitive2(int i, int j) {}
217279
}
218280

219281

0 commit comments

Comments
 (0)