blob: e3299a3a97b07026642608ccf1e93ee7b7d71ddf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 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.core.tests.compiler.regression;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import org.eclipse.jdt.core.search.SearchDocument;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.tests.junit.extension.StopableTestCase;
import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
import org.eclipse.jdt.core.tests.util.CompilerTestSetup;
import org.eclipse.jdt.core.tests.util.TestVerifier;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.core.search.JavaSearchParticipant;
import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
public final static String PACKAGE_INFO_NAME = new String(TypeConstants.PACKAGE_INFO_NAME);
public static String OUTPUT_DIR = Util.getOutputDirectory() + File.separator + "regression";
public static int INDENT = 2;
public static boolean SHIFT = false;
protected INameEnvironment javaClassLib;
protected String[] classpaths;
protected TestVerifier verifier;
protected boolean createdVerifier;
public AbstractRegressionTest(String name) {
super(name);
}
/*
* 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.jdt.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());
BinaryIndexer indexer = new BinaryIndexer(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_ReportLocalVariableHiding, CompilerOptions.WARNING);
defaultOptions.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.WARNING);
defaultOptions.put(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, CompilerOptions.WARNING);
defaultOptions.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.WARNING);
defaultOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
defaultOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
defaultOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.WARNING );
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;
}
}
protected void runConformTest(String[] testFiles) {
runConformTest(testFiles, null, null, true, null);
}
protected void runConformTest(String[] testFiles, String[] vmArguments) {
runConformTest(testFiles, null, null, true, vmArguments);
}
protected void runConformTest(
String[] testFiles,
String expectedSuccessOutputString,
String[] vmArguments) {
runConformTest(testFiles, expectedSuccessOutputString, null, true, vmArguments);
}
protected void runConformTest(String[] testFiles, String expectedSuccessOutputString) {
runConformTest(testFiles, expectedSuccessOutputString, null, true, null);
}
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*/);
}
protected void runConformTest(
String[] testFiles,
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,
false,
clientRequestor);
Map options = getCompilerOptions();
if (customOptions != null) {
options.putAll(customOptions);
}
Compiler batchCompiler =
new Compiler(
getNameEnvironment(new String[]{}, classLib),
getErrorHandlingPolicy(),
options,
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;
}
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);
}
}
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*/);
Compiler batchCompiler =
new Compiler(
getNameEnvironment(new String[]{}, classLib),
getErrorHandlingPolicy(),
getCompilerOptions(),
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);
}
}
}
/**
* Log contains all problems (warnings+errors)
*/
protected void runNegativeTest(String[] testFiles, String expectedProblemLog) {
runNegativeTest(testFiles, expectedProblemLog, null, true);
}
/**
* Log contains all problems (warnings+errors)
*/
protected void runNegativeTest(
String[] testFiles,
String expectedProblemLog,
String[] classLib,
boolean shouldFlushOutputDirectory) {
runNegativeTest(testFiles, expectedProblemLog, classLib, shouldFlushOutputDirectory, null);
}
/**
* 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);
}
/**
* Log contains all problems (warnings+errors)
*/
protected void runNegativeTest(
String[] testFiles,
String expectedProblemLog,
String[] classLib,
boolean shouldFlushOutputDirectory,
Map customOptions,
boolean generateOutput) {
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*/);
Map options = getCompilerOptions();
if (customOptions != null) {
options.putAll(customOptions);
}
Compiler batchCompiler =
new Compiler(
getNameEnvironment(new String[]{}, classLib),
getErrorHandlingPolicy(),
options,
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 {
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);
}
}
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);
Map options = getCompilerOptions();
if (customOptions != null) {
options.putAll(customOptions);
}
Compiler batchCompiler =
new Compiler(
getNameEnvironment(new String[]{}, classLib),
getErrorHandlingPolicy(),
options,
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;
}
}
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);
outputDir.delete();
}
super.tearDown();
}
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;
}
}
}