Skip to content

Commit 1b64fb2

Browse files
committedJun 12, 2020
8247334: Trees.getScope crashes for annotated local records
Reviewed-by: vromero
1 parent 24f040d commit 1b64fb2

File tree

2 files changed

+82
-8
lines changed

2 files changed

+82
-8
lines changed
 

‎src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -995,11 +995,13 @@ protected void runPhase(Env<AttrContext> env) {
995995
ClassSymbol sym = tree.sym;
996996
ClassType ct = (ClassType)sym.type;
997997

998+
JCTree defaultConstructor = null;
999+
9981000
// Add default constructor if needed.
9991001
DefaultConstructorHelper helper = getDefaultConstructorHelper(env);
10001002
if (helper != null) {
1001-
JCTree constrDef = defaultConstructor(make.at(tree.pos), helper);
1002-
tree.defs = tree.defs.prepend(constrDef);
1003+
defaultConstructor = defaultConstructor(make.at(tree.pos), helper);
1004+
tree.defs = tree.defs.prepend(defaultConstructor);
10031005
}
10041006
if (!sym.isRecord()) {
10051007
enterThisAndSuper(sym, env);
@@ -1011,7 +1013,7 @@ protected void runPhase(Env<AttrContext> env) {
10111013
}
10121014
}
10131015

1014-
finishClass(tree, env);
1016+
finishClass(tree, defaultConstructor, env);
10151017

10161018
if (allowTypeAnnos) {
10171019
typeAnnotations.organizeTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
@@ -1052,7 +1054,7 @@ DefaultConstructorHelper getDefaultConstructorHelper(Env<AttrContext> env) {
10521054

10531055
/** Enter members for a class.
10541056
*/
1055-
void finishClass(JCClassDecl tree, Env<AttrContext> env) {
1057+
void finishClass(JCClassDecl tree, JCTree defaultConstructor, Env<AttrContext> env) {
10561058
if ((tree.mods.flags & Flags.ENUM) != 0 &&
10571059
!tree.sym.type.hasTag(ERROR) &&
10581060
(types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
@@ -1063,9 +1065,7 @@ void finishClass(JCClassDecl tree, Env<AttrContext> env) {
10631065
if (isRecord) {
10641066
alreadyEntered = List.convert(JCTree.class, TreeInfo.recordFields(tree));
10651067
alreadyEntered = alreadyEntered.prependList(tree.defs.stream()
1066-
.filter(t -> TreeInfo.isConstructor(t) &&
1067-
((JCMethodDecl)t).sym != null &&
1068-
(((JCMethodDecl)t).sym.flags_field & Flags.GENERATEDCONSTR) == 0).collect(List.collector()));
1068+
.filter(t -> TreeInfo.isConstructor(t) && t != defaultConstructor).collect(List.collector()));
10691069
}
10701070
List<JCTree> defsToEnter = isRecord ?
10711071
tree.defs.diff(alreadyEntered) : tree.defs;

‎test/langtools/tools/javac/api/TestGetScopeResult.java

+75-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8205418 8207229 8207230 8230847 8245786
26+
* @bug 8205418 8207229 8207230 8230847 8245786 8247334
2727
* @summary Test the outcomes from Trees.getScope
2828
* @modules jdk.compiler/com.sun.tools.javac.api
2929
* jdk.compiler/com.sun.tools.javac.comp
@@ -42,6 +42,7 @@
4242
import javax.tools.StandardJavaFileManager;
4343
import javax.tools.ToolProvider;
4444

45+
import com.sun.source.tree.AnnotationTree;
4546
import com.sun.source.tree.BlockTree;
4647
import com.sun.source.tree.ClassTree;
4748
import com.sun.source.tree.CompilationUnitTree;
@@ -80,6 +81,7 @@ public static void main(String... args) throws IOException {
8081
new TestGetScopeResult().testAnnotationsLazy();
8182
new TestGetScopeResult().testCircular();
8283
new TestGetScopeResult().testRecord();
84+
new TestGetScopeResult().testLocalRecordAnnotation();
8385
}
8486

8587
public void run() throws IOException {
@@ -562,6 +564,78 @@ public Void visitClass(ClassTree node, Void p) {
562564
}
563565
}
564566

567+
void testLocalRecordAnnotation() throws IOException {
568+
JavacTool c = JavacTool.create();
569+
try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
570+
class Variant {
571+
final String code;
572+
final List<List<String>> expectedScopeContent;
573+
public Variant(String code, List<List<String>> expectedScopeContent) {
574+
this.code = code;
575+
this.expectedScopeContent = expectedScopeContent;
576+
}
577+
}
578+
Variant[] variants = new Variant[] {
579+
new Variant("""
580+
class Test {
581+
void t() {
582+
record R(@Annotation int i) {
583+
void stop () {}
584+
}
585+
}
586+
}
587+
@interface Annotation {}
588+
""",
589+
List.of(
590+
List.of("super:java.lang.Object", "this:Test"),
591+
List.of("super:java.lang.Object", "this:Test")
592+
)),
593+
new Variant("""
594+
record Test(@Annotation int i) {}
595+
@interface Annotation {}
596+
""",
597+
List.of(
598+
List.of("i:int", "super:java.lang.Record", "this:Test"),
599+
List.of("super:java.lang.Record", "this:Test")
600+
))
601+
};
602+
for (Variant currentVariant : variants) {
603+
class MyFileObject extends SimpleJavaFileObject {
604+
MyFileObject() {
605+
super(URI.create("myfo:///Test.java"), SOURCE);
606+
}
607+
@Override
608+
public String getCharContent(boolean ignoreEncodingErrors) {
609+
return currentVariant.code;
610+
}
611+
}
612+
Context ctx = new Context();
613+
TestAnalyzer.preRegister(ctx);
614+
List<String> options = List.of("--enable-preview",
615+
"-source", System.getProperty("java.specification.version"));
616+
JavacTask t = (JavacTask) c.getTask(null, fm, null, options, null,
617+
List.of(new MyFileObject()), ctx);
618+
CompilationUnitTree cut = t.parse().iterator().next();
619+
t.analyze();
620+
621+
List<List<String>> actual = new ArrayList<>();
622+
623+
new TreePathScanner<Void, Void>() {
624+
@Override
625+
public Void visitAnnotation(AnnotationTree node, Void p) {
626+
Scope scope = Trees.instance(t).getScope(getCurrentPath());
627+
actual.add(dumpScope(scope));
628+
return super.visitAnnotation(node, p);
629+
}
630+
}.scan(cut, null);
631+
632+
if (!currentVariant.expectedScopeContent.equals(actual)) {
633+
throw new AssertionError("Unexpected Scope content: " + actual);
634+
}
635+
}
636+
}
637+
}
638+
565639
private List<String> dumpScope(Scope scope) {
566640
List<String> content = new ArrayList<>();
567641
while (scope.getEnclosingClass() != null) {

0 commit comments

Comments
 (0)
Please sign in to comment.