View | Details | Raw Unified | Return to bug 93904 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java (+991 lines)
Lines 10-26 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.core.tests.compiler.regression;
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
12
13
import java.io.File;
14
import java.io.FileNotFoundException;
15
import java.io.FileOutputStream;
16
import java.io.PrintWriter;
13
import junit.framework.Test;
17
import junit.framework.Test;
18
import junit.framework.TestSuite;
14
19
20
import org.eclipse.jdt.core.tests.util.Util;
15
import org.eclipse.jdt.internal.compiler.batch.Main;
21
import org.eclipse.jdt.internal.compiler.batch.Main;
16
22
17
public class BatchCompilerTest extends AbstractRegressionTest {
23
public class BatchCompilerTest extends AbstractRegressionTest {
24
	public static final String OUTPUT_DIR_PLACEHOLDER = "---OUTPUT_DIR_PLACEHOLDER---";
25
	static final String JRE_HOME_DIR = Util.getJREDirectory();
26
	
18
public BatchCompilerTest(String name) {
27
public BatchCompilerTest(String name) {
19
	super(name);
28
	super(name);
20
}
29
}
21
public static Test suite() {
30
public static Test suite() {
31
	if (false) {
32
		TestSuite suite = new TestSuite();
33
		suite.addTest(new BatchCompilerTest("test013"));
34
		suite.addTest(new BatchCompilerTest("test014"));
35
		suite.addTest(new BatchCompilerTest("test015"));
36
		return suite;
37
	}
22
	return setupSuite(testClass());
38
	return setupSuite(testClass());
39
	// TODO find a way to reduce the number of command line tests to one per 
40
	//      test run (aka do not add 1.3, 1.4, 1.5 supplementary level)
23
}
41
}
42
43
	/**
44
	 * Run a compilation test that is expected to complete successfully and
45
	 * compare the outputs to expected ones.
46
	 * 
47
	 * @param testFiles
48
	 *            the source files, given as a suite of file name, file content;
49
	 *            file names are relative to the output directory
50
	 * @param commandLine
51
	 *            the command line to pass to
52
	 *            {@link Main#compile(String) Main#compile}
53
	 * @param expectedSuccessOutOutputString
54
	 *            the expected contents of the standard output stream; pass null
55
	 *            to bypass the comparison
56
	 * @param expectedSuccessErrOutputString
57
	 *            the expected contents of the standard error output stream;
58
	 *            pass null to bypass the comparison
59
	 * @param shouldFlushOutputDirectory
60
	 *            pass true to get the output directory flushed before the test
61
	 *            runs
62
	 */
63
	protected void runConformTest(String[] testFiles, String commandLine,
64
			String expectedSuccessOutOutputString,
65
			String expectedSuccessErrOutputString,
66
			boolean shouldFlushOutputDirectory) {
67
		runTest(true, testFiles, commandLine, expectedSuccessOutOutputString,
68
				expectedSuccessErrOutputString, shouldFlushOutputDirectory);
69
	}
70
71
	/**
72
	 * Run a compilation test that is expected to fail and compare the outputs
73
	 * to expected ones.
74
	 * 
75
	 * @param testFiles
76
	 *            the source files, given as a suite of file name, file content;
77
	 *            file names are relative to the output directory
78
	 * @param commandLine
79
	 *            the command line to pass to
80
	 *            {@link Main#compile(String) Main#compile}
81
	 * @param expectedFailureOutOutputString
82
	 *            the expected contents of the standard output stream; pass null
83
	 *            to bypass the comparison
84
	 * @param expectedFailureErrOutputString
85
	 *            the expected contents of the standard error output stream;
86
	 *            pass null to bypass the comparison
87
	 * @param shouldFlushOutputDirectory
88
	 *            pass true to get the output directory flushed before the test
89
	 *            runs
90
	 */
91
	protected void runNegativeTest(String[] testFiles, String commandLine,
92
			String expectedFailureOutOutputString,
93
			String expectedFailureErrOutputString,
94
			boolean shouldFlushOutputDirectory) {
95
		runTest(false, testFiles, commandLine, expectedFailureOutOutputString,
96
				expectedFailureErrOutputString, shouldFlushOutputDirectory);
97
	}
98
99
	/**
100
	 * Worker method for runConformTest and runNegativeTest.
101
	 * 
102
	 * @param shouldCompileOK
103
	 *            set to true if the compiler should compile the given sources
104
	 *            without errors
105
	 * @param testFiles
106
	 *            the source files, given as a suite of file name, file content;
107
	 *            file names are relative to the output directory
108
	 * @param commandLine
109
	 *            the command line to pass to
110
	 *            {@link Main#compile(String) Main#compile}
111
	 * @param expectedOutOutputString
112
	 *            the expected contents of the standard output stream; pass null
113
	 *            to bypass the comparison
114
	 * @param expectedErrOutputString
115
	 *            the expected contents of the standard error output stream;
116
	 *            pass null to bypass the comparison
117
	 * @param shouldFlushOutputDirectory
118
	 *            pass true to get the output directory flushed before the test
119
	 *            runs
120
	 */
121
	private void runTest(boolean shouldCompileOK, String[] testFiles, String commandLine,
122
			String expectedOutOutputString,
123
			String expectedErrOutputString,
124
			boolean shouldFlushOutputDirectory) {
125
		File outputDirectory = new File(OUTPUT_DIR);
126
		if (shouldFlushOutputDirectory)
127
			Util.flushDirectoryContent(outputDirectory);
128
		try {
129
			if (!outputDirectory.isDirectory()) {
130
				outputDirectory.mkdirs();
131
			}
132
			PrintWriter sourceFileWriter;
133
			for (int i = 0; i < testFiles.length; i += 2) {
134
				String fileName = OUTPUT_DIR + File.separator + testFiles[i];
135
				File file = new File(fileName), innerOutputDirectory = file
136
						.getParentFile();
137
				if (!innerOutputDirectory.isDirectory()) {
138
					innerOutputDirectory.mkdirs();
139
				}
140
				sourceFileWriter = new PrintWriter(new FileOutputStream(file));
141
				sourceFileWriter.write(testFiles[i + 1]);
142
				sourceFileWriter.close();
143
			}
144
		} catch (FileNotFoundException e) {
145
			e.printStackTrace();
146
			throw new RuntimeException(e);
147
		}
148
		String printerWritersNameRoot = OUTPUT_DIR + File.separator + testName();
149
		String outFileName = printerWritersNameRoot + "out.txt", 
150
			   errFileName = printerWritersNameRoot + "err.txt";
151
		Main batchCompiler;
152
		try {
153
			batchCompiler = new Main(new PrintWriter(new FileOutputStream(
154
					outFileName)), new PrintWriter(new FileOutputStream(
155
					errFileName)), false);
156
		} catch (FileNotFoundException e) {
157
			System.out.println(getClass().getName() + '#' + getName());
158
			e.printStackTrace();
159
			throw new RuntimeException(e);
160
		}
161
		boolean compileOK;
162
		try {
163
			compileOK = batchCompiler.compile(Main.tokenize(commandLine));
164
		} catch (RuntimeException e) {
165
			compileOK = false;
166
			System.out.println(getClass().getName() + '#' + getName());
167
			e.printStackTrace();
168
			throw e;
169
		}
170
		String outOutputString = Util.fileContent(outFileName), 
171
		       errOutputString = Util.fileContent(errFileName);
172
		boolean compareOK = false;
173
		if (compileOK == shouldCompileOK) {
174
			compareOK = semiNormalizedComparison(expectedOutOutputString,
175
					outOutputString, outputDirNormalizer)
176
					&& semiNormalizedComparison(expectedErrOutputString,
177
							errOutputString, outputDirNormalizer);
178
		}
179
		if (compileOK != shouldCompileOK || !compareOK) {
180
			System.out.println(getClass().getName() + '#' + getName());
181
			for (int i = 0; i < testFiles.length; i += 2) {
182
				System.out.print(testFiles[i]);
183
				System.out.println(" [");
184
				System.out.println(testFiles[i + 1]);
185
				System.out.println("]");
186
			}
187
		}
188
		if (compileOK != shouldCompileOK)
189
			System.out.println(errOutputString);
190
		if (compileOK == shouldCompileOK && !compareOK) {
191
			System.out.println(
192
					    "------------ [START OUT] ------------\n"
193
					+   "------------- Expected: -------------\n"
194
					+ expectedOutOutputString
195
					+ "\n------------- but was:  -------------\n"
196
					+ outOutputString
197
					+ "\n--------- (cut and paste:) ----------\n"
198
					+ Util.displayString(outputDirNormalizer
199
							.normalized(outOutputString))
200
					+ "\n------------- [END OUT] -------------\n"
201
					+   "------------ [START ERR] ------------\n"
202
					+   "------------- Expected: -------------\n"
203
					+ expectedErrOutputString
204
					+ "\n------------- but was:  -------------\n"
205
					+ errOutputString
206
					+ "\n--------- (cut and paste:) ----------\n"
207
					+ Util.displayString(outputDirNormalizer
208
							.normalized(errOutputString))
209
					+ "\n------------- [END ERR] -------------\n");
210
		}
211
		if (shouldCompileOK)
212
			assertTrue("Unexpected problems: " + errOutputString, compileOK);
213
		else
214
			assertTrue("Unexpected success: " + errOutputString, !compileOK);
215
		assertTrue("Unexpected output for invocation with arguments ["
216
				+ commandLine + "]:\n--[START]--\n" + outOutputString + "\n"
217
				+ errOutputString + "\n---[END]---\n", compareOK);
218
	}
219
	
220
	/**
221
	 * Abstract normalizer for output comparison. This class merely embodies a
222
	 * chain of responsibility, plus the signature of the method of interest
223
	 * here, that is {@link #normalized(String) normalized}.
224
	 */
225
	private static abstract class Normalizer {
226
		private Normalizer nextInChain;
227
		Normalizer(Normalizer nextInChain) {
228
			this.nextInChain = nextInChain;
229
		}
230
		String normalized(String originalValue) {
231
			if (nextInChain == null)
232
				return originalValue;
233
			else
234
				return nextInChain.normalized(originalValue);
235
		}
236
	}
237
238
	/**
239
	 * This normalizer replaces occurrences of a given string with a given
240
	 * placeholder.
241
	 */
242
	private static class StringNormalizer extends Normalizer {
243
		private String match;
244
		private int matchLength;
245
		private String placeholder;
246
		StringNormalizer(Normalizer nextInChain, String match, String placeholder) {
247
			super(nextInChain);
248
			this.match = match;
249
			this.matchLength = match.length();
250
			this.placeholder = placeholder;
251
		}
252
		String normalized(String originalValue) {
253
			StringBuffer normalizedValueBuffer = new StringBuffer(originalValue);
254
			int nextOccurrenceIndex;
255
			while ((nextOccurrenceIndex = normalizedValueBuffer.indexOf(match)) != -1)
256
				normalizedValueBuffer.replace(nextOccurrenceIndex,
257
						nextOccurrenceIndex + matchLength, placeholder);
258
			return super.normalized(normalizedValueBuffer.toString());
259
		}
260
	}
261
	
262
	/**
263
	 * This normalizer replaces the whole classpaths section of a log file with
264
	 * a normalized placeholder. 
265
	 */
266
	private static class XMLClasspathsSectionNormalizer extends Normalizer {
267
		XMLClasspathsSectionNormalizer() {
268
			super(null);
269
		}
270
		XMLClasspathsSectionNormalizer(Normalizer nextInChain) {
271
			super(nextInChain);
272
		}
273
		String normalized(String originalValue) {
274
			StringBuffer normalizedValueBuffer = new StringBuffer(originalValue);
275
			int classpathsStartTagStart = normalizedValueBuffer
276
					.indexOf("<classpaths>"), classpathsEndTagStart = normalizedValueBuffer
277
					.indexOf("</classpaths>");
278
			if (classpathsStartTagStart != -1 && classpathsEndTagStart != -1
279
					&& classpathsStartTagStart < classpathsEndTagStart)
280
				normalizedValueBuffer.replace(classpathsStartTagStart + 12,
281
						classpathsEndTagStart, "NORMALIZED SECTION");
282
			return super.normalized(normalizedValueBuffer.toString());
283
		}
284
	}
285
286
	/**
287
	 * Normalizer instance that replaces occurrences of OUTPUT_DIR with 
288
	 * OUTPUT_DIR_PLACEHOLDER.
289
	 */
290
	private static Normalizer outputDirNormalizer = new StringNormalizer(null,
291
			OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
292
	/**
293
	 * Normalizer instance that replaces the list of concrete classpaths XML 
294
	 * elements of an XML log file with a placeholder, and occurrences of
295
	 * OUTPUT_DIR with OUTPUT_DIR_PLACEHOLDER. 
296
	 */
297
	private static Normalizer xmlClasspathsNormalizer = new StringNormalizer(
298
			new XMLClasspathsSectionNormalizer(), OUTPUT_DIR,
299
			OUTPUT_DIR_PLACEHOLDER);
300
	
301
302
	/**
303
	 * Return true if and only if the two strings passed as parameters compare
304
	 * equal, modulo the transformation of the second string by a normalizer
305
	 * passed in parameter. This is meant to erase the variations of subparts of
306
	 * the compared strings in function of the test machine, the user account,
307
	 * etc.
308
	 * 
309
	 * @param keep
310
	 *            the first string to compare, gets compared as it is
311
	 * @param normalize
312
	 *            the second string to compare, passed through the normalizer
313
	 *            before comparison
314
	 * @param normalizer
315
	 *            the transformation applied to normalize
316
	 * @return true if keep and normalize compare equal after normalize has been
317
	 *         normalized
318
	 */
319
	private boolean semiNormalizedComparison(String keep, String normalize,
320
			Normalizer normalizer) {
321
		if (keep == null)
322
			return normalize == null;
323
		if (normalize == null)
324
			return false;
325
		return keep.equals(normalizer.normalized(normalize));
326
	}
327
24
public void test01() {
328
public void test01() {
25
	
329
	
26
		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";
330
		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";
Lines 117-122 Link Here
117
			expected,
421
			expected,
118
			result);
422
			result);
119
}
423
}
424
// test the tester - runConformTest
425
public void test007(){
426
	this.runConformTest(
427
		new String[] {
428
			"X.java",
429
			"import java.util.List;\n" + 
430
			"\n" + 
431
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
432
			")\n" + 
433
			"public class X {\n" + 
434
			"	public static void main(String[] args) {\n" + 
435
			"		if (false) {\n" + 
436
			"			;\n" + 
437
			"		} else {\n" + 
438
			"		}\n" + 
439
			"		// Zork z;\n" + 
440
			"	}\n" + 
441
			"}"
442
        },
443
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
444
        + " -1.5 -g -preserveAllLocals"
445
        + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar"
446
        + " -cp " + JRE_HOME_DIR + "/lib/jce.jar"
447
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
448
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
449
        "[1 .class file generated]\r\n", 
450
        "----------\r\n" + 
451
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
452
        " (at line 1)\r\n" + 
453
        "	import java.util.List;\r\n" + 
454
        "	       ^^^^^^^^^^^^^^\r\n" + 
455
        "The import java.util.List is never used\r\n" + 
456
        "----------\r\n" + 
457
        "1 problem (1 warning)", true);
458
}
459
// test the tester - runNegativeTest
460
public void test008(){
461
	this.runNegativeTest(
462
		new String[] {
463
			"X.java",
464
			"import java.util.List;\n" + 
465
			"\n" + 
466
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
467
			")\n" + 
468
			"public class X {\n" + 
469
			"	public static void main(String[] args) {\n" + 
470
			"		if (false) {\n" + 
471
			"			;\n" + 
472
			"		} else {\n" + 
473
			"		}\n" + 
474
			"		Zork z;\n" + 
475
			"	}\n" + 
476
			"}"
477
        },
478
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
479
        + " -1.5 -g -preserveAllLocals"
480
        + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar"
481
        + " -cp " + JRE_HOME_DIR + "/lib/jce.jar"
482
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
483
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
484
        "[1 .class file generated]\r\n", 
485
        "----------\r\n" + 
486
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
487
        " (at line 1)\r\n" + 
488
        "	import java.util.List;\r\n" + 
489
        "	       ^^^^^^^^^^^^^^\r\n" + 
490
        "The import java.util.List is never used\r\n" + 
491
        "----------\r\n" + 
492
        "----------\r\n" + 
493
        "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
494
        " (at line 11)\r\n" + 
495
        "	Zork z;\r\n" + 
496
        "	^^^^\r\n" + 
497
        "Zork cannot be resolved to a type\r\n" + 
498
        "----------\r\n" + 
499
        "2 problems (1 error, 1 warning)", true);
500
}
501
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- a case that works, another that does not
502
// revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349
503
public void test009(){
504
	this.runNegativeTest(
505
		new String[] {
506
			"X.java",
507
			"/** */\n" + 
508
			"public class X {\n" + 
509
			"	OK1 ok1;\n" + 
510
			"	OK2 ok2;\n" + 
511
			"	Warn warn;\n" + 
512
			"	KO ko;\n" + 
513
	        "	Zork z;\r\n" + 
514
			"}",
515
			"OK1.java",
516
			"/** */\n" + 
517
			"public class OK1 {\n" + 
518
			"	// empty\n" + 
519
			"}",
520
			"OK2.java",
521
			"/** */\n" + 
522
			"public class OK2 {\n" + 
523
			"	// empty\n" + 
524
			"}",
525
			"Warn.java",
526
			"/** */\n" + 
527
			"public class Warn {\n" + 
528
			"	// empty\n" + 
529
			"}",
530
			"KO.java",
531
			"/** */\n" + 
532
			"public class KO {\n" + 
533
			"	// empty\n" + 
534
			"}",
535
		},
536
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
537
        + " -1.5 -g -preserveAllLocals"
538
        + " -cp \"" + OUTPUT_DIR + "[+OK2.java;~Warn.java;-KO.java]\""
539
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
540
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
541
        "[5 .class files generated]\r\n", 
542
        "----------\r\n" + 
543
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
544
        " (at line 5)\r\n" + 
545
        "	Warn warn;\r\n" + 
546
        "	^^^^\r\n" + 
547
        "Discouraged access: Warn\r\n" + 
548
        "----------\r\n" + 
549
        "----------\r\n" + 
550
        "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
551
        " (at line 6)\r\n" + 
552
        "	KO ko;\r\n" + 
553
        "	^^\r\n" + 
554
        "Access restriction: KO\r\n" + 
555
        "----------\r\n" + 
556
        "----------\r\n" + 
557
        "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
558
        " (at line 7)\r\n" + 
559
        "	Zork z;\r\n" + 
560
        "	^^^^\r\n" + 
561
        "Zork cannot be resolved to a type\r\n" + 
562
        "----------\r\n" + 
563
        "3 problems (1 error, 2 warnings)",
564
        true);
565
}
566
// command line - no user classpath nor bootclasspath
567
public void test010(){
568
	this.runConformTest(
569
		new String[] {
570
			"X.java",
571
			"import java.util.List;\n" + 
572
			"\n" + 
573
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
574
			")\n" + 
575
			"public class X {\n" + 
576
			"	public static void main(String[] args) {\n" + 
577
			"		if (false) {\n" + 
578
			"			;\n" + 
579
			"		} else {\n" + 
580
			"		}\n" + 
581
			"		// Zork z;\n" + 
582
			"	}\n" + 
583
			"}"
584
        },
585
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
586
        + " -1.5 -g -preserveAllLocals"
587
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
588
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
589
        "[1 .class file generated]\r\n", 
590
        "----------\r\n" + 
591
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
592
        " (at line 1)\r\n" + 
593
        "	import java.util.List;\r\n" + 
594
        "	       ^^^^^^^^^^^^^^\r\n" + 
595
        "The import java.util.List is never used\r\n" + 
596
        "----------\r\n" + 
597
        "1 problem (1 warning)", true);
598
}
599
// command line - unusual classpath (ends with ';', still OK)
600
public void test011(){
601
	this.runConformTest(
602
		new String[] {
603
			"X.java",
604
			"/** */\n" + 
605
			"public class X {\n" + 
606
			"}",
607
		},
608
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
609
        + " -1.5 -g -preserveAllLocals"
610
        + " -cp \"" + OUTPUT_DIR + "[+**/OK2.java;~**/Warn.java;-KO.java]"
611
        + "\";"
612
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
613
        "",
614
        "",
615
        true);
616
}
617
// command line - help
618
public void test012(){
619
	this.runConformTest(
620
		new String[0],
621
        " -help -showversion -referenceInfo",
622
        "Eclipse Java Compiler 0.558, pre-3.1.0 release candidate-1, Copyright IBM Corp 2000, 2005. All rights reserved.\n" + 
623
        " \n" + 
624
        " Usage: <options> <source files | directories>\n" + 
625
        " If directories are specified, then their source contents are compiled.\n" + 
626
        " Possible options are listed below. Options enabled by default are prefixed with \'+\'\n" + 
627
        " \n" + 
628
        " Classpath options:\n" + 
629
        "    -cp -classpath <directories and zip/jar files separated by ;>\n" + 
630
        "                       specify location for application classes and sources. Each\n" + 
631
        "                       directory or file can specify access rules for types between\n" + 
632
        "                       \'[\' and \']\' (e.g. [-X.java] to deny access to type X)\n" + 
633
        "    -bootclasspath <directories and zip/jar files separated by ;>\n" + 
634
        "                       specify location for system classes. Each directory or file can\n" + 
635
        "                       specify access rules for types between \'[\' and \']\' (e.g. [-X.java]\n" + 
636
        "                       to deny access to type X)\n" + 
637
        "    -d <dir>           destination directory (if omitted, no directory is created)\n" + 
638
        "    -d none            generate no .class files\n" + 
639
        "    -encoding <enc>    specify custom encoding for all sources. Each file/directory can override it\n" + 
640
        "                       when suffixed with \'[\'<enc>\']\' (e.g. X.java[utf8])\n" + 
641
        " \n" + 
642
        " Compliance options:\n" + 
643
        "    -1.3               use 1.3 compliance level (implicit -source 1.3 -target 1.1)\n" + 
644
        "    -1.4             + use 1.4 compliance level (implicit -source 1.3 -target 1.2)\n" + 
645
        "    -1.5               use 1.5 compliance level (implicit -source 1.5 -target 1.5)\n" + 
646
        "    -source <version>  set source level: 1.3 to 1.5 (or 5 or 5.0)\n" + 
647
        "    -target <version>  set classfile target level: 1.1 to 1.5 (or 5 or 5.0)\n" + 
648
        " \n" + 
649
        " Warning options:\n" + 
650
        "    -deprecation     + deprecation outside deprecated code\n" + 
651
        "    -nowarn            disable all warnings\n" + 
652
        "    -warn:none         disable all warnings\n" + 
653
        "    -warn:<warnings separated by ,>    enable exactly the listed warnings\n" + 
654
        "    -warn:+<warnings separated by ,>   enable additional warnings\n" + 
655
        "    -warn:-<warnings separated by ,>   disable specific warnings\n" + 
656
        "      allDeprecation       deprecation including inside deprecated code\n" + 
657
        "      allJavadoc           invalid or missing javadoc\n" + 
658
        "      assertIdentifier   + \'assert\' used as identifier\n" + 
659
        "      boxing               autoboxing conversion\n" + 
660
        "      charConcat         + char[] in String concat\n" + 
661
        "      conditionAssign      possible accidental boolean assignment\n" + 
662
        "      constructorName    + method with constructor name\n" + 
663
        "      dep-ann              missing @Deprecated annotation\n" + 
664
        "      deprecation        + deprecation outside deprecated code\n" + 
665
        "      emptyBlock           undocumented empty block\n" + 
666
        "      enumSwitch           incomplete enum switch\n" + 
667
        "      fieldHiding          field hiding another variable\n" + 
668
        "      finalBound           type parameter with final bound\n" + 
669
        "      finally            + finally block not completing normally\n" + 
670
        "      indirectStatic       indirect reference to static member\n" + 
671
        "      intfAnnotation     + annotation type used as super interface\n" + 
672
        "      intfNonInherited   + interface non-inherited method compatibility\n" + 
673
        "      javadoc              invalid javadoc\n" + 
674
        "      localHiding          local variable hiding another variable\n" + 
675
        "      maskedCatchBlock   + hidden catch block\n" + 
676
        "      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n" + 
677
        "      noEffectAssign     + assignment without effect\n" + 
678
        "      null                 missing or redundant null check\n" + 
679
        "      over-ann             missing @Override annotation\n" + 
680
        "      pkgDefaultMethod   + attempt to override package-default method\n" + 
681
        "      semicolon            unnecessary semicolon, empty statement\n" + 
682
        "      serial             + missing serialVersionUID\n" + 
683
        "      suppress           + enable @SuppressWarnings\n" + 
684
        "      unqualifiedField     unqualified reference to field\n" + 
685
        "      unchecked          + unchecked type operation\n" + 
686
        "      unusedArgument       unread method parameter\n" + 
687
        "      unusedImport       + unused import declaration\n" + 
688
        "      unusedLocal          unread local variable\n" + 
689
        "      unusedPrivate        unused private member declaration\n" + 
690
        "      unusedThrown         unused declared thrown exception\n" + 
691
        "      unnecessaryElse      unnecessary else clause\n" + 
692
        "      uselessTypeCheck     unnecessary cast/instanceof operation\n" + 
693
        "      specialParamHiding   constructor or setter parameter hiding another field\n" + 
694
        "      staticReceiver     + non-static reference to static member\n" + 
695
        "      syntheticAccess      synthetic access for innerclass\n" + 
696
        "      tasks(<tags separated by |>) tasks identified by tags inside comments\n" + 
697
        "      typeHiding         + type parameter hiding another type\n" + 
698
        "      varargsCast        + varargs argument need explicit cast\n" + 
699
        "      warningToken       + unhandled warning token in @SuppressWarnings\n" + 
700
        " \n" + 
701
        " Debug options:\n" + 
702
        "    -g[:lines,vars,source] custom debug info\n" + 
703
        "    -g:lines,source  + both lines table and source debug info\n" + 
704
        "    -g                 all debug info\n" + 
705
        "    -g:none            no debug info\n" + 
706
        "    -preserveAllLocals preserve unused local vars for debug purpose\n" + 
707
        " \n" + 
708
        " Advanced options:\n" + 
709
        "    @<file>            read command line arguments from file\n" + 
710
        "    -maxProblems <n>   max number of problems per compilation unit (100 by default)\n" + 
711
        "    -log <file>        log to a file\n" + 
712
        "    -proceedOnError    do not stop at first error, dumping class files with problem methods\n" + 
713
        "    -verbose           enable verbose output\n" + 
714
        "    -referenceInfo     compute reference info\n" + 
715
        "    -progress          show progress (only in -log mode)\n" + 
716
        "    -time              display speed information \n" + 
717
        "    -noExit            do not call System.exit(n) at end of compilation (n==0 if no error)\n" + 
718
        "    -repeat <n>        repeat compilation process <n> times for perf analysis\n" + 
719
        "    -inlineJSR         inline JSR bytecode (implicit if target >= 1.5)\n" + 
720
        "    -enableJavadoc     consider references in javadoc\n" + 
721
        " \n" + 
722
        "    -? -help           print this help message\n" + 
723
        "    -v -version        print compiler version\n" + 
724
        "    -showversion       print compiler version and continue\n" + 
725
        "\r\n", 
726
        "", true);
727
}
728
729
	// command line - xml log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
730
	public void test013() {
731
		String logFileName = OUTPUT_DIR + File.separator + "log.xml";
732
		this.runNegativeTest(new String[] { 
733
				"X.java",
734
				"/** */\n" + 
735
				"public class X {\n" + 
736
				"	Zork z;\n" + 
737
				"}", },
738
				"\"" + OUTPUT_DIR + File.separator + "X.java\""
739
				+ " -1.5 -proceedOnError"
740
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
741
				"", 
742
				"----------\r\n" + 
743
				"1. ERROR in " + OUTPUT_DIR_PLACEHOLDER + "\\X.java\r\n" + 
744
				" (at line 3)\r\n" + 
745
				"	Zork z;\r\n" + 
746
				"	^^^^\r\n" + 
747
				"Zork cannot be resolved to a type\r\n" + 
748
				"----------\r\n" + 
749
				"1 problem (1 error)", 
750
				true);
751
		String logContents = Util.fileContent(logFileName);
752
		String expectedLogContents = 
753
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
754
			"<!DOCTYPE compiler SYSTEM \"compiler.dtd\">\r\n" + 
755
			"<compiler name=\"Eclipse Java Compiler\" copyright=\"Copyright IBM Corp 2000, 2005. All rights reserved.\" version=\"0.558, pre-3.1.0 release candidate-1\">\r\n" + 
756
			"	<command_line>\r\n" + 
757
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\\X.java\"/>\r\n" + 
758
			"		<argument value=\"-1.5\"/>\r\n" + 
759
			"		<argument value=\"-proceedOnError\"/>\r\n" + 
760
			"		<argument value=\"-log\"/>\r\n" + 
761
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\\log.xml\"/>\r\n" + 
762
			"		<argument value=\"-d\"/>\r\n" + 
763
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\r\n" + 
764
			"	</command_line>\r\n" + 
765
			"	<options>\r\n" + 
766
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\r\n" + 
767
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\r\n" + 
768
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\r\n" + 
769
			"		<option key=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.5\"/>\r\n" + 
770
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.lineNumber\" value=\"generate\"/>\r\n" + 
771
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.localVariable\" value=\"do not generate\"/>\r\n" + 
772
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.sourceFile\" value=\"generate\"/>\r\n" + 
773
			"		<option key=\"org.eclipse.jdt.core.compiler.doc.comment.support\" value=\"disabled\"/>\r\n" + 
774
			"		<option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\r\n" + 
775
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\r\n" + 
776
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\r\n" + 
777
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\r\n" + 
778
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecation\" value=\"warning\"/>\r\n" + 
779
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode\" value=\"disabled\"/>\r\n" + 
780
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\r\n" + 
781
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\r\n" + 
782
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\r\n" + 
783
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\r\n" + 
784
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\r\n" + 
785
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finalParameterBound\" value=\"warning\"/>\r\n" + 
786
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally\" value=\"warning\"/>\r\n" + 
787
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.forbiddenReference\" value=\"warning\"/>\r\n" + 
788
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock\" value=\"warning\"/>\r\n" + 
789
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod\" value=\"warning\"/>\r\n" + 
790
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch\" value=\"ignore\"/>\r\n" + 
791
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.indirectStaticAccess\" value=\"ignore\"/>\r\n" + 
792
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadoc\" value=\"ignore\"/>\r\n" + 
793
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTags\" value=\"enabled\"/>\r\n" + 
794
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef\" value=\"enabled\"/>\r\n" + 
795
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef\" value=\"enabled\"/>\r\n" + 
796
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility\" value=\"private\"/>\r\n" + 
797
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.localVariableHiding\" value=\"ignore\"/>\r\n" + 
798
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName\" value=\"warning\"/>\r\n" + 
799
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation\" value=\"ignore\"/>\r\n" + 
800
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocComments\" value=\"ignore\"/>\r\n" + 
801
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding\" value=\"enabled\"/>\r\n" + 
802
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility\" value=\"public\"/>\r\n" + 
803
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTags\" value=\"ignore\"/>\r\n" + 
804
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding\" value=\"enabled\"/>\r\n" + 
805
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility\" value=\"private\"/>\r\n" + 
806
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation\" value=\"ignore\"/>\r\n" + 
807
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSerialVersion\" value=\"warning\"/>\r\n" + 
808
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\r\n" + 
809
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\r\n" + 
810
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\r\n" + 
811
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"ignore\"/>\r\n" + 
812
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\r\n" + 
813
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\r\n" + 
814
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\r\n" + 
815
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\r\n" + 
816
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressWarnings\" value=\"enabled\"/>\r\n" + 
817
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation\" value=\"ignore\"/>\r\n" + 
818
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\r\n" + 
819
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\r\n" + 
820
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\r\n" + 
821
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\r\n" + 
822
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\r\n" + 
823
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck\" value=\"ignore\"/>\r\n" + 
824
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess\" value=\"ignore\"/>\r\n" + 
825
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException\" value=\"ignore\"/>\r\n" + 
826
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding\" value=\"disabled\"/>\r\n" + 
827
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedImport\" value=\"warning\"/>\r\n" + 
828
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLocal\" value=\"ignore\"/>\r\n" + 
829
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameter\" value=\"ignore\"/>\r\n" + 
830
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract\" value=\"disabled\"/>\r\n" + 
831
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete\" value=\"disabled\"/>\r\n" + 
832
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedPrivateMember\" value=\"ignore\"/>\r\n" + 
833
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast\" value=\"warning\"/>\r\n" + 
834
			"		<option key=\"org.eclipse.jdt.core.compiler.source\" value=\"1.5\"/>\r\n" + 
835
			"		<option key=\"org.eclipse.jdt.core.compiler.taskCaseSensitive\" value=\"enabled\"/>\r\n" + 
836
			"		<option key=\"org.eclipse.jdt.core.compiler.taskPriorities\" value=\"\"/>\r\n" + 
837
			"		<option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\r\n" + 
838
			"	</options>\r\n" + 
839
			"	<classpaths>NORMALIZED SECTION</classpaths>\r\n" + 
840
			"	<sources>\r\n" + 
841
			"		<source path=\"---OUTPUT_DIR_PLACEHOLDER---\\X.java\">\r\n" + 
842
			"			<problems problems=\"1\" errors=\"1\" warnings=\"0\">\r\n" + 
843
			"				<problem charEnd=\"28\" charStart=\"25\" severity=\"ERROR\" line=\"3\" id=\"UndefinedType\">\r\n" + 
844
			"					<message value=\"Zork cannot be resolved to a type\"/>\r\n" + 
845
			"					<source_context value=\"Zork z;\" sourceStart=\"0\" sourceEnd=\"3\"/>\r\n" + 
846
			"					<arguments>\r\n" + 
847
			"						<argument value=\"Zork\"/>\r\n" + 
848
			"					</arguments>\r\n" + 
849
			"				</problem>\r\n" + 
850
			"			</problems>\r\n" + 
851
			"			<classfile path=\"---OUTPUT_DIR_PLACEHOLDER---\\X.class\"/>\r\n" + 
852
			"		</source>\r\n" + 
853
			"	</sources>\r\n" + 
854
			"	<stats>\r\n" + 
855
			"		<problem_summary problems=\"1\" errors=\"1\" warnings=\"0\" tasks=\"0\"/>\r\n" + 
856
			"	</stats>\r\n" + 
857
			"</compiler>\r\n";
858
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
859
				logContents, xmlClasspathsNormalizer);
860
		if (!compareOK) {
861
			System.out.println(getClass().getName() + '#' + getName());
862
			System.out.println(
863
					  "------------ [START LOG] ------------\n"
864
					+ "------------- Expected: -------------\n"
865
					+ expectedLogContents
866
				  + "\n------------- but was:  -------------\n"
867
					+ xmlClasspathsNormalizer.normalized(logContents)
868
				  + "\n--------- (cut and paste:) ----------\n"
869
					+ Util.displayString(xmlClasspathsNormalizer.normalized(logContents))
870
				  + "\n------------- [END LOG] -------------\n");
871
		}
872
		assertTrue("unexpected log contents", compareOK);
873
	}
