8369508: Type annotations on anonymous new class creation expressions can't be retrieved

Reviewed-by: vromero
This commit is contained in:
Liam Miller-Cushon 2025-10-29 07:26:00 +00:00
parent 0687f120cc
commit c97d50d793
3 changed files with 19 additions and 21 deletions

View File

@ -332,6 +332,13 @@ public class Annotate {
Assert.checkNonNull(c, "Failed to create annotation");
if (env.info.isAnonymousNewClass) {
// Annotations on anonymous class instantiations should be attributed,
// but not attached to the enclosing element. They will be visited
// separately and attached to the synthetic class declaration.
continue;
}
if (a.type.isErroneous() || a.type.tsym.isAnnotationType()) {
if (annotated.containsKey(a.type.tsym)) {
ListBuffer<T> l = annotated.get(a.type.tsym);
@ -1144,8 +1151,11 @@ public class Annotate {
public void visitNewClass(JCNewClass tree) {
scan(tree.encl);
scan(tree.typeargs);
if (tree.def == null) {
try {
env.info.isAnonymousNewClass = tree.def != null;
scan(tree.clazz);
} finally {
env.info.isAnonymousNewClass = false;
}
scan(tree.args);
// the anonymous class instantiation if any will be visited separately.

View File

@ -2777,16 +2777,9 @@ public class Attr extends JCTree.Visitor {
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
Type clazztype;
try {
env.info.isAnonymousNewClass = tree.def != null;
clazztype = TreeInfo.isEnumInit(env.tree) ?
attribIdentAsEnumType(env, (JCIdent)clazz) :
attribType(clazz, env);
} finally {
env.info.isAnonymousNewClass = false;
}
Type clazztype = TreeInfo.isEnumInit(env.tree) ?
attribIdentAsEnumType(env, (JCIdent)clazz) :
attribType(clazz, env);
clazztype = chk.checkDiamond(tree, clazztype);
chk.validate(clazz, localEnv);
@ -5256,8 +5249,7 @@ public class Attr extends JCTree.Visitor {
Type underlyingType = attribType(tree.underlyingType, env);
Type annotatedType = underlyingType.preannotatedType();
if (!env.info.isAnonymousNewClass)
annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
result = tree.type = annotatedType;
}

View File

@ -31,7 +31,6 @@
* @run main NewClassTypeAnnotation
*/
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.source.util.TreePathScanner;
@ -91,6 +90,7 @@ public class NewClassTypeAnnotation extends TestRunner {
public void testMethod() {
new Test<@TypeAnnotation String>();
new Test<@TypeAnnotation String>() {};
}
}
""");
@ -112,11 +112,7 @@ public class NewClassTypeAnnotation extends TestRunner {
@Override
public Void visitNewClass(final NewClassTree node, final Void unused) {
TypeMirror type = trees.getTypeMirror(getCurrentPath());
System.err.println(">>> " + type);
for (Tree t : getCurrentPath()) {
System.err.println(t);
}
actual.add(String.format("Expression: %s, Type: %s", node, type));
actual.add(String.format("Type: %s", type));
return null;
}
}
@ -144,8 +140,8 @@ public class NewClassTypeAnnotation extends TestRunner {
List<String> expected =
List.of(
"Expression: new Test<@TypeAnnotation String>(), Type:"
+ " test.Test<java.lang.@test.Test.TypeAnnotation String>");
"Type: test.Test<java.lang.@test.Test.TypeAnnotation String>",
"Type: <anonymous test.Test<java.lang.@test.Test.TypeAnnotation String>>");
if (!expected.equals(actual)) {
throw new AssertionError("expected: " + expected + ", actual: " + actual);
}