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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java (+1105 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
	 * This normalizer removes a selected range of lines from a log file.
288
	 */
289
	private static class LinesRangeNormalizer extends Normalizer {
290
		private int first, number;
291
292
		LinesRangeNormalizer() {
293
			super(null);
294
			first = number = 0;
295
		}
296
297
		LinesRangeNormalizer(Normalizer nextInChain) {
298
			super(nextInChain);
299
			first = number = 0;
300
		}
301
302
		/**
303
		 * Make a new normalizer able to suppress a range of lines delimited by
304
		 * "\r\n" sequences from a log file (or another string).
305
		 * 
306
		 * @param nextInChain
307
		 *            the next normalizer in the chain of responsibility; pass
308
		 *            null if none is needed
309
		 * @param firstLineToRemove
310
		 *            the index of the first line to remove, starting at 0
311
		 * @param linesNumber
312
		 *            the number or lines to remove; if 0, no other
313
		 *            transformation occurs than those operated by nextInChain
314
		 *            (if any)
315
		 */
316
		LinesRangeNormalizer(Normalizer nextInChain, int firstLineToRemove,
317
				int linesNumber) {
318
			super(nextInChain);
319
			first = firstLineToRemove;
320
			number = linesNumber >= 0 ? linesNumber : 0;
321
		}
322
323
		String normalized(String originalValue) {
324
			if (number == 0 || originalValue.length() == 0)
325
				return super.normalized(originalValue);
326
			final int START = 0, KEEPING = 1, KEEPING_R = 2, SKIPING = 3, SKIPING_R = 4, END = 5, ERROR = 6;
327
			int state = START, currentLineIndex = 0, currentCharIndex = 0, sourceLength;
328
			char currentChar = '\0';
329
			if (first <= 0)
330
				state = SKIPING;
331
			else
332
				state = KEEPING;
333
			StringBuffer normalizedValueBuffer = new StringBuffer(), source = new StringBuffer(
334
					originalValue);
335
			sourceLength = source.length();
336
			while (state != END && state != ERROR) {
337
				if (currentCharIndex < sourceLength) {
338
					currentChar = source.charAt(currentCharIndex++);
339
					switch (currentChar) {
340
					case '\r':
341
						switch (state) {
342
						case KEEPING:
343
							normalizedValueBuffer.append(currentChar);
344
							state = KEEPING_R;
345
							break;
346
						case SKIPING:
347
							state = SKIPING_R;
348
							break;
349
						default:
350
							state = ERROR;
351
						}
352
						break;
353
					case '\n':
354
						currentLineIndex++;
355
						switch (state) {
356
						case KEEPING_R:
357
							normalizedValueBuffer.append(currentChar);
358
							if (currentLineIndex == first) {
359
								state = SKIPING;
360
							}
361
							break;
362
						case SKIPING_R:
363
							// in effect, we tolerate too big first and number
364
							// values
365
							if (currentLineIndex >= first + number) {
366
								if (currentCharIndex < sourceLength)
367
									normalizedValueBuffer.append(source
368
											.substring(currentCharIndex));
369
								state = END;
370
							}
371
							break;
372
						default:
373
							state = ERROR;
374
						}
375
						break;
376
					default:
377
						switch (state) {
378
						case KEEPING:
379
							normalizedValueBuffer.append(currentChar);
380
							break;
381
						case SKIPING:
382
							break;
383
						default:
384
							state = ERROR;
385
						}
386
387
					}
388
				} 
389
				else if (currentChar == '\n')
390
					state = END;
391
				else
392
					state = ERROR;
393
			}
394
			if (state == ERROR)
395
				normalizedValueBuffer
396
						.append("UNEXPECTED ERROR in LinesRangeNormalizer");
397
			return super.normalized(normalizedValueBuffer.toString());
398
		}
399
	}
400
401
	/**
402
	 * Normalizer instance that replaces occurrences of OUTPUT_DIR with 
403
	 * OUTPUT_DIR_PLACEHOLDER.
404
	 */
405
	private static Normalizer outputDirNormalizer = new StringNormalizer(null,
406
			OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
407
408
	/**
409
	 * Normalizer instance for non XML log files. 
410
	 */
411
	private static Normalizer textLogsNormalizer = new StringNormalizer(
412
			new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null,
413
					0, 1)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
414
415
	/**
416
	 * Normalizer instance for XML log files.
417
	 */
418
	private static Normalizer xmlLogsNormalizer = new StringNormalizer(
419
			new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null,
420
					1, 1)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER);
421
	
422
423
	/**
424
	 * Return true if and only if the two strings passed as parameters compare
425
	 * equal, modulo the transformation of the second string by a normalizer
426
	 * passed in parameter. This is meant to erase the variations of subparts of
427
	 * the compared strings in function of the test machine, the user account,
428
	 * etc.
429
	 * 
430
	 * @param keep
431
	 *            the first string to compare, gets compared as it is
432
	 * @param normalize
433
	 *            the second string to compare, passed through the normalizer
434
	 *            before comparison
435
	 * @param normalizer
436
	 *            the transformation applied to normalize
437
	 * @return true if keep and normalize compare equal after normalize has been
438
	 *         normalized
439
	 */
440
	private boolean semiNormalizedComparison(String keep, String normalize,
441
			Normalizer normalizer) {
442
		if (keep == null)
443
			return normalize == null;
444
		if (normalize == null)
445
			return false;
446
		return keep.equals(normalizer.normalized(normalize));
447
	}
448
24
public void test01() {
449
public void test01() {
25
	
450
	
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";
451
		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,
542
			expected,
118
			result);
543
			result);
119
}
544
}
545
// test the tester - runConformTest
546
public void test007(){
547
	this.runConformTest(
548
		new String[] {
549
			"X.java",
550
			"import java.util.List;\n" + 
551
			"\n" + 
552
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
553
			")\n" + 
554
			"public class X {\n" + 
555
			"	public static void main(String[] args) {\n" + 
556
			"		if (false) {\n" + 
557
			"			;\n" + 
558
			"		} else {\n" + 
559
			"		}\n" + 
560
			"		// Zork z;\n" + 
561
			"	}\n" + 
562
			"}"
563
        },
564
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
565
        + " -1.5 -g -preserveAllLocals"
566
        + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar"
567
        + " -cp " + JRE_HOME_DIR + "/lib/jce.jar"
568
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
569
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
570
        "[1 .class file generated]\r\n", 
571
        "----------\r\n" + 
572
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
573
        " (at line 1)\r\n" + 
574
        "	import java.util.List;\r\n" + 
575
        "	       ^^^^^^^^^^^^^^\r\n" + 
576
        "The import java.util.List is never used\r\n" + 
577
        "----------\r\n" + 
578
        "1 problem (1 warning)", true);
579
}
580
// test the tester - runNegativeTest; waiting decision about "errors hide warnings"
581
public void test008(){
582
	this.runNegativeTest(
583
		new String[] {
584
			"X.java",
585
			"import java.util.List;\n" + 
586
			"\n" + 
587
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
588
			")\n" + 
589
			"public class X {\n" + 
590
			"	public static void main(String[] args) {\n" + 
591
			"		if (false) {\n" + 
592
			"			;\n" + 
593
			"		} else {\n" + 
594
			"		}\n" + 
595
			"		Zork z;\n" + 
596
			"	}\n" + 
597
			"}"
598
        },
599
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
600
        + " -1.5 -g -preserveAllLocals"
601
        + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar"
602
        + " -cp " + JRE_HOME_DIR + "/lib/jce.jar"
603
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
604
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
605
        "[1 .class file generated]\r\n", 
606
        "----------\r\n" + 
607
        "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
608
        " (at line 11)\r\n" + 
609
        "	Zork z;\r\n" + 
610
        "	^^^^\r\n" + 
611
        "Zork cannot be resolved to a type\r\n" + 
612
        "----------\r\n" + 
613
        "1 problem (1 error)", true);
614
}
615
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- a case that works, another that does not
616
// revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349
617
public void test009(){
618
	this.runNegativeTest(
619
		new String[] {
620
			"X.java",
621
			"/** */\n" + 
622
			"public class X {\n" + 
623
			"	OK1 ok1;\n" + 
624
			"	OK2 ok2;\n" + 
625
			"	Warn warn;\n" + 
626
			"	KO ko;\n" + 
627
	        "	Zork z;\r\n" + 
628
			"}",
629
			"OK1.java",
630
			"/** */\n" + 
631
			"public class OK1 {\n" + 
632
			"	// empty\n" + 
633
			"}",
634
			"OK2.java",
635
			"/** */\n" + 
636
			"public class OK2 {\n" + 
637
			"	// empty\n" + 
638
			"}",
639
			"Warn.java",
640
			"/** */\n" + 
641
			"public class Warn {\n" + 
642
			"	// empty\n" + 
643
			"}",
644
			"KO.java",
645
			"/** */\n" + 
646
			"public class KO {\n" + 
647
			"	// empty\n" + 
648
			"}",
649
		},
650
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
651
        + " -1.5 -g -preserveAllLocals"
652
        + " -cp \"" + OUTPUT_DIR + "[+OK2.java;~Warn.java;-KO.java]\""
653
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
654
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
655
        "[5 .class files generated]\r\n", 
656
        "----------\r\n" + 
657
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
658
        " (at line 5)\r\n" + 
659
        "	Warn warn;\r\n" + 
660
        "	^^^^\r\n" + 
661
        "Discouraged access: Warn\r\n" + 
662
        "----------\r\n" + 
663
        "----------\r\n" + 
664
        "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
665
        " (at line 6)\r\n" + 
666
        "	KO ko;\r\n" + 
667
        "	^^\r\n" + 
668
        "Access restriction: KO\r\n" + 
669
        "----------\r\n" + 
670
        "----------\r\n" + 
671
        "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
672
        " (at line 7)\r\n" + 
673
        "	Zork z;\r\n" + 
674
        "	^^^^\r\n" + 
675
        "Zork cannot be resolved to a type\r\n" + 
676
        "----------\r\n" + 
677
        "3 problems (1 error, 2 warnings)",
678
        true);
679
}
680
// command line - no user classpath nor bootclasspath
681
public void test010(){
682
	this.runConformTest(
683
		new String[] {
684
			"X.java",
685
			"import java.util.List;\n" + 
686
			"\n" + 
687
			"@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + 
688
			")\n" + 
689
			"public class X {\n" + 
690
			"	public static void main(String[] args) {\n" + 
691
			"		if (false) {\n" + 
692
			"			;\n" + 
693
			"		} else {\n" + 
694
			"		}\n" + 
695
			"		// Zork z;\n" + 
696
			"	}\n" + 
697
			"}"
698
        },
699
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
700
        + " -1.5 -g -preserveAllLocals"
701
        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal"
702
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
703
        "[1 .class file generated]\r\n", 
704
        "----------\r\n" + 
705
        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
706
        " (at line 1)\r\n" + 
707
        "	import java.util.List;\r\n" + 
708
        "	       ^^^^^^^^^^^^^^\r\n" + 
709
        "The import java.util.List is never used\r\n" + 
710
        "----------\r\n" + 
711
        "1 problem (1 warning)", true);
712
}
713
// command line - unusual classpath (ends with ';', still OK)
714
public void test011(){
715
	this.runConformTest(
716
		new String[] {
717
			"X.java",
718
			"/** */\n" + 
719
			"public class X {\n" + 
720
			"}",
721
		},
722
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
723
        + " -1.5 -g -preserveAllLocals"
724
        + " -cp \"" + OUTPUT_DIR + "[+**/OK2.java;~**/Warn.java;-KO.java]"
725
        + "\";"
726
        + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"",
727
        "",
728
        "",
729
        true);
730
}
731
// command line - help
732
public void test012(){
733
	this.runConformTest(
734
		new String[0],
735
        " -help -showversion -referenceInfo",
736
        "Eclipse Java Compiler 0.558, pre-3.1.0 release candidate-1, Copyright IBM Corp 2000, 2005. All rights reserved.\n" + 
737
        " \n" + 
738
        " Usage: <options> <source files | directories>\n" + 
739
        " If directories are specified, then their source contents are compiled.\n" + 
740
        " Possible options are listed below. Options enabled by default are prefixed with \'+\'\n" + 
741
        " \n" + 
742
        " Classpath options:\n" + 
743
        "    -cp -classpath <directories and zip/jar files separated by ;>\n" + 
744
        "                       specify location for application classes and sources. Each\n" + 
745
        "                       directory or file can specify access rules for types between\n" + 
746
        "                       \'[\' and \']\' (e.g. [-X.java] to deny access to type X)\n" + 
747
        "    -bootclasspath <directories and zip/jar files separated by ;>\n" + 
748
        "                       specify location for system classes. Each directory or file can\n" + 
749
        "                       specify access rules for types between \'[\' and \']\' (e.g. [-X.java]\n" + 
750
        "                       to deny access to type X)\n" + 
751
        "    -d <dir>           destination directory (if omitted, no directory is created)\n" + 
752
        "    -d none            generate no .class files\n" + 
753
        "    -encoding <enc>    specify custom encoding for all sources. Each file/directory can override it\n" + 
754
        "                       when suffixed with \'[\'<enc>\']\' (e.g. X.java[utf8])\n" + 
755
        " \n" + 
756
        " Compliance options:\n" + 
757
        "    -1.3               use 1.3 compliance level (implicit -source 1.3 -target 1.1)\n" + 
758
        "    -1.4             + use 1.4 compliance level (implicit -source 1.3 -target 1.2)\n" + 
759
        "    -1.5               use 1.5 compliance level (implicit -source 1.5 -target 1.5)\n" + 
760
        "    -source <version>  set source level: 1.3 to 1.5 (or 5 or 5.0)\n" + 
761
        "    -target <version>  set classfile target level: 1.1 to 1.5 (or 5 or 5.0)\n" + 
762
        " \n" + 
763
        " Warning options:\n" + 
764
        "    -deprecation     + deprecation outside deprecated code\n" + 
765
        "    -nowarn            disable all warnings\n" + 
766
        "    -warn:none         disable all warnings\n" + 
767
        "    -warn:<warnings separated by ,>    enable exactly the listed warnings\n" + 
768
        "    -warn:+<warnings separated by ,>   enable additional warnings\n" + 
769
        "    -warn:-<warnings separated by ,>   disable specific warnings\n" + 
770
        "      allDeprecation       deprecation including inside deprecated code\n" + 
771
        "      allJavadoc           invalid or missing javadoc\n" + 
772
        "      assertIdentifier   + \'assert\' used as identifier\n" + 
773
        "      boxing               autoboxing conversion\n" + 
774
        "      charConcat         + char[] in String concat\n" + 
775
        "      conditionAssign      possible accidental boolean assignment\n" + 
776
        "      constructorName    + method with constructor name\n" + 
777
        "      dep-ann              missing @Deprecated annotation\n" + 
778
        "      deprecation        + deprecation outside deprecated code\n" + 
779
        "      emptyBlock           undocumented empty block\n" + 
780
        "      enumSwitch           incomplete enum switch\n" + 
781
        "      fieldHiding          field hiding another variable\n" + 
782
        "      finalBound           type parameter with final bound\n" + 
783
        "      finally            + finally block not completing normally\n" + 
784
        "      indirectStatic       indirect reference to static member\n" + 
785
        "      intfAnnotation     + annotation type used as super interface\n" + 
786
        "      intfNonInherited   + interface non-inherited method compatibility\n" + 
787
        "      javadoc              invalid javadoc\n" + 
788
        "      localHiding          local variable hiding another variable\n" + 
789
        "      maskedCatchBlock   + hidden catch block\n" + 
790
        "      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n" + 
791
        "      noEffectAssign     + assignment without effect\n" + 
792
        "      null                 missing or redundant null check\n" + 
793
        "      over-ann             missing @Override annotation\n" + 
794
        "      pkgDefaultMethod   + attempt to override package-default method\n" + 
795
        "      semicolon            unnecessary semicolon, empty statement\n" + 
796
        "      serial             + missing serialVersionUID\n" + 
797
        "      suppress           + enable @SuppressWarnings\n" + 
798
        "      unqualifiedField     unqualified reference to field\n" + 
799
        "      unchecked          + unchecked type operation\n" + 
800
        "      unusedArgument       unread method parameter\n" + 
801
        "      unusedImport       + unused import declaration\n" + 
802
        "      unusedLocal          unread local variable\n" + 
803
        "      unusedPrivate        unused private member declaration\n" + 
804
        "      unusedThrown         unused declared thrown exception\n" + 
805
        "      unnecessaryElse      unnecessary else clause\n" + 
806
        "      uselessTypeCheck     unnecessary cast/instanceof operation\n" + 
807
        "      specialParamHiding   constructor or setter parameter hiding another field\n" + 
808
        "      staticReceiver     + non-static reference to static member\n" + 
809
        "      syntheticAccess      synthetic access for innerclass\n" + 
810
        "      tasks(<tags separated by |>) tasks identified by tags inside comments\n" + 
811
        "      typeHiding         + type parameter hiding another type\n" + 
812
        "      varargsCast        + varargs argument need explicit cast\n" + 
813
        "      warningToken       + unhandled warning token in @SuppressWarnings\n" + 
814
        " \n" + 
815
        " Debug options:\n" + 
816
        "    -g[:lines,vars,source] custom debug info\n" + 
817
        "    -g:lines,source  + both lines table and source debug info\n" + 
818
        "    -g                 all debug info\n" + 
819
        "    -g:none            no debug info\n" + 
820
        "    -preserveAllLocals preserve unused local vars for debug purpose\n" + 
821
        " \n" + 
822
        " Advanced options:\n" + 
823
        "    @<file>            read command line arguments from file\n" + 
824
        "    -maxProblems <n>   max number of problems per compilation unit (100 by default)\n" + 
825
        "    -log <file>        log to a file\n" + 
826
        "    -proceedOnError    do not stop at first error, dumping class files with problem methods\n" + 
827
        "    -verbose           enable verbose output\n" + 
828
        "    -referenceInfo     compute reference info\n" + 
829
        "    -progress          show progress (only in -log mode)\n" + 
830
        "    -time              display speed information \n" + 
831
        "    -noExit            do not call System.exit(n) at end of compilation (n==0 if no error)\n" + 
832
        "    -repeat <n>        repeat compilation process <n> times for perf analysis\n" + 
833
        "    -inlineJSR         inline JSR bytecode (implicit if target >= 1.5)\n" + 
834
        "    -enableJavadoc     consider references in javadoc\n" + 
835
        " \n" + 
836
        "    -? -help           print this help message\n" + 
837
        "    -v -version        print compiler version\n" + 
838
        "    -showversion       print compiler version and continue\n" + 
839
        "\r\n", 
840
        "", true);
841
}
842
843
	// command line - xml log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