874
875
	// command line - txt log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
876
	public void test014() {
877
		String logFileName = OUTPUT_DIR + File.separator + "log.txt";
878
		this.runNegativeTest(new String[] { 
879
				"X.java",
880
				"/** */\n" + 
881
				"public class X {\n" + 
882
				"	Zork z;\n" + 
883
				"}", },
884
				"\"" + OUTPUT_DIR + File.separator + "X.java\"" 
885
				+ " -1.5 -proceedOnError"
886
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
887
				"", 
888
				"----------\r\n" + 
889
				"1. ERROR in " + OUTPUT_DIR_PLACEHOLDER + "\\X.java\r\n" + 
890
				" (at line 3)\r\n" + 
891
				"	Zork z;\r\n" + 
892
				"	^^^^\r\n" + 
893
				"Zork cannot be resolved to a type\r\n" + 
894
				"----------\r\n" + 
895
				"1 problem (1 error)", 
896
				false);
897
		String logContents = Util.fileContent(logFileName);
898
		String expectedLogContents = 
899
			"----------\r\n" + 
900
			"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
901
			" (at line 3)\r\n" + 
902
			"	Zork z;\r\n" + 
903
			"	^^^^\r\n" + 
904
			"Zork cannot be resolved to a type\r\n" + 
905
			"----------\r\n" + 
906
			"1 problem (1 error)";
907
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
908
				logContents, outputDirNormalizer);
