/*******************************************************************************
* Copyright (c) 2000, 2007 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.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import junit.framework.Test;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.batch.ClasspathLocation;
import org.eclipse.jdt.internal.compiler.batch.Main;
public class BatchCompilerTest extends AbstractRegressionTest {
public static final String OUTPUT_DIR_PLACEHOLDER = "---OUTPUT_DIR_PLACEHOLDER---";
static final String JRE_HOME_DIR = Util.getJREDirectory();
private static final Main MAIN = new Main(null, null, false);
static {
// TESTS_NAMES = new String[] { "test000" };
// TESTS_NUMBERS = new int[] { 24 };
// TESTS_RANGE = new int[] { 107, -1 };
}
public BatchCompilerTest(String name) {
super(name);
}
/**
* This test suite only needs to be run on one compliance.
* As it includes some specific 1.5 tests, it must be used with a least a 1.5 VM
* and not be duplicated in general test suite.
* @see TestAll
*/
public static Test suite() {
return buildUniqueComplianceTestSuite(testClass(), COMPLIANCE_1_5);
}
private String getLibraryClasses() {
String[] paths = Util.getJavaClassLibs();
StringBuffer buffer = new StringBuffer();
for (int i = 0, max = paths.length; i < max; i++) {
if (i != 0) {
buffer.append(File.pathSeparatorChar);
}
buffer.append(paths[i]);
}
return String.valueOf(buffer);
}
private String getJCEJar() {
if (Util.isMacOS()) {
return JRE_HOME_DIR + "/../Classes/jce.jar";
}
return JRE_HOME_DIR + "/lib/jce.jar";
}
private String getExtDirectory() {
return JRE_HOME_DIR + "/lib/ext";
}
/**
* Run a compilation test that is expected to complete successfully and
* compare the outputs to expected ones.
*
* @param testFiles
* the source files, given as a suite of file name, file content;
* file names are relative to the output directory
* @param commandLine
* the command line to pass to
* {@link Main#compile(String) Main#compile}
* @param expectedSuccessOutOutputString
* the expected contents of the standard output stream; pass null
* to bypass the comparison
* @param expectedSuccessErrOutputString
* the expected contents of the standard error output stream;
* pass null to bypass the comparison
* @param shouldFlushOutputDirectory
* pass true to get the output directory flushed before the test
* runs
*/
protected void runConformTest(String[] testFiles, String commandLine,
String expectedSuccessOutOutputString,
String expectedSuccessErrOutputString,
boolean shouldFlushOutputDirectory) {
runTest(true, testFiles, commandLine, expectedSuccessOutOutputString,
expectedSuccessErrOutputString, shouldFlushOutputDirectory);
}
/**
* Run a compilation test that is expected to fail and compare the outputs
* to expected ones.
*
* @param testFiles
* the source files, given as a suite of file name, file content;
* file names are relative to the output directory
* @param commandLine
* the command line to pass to
* {@link Main#compile(String) Main#compile}
* @param expectedFailureOutOutputString
* the expected contents of the standard output stream; pass null
* to bypass the comparison
* @param expectedFailureErrOutputString
* the expected contents of the standard error output stream;
* pass null to bypass the comparison
* @param shouldFlushOutputDirectory
* pass true to get the output directory flushed before the test
* runs
*/
protected void runNegativeTest(String[] testFiles, String commandLine,
String expectedFailureOutOutputString,
String expectedFailureErrOutputString,
boolean shouldFlushOutputDirectory) {
runTest(false, testFiles, commandLine, expectedFailureOutOutputString,
expectedFailureErrOutputString, shouldFlushOutputDirectory);
}
/**
* Worker method for runConformTest and runNegativeTest.
*
* @param shouldCompileOK
* set to true if the compiler should compile the given sources
* without errors
* @param testFiles
* the source files, given as a suite of file name, file content;
* file names are relative to the output directory
* @param commandLine
* the command line to pass to
* {@link Main#compile(String) Main#compile}
* @param expectedOutOutputString
* the expected contents of the standard output stream; pass null
* to bypass the comparison
* @param expectedErrOutputString
* the expected contents of the standard error output stream;
* pass null to bypass the comparison
* @param shouldFlushOutputDirectory
* pass true to get the output directory flushed before the test
* runs
*/
private void runTest(boolean shouldCompileOK, String[] testFiles, String commandLine,
String expectedOutOutputString,
String expectedErrOutputString,
boolean shouldFlushOutputDirectory) {
File outputDirectory = new File(OUTPUT_DIR);
if (shouldFlushOutputDirectory)
Util.flushDirectoryContent(outputDirectory);
try {
if (!outputDirectory.isDirectory()) {
outputDirectory.mkdirs();
}
PrintWriter sourceFileWriter;
for (int i = 0; i < testFiles.length; i += 2) {
String fileName = OUTPUT_DIR + File.separator + testFiles[i];
File file = new File(fileName), innerOutputDirectory = file
.getParentFile();
if (!innerOutputDirectory.isDirectory()) {
innerOutputDirectory.mkdirs();
}
sourceFileWriter = new PrintWriter(new FileOutputStream(file));
sourceFileWriter.write(testFiles[i + 1]);
sourceFileWriter.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
String printerWritersNameRoot = OUTPUT_DIR + File.separator + testName();
String outFileName = printerWritersNameRoot + "out.txt",
errFileName = printerWritersNameRoot + "err.txt";
Main batchCompiler;
PrintWriter out = null;
PrintWriter err = null;
boolean compileOK;
try {
try {
out = new PrintWriter(new FileOutputStream(outFileName));
err = new PrintWriter(new FileOutputStream(errFileName));
batchCompiler = new Main(out, err, false);
} catch (FileNotFoundException e) {
System.out.println(getClass().getName() + '#' + getName());
e.printStackTrace();
throw new RuntimeException(e);
}
try {
final String[] tokenizeCommandLine = Main.tokenize(commandLine);
compileOK = batchCompiler.compile(tokenizeCommandLine);
} catch (RuntimeException e) {
compileOK = false;
System.out.println(getClass().getName() + '#' + getName());
e.printStackTrace();
throw e;
}
} finally {
if (out != null)
out.close();
if (err != null)
err.close();
}
String outOutputString = Util.fileContent(outFileName),
errOutputString = Util.fileContent(errFileName);
boolean compareOK = false, outCompareOK = false, errCompareOK = false;
if (compileOK == shouldCompileOK) {
compareOK =
(outCompareOK = semiNormalizedComparison(expectedOutOutputString,
outOutputString, outputDirNormalizer))
&& (errCompareOK = semiNormalizedComparison(expectedErrOutputString,
errOutputString, outputDirNormalizer));
}
if (compileOK != shouldCompileOK || !compareOK) {
System.out.println(getClass().getName() + '#' + getName());
for (int i = 0; i < testFiles.length; i += 2) {
System.out.print(testFiles[i]);
System.out.println(" [");
System.out.println(testFiles[i + 1]);
System.out.println("]");
}
}
if (compileOK != shouldCompileOK)
System.out.println(errOutputString);
if (compileOK == shouldCompileOK && !compareOK) {
System.out.println(
"------------ [START OUT] ------------\n"
+ "------------- Expected: -------------\n"
+ expectedOutOutputString
+ "\n------------- but was: -------------\n"
+ outOutputString
+ "\n--------- (cut and paste:) ----------\n"
+ Util.displayString(outputDirNormalizer
.normalized(outOutputString))
+ "\n------------- [END OUT] -------------\n"
+ "------------ [START ERR] ------------\n"
+ "------------- Expected: -------------\n"
+ expectedErrOutputString
+ "\n------------- but was: -------------\n"
+ errOutputString
+ "\n--------- (cut and paste:) ----------\n"
+ Util.displayString(outputDirNormalizer
.normalized(errOutputString))
+ "\n------------- [END ERR] -------------\n");
}
if (shouldCompileOK)
assertTrue("Unexpected problems: " + errOutputString, compileOK);
else
assertTrue("Unexpected success: " + errOutputString, !compileOK);
if (!outCompareOK) {
// calling assertEquals to benefit from the comparison UI
// (need appropriate exception)
assertEquals(
"Unexpected standard output for invocation with arguments ["
+ commandLine + "]",
expectedOutOutputString,
outOutputString);
}
if (!errCompareOK) {
assertEquals(
"Unexpected error output for invocation with arguments ["
+ commandLine + "]",
expectedErrOutputString,
errOutputString);
}
}
private void runClasspathTest(String classpathInput, String[] expectedClasspathEntries,
String expectedError) {
File outputDirectory = new File(OUTPUT_DIR);
if (!outputDirectory.isDirectory()) {
outputDirectory.mkdirs();
}
ArrayList paths = new ArrayList(Main.DEFAULT_SIZE_CLASSPATH);
try {
(new Main(new PrintWriter(System.out), new PrintWriter(System.err), true)).
processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, classpathInput, null /* customEncoding */, true /* isSourceOnly */, false /* rejectDestinationPathOnJars*/);
} catch (InvalidInputException e) {
// e.printStackTrace();
if (expectedError == null) {
fail("unexpected invalid input exception: " + e.getMessage());
} else if (! expectedError.equals(e.getMessage())) {
System.out.println("\"" + e.getMessage() + "\"");
assertEquals(expectedError, e.getMessage());
}
return;
}
if (expectedError == null) {
int l = paths.size();
assertEquals("unexpected classpaths entries number: ",
expectedClasspathEntries == null ? 0 : expectedClasspathEntries.length / 3, l);
for (int i = 0, j = 0; i < l ; i++) {
ClasspathLocation result = (ClasspathLocation) paths.get(i);
String expected = expectedClasspathEntries[j++];
String actual = result.toString();
if (! actual.equals("ClasspathDirectory " + expected + File.separator) &&
! actual.equals("Classpath for jar file " + expected)) {
assertEquals("dir/jar " + expected, actual);
}
expected = expectedClasspathEntries[j++];
if (result.accessRuleSet == null) {
assertNull("actual access rule is null instead of <" + expected +">", expected);
} else if (! result.accessRuleSet.toString(false).
startsWith("AccessRuleSet " + expected)) {
System.out.println("\"" + result.accessRuleSet.toString(false) + "\"");
fail("inappropriate rules (expected " + expected +
", got " + result.accessRuleSet.toString(false));
}
expected = expectedClasspathEntries[j++];
if (expected == null) {
assertNull(result.destinationPath);
} else if (expected == Main.NONE &&
result.destinationPath != Main.NONE) {
fail("expected 'none' output directory");
} else if (! expected.equals(result.destinationPath)) {
System.out.println("\"" + result.destinationPath + "\"");
assertEquals(expected, result.destinationPath);
}
}
} else {
fail("missing error: " + expectedError);
}
}
/**
* Check that no line of message extends beyond width columns. Tabs count for
* 4 characters.
* @param message the message to check
* @param width the maximum number of columns for the message
*/
private void checkWidth(String message, int width) {
BufferedReader reader = new BufferedReader(
new StringReader(message.replaceAll("\t", " ")));
String line;
try {
while ((line = reader.readLine()) != null) {
assertTrue("line exceeds " + width + "characters: " + line,
line.length() <= width);
}
} catch (IOException e) {
// should never happen on a StringReader
}
}
/**
* Abstract normalizer for output comparison. This class merely embodies a
* chain of responsibility, plus the signature of the method of interest
* here, that is {@link #normalized(String) normalized}.
*/
private static abstract class Normalizer {
private Normalizer nextInChain;
Normalizer(Normalizer nextInChain) {
this.nextInChain = nextInChain;
}
String normalized(String originalValue) {
String result;
if (nextInChain == null)
result = Util.convertToIndependantLineDelimiter(originalValue);
else
result = nextInChain.normalized(originalValue);
return result;
}
}
/**
* This normalizer replaces occurrences of a given string with a given
* placeholder.
*/
private static class StringNormalizer extends Normalizer {
private String match;
private int matchLength;
private String placeholder;
StringNormalizer(Normalizer nextInChain, String match, String placeholder) {
super(nextInChain);
this.match = match;
this.matchLength = match.length();
this.placeholder = placeholder;
}
String normalized(String originalValue) {
String result;
StringBuffer normalizedValueBuffer = new StringBuffer(originalValue);
int nextOccurrenceIndex;
while ((nextOccurrenceIndex = normalizedValueBuffer.indexOf(match)) != -1)
normalizedValueBuffer.replace(nextOccurrenceIndex,
nextOccurrenceIndex + matchLength, placeholder);
result = super.normalized(normalizedValueBuffer.toString());
return result;
}
}
/**
* This normalizer replaces the whole classpaths section of a log file with
* a normalized placeholder.
*/
private static class XMLClasspathsSectionNormalizer extends Normalizer {
XMLClasspathsSectionNormalizer() {
super(null);
}
XMLClasspathsSectionNormalizer(Normalizer nextInChain) {
super(nextInChain);
}
String normalized(String originalValue) {
String result;
StringBuffer normalizedValueBuffer = new StringBuffer(originalValue);
int classpathsStartTagStart = normalizedValueBuffer
.indexOf(""), classpathsEndTagStart = normalizedValueBuffer
.indexOf("");
if (classpathsStartTagStart != -1 && classpathsEndTagStart != -1
&& classpathsStartTagStart < classpathsEndTagStart)
normalizedValueBuffer.replace(classpathsStartTagStart + 12,
classpathsEndTagStart, "NORMALIZED SECTION");
result = super.normalized(normalizedValueBuffer.toString());
return result;
}
}
/**
* This normalizer removes a selected range of lines from a log file.
*/
private static class LinesRangeNormalizer extends Normalizer {
private int first, number;
LinesRangeNormalizer() {
super(null);
first = number = 0;
}
LinesRangeNormalizer(Normalizer nextInChain) {
super(nextInChain);
first = number = 0;
}
/**
* Make a new normalizer able to suppress a range of lines delimited by
* "\n" sequences from a log file (or another string).
*
* @param nextInChain
* the next normalizer in the chain of responsibility; pass
* null if none is needed
* @param firstLineToRemove
* the index of the first line to remove, starting at 0
* @param linesNumber
* the number or lines to remove; if 0, no other
* transformation occurs than those operated by nextInChain
* (if any)
*/
LinesRangeNormalizer(Normalizer nextInChain, int firstLineToRemove,
int linesNumber) {
super(nextInChain);
first = firstLineToRemove;
number = linesNumber >= 0 ? linesNumber : 0;
}
String normalized(String originalValue) {
String result;
if (number == 0 || originalValue.length() == 0)
result = super.normalized(originalValue);
else {
final int START = 0, KEEPING = 1, KEEPING_R = 2, SKIPING = 3, SKIPING_R = 4, END = 5, ERROR = 6;
int state = START, currentLineIndex = 0, currentCharIndex = 0, sourceLength;
char currentChar = '\0';
if (first <= 0)
state = SKIPING;
else
state = KEEPING;
StringBuffer normalizedValueBuffer = new StringBuffer(), source = new StringBuffer(
originalValue);
sourceLength = source.length();
while (state != END && state != ERROR) {
if (currentCharIndex < sourceLength) {
currentChar = source.charAt(currentCharIndex++);
switch (currentChar) {
case '\r':
switch (state) {
case KEEPING:
normalizedValueBuffer.append(currentChar);
state = KEEPING_R;
break;
case SKIPING:
state = SKIPING_R;
break;
default:
state = ERROR;
}
break;
case '\n':
currentLineIndex++;
switch (state) {
case KEEPING: // tolerate Linux line delimiters
case KEEPING_R:
normalizedValueBuffer.append(currentChar);
if (currentLineIndex == first) {
state = SKIPING;
}
break;
case SKIPING: // tolerate Linux line delimiters
case SKIPING_R:
// in effect, we tolerate too big first and number
// values
if (currentLineIndex >= first + number) {
if (currentCharIndex < sourceLength)
normalizedValueBuffer.append(source
.substring(currentCharIndex));
state = END;
} else {
state = SKIPING;
}
break;
default:
state = ERROR;
}
break;
default:
switch (state) {
case KEEPING:
normalizedValueBuffer.append(currentChar);
break;
case SKIPING:
break;
default:
state = ERROR;
}
}
}
else if (currentChar == '\n')
state = END;
else
state = ERROR;
}
if (state == ERROR)
normalizedValueBuffer
.append("UNEXPECTED ERROR in LinesRangeNormalizer");
result = super.normalized(normalizedValueBuffer.toString());
}
return result;
}
}
/**
* Normalizer instance that replaces occurrences of OUTPUT_DIR with
* OUTPUT_DIR_PLACEHOLDER and changes file separator to / if the
* platform file separator is different from /.
*/
private static Normalizer outputDirNormalizer;
static {
if (File.separatorChar == '/') {
outputDirNormalizer = new StringNormalizer(
null, OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
}
else {
outputDirNormalizer = new StringNormalizer(
new StringNormalizer(
null, File.separator, "/"),
OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
}
}
/**
* Normalizer instance for non XML log files.
*/
private static Normalizer textLogsNormalizer = new StringNormalizer(
new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null,
0, 2)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
/**
* Normalizer instance for XML log files.
*/
private static Normalizer xmlLogsNormalizer = new StringNormalizer(
new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null,
1, 1)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
/**
* Return true if and only if the two strings passed as parameters compare
* equal, modulo the transformation of the second string by a normalizer
* passed in parameter. This is meant to erase the variations of subparts of
* the compared strings in function of the test machine, the user account,
* etc.
*
* @param keep
* the first string to compare, gets compared as it is
* @param normalize
* the second string to compare, passed through the normalizer
* before comparison
* @param normalizer
* the transformation applied to normalize
* @return true if keep and normalize compare equal after normalize has been
* normalized
*/
private boolean semiNormalizedComparison(String keep, String normalize,
Normalizer normalizer) {
if (keep == null)
return normalize == null;
if (normalize == null)
return false;
// return keep.equals(normalizer.normalized(normalize));
return equals(keep, normalizer.normalized(normalize));
}
private static boolean equals(String a, String b) {
StringBuffer aBuffer = new StringBuffer(a), bBuffer = new StringBuffer(b);
int length = aBuffer.length(), bLength;
boolean result = true;
if (length != (bLength = bBuffer.length())) {
System.err.println("a and b lengths differ");
if (length > bLength) {
length = bLength;
}
result = false;
}
for (int i = 0; i < length; i++)
if (aBuffer.charAt(i) != bBuffer.charAt(i)) {
int beforeStart = i - 5, beforeEnd = i - 1, afterStart = i + 1, afterEnd = i + 5;
if (beforeStart < 0) {
beforeStart = 0;
if (beforeEnd < 0)
beforeEnd = 0;
}
if (afterEnd >= length) {
afterEnd = length - 1;
if (afterStart >= length)
afterStart = length - 1;
}
System.err.println("a and b differ at rank: " + i
+ "\na: ..." + aBuffer.substring(beforeStart, beforeEnd)
+ "<" + aBuffer.charAt(i) + ">"
+ aBuffer.substring(afterStart, afterEnd) + "..."
+ "\nb: ..." + bBuffer.substring(beforeStart, beforeEnd)
+ "<" + bBuffer.charAt(i) + ">"
+ bBuffer.substring(afterStart, afterEnd) + "...");
return false;
}
return result; // may be false if one of the strings equals the beginning
// of the other one, which is longer anyway
}
public void test001() {
String commandLine = "-classpath \"D:/a folder\";d:/jdk1.4/jre/lib/rt.jar -1.4 -preserveAllLocals -g -verbose d:/eclipse/workspaces/development2.0/plugins/Bar/src2/ -d d:/test";
String expected = " <-classpath> <-1.4> <-preserveAllLocals> <-g> <-verbose> <-d> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
public void test002() {
String commandLine = "-classpath \"a folder\";\"b folder\"";
String expected = " <-classpath> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
public void test003() {
String commandLine = "-classpath \"a folder;b folder\"";
String expected = " <-classpath> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
public void test004() {
String commandLine = "\"d:/tmp A/\"A.java -classpath \"d:/tmp A\";d:/jars/rt.jar -nowarn -time -g -d d:/tmp";
String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
public void test005() {
String commandLine = "\"d:/tmp A/\"A.java -classpath d:/jars/rt.jar;\"d:/tmp A\";\"toto\" -nowarn -time -g -d d:/tmp";
String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
public void test006() {
String commandLine = "\"d:/tmp A/A.java\" -classpath d:/jars/rt.jar;\"d:/tmp A\";d:/tmpB/ -nowarn -time -g -d d:/tmp";
String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> ";
String[] args = Main.tokenize(commandLine);
StringBuffer buffer = new StringBuffer(30);
for (int i = 0; i < args.length; i++){
buffer.append(" <"+args[i]+">");
}
String result = buffer.toString();
//System.out.println(Util.displayString(result, 2));
assertEquals("incorrect tokenized command line",
expected,
result);
}
// test the tester - runConformTest
public void test007(){
this.runConformTest(
new String[] {
"X.java",
"import java.util.List;\n" +
"\n" +
"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" +
")\n" +
"public class X {\n" +
" public static void main(String[] args) {\n" +
" if (false) {\n" +
" ;\n" +
" } else {\n" +
" }\n" +
" // Zork z;\n" +
" }\n" +
"}"
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -bootclasspath " + "\"" + getLibraryClasses() + "\""
+ " -cp " + "\"" + getJCEJar() + "\""
+ " -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
+ " -verbose -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
"[parsing ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[reading java/lang/Object.class]\n" +
"[analyzing ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[reading java/util/List.class]\n" +
"[reading java/lang/SuppressWarnings.class]\n" +
"[reading java/lang/String.class]\n" +
"[writing X.class - #1]\n" +
"[completed ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[1 unit compiled]\n" +
"[1 .class file generated]\n",
"", // changed with bug 123522: now the SuppressWarning upon the first type
// influences warnings on unused imports
true);
}
// test the tester - runNegativeTest
public void test008(){
this.runNegativeTest(
new String[] {
"X.java",
"import java.util.List;\n" +
"\n" +
"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" +
")\n" +
"public class X {\n" +
" public static void main(String[] args) {\n" +
" if (false) {\n" +
" ;\n" +
" } else {\n" +
" }\n" +
" Zork z;\n" +
" }\n" +
"}"
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -bootclasspath " + "\"" + getLibraryClasses() + "\""
+ " -cp " + "\"" + getJCEJar() + "\""
+ " -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
+ " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
"",
"----------\n" +
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 11)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
"----------\n" +
"1 problem (1 error)",
true);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- a case that works, another that does not
// revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349
public void test009(){
this.runNegativeTest(
new String[] {
"X.java",
"/** */\n" +
"public class X {\n" +
" OK1 ok1;\n" +
" OK2 ok2;\n" +
" Warn warn;\n" +
" KO ko;\n" +
" Zork z;\n" +
"}",
"OK1.java",
"/** */\n" +
"public class OK1 {\n" +
" // empty\n" +
"}",
"OK2.java",
"/** */\n" +
"public class OK2 {\n" +
" // empty\n" +
"}",
"Warn.java",
"/** */\n" +
"public class Warn {\n" +
" // empty\n" +
"}",
"KO.java",
"/** */\n" +
"public class KO {\n" +
" // empty\n" +
"}",
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -cp \"" + OUTPUT_DIR + "[+OK2" + File.pathSeparator + "~Warn"
+ File.pathSeparator + "-KO]\""
+ " -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
+ " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
"",
"----------\n" +
"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 5)\n" +
" Warn warn;\n" +
" ^^^^\n" +
"Discouraged access: The type Warn is not accessible due to restriction on classpath entry ---OUTPUT_DIR_PLACEHOLDER---\n" +
"----------\n" +
"2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 6)\n" +
" KO ko;\n" +
" ^^\n" +
"Access restriction: The type KO is not accessible due to restriction on classpath entry ---OUTPUT_DIR_PLACEHOLDER---\n" +
"----------\n" +
"3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 7)\n" +
" Zork z;\n" +
" ^^^^\n" +
"Zork cannot be resolved to a type\n" +
"----------\n" +
"3 problems (1 error, 2 warnings)",
true);
}
// command line - no user classpath nor bootclasspath
public void test010(){
this.runConformTest(
new String[] {
"X.java",
"import java.util.List;\n" +
"\n" +
"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" +
")\n" +
"public class X {\n" +
" public static void main(String[] args) {\n" +
" if (false) {\n" +
" ;\n" +
" } else {\n" +
" }\n" +
" // Zork z;\n" +
" }\n" +
"}"
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
+ " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
"[parsing ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[reading java/lang/Object.class]\n" +
"[analyzing ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[reading java/util/List.class]\n" +
"[reading java/lang/SuppressWarnings.class]\n" +
"[reading java/lang/String.class]\n" +
"[writing X.class - #1]\n" +
"[completed ---OUTPUT_DIR_PLACEHOLDER---/X.java - #1/1]\n" +
"[1 unit compiled]\n" +
"[1 .class file generated]\n",
"",
true);
}
// command line - unusual classpath (ends with ';', still OK)
public void test011_classpath(){
this.runConformTest(
new String[] {
"X.java",
"/** */\n" +
"public class X {\n" +
"}",
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
+ " -1.5 -g -preserveAllLocals"
+ " -cp \"" + OUTPUT_DIR + "[+**/OK2;~**/Warn;-KO]"
+ "\"" + File.pathSeparator
+ " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
"",
"",
true);
}
// command line - help
// amended for https://bugs.eclipse.org/bugs/show_bug.cgi?id=141512 (checking
// width)
public void test012(){
final String expectedOutput =
"{0} {1}\n" +
"{2}\n" +
" \n" +
" Usage: