test/langtools/tools/javac/api/TestGetScopeResult.java
changeset 58906 d58a21542c04
parent 52697 605878cd4009
equal deleted inserted replaced
58905:75eedcd30a2a 58906:d58a21542c04
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 8205418 8207229 8207230
    26  * @bug 8205418 8207229 8207230 8230847
    27  * @summary Test the outcomes from Trees.getScope
    27  * @summary Test the outcomes from Trees.getScope
    28  * @modules jdk.compiler/com.sun.tools.javac.api
    28  * @modules jdk.compiler/com.sun.tools.javac.api
    29  *          jdk.compiler/com.sun.tools.javac.comp
    29  *          jdk.compiler/com.sun.tools.javac.comp
    30  *          jdk.compiler/com.sun.tools.javac.tree
    30  *          jdk.compiler/com.sun.tools.javac.tree
    31  *          jdk.compiler/com.sun.tools.javac.util
    31  *          jdk.compiler/com.sun.tools.javac.util
    40 import javax.tools.JavaCompiler;
    40 import javax.tools.JavaCompiler;
    41 import javax.tools.SimpleJavaFileObject;
    41 import javax.tools.SimpleJavaFileObject;
    42 import javax.tools.StandardJavaFileManager;
    42 import javax.tools.StandardJavaFileManager;
    43 import javax.tools.ToolProvider;
    43 import javax.tools.ToolProvider;
    44 
    44 
       
    45 import com.sun.source.tree.BlockTree;
    45 import com.sun.source.tree.CompilationUnitTree;
    46 import com.sun.source.tree.CompilationUnitTree;
       
    47 import com.sun.source.tree.ConditionalExpressionTree;
       
    48 import com.sun.source.tree.IdentifierTree;
    46 import com.sun.source.tree.LambdaExpressionTree;
    49 import com.sun.source.tree.LambdaExpressionTree;
       
    50 import com.sun.source.tree.MethodInvocationTree;
       
    51 import com.sun.source.tree.MethodTree;
    47 import com.sun.source.tree.Scope;
    52 import com.sun.source.tree.Scope;
       
    53 import com.sun.source.tree.Tree;
    48 import com.sun.source.tree.VariableTree;
    54 import com.sun.source.tree.VariableTree;
    49 import com.sun.source.util.JavacTask;
    55 import com.sun.source.util.JavacTask;
       
    56 import com.sun.source.util.TaskEvent;
       
    57 import com.sun.source.util.TaskListener;
    50 import com.sun.source.util.TreePath;
    58 import com.sun.source.util.TreePath;
    51 import com.sun.source.util.TreePathScanner;
    59 import com.sun.source.util.TreePathScanner;
    52 import com.sun.source.util.Trees;
    60 import com.sun.source.util.Trees;
    53 
    61 
    54 import com.sun.tools.javac.api.JavacTool;
    62 import com.sun.tools.javac.api.JavacTool;
    63 
    71 
    64 public class TestGetScopeResult {
    72 public class TestGetScopeResult {
    65     public static void main(String... args) throws IOException {
    73     public static void main(String... args) throws IOException {
    66         new TestGetScopeResult().run();
    74         new TestGetScopeResult().run();
    67         new TestGetScopeResult().testAnalyzerDisabled();
    75         new TestGetScopeResult().testAnalyzerDisabled();
       
    76         new TestGetScopeResult().testVariablesInSwitch();
       
    77         new TestGetScopeResult().testMemberRefs();
       
    78         new TestGetScopeResult().testAnnotations();
       
    79         new TestGetScopeResult().testAnnotationsLazy();
       
    80         new TestGetScopeResult().testCircular();
    68     }
    81     }
    69 
    82 
    70     public void run() throws IOException {
    83     public void run() throws IOException {
    71         String[] simpleLambda = {
    84         String[] simpleLambda = {
    72             "s:java.lang.String",
    85             "s:java.lang.String",
   257         protected void analyze(JCStatement statement, Env<AttrContext> env) {
   270         protected void analyze(JCStatement statement, Env<AttrContext> env) {
   258             analyzeCalled = true;
   271             analyzeCalled = true;
   259             super.analyze(statement, env);
   272             super.analyze(statement, env);
   260         }
   273         }
   261     }
   274     }
       
   275 
       
   276     void testVariablesInSwitch() throws IOException {
       
   277         JavacTool c = JavacTool.create();
       
   278         try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
       
   279             class MyFileObject extends SimpleJavaFileObject {
       
   280                 MyFileObject() {
       
   281                     super(URI.create("myfo:///Test.java"), SOURCE);
       
   282                 }
       
   283                 @Override
       
   284                 public String getCharContent(boolean ignoreEncodingErrors) {
       
   285                     return "class Test {" +
       
   286                            "    void test() {\n" +
       
   287                            "        E e = E.A;\n" +
       
   288                            "        Object o = E.A;\n" +
       
   289                            "        switch (e) {\n" +
       
   290                            "            case A:\n" +
       
   291                            "                return;\n" +
       
   292                            "            case B:\n" +
       
   293                            "                test();\n" +
       
   294                            "                E ee = null;\n" +
       
   295                            "                break;\n" +
       
   296                            "        }\n" +
       
   297                            "    }\n" +
       
   298                            "    enum E {A, B}\n" +
       
   299                            "}";
       
   300                 }
       
   301             }
       
   302             Context ctx = new Context();
       
   303             TestAnalyzer.preRegister(ctx);
       
   304             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null,
       
   305                                                 List.of(new MyFileObject()), ctx);
       
   306             CompilationUnitTree cut = t.parse().iterator().next();
       
   307             t.analyze();
       
   308 
       
   309             new TreePathScanner<Void, Void>() {
       
   310                 @Override
       
   311                 public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
       
   312                     Trees.instance(t).getScope(getCurrentPath());
       
   313                     return super.visitMethodInvocation(node, p);
       
   314                 }
       
   315             }.scan(cut, null);
       
   316         }
       
   317     }
       
   318 
       
   319     void testMemberRefs() throws IOException {
       
   320         JavacTool c = JavacTool.create();
       
   321         try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
       
   322             class MyFileObject extends SimpleJavaFileObject {
       
   323                 MyFileObject() {
       
   324                     super(URI.create("myfo:///Test.java"), SOURCE);
       
   325                 }
       
   326                 @Override
       
   327                 public String getCharContent(boolean ignoreEncodingErrors) {
       
   328                     return "class Test {" +
       
   329                            "    void test() {\n" +
       
   330                            "        Test t = this;\n" +
       
   331                            "        Runnable r1 = t::test;\n" +
       
   332                            "        Runnable r2 = true ? t::test : t::test;\n" +
       
   333                            "        c(t::test);\n" +
       
   334                            "        c(true ? t::test : t::test);\n" +
       
   335                            "    }\n" +
       
   336                            "    void c(Runnable r) {}\n" +
       
   337                            "}";
       
   338                 }
       
   339             }
       
   340             Context ctx = new Context();
       
   341             TestAnalyzer.preRegister(ctx);
       
   342             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null,
       
   343                                                 List.of(new MyFileObject()), ctx);
       
   344             CompilationUnitTree cut = t.parse().iterator().next();
       
   345             t.analyze();
       
   346 
       
   347             new TreePathScanner<Void, Void>() {
       
   348                 @Override
       
   349                 public Void visitConditionalExpression(ConditionalExpressionTree node, Void p) {
       
   350                     Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getCondition()));
       
   351                     return super.visitConditionalExpression(node, p);
       
   352                 }
       
   353 
       
   354                 @Override
       
   355                 public Void visitBlock(BlockTree node, Void p) {
       
   356                     Trees.instance(t).getScope(getCurrentPath());
       
   357                     return super.visitBlock(node, p);
       
   358                 }
       
   359             }.scan(cut, null);
       
   360         }
       
   361     }
       
   362 
       
   363     void testAnnotations() throws IOException {
       
   364         JavacTool c = JavacTool.create();
       
   365         try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
       
   366             class MyFileObject extends SimpleJavaFileObject {
       
   367                 MyFileObject() {
       
   368                     super(URI.create("myfo:///Test.java"), SOURCE);
       
   369                 }
       
   370                 @Override
       
   371                 public String getCharContent(boolean ignoreEncodingErrors) {
       
   372                     return "class Test {" +
       
   373                            "    void test() {\n" +
       
   374                            "        new Object() {\n" +
       
   375                            "            @A\n" +
       
   376                            "            public String t() { return null; }\n" +
       
   377                            "        };\n" +
       
   378                            "    }\n" +
       
   379                            "    @interface A {}\n" +
       
   380                            "}";
       
   381                 }
       
   382             }
       
   383             Context ctx = new Context();
       
   384             TestAnalyzer.preRegister(ctx);
       
   385             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null,
       
   386                                                 List.of(new MyFileObject()), ctx);
       
   387             CompilationUnitTree cut = t.parse().iterator().next();
       
   388             t.analyze();
       
   389 
       
   390             new TreePathScanner<Void, Void>() {
       
   391                 @Override
       
   392                 public Void visitIdentifier(IdentifierTree node, Void p) {
       
   393                     if (node.getName().contentEquals("A")) {
       
   394                         Trees.instance(t).getScope(getCurrentPath());
       
   395                     }
       
   396                     return super.visitIdentifier(node, p);
       
   397                 }
       
   398 
       
   399                 @Override
       
   400                 public Void visitMethod(MethodTree node, Void p) {
       
   401                     super.visitMethod(node, p);
       
   402                     if (node.getReturnType() != null) {
       
   403                         Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getReturnType()));
       
   404                     }
       
   405                     return null;
       
   406                 }
       
   407             }.scan(cut, null);
       
   408         }
       
   409     }
       
   410 
       
   411     void testAnnotationsLazy() throws IOException {
       
   412         JavacTool c = JavacTool.create();
       
   413         try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
       
   414             class MyFileObject extends SimpleJavaFileObject {
       
   415                 MyFileObject() {
       
   416                     super(URI.create("myfo:///Test.java"), SOURCE);
       
   417                 }
       
   418                 @Override
       
   419                 public String getCharContent(boolean ignoreEncodingErrors) {
       
   420                     return "import java.lang.annotation.*;\n" +
       
   421                            "\n" +
       
   422                            "class ClassA {\n" +
       
   423                            "    Object o = ClassB.lcv;\n" +
       
   424                            "}\n" +
       
   425                            "\n" +
       
   426                            "class ClassB {\n" +
       
   427                            "    static final String[] lcv = new @TA String[0];\n" +
       
   428                            "}\n" +
       
   429                            "\n" +
       
   430                            "class ClassC {\n" +
       
   431                            "    static final Object o = (@TA Object) null;\n" +
       
   432                            "}\n" +
       
   433                            "\n" +
       
   434                            "@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})\n" +
       
   435                            "@interface TA {}\n";
       
   436                 }
       
   437             }
       
   438             Context ctx = new Context();
       
   439             TestAnalyzer.preRegister(ctx);
       
   440             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null,
       
   441                                                 List.of(new MyFileObject()), ctx);
       
   442             t.addTaskListener(new TaskListener() {
       
   443                 @Override
       
   444                 public void finished(TaskEvent e) {
       
   445                     if (e.getKind() == TaskEvent.Kind.ANALYZE) {
       
   446                         new TreePathScanner<Void, Void>() {
       
   447                             @Override
       
   448                             public Void scan(Tree tree, Void p) {
       
   449                                 if (tree != null) {
       
   450                                     Trees.instance(t).getScope(new TreePath(getCurrentPath(), tree));
       
   451                                 }
       
   452                                 return super.scan(tree, p);
       
   453                             }
       
   454                         }.scan(Trees.instance(t).getPath(e.getTypeElement()), null);
       
   455                     }
       
   456                 }
       
   457             });
       
   458 
       
   459             t.call();
       
   460         }
       
   461     }
       
   462 
       
   463     void testCircular() throws IOException {
       
   464         JavacTool c = JavacTool.create();
       
   465         try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
       
   466             class MyFileObject extends SimpleJavaFileObject {
       
   467                 MyFileObject() {
       
   468                     super(URI.create("myfo:///Test.java"), SOURCE);
       
   469                 }
       
   470                 @Override
       
   471                 public String getCharContent(boolean ignoreEncodingErrors) {
       
   472                     return "class Test extends Test {" +
       
   473                            "    {\n" +
       
   474                            "        int i;\n" +
       
   475                            "    }\n" +
       
   476                            "}";
       
   477                 }
       
   478             }
       
   479             Context ctx = new Context();
       
   480             TestAnalyzer.preRegister(ctx);
       
   481             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null,
       
   482                                                 List.of(new MyFileObject()), ctx);
       
   483             CompilationUnitTree cut = t.parse().iterator().next();
       
   484             t.analyze();
       
   485 
       
   486             new TreePathScanner<Void, Void>() {
       
   487                 @Override
       
   488                 public Void visitBlock(BlockTree node, Void p) {
       
   489                     Trees.instance(t).getScope(getCurrentPath());
       
   490                     return super.visitBlock(node, p);
       
   491                 }
       
   492             }.scan(cut, null);
       
   493         }
       
   494     }
       
   495 
   262 }
   496 }
   263