909
		if (!compareOK) {
910
			System.out.println(getClass().getName() + '#' + getName());
911
			System.out.println(
912
							  "------------ [START LOG] ------------\n"
913
							+ "------------- Expected: -------------\n"
914
							+ expectedLogContents
915
						  + "\n------------- but was:  -------------\n"
916
							+ outputDirNormalizer.normalized(logContents)
917
						  + "\n--------- (cut and paste:) ----------\n"
918
							+ Util.displayString(outputDirNormalizer.normalized(logContents))
919
						  + "\n------------- [END LOG] -------------\n");
920
		}
921
		assertTrue("unexpected log contents", compareOK);
922
	}
923
924
	// command line - no extension log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
925
	public void test015() {
926
		String logFileName = OUTPUT_DIR + File.separator + "log";
927
		this.runNegativeTest(new String[] { 
928
				"X.java",
929
				"/** */\n" + 
930
				"public class X {\n" + 
931
				"	Zork z;\n" + 
932
				"}", },
933
				"\"" + OUTPUT_DIR + File.separator + "X.java\""
934
				+ " -1.5 -proceedOnError"
935
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
936
				"", 
937
				"----------\r\n" + 
938
				"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
939
				" (at line 3)\r\n" + 
940
				"	Zork z;\r\n" + 
941
				"	^^^^\r\n" + 
942
				"Zork cannot be resolved to a type\r\n" + 
943
				"----------\r\n" + 
944
				"1 problem (1 error)", 
945
				false);
946
		String logContents = Util.fileContent(logFileName);
947
		String expectedLogContents = 
948
			"----------\r\n" + 
949
			"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
950
			" (at line 3)\r\n" + 
951
			"	Zork z;\r\n" + 
952
			"	^^^^\r\n" + 
953
			"Zork cannot be resolved to a type\r\n" + 
954
			"----------\r\n" + 
955
			"1 problem (1 error)";
956
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
957
				logContents, outputDirNormalizer);
958
		if (!compareOK) {
959
			System.out.println(getClass().getName() + '#' + getName());
960
			System.out.println(
961
					  "------------ [START LOG] ------------\n"
962
					+ "------------- Expected: -------------\n"
963
					+ expectedLogContents
964
				  + "\n------------- but was:  -------------\n"
965
					+ outputDirNormalizer.normalized(logContents)
966
				  + "\n--------- (cut and paste:) ----------\n"
967
					+ Util.displayString(outputDirNormalizer.normalized(logContents))
968
				  + "\n------------- [END LOG] -------------\n");
969
		}
970
		assertTrue("unexpected log contents", compareOK);
971
	}
972
//	 command line - unusual classpath (contains multiple empty members, still OK)
973
	public void test016(){
974
		this.runConformTest(
975
			new String[] {
976
					"X.java",
977
					"/** */\n" + 
978
					"public class X {\n" + 
979
					"	OK1 ok1;\n" + 
980
					"}",
981
					"OK1.java",
982
					"/** */\n" + 
983
					"public class OK1 {\n" + 
984
					"	// empty\n" + 
985
					"}"
986
			},
987
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
988
	        + " -1.5 -g -preserveAllLocals"
989
	        + " -cp .;;;\"" + OUTPUT_DIR + "\""
990
	        + " -verbose -proceedOnError -referenceInfo"
991
	        + " -d \"" + OUTPUT_DIR + "\"",
992
	        "[2 .class files generated]\r\n",
993
	        "",
994
	        true);
995
	}
