diff -r 75eedcd30a2a -r d58a21542c04 test/langtools/tools/javac/api/TestGetScopeResult.java --- a/test/langtools/tools/javac/api/TestGetScopeResult.java Wed Oct 30 14:52:27 2019 +0100 +++ b/test/langtools/tools/javac/api/TestGetScopeResult.java Mon Nov 04 10:58:14 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8205418 8207229 8207230 + * @bug 8205418 8207229 8207230 8230847 * @summary Test the outcomes from Trees.getScope * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.comp @@ -42,11 +42,19 @@ import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; +import com.sun.source.tree.BlockTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.ConditionalExpressionTree; +import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.LambdaExpressionTree; +import com.sun.source.tree.MethodInvocationTree; +import com.sun.source.tree.MethodTree; import com.sun.source.tree.Scope; +import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; import com.sun.source.util.JavacTask; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; import com.sun.source.util.Trees; @@ -65,6 +73,11 @@ public static void main(String... args) throws IOException { new TestGetScopeResult().run(); new TestGetScopeResult().testAnalyzerDisabled(); + new TestGetScopeResult().testVariablesInSwitch(); + new TestGetScopeResult().testMemberRefs(); + new TestGetScopeResult().testAnnotations(); + new TestGetScopeResult().testAnnotationsLazy(); + new TestGetScopeResult().testCircular(); } public void run() throws IOException { @@ -259,5 +272,225 @@ super.analyze(statement, env); } } + + void testVariablesInSwitch() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return "class Test {" + + " void test() {\n" + + " E e = E.A;\n" + + " Object o = E.A;\n" + + " switch (e) {\n" + + " case A:\n" + + " return;\n" + + " case B:\n" + + " test();\n" + + " E ee = null;\n" + + " break;\n" + + " }\n" + + " }\n" + + " enum E {A, B}\n" + + "}"; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(new MyFileObject()), ctx); + CompilationUnitTree cut = t.parse().iterator().next(); + t.analyze(); + + new TreePathScanner() { + @Override + public Void visitMethodInvocation(MethodInvocationTree node, Void p) { + Trees.instance(t).getScope(getCurrentPath()); + return super.visitMethodInvocation(node, p); + } + }.scan(cut, null); + } + } + + void testMemberRefs() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return "class Test {" + + " void test() {\n" + + " Test t = this;\n" + + " Runnable r1 = t::test;\n" + + " Runnable r2 = true ? t::test : t::test;\n" + + " c(t::test);\n" + + " c(true ? t::test : t::test);\n" + + " }\n" + + " void c(Runnable r) {}\n" + + "}"; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(new MyFileObject()), ctx); + CompilationUnitTree cut = t.parse().iterator().next(); + t.analyze(); + + new TreePathScanner() { + @Override + public Void visitConditionalExpression(ConditionalExpressionTree node, Void p) { + Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getCondition())); + return super.visitConditionalExpression(node, p); + } + + @Override + public Void visitBlock(BlockTree node, Void p) { + Trees.instance(t).getScope(getCurrentPath()); + return super.visitBlock(node, p); + } + }.scan(cut, null); + } + } + + void testAnnotations() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return "class Test {" + + " void test() {\n" + + " new Object() {\n" + + " @A\n" + + " public String t() { return null; }\n" + + " };\n" + + " }\n" + + " @interface A {}\n" + + "}"; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(new MyFileObject()), ctx); + CompilationUnitTree cut = t.parse().iterator().next(); + t.analyze(); + + new TreePathScanner() { + @Override + public Void visitIdentifier(IdentifierTree node, Void p) { + if (node.getName().contentEquals("A")) { + Trees.instance(t).getScope(getCurrentPath()); + } + return super.visitIdentifier(node, p); + } + + @Override + public Void visitMethod(MethodTree node, Void p) { + super.visitMethod(node, p); + if (node.getReturnType() != null) { + Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getReturnType())); + } + return null; + } + }.scan(cut, null); + } + } + + void testAnnotationsLazy() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return "import java.lang.annotation.*;\n" + + "\n" + + "class ClassA {\n" + + " Object o = ClassB.lcv;\n" + + "}\n" + + "\n" + + "class ClassB {\n" + + " static final String[] lcv = new @TA String[0];\n" + + "}\n" + + "\n" + + "class ClassC {\n" + + " static final Object o = (@TA Object) null;\n" + + "}\n" + + "\n" + + "@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})\n" + + "@interface TA {}\n"; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(new MyFileObject()), ctx); + t.addTaskListener(new TaskListener() { + @Override + public void finished(TaskEvent e) { + if (e.getKind() == TaskEvent.Kind.ANALYZE) { + new TreePathScanner() { + @Override + public Void scan(Tree tree, Void p) { + if (tree != null) { + Trees.instance(t).getScope(new TreePath(getCurrentPath(), tree)); + } + return super.scan(tree, p); + } + }.scan(Trees.instance(t).getPath(e.getTypeElement()), null); + } + } + }); + + t.call(); + } + } + + void testCircular() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + class MyFileObject extends SimpleJavaFileObject { + MyFileObject() { + super(URI.create("myfo:///Test.java"), SOURCE); + } + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return "class Test extends Test {" + + " {\n" + + " int i;\n" + + " }\n" + + "}"; + } + } + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(new MyFileObject()), ctx); + CompilationUnitTree cut = t.parse().iterator().next(); + t.analyze(); + + new TreePathScanner() { + @Override + public Void visitBlock(BlockTree node, Void p) { + Trees.instance(t).getScope(getCurrentPath()); + return super.visitBlock(node, p); + } + }.scan(cut, null); + } + } + } -