test/langtools/tools/javac/api/TestGetScopeResult.java
changeset 58906 d58a21542c04
parent 52697 605878cd4009
--- 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<Void, Void>() {
+                @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<Void, Void>() {
+                @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<Void, Void>() {
+                @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<Void, Void>() {
+                            @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<Void, Void>() {
+                @Override
+                public Void visitBlock(BlockTree node, Void p) {
+                    Trees.instance(t).getScope(getCurrentPath());
+                    return super.visitBlock(node, p);
+                }
+            }.scan(cut, null);
+        }
+    }
+
 }
-