996
//	 command line - unusual classpath (contains erroneous members, still OK)
997
	public void test017(){
998
		this.runConformTest(
999
			new String[] {
1000
					"X.java",
1001
					"/** */\n" + 
1002
					"public class X {\n" + 
1003
					"	OK1 ok1;\n" + 
1004
					"}",
1005
					"OK1.java",
1006
					"/** */\n" + 
1007
					"public class OK1 {\n" + 
1008
					"	// empty\n" + 
1009
					"}"
1010
			},
1011
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1012
	        + " -1.5 -g -preserveAllLocals"
1013
	        + " -cp dummmy_dir;dummy.jar;;\"" + OUTPUT_DIR + "\"" 
1014
	        + " -verbose -proceedOnError -referenceInfo" 
1015
	        + " -d \"" + OUTPUT_DIR + "\"", 
1016
	        "[2 .class files generated]\r\n",
1017
	        "",
1018
	        true);
1019
	}
1020
// command line - unusual classpath (empty, but using current directory, still OK provided 
1021
//	that we execute from the appropriate directory)
1022
	public void _test018(){
1023
		this.runConformTest(
1024
			new String[] {
1025
					"X.java",
1026
					"/** */\n" + 
1027
					"public class X {\n" + 
1028
					"	OK1 ok1;\n" + 
1029
					"}",
1030
					"OK1.java",
1031
					"/** */\n" + 
1032
					"public class OK1 {\n" + 
1033
					"	// empty\n" + 
1034
					"}"
1035
			},
1036
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1037
	        + " -1.5 -g -preserveAllLocals"
1038
	        + " -verbose -proceedOnError -referenceInfo"
1039
	        + " -d \"" + OUTPUT_DIR + "\"",
1040
	        "[2 .class files generated]\r\n",
1041
	        "",
1042
	        true);
1043
	}