844
	public void test013() {
845
		String logFileName = OUTPUT_DIR + File.separator + "log.xml";
846
		this.runNegativeTest(new String[] { 
847
				"X.java",
848
				"/** */\n" + 
849
				"public class X {\n" + 
850
				"	Zork z;\n" + 
851
				"}", },
852
				"\"" + OUTPUT_DIR + File.separator + "X.java\""
853
				+ " -1.5 -proceedOnError"
854
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
855
				"", 
856
				"----------\r\n" + 
857
				"1. ERROR in " + OUTPUT_DIR_PLACEHOLDER + "\\X.java\r\n" + 
858
				" (at line 3)\r\n" + 
859
				"	Zork z;\r\n" + 
860
				"	^^^^\r\n" + 
861
				"Zork cannot be resolved to a type\r\n" + 
862
				"----------\r\n" + 
863
				"1 problem (1 error)", 
864
				true);
865
		String logContents = Util.fileContent(logFileName);
866
		String expectedLogContents = 
867
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
868
			"<!DOCTYPE compiler SYSTEM \"compiler.dtd\">\r\n" + 
869
			"<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" + 
870
			"	<command_line>\r\n" + 
871
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\\X.java\"/>\r\n" + 
872
			"		<argument value=\"-1.5\"/>\r\n" + 
873
			"		<argument value=\"-proceedOnError\"/>\r\n" + 
874
			"		<argument value=\"-log\"/>\r\n" + 
875
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\\log.xml\"/>\r\n" + 
876
			"		<argument value=\"-d\"/>\r\n" + 
877
			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\r\n" + 
878
			"	</command_line>\r\n" + 
879
			"	<options>\r\n" + 
880
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\r\n" + 
881
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\r\n" + 
882
			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\r\n" + 
883
			"		<option key=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.5\"/>\r\n" + 
884
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.lineNumber\" value=\"generate\"/>\r\n" + 
885
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.localVariable\" value=\"do not generate\"/>\r\n" + 
886
			"		<option key=\"org.eclipse.jdt.core.compiler.debug.sourceFile\" value=\"generate\"/>\r\n" + 
887
			"		<option key=\"org.eclipse.jdt.core.compiler.doc.comment.support\" value=\"disabled\"/>\r\n" + 
888
			"		<option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\r\n" + 
889
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\r\n" + 
890
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\r\n" + 
891
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\r\n" + 
892
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecation\" value=\"warning\"/>\r\n" + 
893
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode\" value=\"disabled\"/>\r\n" + 
894
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\r\n" + 
895
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\r\n" + 
896
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\r\n" + 
897
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\r\n" + 
898
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\r\n" + 
899
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finalParameterBound\" value=\"warning\"/>\r\n" + 
900
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally\" value=\"warning\"/>\r\n" + 
901
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.forbiddenReference\" value=\"warning\"/>\r\n" + 
902
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock\" value=\"warning\"/>\r\n" + 
903
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod\" value=\"warning\"/>\r\n" + 
904
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch\" value=\"ignore\"/>\r\n" + 
905
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.indirectStaticAccess\" value=\"ignore\"/>\r\n" + 
906
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadoc\" value=\"ignore\"/>\r\n" + 
907
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTags\" value=\"enabled\"/>\r\n" + 
908
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef\" value=\"enabled\"/>\r\n" + 
909
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef\" value=\"enabled\"/>\r\n" + 
910
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility\" value=\"private\"/>\r\n" + 
911
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.localVariableHiding\" value=\"ignore\"/>\r\n" + 
912
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName\" value=\"warning\"/>\r\n" + 
913
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation\" value=\"ignore\"/>\r\n" + 
914
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocComments\" value=\"ignore\"/>\r\n" + 
915
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding\" value=\"disabled\"/>\r\n" + 
916
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility\" value=\"public\"/>\r\n" + 
917
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTags\" value=\"ignore\"/>\r\n" + 
918
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding\" value=\"disabled\"/>\r\n" + 
919
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility\" value=\"private\"/>\r\n" + 
920
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation\" value=\"ignore\"/>\r\n" + 
921
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSerialVersion\" value=\"warning\"/>\r\n" + 
922
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\r\n" + 
923
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\r\n" + 
924
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\r\n" + 
925
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"ignore\"/>\r\n" + 
926
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\r\n" + 
927
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\r\n" + 
928
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\r\n" + 
929
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\r\n" + 
930
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressWarnings\" value=\"enabled\"/>\r\n" + 
931
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation\" value=\"ignore\"/>\r\n" + 
932
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\r\n" + 
933
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\r\n" + 
934
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\r\n" + 
935
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\r\n" + 
936
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\r\n" + 
937
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck\" value=\"ignore\"/>\r\n" + 
938
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess\" value=\"ignore\"/>\r\n" + 
939
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException\" value=\"ignore\"/>\r\n" + 
940
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding\" value=\"disabled\"/>\r\n" + 
941
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedImport\" value=\"warning\"/>\r\n" + 
942
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLocal\" value=\"ignore\"/>\r\n" + 
943
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameter\" value=\"ignore\"/>\r\n" + 
944
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract\" value=\"disabled\"/>\r\n" + 
945
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete\" value=\"disabled\"/>\r\n" + 
946
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedPrivateMember\" value=\"ignore\"/>\r\n" + 
947
			"		<option key=\"org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast\" value=\"warning\"/>\r\n" + 
948
			"		<option key=\"org.eclipse.jdt.core.compiler.source\" value=\"1.5\"/>\r\n" + 
949
			"		<option key=\"org.eclipse.jdt.core.compiler.taskCaseSensitive\" value=\"enabled\"/>\r\n" + 
950
			"		<option key=\"org.eclipse.jdt.core.compiler.taskPriorities\" value=\"\"/>\r\n" + 
951
			"		<option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\r\n" + 
952
			"	</options>\r\n" + 
953
			"	<classpaths>NORMALIZED SECTION</classpaths>\r\n" + 
954
			"	<sources>\r\n" + 
955
			"		<source path=\"---OUTPUT_DIR_PLACEHOLDER---\\X.java\">\r\n" + 
956
			"			<problems problems=\"1\" errors=\"1\" warnings=\"0\">\r\n" + 
957
			"				<problem charEnd=\"28\" charStart=\"25\" severity=\"ERROR\" line=\"3\" id=\"UndefinedType\">\r\n" + 
958
			"					<message value=\"Zork cannot be resolved to a type\"/>\r\n" + 
959
			"					<source_context value=\"Zork z;\" sourceStart=\"0\" sourceEnd=\"3\"/>\r\n" + 
960
			"					<arguments>\r\n" + 
961
			"						<argument value=\"Zork\"/>\r\n" + 
962
			"					</arguments>\r\n" + 
963
			"				</problem>\r\n" + 
964
			"			</problems>\r\n" + 
965
			"			<classfile path=\"---OUTPUT_DIR_PLACEHOLDER---\\X.class\"/>\r\n" + 
966
			"		</source>\r\n" + 
967
			"	</sources>\r\n" + 
968
			"	<stats>\r\n" + 
969
			"		<problem_summary problems=\"1\" errors=\"1\" warnings=\"0\" tasks=\"0\"/>\r\n" + 
970
			"	</stats>\r\n" + 
971
			"</compiler>\r\n";
972
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
973
				logContents, xmlLogsNormalizer);
974
		if (!compareOK) {
975
			System.out.println(getClass().getName() + '#' + getName());
976
			System.out.println(
977
					  "------------ [START LOG] ------------\n"
978
					+ "------------- Expected: -------------\n"
979
					+ expectedLogContents
980
				  + "\n------------- but was:  -------------\n"
981
					+ xmlLogsNormalizer.normalized(logContents)
982
				  + "\n--------- (cut and paste:) ----------\n"
983
					+ Util.displayString(xmlLogsNormalizer.normalized(logContents))
984
				  + "\n------------- [END LOG] -------------\n");
985
		}
986
		assertTrue("unexpected log contents", compareOK);
987
	}
988
989
	// command line - txt log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
990
	public void test014() {
991
		String logFileName = OUTPUT_DIR + File.separator + "log.txt";
992
		this.runNegativeTest(new String[] { 
993
				"X.java",
994
				"/** */\n" + 
995
				"public class X {\n" + 
996
				"	Zork z;\n" + 
997
				"}", },
998
				"\"" + OUTPUT_DIR + File.separator + "X.java\"" 
999
				+ " -1.5 -proceedOnError"
1000
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
1001
				"", 
1002
				"----------\r\n" + 
1003
				"1. ERROR in " + OUTPUT_DIR_PLACEHOLDER + "\\X.java\r\n" + 
1004
				" (at line 3)\r\n" + 
1005
				"	Zork z;\r\n" + 
1006
				"	^^^^\r\n" + 
1007
				"Zork cannot be resolved to a type\r\n" + 
1008
				"----------\r\n" + 
1009
				"1 problem (1 error)", 
1010
				false);
1011
		String logContents = Util.fileContent(logFileName);
1012
		String expectedLogContents = 
1013
			"----------\r\n" + 
1014
			"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1015
			" (at line 3)\r\n" + 
1016
			"	Zork z;\r\n" + 
1017
			"	^^^^\r\n" + 
1018
			"Zork cannot be resolved to a type\r\n" + 
1019
			"----------\r\n" + 
1020
			"1 problem (1 error)";
1021
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
1022
				logContents, textLogsNormalizer);
1023
		if (!compareOK) {
1024
			System.out.println(getClass().getName() + '#' + getName());
1025
			System.out.println(
1026
							  "------------ [START LOG] ------------\n"
1027
							+ "------------- Expected: -------------\n"
1028
							+ expectedLogContents
1029
						  + "\n------------- but was:  -------------\n"
1030
							+ outputDirNormalizer.normalized(logContents)
1031
						  + "\n--------- (cut and paste:) ----------\n"
1032
							+ Util.displayString(outputDirNormalizer.normalized(logContents))
1033
						  + "\n------------- [END LOG] -------------\n");
1034
		}
1035
		assertTrue("unexpected log contents", compareOK);
1036
	}
1037
1038
	// command line - no extension log contents https://bugs.eclipse.org/bugs/show_bug.cgi?id=93904
1039
	public void test015() {
1040
		String logFileName = OUTPUT_DIR + File.separator + "log";
1041
		this.runNegativeTest(new String[] { 
1042
				"X.java",
1043
				"/** */\n" + 
1044
				"public class X {\n" + 
1045
				"	Zork z;\n" + 
1046
				"}", },
1047
				"\"" + OUTPUT_DIR + File.separator + "X.java\""
1048
				+ " -1.5 -proceedOnError"
1049
				+ " -log \"" + logFileName + "\" -d \"" + OUTPUT_DIR + "\"",
1050
				"", 
1051
				"----------\r\n" + 
1052
				"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1053
				" (at line 3)\r\n" + 
1054
				"	Zork z;\r\n" + 
1055
				"	^^^^\r\n" + 
1056
				"Zork cannot be resolved to a type\r\n" + 
1057
				"----------\r\n" + 
1058
				"1 problem (1 error)", 
1059
				false);
1060
		String logContents = Util.fileContent(logFileName);
1061
		String expectedLogContents = 
1062
			"----------\r\n" + 
1063
			"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1064
			" (at line 3)\r\n" + 
1065
			"	Zork z;\r\n" + 
1066
			"	^^^^\r\n" + 
1067
			"Zork cannot be resolved to a type\r\n" + 
1068
			"----------\r\n" + 
1069
			"1 problem (1 error)";
1070
		boolean compareOK = semiNormalizedComparison(expectedLogContents,
1071
				logContents, textLogsNormalizer);
1072
		if (!compareOK) {
1073
			System.out.println(getClass().getName() + '#' + getName());
1074
			System.out.println(
1075
					  "------------ [START LOG] ------------\n"
1076
					+ "------------- Expected: -------------\n"
1077
					+ expectedLogContents
1078
				  + "\n------------- but was:  -------------\n"
1079
					+ outputDirNormalizer.normalized(logContents)
1080
				  + "\n--------- (cut and paste:) ----------\n"
1081
					+ Util.displayString(outputDirNormalizer.normalized(logContents))
1082
				  + "\n------------- [END LOG] -------------\n");
1083
		}
1084
		assertTrue("unexpected log contents", compareOK);
1085
	}
1086
//	 command line - unusual classpath (contains multiple empty members, still OK)
1087
	public void test016(){
1088
		this.runConformTest(
1089
			new String[] {
1090
					"X.java",
1091
					"/** */\n" + 
1092
					"public class X {\n" + 
1093
					"	OK1 ok1;\n" + 
1094
					"}",
1095
					"OK1.java",
1096
					"/** */\n" + 
1097
					"public class OK1 {\n" + 
1098
					"	// empty\n" + 
1099
					"}"
1100
			},
1101
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1102
	        + " -1.5 -g -preserveAllLocals"
1103
	        + " -cp .;;;\"" + OUTPUT_DIR + "\""
1104
	        + " -verbose -proceedOnError -referenceInfo"
1105
	        + " -d \"" + OUTPUT_DIR + "\"",
1106
	        "[2 .class files generated]\r\n",
1107
	        "",
1108
	        true);
1109
	}
1110
//	 command line - unusual classpath (contains erroneous members, still OK)
1111
	public void test017(){
1112
		this.runConformTest(
1113
			new String[] {
1114
					"X.java",
1115
					"/** */\n" + 
1116
					"public class X {\n" + 
1117
					"	OK1 ok1;\n" + 
1118
					"}",
1119
					"OK1.java",
1120
					"/** */\n" + 
1121
					"public class OK1 {\n" + 
1122
					"	// empty\n" + 
1123
					"}"
1124
			},
1125
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1126
	        + " -1.5 -g -preserveAllLocals"
1127
	        + " -cp dummmy_dir;dummy.jar;;\"" + OUTPUT_DIR + "\"" 
1128
	        + " -verbose -proceedOnError -referenceInfo" 
1129
	        + " -d \"" + OUTPUT_DIR + "\"", 
1130
	        "[2 .class files generated]\r\n",
1131
	        "",
1132
	        true);
1133
	}
