# HG changeset patch # User jlahoda # Date 1595921512 -7200 # Tue Jul 28 09:31:52 2020 +0200 # Node ID e8ab7486100b22d77552643054dac8ab5c118165 # Parent d847a98a32cf0b4daefa57ee76d61106c5d6f0ea [mq]: 8248641 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -154,7 +154,13 @@ JCCase t = (JCCase) node; List pats = copy(t.pats, p); List stats = copy(t.stats, p); - JCTree body = copy(t.body, p); + JCTree body; + if (node.getCaseKind() == CaseTree.CaseKind.RULE) { + body = t.body instanceof JCExpression && t.stats.head.hasTag(Tag.YIELD) + ? ((JCYield) t.stats.head).value : t.stats.head; + } else { + body = null; + } return M.at(t.pos).Case(t.caseKind, pats, stats, body); } diff --git a/test/langtools/tools/javac/api/TestGetScopeResult.java b/test/langtools/tools/javac/api/TestGetScopeResult.java --- a/test/langtools/tools/javac/api/TestGetScopeResult.java +++ b/test/langtools/tools/javac/api/TestGetScopeResult.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8205418 8207229 8207230 8230847 8245786 8247334 + * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 * @summary Test the outcomes from Trees.getScope * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.comp @@ -34,6 +34,7 @@ import java.io.IOException; import java.net.URI; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.lang.model.element.Element; @@ -60,11 +61,14 @@ import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacScope; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.comp.Analyzer; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCase; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context.Factory; @@ -82,6 +86,7 @@ new TestGetScopeResult().testCircular(); new TestGetScopeResult().testRecord(); new TestGetScopeResult().testLocalRecordAnnotation(); + new TestGetScopeResult().testRuleCases(); } public void run() throws IOException { @@ -636,6 +641,103 @@ } } + void testRuleCases() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + String code = """ + class Test { + void t(int i) { + long local; + System.err.println(switch (i) { + case 0 -> { + String var; + int scopeHere; + yield ""; + } + default -> { + String var; + int scopeHere; + yield ""; + } + }); + switch (i) { + case 0 -> { + String var; + int scopeHere; + } + default -> { + String var; + int scopeHere; + } + }; + switch (i) { + case 0: { + int checkTree; + } + } + } + } + """; + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return code; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + List options = List.of("--enable-preview", + "-source", System.getProperty("java.specification.version")); + JavacTask t = (JavacTask) c.getTask(null, fm, null, options, null, + List.of(new MyFileObject()), ctx); + CompilationUnitTree cut = t.parse().iterator().next(); + t.analyze(); + + List> actual = new ArrayList<>(); + + new TreePathScanner() { + @Override + public Void visitVariable(VariableTree node, Void p) { + if (node.getName().contentEquals("scopeHere")) { + Scope scope = Trees.instance(t).getScope(getCurrentPath()); + actual.add(dumpScope(scope)); + JCTree body = getCaseBody(scope); + if (body == null) { + throw new AssertionError("Unexpected null body."); + } + } else if (node.getName().contentEquals("checkTree")) { + Scope scope = Trees.instance(t).getScope(getCurrentPath()); + JCTree body = getCaseBody(scope); + if (body != null) { + throw new AssertionError("Unexpected body tree: " + body); + } + } + return super.visitVariable(node, p); + } + JCTree getCaseBody(Scope scope) { + return ((JCCase) ((JavacScope) scope).getEnv().next.next.tree).body; + } + }.scan(cut, null); + + List> expected = + Collections.nCopies(4, + List.of("scopeHere:int", + "var:java.lang.String", + "local:long", + "i:int", + "super:java.lang.Object", + "this:Test" + )); + + if (!expected.equals(actual)) { + throw new AssertionError("Unexpected Scope content: " + actual); + } + } + } + private List dumpScope(Scope scope) { List content = new ArrayList<>(); while (scope.getEnclosingClass() != null) {