| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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.wst.jsdt.core.tests.compiler.regression; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.PrintWriter; |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| import java.util.Locale; |
| import java.util.Map; |
| |
| import junit.framework.AssertionFailedError; |
| |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.wst.jsdt.core.compiler.CategorizedProblem; |
| import org.eclipse.wst.jsdt.core.infer.DefaultInferrenceProvider; |
| import org.eclipse.wst.jsdt.core.infer.InferEngine; |
| import org.eclipse.wst.jsdt.core.infer.InferOptions; |
| import org.eclipse.wst.jsdt.core.infer.InferrenceProvider; |
| import org.eclipse.wst.jsdt.core.search.SearchDocument; |
| import org.eclipse.wst.jsdt.core.search.SearchParticipant; |
| import org.eclipse.wst.jsdt.core.tests.junit.extension.StopableTestCase; |
| import org.eclipse.wst.jsdt.core.tests.util.AbstractCompilerTest; |
| import org.eclipse.wst.jsdt.core.tests.util.CompilerTestSetup; |
| import org.eclipse.wst.jsdt.core.tests.util.TestVerifier; |
| import org.eclipse.wst.jsdt.core.tests.util.Util; |
| import org.eclipse.wst.jsdt.core.util.ClassFormatException; |
| import org.eclipse.wst.jsdt.internal.compiler.CompilationResult; |
| import org.eclipse.wst.jsdt.internal.compiler.Compiler; |
| import org.eclipse.wst.jsdt.internal.compiler.DefaultErrorHandlingPolicies; |
| import org.eclipse.wst.jsdt.internal.compiler.ICompilerRequestor; |
| import org.eclipse.wst.jsdt.internal.compiler.IErrorHandlingPolicy; |
| import org.eclipse.wst.jsdt.internal.compiler.IProblemFactory; |
| import org.eclipse.wst.jsdt.internal.compiler.SourceJavadocParser; |
| import org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.eclipse.wst.jsdt.internal.compiler.batch.CompilationUnit; |
| import org.eclipse.wst.jsdt.internal.compiler.batch.FileSystem; |
| import org.eclipse.wst.jsdt.internal.compiler.env.ICompilationUnit; |
| import org.eclipse.wst.jsdt.internal.compiler.env.INameEnvironment; |
| import org.eclipse.wst.jsdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.wst.jsdt.internal.compiler.impl.ReferenceContext; |
| import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeConstants; |
| import org.eclipse.wst.jsdt.internal.compiler.parser.Parser; |
| import org.eclipse.wst.jsdt.internal.compiler.problem.AbortCompilation; |
| import org.eclipse.wst.jsdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.wst.jsdt.internal.compiler.problem.ProblemReporter; |
| import org.eclipse.wst.jsdt.internal.core.search.JavaSearchParticipant; |
| import org.eclipse.wst.jsdt.internal.core.search.indexing.SourceIndexer; |
| |
| public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase { |
| // javac comparison related types, fields and methods - see runJavac for |
| // details |
| class Logger extends Thread { |
| StringBuffer buffer; |
| InputStream inputStream; |
| String type; |
| Logger(InputStream inputStream, String type) { |
| this.inputStream = inputStream; |
| this.type = type; |
| this.buffer = new StringBuffer(); |
| } |
| |
| public void run() { |
| try { |
| BufferedReader reader = new BufferedReader(new InputStreamReader(this.inputStream)); |
| String line = null; |
| while ((line = reader.readLine()) != null) { |
| this.buffer./*append(this.type).append("->").*/append(line).append("\n"); |
| } |
| reader.close(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| protected static int[] DIFF_COUNTERS = new int[3]; |
| protected static final String EVAL_DIRECTORY = Util.getOutputDirectory() + File.separator + "eval"; |
| public static int INDENT = 2; |
| protected static final String JAVA_NAME = |
| File.pathSeparatorChar == ':' ? "java" : "java.exe"; |
| protected static final String JAVAC_NAME = |
| File.pathSeparatorChar == ':' ? "javac" : "javac.exe"; |
| |
| protected static String JAVAC_OUTPUT_DIR = |
| Util.getOutputDirectory() + File.separator + "javac"; |
| protected static String javacCommandLineHeader; |
| protected static PrintWriter javacFullLog; |
| // flags errors so that any error in a test case prevents |
| // java execution |
| private static String javacFullLogFileName; |
| protected static String javaCommandLineHeader; |
| |
| // needed for multiple test calls within a single test method |
| protected static boolean javacTestErrorFlag; |
| |
| protected static String javacTestName; |
| |
| protected static IPath jdkRootDirPath; |
| |
| public static final String OUTPUT_DIR = Util.getOutputDirectory() + File.separator + "regression"; |
| |
| public final static String PACKAGE_INFO_NAME = new String(TypeConstants.PACKAGE_INFO_NAME); |
| |
| public static boolean SHIFT = false; |
| |
| protected static final String SOURCE_DIRECTORY = Util.getOutputDirectory() + File.separator + "source"; |
| |
| public static final String INFERENCE_ENGINES="InferenceEnginesOption"; |
| |
| protected String[] classpaths; |
| protected boolean createdVerifier; |
| protected INameEnvironment javaClassLib; |
| protected TestVerifier verifier; |
| public AbstractRegressionTest(String name) { |
| super(name); |
| } |
| protected void checkClassFile(String className, String source, String expectedOutput) throws ClassFormatException, IOException { |
| // this.checkClassFile("", className, source, expectedOutput, ClassFileBytesDisassembler.SYSTEM); |
| } |
| protected void checkClassFile(String className, String source, String expectedOutput, int mode) throws ClassFormatException, IOException { |
| this.checkClassFile("", className, source, expectedOutput, mode); |
| } |
| protected void checkClassFile(String directoryName, String className, String disassembledClassName, String source, String expectedOutput, int mode) throws ClassFormatException, IOException { |
| // compileAndDeploy(source, directoryName, className); |
| // try { |
| // File directory = new File(EVAL_DIRECTORY, directoryName); |
| // if (!directory.exists()) { |
| // assertTrue(".class file not generated properly in " + directory, false); |
| // } |
| // File f = new File(directory, disassembledClassName + ".class"); |
| // byte[] classFileBytes = org.eclipse.wst.jsdt.internal.compiler.util.Util.getFileByteContent(f); |
| // ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| // String result = disassembler.disassemble(classFileBytes, "\n", mode); |
| // int index = result.indexOf(expectedOutput); |
| // if (index == -1 || expectedOutput.length() == 0) { |
| // System.out.println(Util.displayString(result, 3)); |
| // } |
| // if (index == -1) { |
| // assertEquals("Wrong contents", expectedOutput, result); |
| // } |
| // |
| // try { |
| // FileInputStream stream = new FileInputStream(f); |
| // ClassFileReader.read(stream, className + ".class", true); |
| // stream.close(); |
| // } catch (org.eclipse.wst.jsdt.internal.compiler.classfmt.ClassFormatException e) { |
| // e.printStackTrace(); |
| // assertTrue("ClassFormatException", false); |
| // } catch (IOException e) { |
| // e.printStackTrace(); |
| // assertTrue("IOException", false); |
| // } |
| // } finally { |
| // removeTempClass(className); |
| // } |
| } |
| |
| protected void checkClassFile(String directoryName, String className, String source, String expectedOutput, int mode) throws ClassFormatException, IOException { |
| this.checkClassFile(directoryName, className, className, source, expectedOutput, mode); |
| } |
| |
| protected void checkDisassembledClassFile(String fileName, String className, String expectedOutput) { |
| // this.checkDisassembledClassFile(fileName, className, expectedOutput, ClassFileBytesDisassembler.DETAILED); |
| } |
| protected void checkDisassembledClassFile(String fileName, String className, String expectedOutput, int mode) { |
| // File classFile = new File(fileName); |
| // if (!classFile.exists()) { |
| // assertTrue(".class file doesn't exist", false); |
| // } |
| // String result = null; |
| // try { |
| // byte[] classFileBytes = org.eclipse.wst.jsdt.internal.compiler.util.Util.getFileByteContent(classFile); |
| // ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); |
| // result = disassembler.disassemble(classFileBytes, "\n", mode); |
| // } catch (IOException e) { |
| // e.printStackTrace(); |
| // assertTrue("Should not happen : ", false); |
| // } catch (ClassFormatException e) { |
| // e.printStackTrace(); |
| // assertTrue("Should not happen : ", false); |
| // } |
| // int index = result.indexOf(expectedOutput); |
| // if (index == -1 || expectedOutput.length() == 0) { |
| // System.out.println(Util.displayString(result, 2)); |
| // } |
| // if (index == -1) { |
| // assertEquals("Wrong contents", expectedOutput, result); |
| // } |
| // |
| // try { |
| // FileInputStream stream = new FileInputStream(classFile); |
| // ClassFileReader.read(stream, className + ".class", true); |
| // stream.close(); |
| // } catch (org.eclipse.wst.jsdt.internal.compiler.classfmt.ClassFormatException e) { |
| // e.printStackTrace(); |
| // assertTrue("ClassFormatException", false); |
| // } catch (IOException e) { |
| // e.printStackTrace(); |
| // assertTrue("IOException", false); |
| // } |
| } |
| |
| /*###################################### |
| * Specific method to let tests Sun javac compilation available... |
| #######################################*/ |
| protected void compileAndDeploy(String source, String directoryName, String className) { |
| File directory = new File(SOURCE_DIRECTORY); |
| if (!directory.exists()) { |
| if (!directory.mkdirs()) { |
| System.out.println("Could not create " + SOURCE_DIRECTORY); |
| return; |
| } |
| } |
| if (directoryName != null && directoryName.length() != 0) { |
| directory = new File(SOURCE_DIRECTORY, directoryName); |
| if (!directory.exists()) { |
| if (!directory.mkdirs()) { |
| System.out.println("Could not create " + directory); |
| return; |
| } |
| } |
| } |
| String fileName = directory.getAbsolutePath() + File.separator + className + ".java"; |
| try { |
| BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); |
| writer.write(source); |
| writer.flush(); |
| writer.close(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| return; |
| } |
| StringBuffer buffer = new StringBuffer() |
| .append("\"") |
| .append(fileName) |
| .append("\" -d \"") |
| .append(EVAL_DIRECTORY); |
| if (this.complianceLevel.compareTo(COMPLIANCE_1_5) < 0) { |
| buffer.append("\" -1.4 -source 1.3 -target 1.2"); |
| } else { |
| buffer.append("\" -1.5"); |
| } |
| buffer |
| .append(" -preserveAllLocals -nowarn -g -classpath \"") |
| .append(Util.getJavaClassLibsAsString()) |
| .append(SOURCE_DIRECTORY) |
| .append("\""); |
| org.eclipse.wst.jsdt.internal.compiler.batch.Main.compile(buffer.toString()); |
| } |
| |
| protected void dualPrintln(String message) { |
| System.out.println(message); |
| javacFullLog.println(message); |
| } |
| protected void executeClass( |
| String sourceFile, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments, |
| Map customOptions, |
| ICompilerRequestor clientRequestor) { |
| |
| // Compute class name by removing ".java" and replacing slashes with dots |
| String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.'); |
| if (className.endsWith(PACKAGE_INFO_NAME)) return; |
| |
| if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| boolean passed = |
| this.verifier.verifyClassFiles( |
| sourceFile, |
| className, |
| expectedSuccessOutputString, |
| this.classpaths, |
| null, |
| vmArguments); |
| assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action |
| passed); |
| if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| } |
| |
| /* |
| * Returns the references in the given .class file. |
| */ |
| protected String findReferences(String classFilePath) { |
| // check that "new Z().init()" is bound to "AbstractB.init()" |
| final StringBuffer references = new StringBuffer(10); |
| final SearchParticipant participant = new JavaSearchParticipant() { |
| final SearchParticipant searchParticipant = this; |
| public SearchDocument getDocument(final String documentPath) { |
| return new SearchDocument(documentPath, this.searchParticipant) { |
| public byte[] getByteContents() { |
| try { |
| return org.eclipse.wst.jsdt.internal.compiler.util.Util.getFileByteContent(new File(getPath())); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| return null; |
| } |
| } |
| public char[] getCharContents() { |
| // not used |
| return null; |
| } |
| public String getEncoding() { |
| // not used |
| return null; |
| } |
| }; |
| } |
| }; |
| SearchDocument document = participant.getDocument(new File(classFilePath).getPath()); |
| SourceIndexer indexer = new SourceIndexer(document) { |
| protected void addIndexEntry(char[] category, char[] key) { |
| references.append(category); |
| references.append('/'); |
| references.append(key); |
| references.append('\n'); |
| } |
| }; |
| indexer.indexDocument(); |
| String computedReferences = references.toString(); |
| return computedReferences; |
| } |
| |
| |
| |
| protected INameEnvironment[] getClassLibs() { |
| String encoding = (String)getCompilerOptions().get(CompilerOptions.OPTION_Encoding); |
| if ("".equals(encoding)) |
| encoding = null; |
| |
| INameEnvironment[] classLibs = new INameEnvironment[1]; |
| classLibs[0] = new FileSystem(this.classpaths, new String[]{}, // ignore initial file names |
| encoding // default encoding |
| ); |
| return classLibs; |
| } |
| protected Map getCompilerOptions() { |
| Map defaultOptions = super.getCompilerOptions(); |
| defaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); |
| defaultOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_ReportWrongNumberOfArguments, CompilerOptions.WARNING); |
| defaultOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE); |
| defaultOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.WARNING ); |
| defaultOptions.put(CompilerOptions.OPTION_Unresolved_Field, CompilerOptions.ERROR ); |
| defaultOptions.put(CompilerOptions.OPTION_Unresolved_Method, CompilerOptions.ERROR ); |
| defaultOptions.put(CompilerOptions.OPTION_Unresolved_Type, CompilerOptions.ERROR ); |
| return defaultOptions; |
| } |
| |
| protected String[] getDefaultClassPaths() { |
| return Util.concatWithClassLibs(OUTPUT_DIR, false); |
| } |
| protected IErrorHandlingPolicy getErrorHandlingPolicy() { |
| return new IErrorHandlingPolicy() { |
| public boolean stopOnFirstError() { |
| return false; |
| } |
| public boolean proceedOnErrors() { |
| return true; |
| } |
| }; |
| } |
| /* |
| * Will consider first the source units passed as arguments, then investigate the classpath: jdklib + output dir |
| */ |
| protected INameEnvironment getNameEnvironment(final String[] testFiles, String[] classPaths) { |
| this.classpaths = classPaths == null ? getDefaultClassPaths() : classPaths; |
| return new InMemoryNameEnvironment(testFiles, getClassLibs()); |
| } |
| protected IProblemFactory getProblemFactory() { |
| return new DefaultProblemFactory(Locale.getDefault()); |
| } |
| |
| public void initialize(CompilerTestSetup setUp) { |
| super.initialize(setUp); |
| if (setUp instanceof RegressionTestSetup) { |
| RegressionTestSetup regressionTestSetUp = (RegressionTestSetup)setUp; |
| this.javaClassLib = regressionTestSetUp.javaClassLib; |
| this.verifier = regressionTestSetUp.verifier; |
| } |
| } |
| |
| /* |
| * Write given source test files in current output sub-directory. |
| * Use test name for this sub-directory name (ie. test001, test002, etc...) |
| */ |
| protected void printFiles(String[] testFiles) { |
| for (int i=0, length=testFiles.length; i<length; i++) { |
| System.out.println(testFiles[i++]); |
| System.out.println(testFiles[i]); |
| } |
| System.out.println(""); |
| } |
| protected void printJavacResultsSummary() { |
| if (RUN_JAVAC) { |
| Integer count = (Integer)TESTS_COUNTERS.get(CURRENT_CLASS_NAME); |
| if (count != null) { |
| int newCount = count.intValue()-1; |
| TESTS_COUNTERS.put(CURRENT_CLASS_NAME, new Integer(newCount)); |
| if (newCount == 0) { |
| if (DIFF_COUNTERS[0]!=0 || DIFF_COUNTERS[1]!=0 || DIFF_COUNTERS[2]!=0) { |
| dualPrintln("==========================================================================="); |
| dualPrintln("Results summary:"); |
| } |
| if (DIFF_COUNTERS[0]!=0) |
| dualPrintln(" - "+DIFF_COUNTERS[0]+" test(s) where Javac found errors/warnings but Eclipse did not"); |
| if (DIFF_COUNTERS[1]!=0) |
| dualPrintln(" - "+DIFF_COUNTERS[1]+" test(s) where Eclipse found errors/warnings but Javac did not"); |
| if (DIFF_COUNTERS[2]!=0) |
| dualPrintln(" - "+DIFF_COUNTERS[2]+" test(s) where Eclipse and Javac did not have same output"); |
| System.out.println("\n"); |
| } |
| } |
| dualPrintln("\n\nFull results sent to " + javacFullLogFileName); |
| javacFullLog.flush(); |
| } |
| } |
| protected void removeTempClass(String className) { |
| File dir = new File(SOURCE_DIRECTORY); |
| String[] fileNames = dir.list(); |
| if (fileNames != null) { |
| for (int i = 0, max = fileNames.length; i < max; i++) { |
| if (fileNames[i].indexOf(className) != -1) { |
| Util.delete(SOURCE_DIRECTORY + File.separator + fileNames[i]); |
| } |
| } |
| } |
| |
| dir = new File(EVAL_DIRECTORY); |
| fileNames = dir.list(); |
| if (fileNames != null) { |
| for (int i = 0, max = fileNames.length; i < max; i++) { |
| if (fileNames[i].indexOf(className) != -1) { |
| Util.delete(EVAL_DIRECTORY + File.separator + fileNames[i]); |
| } |
| } |
| } |
| |
| } |
| |
| protected void runConformTest(String[] testFiles) { |
| runConformTest( |
| testFiles, |
| null /* no expected output string */, |
| null /* no extra class libraries */, |
| true /* flush output directory */, |
| null /* no vm arguments */, |
| null /* no custom options*/, |
| null /* no custom requestor*/, |
| false /* do not skip javac for this peculiar test */); |
| } |
| |
| protected void runConformTest(String[] testFiles, String expectedSuccessOutputString) { |
| runConformTest( |
| testFiles, |
| expectedSuccessOutputString, |
| null /* no extra class libraries */, |
| true /* flush output directory */, |
| null /* no vm arguments */, |
| null /* no custom options*/, |
| null /* no custom requestor*/, |
| false /* do not skip javac for this peculiar test */); |
| } |
| |
| protected void runConformTest( |
| String[] testFiles, |
| String expectedSuccessOutputString, |
| String[] vmArguments) { |
| runConformTest( |
| testFiles, |
| expectedSuccessOutputString, |
| null /* no extra class libraries */, |
| true /* flush output directory */, |
| vmArguments, |
| null /* no custom options*/, |
| null /* no custom requestor*/, |
| false /* do not skip javac for this peculiar test */); |
| } |
| protected void runConformTest( |
| String[] testFiles, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments) { |
| runConformTest( |
| testFiles, |
| expectedSuccessOutputString, |
| classLib, |
| shouldFlushOutputDirectory, |
| vmArguments, |
| null /* no custom options*/, |
| null /* no custom requestor*/, |
| false /* do not skip javac for this peculiar test */); |
| } |
| protected void runConformTest( |
| String[] testFiles, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments, |
| Map customOptions, |
| ICompilerRequestor clientRequestor) { |
| runConformTest( |
| testFiles, |
| expectedSuccessOutputString, |
| classLib, |
| shouldFlushOutputDirectory, |
| vmArguments, |
| customOptions, |
| clientRequestor, |
| false /* do not skip javac for this peculiar test */); |
| } |
| protected void runConformTest( |
| String[] testFiles, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments, |
| Map customOptions, |
| ICompilerRequestor clientRequestor, |
| boolean skipJavac) { |
| // Non-javac part |
| try { |
| if (shouldFlushOutputDirectory) |
| Util.flushDirectoryContent(new File(OUTPUT_DIR)); |
| |
| IProblemFactory problemFactory = getProblemFactory(); |
| Requestor requestor = |
| new Requestor( |
| problemFactory, |
| OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, |
| false, |
| clientRequestor, |
| false, /* show category */ |
| false /* show warning token*/); |
| |
| Map options = getCompilerOptions(); |
| if (customOptions != null) { |
| options.putAll(customOptions); |
| } |
| CompilerOptions compilerOptions = new CompilerOptions(options); |
| compilerOptions.performMethodsFullRecovery = false; |
| compilerOptions.performStatementsRecovery = false; |
| Compiler batchCompiler = |
| new Compiler( |
| getNameEnvironment(new String[]{}, classLib), |
| getErrorHandlingPolicy(), |
| compilerOptions, |
| requestor, |
| problemFactory); |
| compilerOptions.produceReferenceInfo = true; |
| try { |
| batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together |
| } catch(RuntimeException e) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| e.printStackTrace(); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| throw e; |
| } |
| if (!requestor.hasErrors) { |
| String sourceFile = testFiles[0]; |
| |
| // Compute class name by removing ".java" and replacing slashes with dots |
| String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.'); |
| if (className.endsWith(PACKAGE_INFO_NAME)) return; |
| |
| if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| boolean passed = |
| this.verifier.verifyClassFiles( |
| sourceFile, |
| className, |
| expectedSuccessOutputString, |
| this.classpaths, |
| null, |
| vmArguments); |
| if (!passed) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| } |
| assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action |
| passed); |
| if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| } else { |
| System.out.println(getClass().getName() + '#' + getName()); |
| System.out.println(Util.displayString(requestor.problemLog, INDENT, SHIFT)); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| assertTrue("Unexpected problems: " + requestor.problemLog, false); |
| } |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| if (RUN_JAVAC && !skipJavac) |
| runJavac(testFiles, null, expectedSuccessOutputString, shouldFlushOutputDirectory); |
| // PREMATURE for now, skipping javac implies skipping the compile |
| // and execution steps; yet, only cases for which the |
| // execution step was a problem have been discovered so |
| // far; may consider skipping the execution step only |
| } |
| } |
| protected void runConformTest(String[] testFiles, String[] vmArguments) { |
| runConformTest( |
| testFiles, |
| null /* no expected output string */, |
| null /* no extra class libraries */, |
| true /* flush output directory */, |
| vmArguments, |
| null /* no custom options*/, |
| null /* no custom requestor*/, |
| false /* do not skip javac for this peculiar test */); |
| } |
| // PREMATURE consider whether conform tests throwing errors should |
| // implement javac comparison or not |
| protected void runConformTestThrowingError( |
| String[] testFiles, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments) { |
| |
| if (shouldFlushOutputDirectory) |
| Util.flushDirectoryContent(new File(OUTPUT_DIR)); |
| |
| IProblemFactory problemFactory = getProblemFactory(); |
| Requestor requestor = |
| new Requestor( |
| problemFactory, |
| OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, |
| false, |
| null/*no custom requestor*/, |
| false, /* show category */ |
| false /* show warning token*/); |
| |
| CompilerOptions compilerOptions = new CompilerOptions(getCompilerOptions()); |
| compilerOptions.performMethodsFullRecovery = false; |
| compilerOptions.performStatementsRecovery = false; |
| Compiler batchCompiler = |
| new Compiler( |
| getNameEnvironment(new String[]{}, classLib), |
| getErrorHandlingPolicy(), |
| compilerOptions, |
| requestor, |
| problemFactory); |
| batchCompiler.options.produceReferenceInfo = true; |
| Throwable exception = null; |
| try { |
| batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together |
| } catch(RuntimeException e){ |
| exception = e; |
| throw e; |
| } catch(Error e) { |
| exception = e; |
| throw e; |
| } finally { |
| |
| if (!requestor.hasErrors) { |
| String sourceFile = testFiles[0]; |
| |
| // Compute class name by removing ".java" and replacing slashes with dots |
| String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.'); |
| |
| boolean passed = |
| this.verifier.verifyClassFilesThrowingError( |
| sourceFile, |
| className, |
| expectedSuccessOutputString, |
| this.classpaths, |
| null, |
| vmArguments); |
| if (exception == null) |
| assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action |
| passed); |
| } else { |
| if (exception == null) |
| assertTrue("Unexpected problems: " + requestor.problemLog, false); |
| } |
| } |
| } |
| /* |
| * Run Sun compilation using javac. |
| * Launch compilation in a thread and verify that it does not take more than 5s |
| * to perform it. Otherwise abort the process and log in console. |
| * TODO (maxime) not sure we really do that 5s cap any more. |
| * A semi verbose output is sent to the console that analyzes differences |
| * of behaviors between javac and Eclipse on a per test basis. A more |
| * verbose output is produced into a file which name is printed on the |
| * console. Such files can be compared between various javac releases |
| * to check potential changes. |
| * To enable such tests, specify the following VM properies in the launch |
| * configuration: |
| * -Drun.javac=enabled |
| * mandatory - tells the test suite to run javac tests |
| * -Djdk.root=<the root directory of the tested javac> |
| * optional - enables to find the javac that will be run by the tests |
| * suite; the root directory must be specified as an absolute path and |
| * should point to the JDK root, aka /opt/jdk1.5.0_05 for Linux or |
| * c:/JDK_50 for Windows; in case this property is not specified, the |
| * tests suite will use the runtime JRE of the launching configuration. |
| * Note that enabling javac tests implies running into 1.5 compliance level |
| * (without having to specify it into the VM properties.) |
| * TODO (maxime) consider impacts of Java 6 |
| */ |
| protected void runJavac( |
| String[] testFiles, |
| final String expectedProblemLog, |
| final String expectedSuccessOutputString, |
| boolean shouldFlushOutputDirectory) { |
| String testName = null; |
| Process compileProcess = null; |
| Process execProcess = null; |
| try { |
| // Init test name |
| testName = testName(); |
| |
| // Cleanup javac output dir if needed |
| File javacOutputDirectory = new File(JAVAC_OUTPUT_DIR); |
| if (shouldFlushOutputDirectory) { |
| Util.delete(javacOutputDirectory); |
| } |
| |
| // Write files in dir |
| writeFiles(testFiles); |
| |
| // Prepare command line |
| StringBuffer cmdLine = new StringBuffer(javacCommandLineHeader); |
| // compute extra classpath |
| String[] classpath = Util.concatWithClassLibs(JAVAC_OUTPUT_DIR, false); |
| StringBuffer cp = new StringBuffer(" -classpath "); |
| int length = classpath.length; |
| for (int i = 0; i < length; i++) { |
| if (i > 0) |
| cp.append(File.pathSeparatorChar); |
| if (classpath[i].indexOf(" ") != -1) { |
| cp.append("\"" + classpath[i] + "\""); |
| } else { |
| cp.append(classpath[i]); |
| } |
| } |
| cmdLine.append(cp); |
| // add source files |
| for (int i = 0; i < testFiles.length; i += 2) { |
| // *.java is not enough (p1/X.java, p2/Y.java) |
| cmdLine.append(' '); |
| cmdLine.append(testFiles[i]); |
| } |
| |
| // Launch process |
| compileProcess = Runtime.getRuntime().exec( |
| cmdLine.toString(), null, this.outputTestDirectory); |
| |
| // Log errors |
| Logger errorLogger = new Logger(compileProcess.getErrorStream(), "ERROR"); |
| |
| // Log output |
| Logger outputLogger = new Logger(compileProcess.getInputStream(), "OUTPUT"); |
| |
| // start the threads to run outputs (standard/error) |
| errorLogger.start(); |
| outputLogger.start(); |
| |
| // Wait for end of process |
| int exitValue = compileProcess.waitFor(); |
| errorLogger.join(); // make sure we get the whole output |
| outputLogger.join(); |
| |
| // Report raw javac results |
| if (! testName.equals(javacTestName)) { |
| javacTestName = testName; |
| javacTestErrorFlag = false; |
| javacFullLog.println("-----------------------------------------------------------------"); |
| javacFullLog.println(CURRENT_CLASS_NAME + " " + testName); |
| } |
| if (exitValue != 0) { |
| javacTestErrorFlag = true; |
| } |
| if (errorLogger.buffer.length() > 0) { |
| javacFullLog.println("--- javac err: ---"); |
| javacFullLog.println(errorLogger.buffer.toString()); |
| } |
| if (outputLogger.buffer.length() > 0) { |
| javacFullLog.println("--- javac out: ---"); |
| javacFullLog.println(outputLogger.buffer.toString()); |
| } |
| |
| // Compare compilation results |
| if (expectedProblemLog == null || expectedProblemLog.length() == 0) { |
| // Eclipse found no error and no warning |
| if (exitValue != 0) { |
| // Javac found errors |
| System.out.println("----------------------------------------"); |
| System.out.println(testName + " - Javac has found error(s) but Eclipse expects conform result:\n"); |
| javacFullLog.println("JAVAC_MISMATCH: Javac has found error(s) but Eclipse expects conform result"); |
| System.out.println(errorLogger.buffer.toString()); |
| printFiles(testFiles); |
| DIFF_COUNTERS[0]++; |
| } |
| else { |
| // Javac found no error - may have found warnings |
| if (errorLogger.buffer.length() > 0) { |
| System.out.println("----------------------------------------"); |
| System.out.println(testName + " - Javac has found warning(s) but Eclipse expects conform result:\n"); |
| javacFullLog.println("JAVAC_MISMATCH: Javac has found warning(s) but Eclipse expects conform result"); |
| System.out.println(errorLogger.buffer.toString()); |
| printFiles(testFiles); |
| DIFF_COUNTERS[0]++; |
| } |
| if (expectedSuccessOutputString != null && !javacTestErrorFlag) { |
| // Neither Eclipse nor Javac found errors, and we have a runtime |
| // bench value |
| StringBuffer javaCmdLine = new StringBuffer(javaCommandLineHeader); |
| javaCmdLine.append(cp); |
| javaCmdLine.append(' ').append(testFiles[0].substring(0, testFiles[0].indexOf('.'))); |
| // assume executable class is name of first test file - PREMATURE check if this is also the case in other test fwk classes |
| execProcess = Runtime.getRuntime().exec(javaCmdLine.toString(), null, this.outputTestDirectory); |
| Logger logger = new Logger(execProcess.getInputStream(), ""); |
| // PREMATURE implement consistent error policy |
| logger.start(); |
| exitValue = execProcess.waitFor(); |
| logger.join(); // make sure we get the whole output |
| String javaOutput = logger.buffer.toString().trim(); |
| if (!expectedSuccessOutputString.equals(javaOutput)) { |
| System.out.println("----------------------------------------"); |
| System.out.println(testName + " - Javac and Eclipse runtime output is not the same:"); |
| javacFullLog.println("JAVAC_MISMATCH: Javac and Eclipse runtime output is not the same"); |
| dualPrintln("eclipse:"); |
| dualPrintln(expectedSuccessOutputString); |
| dualPrintln("javac:"); |
| dualPrintln(javaOutput); |
| System.out.println("\n"); |
| printFiles(testFiles); // PREMATURE consider printing files to the log as well |
| DIFF_COUNTERS[2]++; |
| } |
| } |
| } |
| } |
| else { |
| // Eclipse found errors or warnings |
| if (errorLogger.buffer.length() == 0) { |
| System.out.println("----------------------------------------"); |
| System.out.println(testName + " - Eclipse has found error(s)/warning(s) but Javac did not find any:"); |
| javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s)/warning(s) but Javac did not find any"); |
| dualPrintln("eclipse:"); |
| dualPrintln(expectedProblemLog); |
| printFiles(testFiles); |
| DIFF_COUNTERS[1]++; |
| } else if (expectedProblemLog.indexOf("ERROR") > 0 && exitValue == 0){ |
| System.out.println("----------------------------------------"); |
| System.out.println(testName + " - Eclipse has found error(s) but Javac only found warning(s):"); |
| javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s) but Javac only found warning(s)"); |
| dualPrintln("eclipse:"); |
| dualPrintln(expectedProblemLog); |
| System.out.println("javac:"); |
| System.out.println(errorLogger.buffer.toString()); |
| printFiles(testFiles); |
| DIFF_COUNTERS[1]++; |
| } else { |
| // PREMATURE refine comparison |
| // TODO (frederic) compare warnings in each result and verify they are similar... |
| // System.out.println(testName+": javac has found warnings :"); |
| // System.out.print(errorLogger.buffer.toString()); |
| // System.out.println(testName+": we're expecting warning results:"); |
| // System.out.println(expectedProblemLog); |
| } |
| } |
| } |
| catch (InterruptedException e1) { |
| if (compileProcess != null) compileProcess.destroy(); |
| if (execProcess != null) execProcess.destroy(); |
| System.out.println(testName+": Sun javac compilation was aborted!"); |
| javacFullLog.println("JAVAC_WARNING: Sun javac compilation was aborted!"); |
| e1.printStackTrace(javacFullLog); |
| } |
| catch (Throwable e) { |
| System.out.println(testName+": could not launch Sun javac compilation!"); |
| e.printStackTrace(); |
| javacFullLog.println("JAVAC_ERROR: could not launch Sun javac compilation!"); |
| e.printStackTrace(javacFullLog); |
| // PREMATURE failing the javac pass or comparison could also fail |
| // the test itself |
| } |
| finally { |
| // Clean up written file(s) |
| Util.delete(outputTestDirectory); |
| } |
| } |
| /** |
| * Log contains all problems (warnings+errors) |
| */ |
| protected void runNegativeTest(String[] testFiles, String expectedProblemLog) { |
| runNegativeTest(testFiles, expectedProblemLog, null, true); |
| runNegativeTest( |
| testFiles, |
| expectedProblemLog, |
| null /* no extra class libraries */, |
| true /* flush output directory */, |
| null /* no custom options */, |
| false /* do not generate output */, |
| false /* do not show category */, |
| false /* do not show warning token */, |
| false /* do not skip javac for this peculiar test */, |
| false /* do not perform statements recovery */); |
| } |
| /** |
| * Log contains all problems (warnings+errors) |
| */ |
| protected void runNegativeTest( |
| String[] testFiles, |
| String expectedProblemLog, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory) { |
| runNegativeTest( |
| testFiles, |
| expectedProblemLog, |
| classLib, |
| shouldFlushOutputDirectory, |
| null /* no custom options */, |
| false /* do not generate output */, |
| false /* do not show category */, |
| false /* do not show warning token */, |
| false /* do not skip javac for this peculiar test */, |
| false /* do not perform statements recovery */); |
| } |
| /** |
| * Log contains all problems (warnings+errors) |
| */ |
| protected void runNegativeTest( |
| String[] testFiles, |
| String expectedProblemLog, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| Map customOptions) { |
| runNegativeTest( |
| testFiles, |
| expectedProblemLog, |
| classLib, |
| shouldFlushOutputDirectory, |
| customOptions, |
| false /* do not generate output */, |
| false /* do not show category */, |
| false /* do not show warning token */, |
| false /* do not skip javac for this peculiar test */, |
| false /* do not perform statements recovery */); |
| } |
| /** |
| * Log contains all problems (warnings+errors) |
| */ |
| protected void runNegativeTest( |
| String[] testFiles, |
| String expectedProblemLog, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| Map customOptions, |
| boolean generateOutput, |
| boolean showCategory, |
| boolean showWarningToken) { |
| runNegativeTest( |
| testFiles, |
| expectedProblemLog, |
| classLib, |
| shouldFlushOutputDirectory, |
| customOptions, |
| generateOutput, |
| showCategory, |
| showWarningToken, |
| false /* do not skip javac for this peculiar test */, |
| false /* do not perform statements recovery */); |
| } |
| |
| /** |
| * Log contains all problems (warnings+errors) |
| */ |
| protected void runNegativeTest( |
| String[] testFiles, |
| String expectedProblemLog, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| Map customOptions, |
| boolean generateOutput, |
| boolean showCategory, |
| boolean showWarningToken, |
| boolean skipJavac, |
| boolean performStatementsRecovery) { |
| // Non-javac part |
| try { |
| if (shouldFlushOutputDirectory) |
| Util.flushDirectoryContent(new File(OUTPUT_DIR)); |
| |
| IProblemFactory problemFactory = getProblemFactory(); |
| Requestor requestor = |
| new Requestor( |
| problemFactory, |
| OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, |
| generateOutput, |
| null/*no custom requestor*/, |
| showCategory, |
| showWarningToken); |
| Map options = getCompilerOptions(); |
| if (customOptions != null) { |
| options.putAll(customOptions); |
| } |
| CompilerOptions compilerOptions = new CompilerOptions(options); |
| compilerOptions.performMethodsFullRecovery = performStatementsRecovery; |
| compilerOptions.performStatementsRecovery = performStatementsRecovery; |
| Compiler batchCompiler = |
| new Compiler( |
| getNameEnvironment(new String[]{}, classLib), |
| getErrorHandlingPolicy(), |
| compilerOptions, |
| requestor, |
| problemFactory); |
| Object inferEngines=options.get(INFERENCE_ENGINES); |
| if (inferEngines !=null) |
| { |
| batchCompiler.parser.inferenceEngines=(InferEngine []) inferEngines; |
| |
| } |
| batchCompiler.options.produceReferenceInfo = true; |
| Throwable exception = null; |
| try { |
| batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together |
| } catch(RuntimeException e){ |
| exception = e; |
| throw e; |
| } catch(Error e) { |
| exception = e; |
| throw e; |
| } finally { |
| String computedProblemLog = Util.convertToIndependantLineDelimiter(requestor.problemLog.toString()); |
| String platformIndependantExpectedLog = Util.convertToIndependantLineDelimiter(expectedProblemLog); |
| if (!platformIndependantExpectedLog.equals(computedProblemLog)) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| System.out.println(Util.displayString(computedProblemLog, INDENT, SHIFT)); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| } |
| if (exception == null) |
| assertEquals("Invalid problem log ", platformIndependantExpectedLog, computedProblemLog); |
| } |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| if (RUN_JAVAC && !skipJavac) |
| runJavac(testFiles, expectedProblemLog, null, shouldFlushOutputDirectory); |
| } |
| } |
| |
| protected void runNegativeTestWithExecution( |
| String[] testFiles, |
| String expectedProblemLog, |
| String expectedSuccessOutputString, |
| String[] classLib, |
| boolean shouldFlushOutputDirectory, |
| String[] vmArguments, |
| Map customOptions, |
| ICompilerRequestor clientRequestor) { |
| |
| if (shouldFlushOutputDirectory) |
| Util.flushDirectoryContent(new File(OUTPUT_DIR)); |
| |
| IProblemFactory problemFactory = getProblemFactory(); |
| Requestor requestor = |
| new Requestor( |
| problemFactory, |
| OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, |
| true, |
| clientRequestor, |
| false /*show category*/, |
| false /*show warning token*/); |
| |
| Map options = getCompilerOptions(); |
| if (customOptions != null) { |
| options.putAll(customOptions); |
| } |
| CompilerOptions compilerOptions = new CompilerOptions(options); |
| compilerOptions.performMethodsFullRecovery = false; |
| compilerOptions.performStatementsRecovery = false; |
| Compiler batchCompiler = |
| new Compiler( |
| getNameEnvironment(new String[]{}, classLib), |
| getErrorHandlingPolicy(), |
| compilerOptions, |
| requestor, |
| problemFactory); |
| batchCompiler.options.produceReferenceInfo = true; |
| try { |
| batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together |
| } catch(RuntimeException e) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| e.printStackTrace(); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| throw e; |
| } |
| assertTrue("Must have errors", requestor.hasErrors); |
| |
| String computedProblemLog = Util.convertToIndependantLineDelimiter(requestor.problemLog.toString()); |
| String platformIndependantExpectedLog = Util.convertToIndependantLineDelimiter(expectedProblemLog); |
| if (!platformIndependantExpectedLog.equals(computedProblemLog)) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| System.out.println(Util.displayString(computedProblemLog, INDENT, SHIFT)); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| assertEquals("Invalid problem log ", platformIndependantExpectedLog, computedProblemLog); |
| } |
| |
| String sourceFile = testFiles[0]; |
| |
| // Compute class name by removing ".java" and replacing slashes with dots |
| String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.'); |
| if (className.endsWith(PACKAGE_INFO_NAME)) return; |
| |
| if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| boolean passed = |
| this.verifier.verifyClassFiles( |
| sourceFile, |
| className, |
| expectedSuccessOutputString, |
| this.classpaths, |
| null, |
| vmArguments); |
| if (!passed) { |
| String platformIndependantExpectedSuccessOutputString = Util.convertToIndependantLineDelimiter(expectedSuccessOutputString); |
| String platformIndependantFailureReason = Util.convertToIndependantLineDelimiter(this.verifier.failureReason); |
| if (platformIndependantFailureReason.indexOf(platformIndependantExpectedSuccessOutputString) == -1) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| System.out.println(Util.displayString(platformIndependantFailureReason, INDENT, SHIFT)); |
| assertEquals("Invalid runtime log ", platformIndependantExpectedSuccessOutputString, platformIndependantFailureReason); |
| System.out.println(getClass().getName() + '#' + getName()); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| } |
| } else if (vmArguments != null) { |
| if (this.verifier != null) { |
| this.verifier.shutDown(); |
| } |
| this.verifier = new TestVerifier(false); |
| this.createdVerifier = true; |
| } |
| } |
| |
| protected void setUp() throws Exception { |
| super.setUp(); |
| if (this.verifier == null) { |
| this.verifier = new TestVerifier(true); |
| this.createdVerifier = true; |
| } |
| if (RUN_JAVAC) { |
| if (isFirst()) { |
| if (javacFullLog == null) { |
| // One time initialization of javac related concerns |
| // compute command lines and extract javac version |
| String jdkRootDirectory = System.getProperty("jdk.root"); |
| if (jdkRootDirectory == null) |
| jdkRootDirPath = (new Path(Util.getJREDirectory())).removeLastSegments(1); |
| else |
| jdkRootDirPath = new Path(jdkRootDirectory); |
| |
| StringBuffer cmdLineHeader = new StringBuffer(jdkRootDirPath. |
| append("bin").append(JAVA_NAME).toString()); // PREMATURE replace JAVA_NAME and JAVAC_NAME with locals? depends on potential reuse |
| javaCommandLineHeader = cmdLineHeader.toString(); |
| cmdLineHeader = new StringBuffer(jdkRootDirPath. |
| append("bin").append(JAVAC_NAME).toString()); |
| cmdLineHeader.append(" -classpath . "); |
| // start with the current directory which contains the source files |
| Process compileProcess = Runtime.getRuntime().exec( |
| cmdLineHeader.toString() + " -version", null, null); |
| Logger versionLogger = new Logger(compileProcess.getErrorStream(), ""); |
| // PREMATURE implement consistent error policy |
| versionLogger.start(); |
| compileProcess.waitFor(); |
| versionLogger.join(); // make sure we get the whole output |
| String version = versionLogger.buffer.toString(); |
| int eol = version.indexOf('\n'); |
| version = version.substring(0, eol); |
| cmdLineHeader.append(" -d "); |
| cmdLineHeader.append(JAVAC_OUTPUT_DIR.indexOf(" ") != -1 ? "\"" + JAVAC_OUTPUT_DIR + "\"" : JAVAC_OUTPUT_DIR); |
| cmdLineHeader.append(" -source 1.5 -deprecation -Xlint:unchecked "); // enable recommended warnings |
| // REVIEW consider enabling all warnings instead? Philippe does not see |
| // this as ez to use (too many changes in logs) |
| javacCommandLineHeader = cmdLineHeader.toString(); |
| new File(Util.getOutputDirectory()).mkdirs(); |
| // TODO maxime check why this happens to miss in some cases |
| javacFullLogFileName = Util.getOutputDirectory() + File.separatorChar + |
| version.replace(' ', '_') + "_" + |
| (new SimpleDateFormat("yyyyMMdd_HHmmss")).format(new Date()) + |
| ".txt"; |
| javacFullLog = |
| new PrintWriter(new FileOutputStream(javacFullLogFileName)); |
| javacFullLog.println(version); // so that the contents is self sufficient |
| System.out.println("***************************************************************************"); |
| System.out.println("* Sun Javac compiler output archived into file:"); |
| System.out.println("* " + javacFullLogFileName); |
| System.out.println("***************************************************************************"); |
| } |
| // per class initialization |
| CURRENT_CLASS_NAME = getClass().getName(); |
| dualPrintln("***************************************************************************"); |
| System.out.print("* Comparison with Sun Javac compiler for class "); |
| dualPrintln(CURRENT_CLASS_NAME.substring(CURRENT_CLASS_NAME.lastIndexOf('.')+1) + |
| " (" + TESTS_COUNTERS.get(CURRENT_CLASS_NAME) + " tests)"); |
| System.out.println("***************************************************************************"); |
| DIFF_COUNTERS[0] = 0; |
| DIFF_COUNTERS[1] = 0; |
| DIFF_COUNTERS[2] = 0; |
| } |
| } |
| } |
| |
| public void stop() { |
| this.verifier.shutDown(); |
| } |
| |
| protected void tearDown() throws Exception { |
| if (this.createdVerifier) { |
| this.stop(); |
| } |
| // clean up output dir |
| File outputDir = new File(OUTPUT_DIR); |
| if (outputDir.exists()) { |
| Util.flushDirectoryContent(outputDir); |
| } |
| super.tearDown(); |
| if (RUN_JAVAC) { |
| printJavacResultsSummary(); |
| } |
| } |
| |
| protected void runBasicTest(String[] testFiles) { |
| runBasicTest( |
| testFiles, |
| null /* no extra class libraries */, |
| null /* no custom options*/, |
| null /* no custom requestor*/ ); |
| } |
| |
| protected void runBasicTest( |
| String[] testFiles, |
| String[] classLib, |
| Map customOptions, |
| ICompilerRequestor clientRequestor) { |
| // Non-javac part |
| try { |
| |
| IProblemFactory problemFactory = getProblemFactory(); |
| Requestor requestor = |
| new Requestor( |
| problemFactory, |
| OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator, |
| false, |
| clientRequestor, |
| false, /* show category */ |
| false /* show warning token*/); |
| |
| Map options = getCompilerOptions(); |
| if (customOptions != null) { |
| options.putAll(customOptions); |
| } |
| CompilerOptions compilerOptions = new CompilerOptions(options); |
| compilerOptions.performStatementsRecovery = false; |
| Compiler batchCompiler = |
| new Compiler( |
| getNameEnvironment(new String[]{}, classLib), |
| getErrorHandlingPolicy(), |
| compilerOptions, |
| requestor, |
| problemFactory); |
| compilerOptions.produceReferenceInfo = true; |
| try { |
| batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together |
| } catch(RuntimeException e) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| e.printStackTrace(); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| throw e; |
| } |
| if (!requestor.hasErrors) { |
| String sourceFile = testFiles[0]; |
| boolean passed=true; |
| if (!passed) { |
| System.out.println(getClass().getName() + '#' + getName()); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| } |
| assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action |
| passed); |
| } else { |
| System.out.println(getClass().getName() + '#' + getName()); |
| System.out.println(Util.displayString(requestor.problemLog, INDENT, SHIFT)); |
| for (int i = 0; i < testFiles.length; i += 2) { |
| System.out.print(testFiles[i]); |
| System.out.println(" ["); //$NON-NLS-1$ |
| System.out.println(testFiles[i + 1]); |
| System.out.println("]"); //$NON-NLS-1$ |
| } |
| assertTrue("Unexpected problems: " + requestor.problemLog, false); |
| } |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| } |
| } |
| |
| |
| |
| static class TestParser extends Parser |
| { |
| |
| public TestParser( |
| IProblemFactory problemFactory, |
| CompilerOptions options, |
| boolean optimizeStringLiterals, |
| boolean useSourceJavadocParser) { |
| |
| super( |
| new ProblemReporter( |
| DefaultErrorHandlingPolicies.exitAfterAllProblems(), |
| options, |
| problemFactory), |
| optimizeStringLiterals); |
| |
| // we want to notify all syntax error with the acceptProblem API |
| // To do so, we define the record method of the ProblemReporter |
| this.problemReporter = new ProblemReporter( |
| DefaultErrorHandlingPolicies.exitAfterAllProblems(), |
| options, |
| problemFactory) { |
| public void record(CategorizedProblem problem, CompilationResult unitResult, ReferenceContext context) { |
| unitResult.record(problem, context); // TODO (jerome) clients are trapping problems either through factory or requestor... is result storing needed? |
| System.out.println("PARSER ERROR: "+problem.toString()); |
| assertTrue("unexpected parse Error", false); |
| } |
| }; |
| this.options = options; |
| // set specific javadoc parser |
| if (useSourceJavadocParser) { |
| this.javadocParser = new SourceJavadocParser(this); |
| |
| } |
| } |
| |
| public CompilationUnitDeclaration parseCompilationUnit( |
| ICompilationUnit unit, |
| boolean fullParse) { |
| |
| boolean old = diet; |
| |
| try { |
| diet = !fullParse; |
| CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit); |
| CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult); |
| int initialStart = this.scanner.initialPosition; |
| int initialEnd = this.scanner.eofPosition; |
| if ( fullParse){ |
| diet = false; |
| this.getMethodBodies(parsedUnit); |
| } |
| this.scanner.resetTo(initialStart, initialEnd); |
| assertTrue(this.expressionPtr<0); |
| assertTrue(this.expressionLengthPtr<0); |
| assertTrue(this.astPtr<0); |
| assertTrue(this.astLengthPtr<0); |
| assertTrue(this.intPtr<0); |
| return parsedUnit; |
| } catch (AbortCompilation e) { |
| // ignore this exception |
| } finally { |
| diet = old; |
| } |
| return null; |
| } |
| } |
| protected CompilationUnitDeclaration runParseTest( |
| String s, String testName,String expected |
| ) { |
| // Non-javac part |
| try { |
| |
| char[] source = s.toCharArray(); |
| TestParser parser = |
| new TestParser( |
| new DefaultProblemFactory(Locale.getDefault()), |
| new CompilerOptions(getCompilerOptions()), |
| true/*optimize string literals*/, |
| false); |
| |
| ICompilationUnit sourceUnit = new CompilationUnit(source, testName, null); |
| |
| CompilationUnitDeclaration compUnit= parser.parseCompilationUnit(sourceUnit, true); |
| if (expected!=null) |
| { |
| String result=compUnit.toString(); |
| assertEquals(expected, result); |
| } |
| return compUnit; |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| } |
| } |
| |
| protected CompilationUnitDeclaration runJSDocParseTest( |
| String s, String testName,String expected |
| ) { |
| // Non-javac part |
| try { |
| |
| char[] source = s.toCharArray(); |
| TestParser parser = |
| new TestParser( |
| new DefaultProblemFactory(Locale.getDefault()), |
| new CompilerOptions(getCompilerOptions()), |
| true/*optimize string literals*/, |
| false); |
| |
| parser.javadocParser.checkDocComment=true; |
| ICompilationUnit sourceUnit = new CompilationUnit(source, testName, null); |
| |
| CompilationUnitDeclaration compUnit= parser.parseCompilationUnit(sourceUnit, true); |
| if (expected!=null) |
| { |
| String result=compUnit.toString(); |
| assertEquals(expected, result); |
| } |
| return compUnit; |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| } |
| } |
| |
| |
| |
| protected CompilationUnitDeclaration runInferTest( |
| String s, |
| String testName,String expected, |
| InferOptions inferOptions |
| ) { |
| |
| return runInferTest(s, testName, expected, inferOptions,new DefaultInferrenceProvider()); |
| } |
| |
| |
| protected CompilationUnitDeclaration runInferTest( |
| String s, |
| String testName,String expected, |
| InferOptions inferOptions, |
| InferrenceProvider inferrenceProvider |
| ) { |
| // Non-javac part |
| try { |
| |
| char[] source = s.toCharArray(); |
| CompilerOptions compilerOptions = new CompilerOptions(getCompilerOptions()); |
| compilerOptions.inferOptions=inferOptions; |
| TestParser parser = |
| new TestParser( |
| new DefaultProblemFactory(Locale.getDefault()), |
| compilerOptions, |
| true/*optimize string literals*/, |
| false); |
| |
| parser.javadocParser.checkDocComment=true; |
| |
| ICompilationUnit sourceUnit = new CompilationUnit(source, testName, null); |
| |
| CompilationUnitDeclaration compUnit= parser.parseCompilationUnit(sourceUnit, true); |
| |
| InferEngine inferEngine=inferrenceProvider.getInferEngine(); |
| |
| inferEngine.initialize(); |
| inferEngine.setCompilationUnit(compUnit); |
| inferEngine.doInfer(); |
| if (expected!=null) |
| { |
| StringBuffer sb = new StringBuffer(); |
| compUnit.printInferredTypes(sb); |
| String result=sb.toString(); |
| assertEquals(expected, result); |
| } |
| return compUnit; |
| // javac part |
| } catch (AssertionFailedError e) { |
| throw e; |
| } finally { |
| } |
| } |
| |
| |
| } |