1044
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- with wildcards 
1045
// a case that works, another that does not
1046
// revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349
1047
	public void test019(){
1048
		this.runNegativeTest(
1049
			new String[] {
1050
				"X.java",
1051
				"/** */\n" + 
1052
				"public class X {\n" + 
1053
				"	OK1 ok1;\n" + 
1054
				"	OK2 ok2;\n" + 
1055
				"	Warn warn;\n" + 
1056
				"	KO ko;\n" + 
1057
		        "	Zork z;\r\n" + 
1058
				"}",
1059
				"OK1.java",
1060
				"/** */\n" + 
1061
				"public class OK1 {\n" + 
1062
				"	// empty\n" + 
1063
				"}",
1064
				"OK2.java",
1065
				"/** */\n" + 
1066
				"public class OK2 {\n" + 
1067
				"	// empty\n" + 
1068
				"}",
1069
				"Warn.java",
1070
				"/** */\n" + 
1071
				"public class Warn {\n" + 
1072
				"	// empty\n" + 
1073
				"}",
1074
				"KO.java",
1075
				"/** */\n" + 
1076
				"public class KO {\n" + 
1077
				"	// empty\n" + 
1078
				"}",
1079
			},
1080
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1081
	        + " -1.5 -g -preserveAllLocals" 
1082
	        + " -cp \"" + OUTPUT_DIR + "[+OK2.*;~Warn.*;-KO.*]\""
1083
	        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" 
1084
	        + " -proceedOnError -referenceInfo"
1085
	        + " -d \"" + OUTPUT_DIR + "\"", 
1086
	        "[5 .class files generated]\r\n", 
1087
	        "----------\r\n" + 
1088
	        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1089
	        " (at line 5)\r\n" + 
1090
	        "	Warn warn;\r\n" + 
1091
	        "	^^^^\r\n" + 
1092
	        "Discouraged access: Warn\r\n" + 
1093
	        "----------\r\n" + 
1094
	        "----------\r\n" + 
1095
	        "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1096
	        " (at line 6)\r\n" + 
1097
	        "	KO ko;\r\n" + 
1098
	        "	^^\r\n" + 
1099
	        "Access restriction: KO\r\n" + 
1100
	        "----------\r\n" + 
1101
	        "----------\r\n" + 
1102
	        "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1103
	        " (at line 7)\r\n" + 
1104
	        "	Zork z;\r\n" + 
1105
	        "	^^^^\r\n" + 
1106
	        "Zork cannot be resolved to a type\r\n" + 
1107
	        "----------\r\n" + 
1108
	        "3 problems (1 error, 2 warnings)",
1109
	        true);
1110
	}
120
public static Class testClass() {
1111
public static Class testClass() {
121
	return BatchCompilerTest.class;
1112
	return BatchCompilerTest.class;
122
}
1113
}

Return to bug 93904