test/langtools/tools/javac/api/ast/ASTBuilder.java
branchjlahoda-tree-builder
changeset 57295 5497ee9d40f4
parent 57267 97aaf02ed830
child 57296 464cc8d22d94
equal deleted inserted replaced
57267:97aaf02ed830 57295:5497ee9d40f4
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 9999999
    26  * @bug 9999999
    27  * @summary XXX
    27  * @summary XXX
    28  * @modules java.compiler
    28  * @library /tools/lib
    29  *          jdk.compiler
    29  * @modules
       
    30  *      jdk.compiler/com.sun.tools.javac.api
       
    31  *      jdk.compiler/com.sun.tools.javac.main
       
    32  * @build toolbox.ToolBox CodeBuilder
       
    33  * @run main ASTBuilder
    30  */
    34  */
    31 
    35 
    32 import java.net.URI;
    36 import java.net.URI;
    33 import java.util.Arrays;
    37 import java.util.Arrays;
    34 import java.util.function.Consumer;
    38 import java.util.function.Consumer;
    44 import com.sun.source.util.TreeBuilder;
    48 import com.sun.source.util.TreeBuilder;
    45 import com.sun.source.util.TreeBuilder.*;
    49 import com.sun.source.util.TreeBuilder.*;
    46 import com.sun.source.util.Trees;
    50 import com.sun.source.util.Trees;
    47 import com.sun.source.util.TreeScanner;
    51 import com.sun.source.util.TreeScanner;
    48 
    52 
       
    53 import javax.tools.StandardLocation;
       
    54 
       
    55 import com.sun.source.tree.ClassTree;
       
    56 import com.sun.source.tree.IdentifierTree;
       
    57 import com.sun.source.tree.MemberReferenceTree;
       
    58 import com.sun.source.tree.MemberSelectTree;
       
    59 import com.sun.source.tree.MethodTree;
       
    60 import com.sun.source.tree.VariableTree;
       
    61 import toolbox.ToolBox.MemoryFileManager;
       
    62 
    49 public class ASTBuilder {
    63 public class ASTBuilder {
    50     
    64     
    51     public static void main(String[] args) throws Exception {
    65     public static void main(String[] args) throws Exception {
    52         runTest("class Test {" +
    66         runTest("class Test {" +
    53                 "    int x;" +
    67                 "    int x;" +
    54                 "}",
    68                 "}",
    55                 U -> U._class("Test", C -> C.field("x", Type::_int)));
    69                 U -> U._class("Test", C -> C.field("x", Type::_int)));
       
    70         runTest("class Test {" +
       
    71                 "    int x1 = 2;" +
       
    72                 "    int x2 = 2 + x1;" +
       
    73                 "}");
    56     }
    74     }
    57 
    75 
    58     private static void runTest(String expectedCode, Consumer<CompilationUnit> actualBuilder) throws Exception {
    76     private static void runTest(String expectedCode, Consumer<CompilationUnit> actualBuilder) throws Exception {
    59         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
    77         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
    60         assert tool != null;
    78         assert tool != null;
    61 
    79 
    62         JavacTask expecteTask = (JavacTask) tool.getTask(null, null, null,
    80         JavacTask expectedTask = (JavacTask) tool.getTask(null, null, null,
    63             null, null, Arrays.asList(new MyFileObject(expectedCode)));
    81             null, null, Arrays.asList(new MyFileObject(expectedCode)));
    64         String expectedDump = dumpTree(expecteTask.parse().iterator().next());
    82         String expectedDump = dumpTree(expectedTask.parse().iterator().next());
    65 
    83 
    66         JavacTask ct = (JavacTask) tool.getTask(null, null, null,
    84         JavacTask ct = (JavacTask) tool.getTask(null, null, null,
    67             null, null, Arrays.asList(new MyFileObject("")));
    85             null, null, Arrays.asList(new MyFileObject("")));
    68         ct.parse(); //init javac
    86         ct.parse(); //init javac
    69         Trees t = Trees.instance(ct);
    87         Trees t = Trees.instance(ct);
    74         
    92         
    75         String actualDump = dumpTree(cut);
    93         String actualDump = dumpTree(cut);
    76         
    94         
    77         if (!actualDump.equals(expectedDump)) {
    95         if (!actualDump.equals(expectedDump)) {
    78             throw new AssertionError("Expected and actual dump differ. Expected: " + expectedDump + "; actual: " + actualDump);
    96             throw new AssertionError("Expected and actual dump differ. Expected: " + expectedDump + "; actual: " + actualDump);
       
    97         }
       
    98     }
       
    99 
       
   100     private static void runTest(String expectedCode) throws Exception {
       
   101         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
       
   102         assert tool != null;
       
   103 
       
   104         JavacTask expectedTask = (JavacTask) tool.getTask(null, null, null,
       
   105             null, null, Arrays.asList(new MyFileObject(expectedCode)));
       
   106         CompilationUnitTree expectedCUT = expectedTask.parse().iterator().next();
       
   107         String builderCode = CodeBuilder.buildCodeToGenerate(expectedCUT, "builder");
       
   108         System.err.println("builderCode:");
       
   109         System.err.println(builderCode);
       
   110         String expectedCodeGen = "import com.sun.source.tree.*; import com.sun.source.util.*; public class CodeGen { public static CompilationUnitTree build(TreeBuilder builder) { return " + builderCode + "; } }";
       
   111         String expectedDump = dumpTree(expectedCUT);
       
   112 
       
   113         try (MemoryFileManager mfm = new MemoryFileManager(tool.getStandardFileManager(null, null, null))) {
       
   114             Boolean res = tool.getTask(null, mfm, null,
       
   115                                        null, null, Arrays.asList(new MyFileObject(expectedCodeGen)))
       
   116                               .call();
       
   117             if (!res) {
       
   118                 throw new IllegalStateException("Could not compile the generated code!");
       
   119             }
       
   120             
       
   121             ClassLoader codeCL = new ClassLoader(ASTBuilder.class.getClassLoader()) {
       
   122                 @Override
       
   123                 protected java.lang.Class<?> findClass(String name) throws ClassNotFoundException {
       
   124                     byte[] bytecode = mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, name);
       
   125                     if (bytecode != null) {
       
   126                         return defineClass(name, bytecode, 0, bytecode.length);
       
   127                     }
       
   128                     return super.findClass(name);
       
   129                 }
       
   130             };
       
   131 
       
   132             JavacTask ct = (JavacTask) tool.getTask(null, null, null,
       
   133                 null, null, Arrays.asList(new MyFileObject("")));
       
   134             ct.parse(); //init javac
       
   135             Trees t = Trees.instance(ct);
       
   136 
       
   137             TreeBuilder builder = t.getTreeBuilder();
       
   138 
       
   139             java.lang.Class<?> codeGen = codeCL.loadClass("CodeGen");
       
   140             CompilationUnitTree cut = (CompilationUnitTree) codeGen.getDeclaredMethod("build", TreeBuilder.class).invoke(null, builder);
       
   141             String actualDump = dumpTree(cut);
       
   142 
       
   143             if (!actualDump.equals(expectedDump)) {
       
   144                 throw new AssertionError("Expected and actual dump differ. Expected: " + expectedDump + "; actual: " + actualDump);
       
   145             }
    79         }
   146         }
    80     }
   147     }
    81 
   148 
    82     static String dumpTree(Tree t) {
   149     static String dumpTree(Tree t) {
    83         StringBuilder result = new StringBuilder();
   150         StringBuilder result = new StringBuilder();
   108                 result.append("(");
   175                 result.append("(");
   109                 super.scan(nodes, p);
   176                 super.scan(nodes, p);
   110                 result.append(")");
   177                 result.append(")");
   111                 return null;
   178                 return null;
   112             }
   179             }
       
   180             @Override
       
   181             public Void visitIdentifier(IdentifierTree node, Void p) {
       
   182                 result.append(node.getName());
       
   183                 return super.visitIdentifier(node, p);
       
   184             }
       
   185             @Override
       
   186             public Void visitMemberSelect(MemberSelectTree node, Void p) {
       
   187                 result.append(node.getIdentifier());
       
   188                 return super.visitMemberSelect(node, p);
       
   189             }
       
   190             @Override
       
   191             public Void visitMemberReference(MemberReferenceTree node, Void p) {
       
   192                 result.append(node.getName());
       
   193                 return super.visitMemberReference(node, p);
       
   194             }
       
   195             @Override
       
   196             public Void visitClass(ClassTree node, Void p) {
       
   197                 result.append(node.getSimpleName());
       
   198                 return super.visitClass(node, p);
       
   199             }
       
   200             @Override
       
   201             public Void visitMethod(MethodTree node, Void p) {
       
   202                 result.append(node.getName());
       
   203                 return super.visitMethod(node, p);
       
   204             }
       
   205             @Override
       
   206             public Void visitVariable(VariableTree node, Void p) {
       
   207                 result.append(node.getName());
       
   208                 return super.visitVariable(node, p);
       
   209             }
   113         }.scan(t, null);
   210         }.scan(t, null);
   114         return result.toString();
   211         return result.toString();
   115     }
   212     }
   116 
   213 
   117     static class MyFileObject extends SimpleJavaFileObject {
   214     static class MyFileObject extends SimpleJavaFileObject {
   124 
   221 
   125         @Override
   222         @Override
   126         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   223         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   127             return text;
   224             return text;
   128         }
   225         }
       
   226 
       
   227         @Override
       
   228         public boolean isNameCompatible(String simpleName, Kind kind) {
       
   229             return true;
       
   230         }
   129     }
   231     }
   130 }
   232 }