1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.test.lib.jittester;
  25 
  26 import java.io.IOException;
  27 import java.util.function.Function;
  28 import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
  29 
  30 /**
  31  * Generates java source code from IRTree
  32  */
  33 public class JavaCodeGenerator extends TestsGenerator {
  34     private static final String DEFAULT_SUFFIX = "java_tests";
  35 
  36     JavaCodeGenerator() {
  37         this(DEFAULT_SUFFIX, JavaCodeGenerator::generatePrerunAction, "-Xcomp");
  38     }
  39 
  40     JavaCodeGenerator(String prefix, Function<String, String[]> preRunActions, String jtDriverOptions) {
  41         super(prefix, preRunActions, jtDriverOptions);
  42     }
  43 
  44     @Override
  45     public void accept(IRNode mainClass, IRNode privateClasses) {
  46         String mainClassName = mainClass.getName();
  47         generateSources(mainClass, privateClasses);
  48         compilePrinter();
  49         compileJavaFile(mainClassName);
  50         generateGoldenOut(mainClassName);
  51     }
  52 
  53     private void generateSources(IRNode mainClass, IRNode privateClasses) {
  54         String mainClassName = mainClass.getName();
  55         StringBuilder code = new StringBuilder();
  56         JavaCodeVisitor vis = new JavaCodeVisitor();
  57         code.append(getJtregHeader(mainClassName));
  58         if (privateClasses != null) {
  59             code.append(privateClasses.accept(vis));
  60         }
  61         code.append(mainClass.accept(vis));
  62         ensureExisting(generatorDir);
  63         writeFile(generatorDir, mainClassName + ".java", code.toString());
  64     }
  65 
  66     private void compileJavaFile(String mainClassName) {
  67         String classPath = tmpDir.toString();
  68         ProcessBuilder pb = new ProcessBuilder(JAVAC,
  69                 "-d", classPath,
  70                 "-cp", classPath,
  71                 generatorDir.resolve(mainClassName + ".java").toString());
  72         try {
  73             int r = runProcess(pb, tmpDir.resolve(mainClassName + ".javac").toString());
  74             if (r != 0) {
  75                 throw new Error("Can't compile sources, exit code = " + r);
  76             }
  77         } catch (IOException | InterruptedException e) {
  78             throw new Error("Can't compile sources ", e);
  79         }
  80     }
  81 
  82     private static String[] generatePrerunAction(String mainClassName) {
  83         return new String[] {"@compile " + mainClassName + ".java"};
  84     }
  85 }