1134
// command line - unusual classpath (empty, but using current directory, still OK provided 
1135
//	that we execute from the appropriate directory)
1136
	public void _test018(){
1137
		this.runConformTest(
1138
			new String[] {
1139
					"X.java",
1140
					"/** */\n" + 
1141
					"public class X {\n" + 
1142
					"	OK1 ok1;\n" + 
1143
					"}",
1144
					"OK1.java",
1145
					"/** */\n" + 
1146
					"public class OK1 {\n" + 
1147
					"	// empty\n" + 
1148
					"}"
1149
			},
1150
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1151
	        + " -1.5 -g -preserveAllLocals"
1152
	        + " -verbose -proceedOnError -referenceInfo"
1153
	        + " -d \"" + OUTPUT_DIR + "\"",
1154
	        "[2 .class files generated]\r\n",
1155
	        "",
1156
	        true);
1157
	}
1158
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- with wildcards 
1159
// a case that works, another that does not
1160
// revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349
1161
	public void test019(){
1162
		this.runNegativeTest(
1163
			new String[] {
1164
				"X.java",
1165
				"/** */\n" + 
1166
				"public class X {\n" + 
1167
				"	OK1 ok1;\n" + 
1168
				"	OK2 ok2;\n" + 
1169
				"	Warn warn;\n" + 
1170
				"	KO ko;\n" + 
1171
		        "	Zork z;\r\n" + 
1172
				"}",
1173
				"OK1.java",
1174
				"/** */\n" + 
1175
				"public class OK1 {\n" + 
1176
				"	// empty\n" + 
1177
				"}",
1178
				"OK2.java",
1179
				"/** */\n" + 
1180
				"public class OK2 {\n" + 
1181
				"	// empty\n" + 
1182
				"}",
1183
				"Warn.java",
1184
				"/** */\n" + 
1185
				"public class Warn {\n" + 
1186
				"	// empty\n" + 
1187
				"}",
1188
				"KO.java",
1189
				"/** */\n" + 
1190
				"public class KO {\n" + 
1191
				"	// empty\n" + 
1192
				"}",
1193
			},
1194
	        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
1195
	        + " -1.5 -g -preserveAllLocals" 
1196
	        + " -cp \"" + OUTPUT_DIR + "[+OK2.*;~Warn.*;-KO.*]\""
1197
	        + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" 
1198
	        + " -proceedOnError -referenceInfo"
1199
	        + " -d \"" + OUTPUT_DIR + "\"", 
1200
	        "[5 .class files generated]\r\n", 
1201
	        "----------\r\n" + 
1202
	        "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1203
	        " (at line 5)\r\n" + 
1204
	        "	Warn warn;\r\n" + 
1205
	        "	^^^^\r\n" + 
1206
	        "Discouraged access: Warn\r\n" + 
1207
	        "----------\r\n" + 
1208
	        "----------\r\n" + 
1209
	        "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1210
	        " (at line 6)\r\n" + 
1211
	        "	KO ko;\r\n" + 
1212
	        "	^^\r\n" + 
1213
	        "Access restriction: KO\r\n" + 
1214
	        "----------\r\n" + 
1215
	        "----------\r\n" + 
1216
	        "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---\\X.java\r\n" + 
1217
	        " (at line 7)\r\n" + 
1218
	        "	Zork z;\r\n" + 
1219
	        "	^^^^\r\n" + 
1220
	        "Zork cannot be resolved to a type\r\n" + 
1221
	        "----------\r\n" + 
1222
	        "3 problems (1 error, 2 warnings)",
1223
	        true);
1224
	}
120
public static Class testClass() {
1225
public static Class testClass() {
121
	return BatchCompilerTest.class;
1226
	return BatchCompilerTest.class;
122
}
1227
}

Return to bug 92398