| /******************************************************************************* |
| * Copyright (c) 2006, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.compiler.tool.tests; |
| |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.nio.charset.Charset; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.ServiceLoader; |
| |
| import javax.tools.FileObject; |
| import javax.tools.ForwardingJavaFileManager; |
| import javax.tools.JavaCompiler; |
| import javax.tools.JavaFileObject; |
| import javax.tools.StandardJavaFileManager; |
| import javax.tools.StandardLocation; |
| //import javax.tools.StandardLocation; |
| import javax.tools.ToolProvider; |
| import javax.tools.JavaCompiler.CompilationTask; |
| import javax.tools.JavaFileObject.Kind; |
| |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; |
| import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler; |
| |
| public class CompilerToolTests extends TestCase { |
| private static final boolean DEBUG = false; |
| |
| public CompilerToolTests(String name) { |
| super(name); |
| } |
| public static TestSuite suite() { |
| TestSuite suite = new TestSuite(); |
| suite.addTest(new CompilerToolTests("testInitializeJavaCompiler")); |
| suite.addTest(new CompilerToolTests("testCheckOptions")); |
| suite.addTest(new CompilerToolTests("testCompilerOneClassWithSystemCompiler")); |
| // suite.addTest(new CompilerToolTests("testCompilerOneClassWithSystemCompiler2")); |
| suite.addTest(new CompilerToolTests("testCompilerOneClassWithEclipseCompiler")); |
| suite.addTest(new CompilerToolTests("testCompilerOneClassWithEclipseCompiler2")); |
| suite.addTest(new CompilerToolTests("testCompilerOneClassWithEclipseCompiler3")); |
| suite.addTest(new CompilerToolTests("testCompilerOneClassWithEclipseCompiler4")); |
| suite.addTest(new CompilerToolTests("testCleanUp")); |
| return suite; |
| } |
| |
| private static JavaCompiler Compiler; |
| static final String[] ONE_ARG_OPTIONS = { |
| "-cp", |
| "-classpath", |
| "-bootclasspath", |
| "-sourcepath", |
| "-extdirs", |
| "-endorseddirs", |
| "-d", |
| "-encoding", |
| "-source", |
| "-target", |
| "-maxProblems", |
| "-log", |
| "-repeat", |
| "-processorpath", |
| "-s", |
| "-processor", |
| "-classNames" |
| }; |
| static final String[] ZERO_ARG_OPTIONS = { |
| "-1.3", |
| "-1.4", |
| "-1.5", |
| "-1.6", |
| "-1.7", |
| "-7", |
| "-7.0", |
| "-6", |
| "-6.0", |
| "-5", |
| "-5.0", |
| "-deprecation", |
| "-nowarn", |
| "-warn:none", |
| "-?:warn", |
| "-g", |
| "-g:lines", |
| "-g:source", |
| "-g:vars", |
| "-g:lines,vars", |
| "-g:none", |
| "-preserveAllLocals", |
| "-X", |
| "-O", |
| "-proceedOnError", |
| "-verbose", |
| "-referenceInfo", |
| "-progress", |
| "-time", |
| "-noExit", |
| "-inlineJSR", |
| "-enableJavadoc", |
| "-Xemacs", |
| "-?", |
| "-help", |
| "-v", |
| "-version", |
| "-showversion", |
| "-XprintRounds", |
| "-XprintProcessorInfo", |
| "-proc:none", |
| "-proc:only", |
| }; |
| static final String[] FAKE_ZERO_ARG_OPTIONS = new String[] { |
| // a series of fake options to test the behavior upon ignored and |
| // pass-through options |
| "-Jignore", |
| "-Xignore", |
| "-Akey=value", |
| }; |
| |
| private void displayLocation(StandardJavaFileManager manager, StandardLocation standardLocation) { |
| System.out.println(standardLocation.getName()); |
| Iterable<? extends File> location = manager.getLocation(standardLocation); |
| if (location == null) return; |
| for (File f : location) { |
| System.out.println(f.getAbsolutePath()); |
| } |
| } |
| |
| /* |
| * Initialize the compiler for all the tests |
| */ |
| public void testInitializeJavaCompiler() { |
| ServiceLoader<JavaCompiler> javaCompilerLoader = ServiceLoader.load(JavaCompiler.class);//, EclipseCompiler.class.getClassLoader()); |
| int compilerCounter = 0; |
| for (JavaCompiler javaCompiler : javaCompilerLoader) { |
| compilerCounter++; |
| if (javaCompiler instanceof EclipseCompiler) { |
| Compiler = javaCompiler; |
| } |
| } |
| assertEquals("Only one compiler available", 1, compilerCounter); |
| } |
| |
| public void testCheckOptions() { |
| assertNotNull("No compiler found", Compiler); |
| for (String option : ONE_ARG_OPTIONS) { |
| assertEquals(option + " requires 1 argument", 1, Compiler.isSupportedOption(option)); |
| } |
| for (String option : ZERO_ARG_OPTIONS) { |
| assertEquals(option + " requires no argument", 0, Compiler.isSupportedOption(option)); |
| } |
| for (String option : FAKE_ZERO_ARG_OPTIONS) { |
| assertEquals(option + " requires no argument", 0, Compiler.isSupportedOption(option)); |
| } |
| } |
| |
| public void testCompilerOneClassWithSystemCompiler() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // System compiler |
| JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); |
| StandardJavaFileManager manager = systemCompiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| |
| ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { |
| @Override |
| public FileObject getFileForInput(Location location, String packageName, String relativeName) |
| throws IOException { |
| if (DEBUG) { |
| System.out.println("Create file for input : " + packageName + " " + relativeName + " in location " + location); |
| } |
| return super.getFileForInput(location, packageName, relativeName); |
| } |
| @Override |
| public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) |
| throws IOException { |
| if (DEBUG) { |
| System.out.println("Create java file for input : " + className + " in location " + location); |
| } |
| return super.getJavaFileForInput(location, className, kind); |
| } |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, |
| String className, |
| Kind kind, |
| FileObject sibling) throws IOException { |
| |
| if (DEBUG) { |
| System.out.println("Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); |
| } |
| JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); |
| if (DEBUG) { |
| System.out.println(javaFileForOutput.toUri()); |
| } |
| return javaFileForOutput; |
| } |
| }; |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| CompilationTask task = systemCompiler.getTask(printWriter, forwardingJavaFileManager, null, options, null, units); |
| assertTrue("Has location CLASS_OUPUT ", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| Boolean result = task.call(); |
| |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| /* |
| * Run the system compiler using the Eclipse java file manager |
| * TODO need to investigate why rt.jar gets removed from the PLATFORM_CLASSPATH location |
| */ |
| public void _testCompilerOneClassWithSystemCompiler2() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // System compiler |
| JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); |
| StandardJavaFileManager manager = Compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| |
| ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { |
| @Override |
| public FileObject getFileForInput(Location location, String packageName, String relativeName) |
| throws IOException { |
| if (DEBUG) { |
| System.out.println("Create file for input : " + packageName + " " + relativeName + " in location " + location); |
| } |
| return super.getFileForInput(location, packageName, relativeName); |
| } |
| @Override |
| public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) |
| throws IOException { |
| if (DEBUG) { |
| System.out.println("Create java file for input : " + className + " in location " + location); |
| } |
| return super.getJavaFileForInput(location, className, kind); |
| } |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, |
| String className, |
| Kind kind, |
| FileObject sibling) throws IOException { |
| |
| if (DEBUG) { |
| System.out.println("Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); |
| } |
| JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); |
| if (DEBUG) { |
| System.out.println(javaFileForOutput.toUri()); |
| } |
| return javaFileForOutput; |
| } |
| }; |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| CompilationTask task = systemCompiler.getTask(printWriter, manager, null, options, null, units); |
| |
| if (DEBUG) { |
| System.out.println("Has location CLASS_OUPUT : " + forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| } |
| |
| Boolean result = task.call(); |
| displayLocation(manager, StandardLocation.CLASS_PATH); |
| displayLocation(manager, StandardLocation.PLATFORM_CLASS_PATH); |
| |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| public void testCompilerOneClassWithEclipseCompiler() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // System compiler |
| StandardJavaFileManager manager = Compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| |
| ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, |
| String className, |
| Kind kind, |
| FileObject sibling) throws IOException { |
| |
| if (DEBUG) { |
| System.out.println("EC: Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); |
| } |
| JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); |
| if (DEBUG) { |
| System.out.println(javaFileForOutput.toUri()); |
| } |
| return javaFileForOutput; |
| } |
| }; |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| CompilationTask task = Compiler.getTask(printWriter, forwardingJavaFileManager, null, options, null, units); |
| // check the classpath location |
| assertTrue("Has no location CLASS_OUPUT", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| Boolean result = task.call(); |
| printWriter.flush(); |
| printWriter.close(); |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| ClassFileReader reader = null; |
| try { |
| reader = ClassFileReader.read(new File(tmpFolder, "p/X.class"), true); |
| } catch (ClassFormatException e) { |
| assertTrue("Should not happen", false); |
| } catch (IOException e) { |
| assertTrue("Should not happen", false); |
| } |
| assertNotNull("No reader", reader); |
| assertEquals("Wrong value", ClassFileConstants.JDK1_6, reader.getVersion()); |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| public void testCompilerOneClassWithEclipseCompiler2() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // System compiler |
| StandardJavaFileManager manager = Compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| |
| ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, |
| String className, |
| Kind kind, |
| FileObject sibling) throws IOException { |
| |
| if (DEBUG) { |
| System.out.println("EC: Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); |
| } |
| JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); |
| if (DEBUG) { |
| System.out.println(javaFileForOutput.toUri()); |
| } |
| return javaFileForOutput; |
| } |
| }; |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| options.add("-1.5"); |
| CompilationTask task = Compiler.getTask(printWriter, forwardingJavaFileManager, null, options, null, units); |
| // check the classpath location |
| assertTrue("Has no location CLASS_OUPUT", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| Boolean result = task.call(); |
| printWriter.flush(); |
| printWriter.close(); |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| File outputFile = new File(tmpFolder, "p/X.class"); |
| assertTrue(outputFile.exists()); |
| ClassFileReader reader = null; |
| try { |
| reader = ClassFileReader.read(outputFile); |
| } catch (ClassFormatException e) { |
| assertTrue("Should not happen", false); |
| } catch (IOException e) { |
| assertTrue("Should not happen", false); |
| } |
| assertNotNull("No reader", reader); |
| assertEquals("Not a 1.5 .class file", ClassFileConstants.JDK1_5, reader.getVersion()); |
| |
| stringWriter = new StringWriter(); |
| printWriter = new PrintWriter(stringWriter); |
| task = Compiler.getTask(printWriter, forwardingJavaFileManager, null, options, null, units); |
| // check the classpath location |
| assertTrue("Has no location CLASS_OUPUT", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| result = task.call(); |
| printWriter.flush(); |
| printWriter.close(); |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| public void testCompilerOneClassWithEclipseCompiler3() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // System compiler |
| StandardJavaFileManager manager = Compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| |
| ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { |
| @Override |
| public JavaFileObject getJavaFileForOutput(Location location, |
| String className, |
| Kind kind, |
| FileObject sibling) throws IOException { |
| |
| if (DEBUG) { |
| System.out.println("Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); |
| } |
| JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); |
| if (DEBUG) { |
| System.out.println(javaFileForOutput.toUri()); |
| } |
| return javaFileForOutput; |
| } |
| }; |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| CompilationTask task = Compiler.getTask(printWriter, manager, null, options, null, units); |
| // check the classpath location |
| assertTrue("Has no location CLASS_OUPUT", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); |
| Boolean result = task.call(); |
| printWriter.flush(); |
| printWriter.close(); |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| |
| try { |
| task.call(); |
| assertTrue("Should not get there", false); |
| } catch (IllegalStateException e) { |
| // ignore: expected |
| } |
| |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| public void testCompilerOneClassWithEclipseCompiler4() { |
| String tmpFolder = System.getProperty("java.io.tmpdir"); |
| File inputFile = new File(tmpFolder, "X.java"); |
| BufferedWriter writer = null; |
| try { |
| writer = new BufferedWriter(new FileWriter(inputFile)); |
| writer.write( |
| "package p;\n" + |
| "public class X {}"); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (writer != null) { |
| try { |
| writer.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| // create new list containing inputfile |
| List<File> files = new ArrayList<File>(); |
| files.add(inputFile); |
| JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); |
| StandardJavaFileManager manager = systemCompiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); |
| Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| |
| List<String> options = new ArrayList<String>(); |
| options.add("-d"); |
| options.add(tmpFolder); |
| CompilationTask task = Compiler.getTask(null, null, null, options, null, units); |
| // check the classpath location |
| Boolean result = task.call(); |
| printWriter.flush(); |
| printWriter.close(); |
| if (!result.booleanValue()) { |
| System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); |
| assertTrue("Compilation failed ", false); |
| } |
| // check that the .class file exist for X |
| assertTrue("delete failed", inputFile.delete()); |
| } |
| |
| /* |
| * Clean up the compiler |
| */ |
| public void testCleanUp() { |
| Compiler = null; |
| } |
| } |