/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; import java.text.MessageFormat; import junit.framework.Test; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.batch.Main; public class BatchCompilerTest extends AbstractRegressionTest { public static final String OUTPUT_DIR_PLACEHOLDER = "---OUTPUT_DIR_PLACEHOLDER---"; static final String JRE_HOME_DIR = Util.getJREDirectory(); static { // TESTS_NAMES = new String[] { "test000" }; // TESTS_NUMBERS = new int[] { 27 }; // TESTS_RANGE = new int[] { 11, -1 }; } public BatchCompilerTest(String name) { super(name); } public static Test suite() { return buildTestSuiteUniqueCompliance(testClass(), COMPLIANCE_1_5); } /** * Run a compilation test that is expected to complete successfully and * compare the outputs to expected ones. * * @param testFiles * the source files, given as a suite of file name, file content; * file names are relative to the output directory * @param commandLine * the command line to pass to * {@link Main#compile(String) Main#compile} * @param expectedSuccessOutOutputString * the expected contents of the standard output stream; pass null * to bypass the comparison * @param expectedSuccessErrOutputString * the expected contents of the standard error output stream; * pass null to bypass the comparison * @param shouldFlushOutputDirectory * pass true to get the output directory flushed before the test * runs */ protected void runConformTest(String[] testFiles, String commandLine, String expectedSuccessOutOutputString, String expectedSuccessErrOutputString, boolean shouldFlushOutputDirectory) { runTest(true, testFiles, commandLine, expectedSuccessOutOutputString, expectedSuccessErrOutputString, shouldFlushOutputDirectory); } /** * Run a compilation test that is expected to fail and compare the outputs * to expected ones. * * @param testFiles * the source files, given as a suite of file name, file content; * file names are relative to the output directory * @param commandLine * the command line to pass to * {@link Main#compile(String) Main#compile} * @param expectedFailureOutOutputString * the expected contents of the standard output stream; pass null * to bypass the comparison * @param expectedFailureErrOutputString * the expected contents of the standard error output stream; * pass null to bypass the comparison * @param shouldFlushOutputDirectory * pass true to get the output directory flushed before the test * runs */ protected void runNegativeTest(String[] testFiles, String commandLine, String expectedFailureOutOutputString, String expectedFailureErrOutputString, boolean shouldFlushOutputDirectory) { runTest(false, testFiles, commandLine, expectedFailureOutOutputString, expectedFailureErrOutputString, shouldFlushOutputDirectory); } /** * Worker method for runConformTest and runNegativeTest. * * @param shouldCompileOK * set to true if the compiler should compile the given sources * without errors * @param testFiles * the source files, given as a suite of file name, file content; * file names are relative to the output directory * @param commandLine * the command line to pass to * {@link Main#compile(String) Main#compile} * @param expectedOutOutputString * the expected contents of the standard output stream; pass null * to bypass the comparison * @param expectedErrOutputString * the expected contents of the standard error output stream; * pass null to bypass the comparison * @param shouldFlushOutputDirectory * pass true to get the output directory flushed before the test * runs */ private void runTest(boolean shouldCompileOK, String[] testFiles, String commandLine, String expectedOutOutputString, String expectedErrOutputString, boolean shouldFlushOutputDirectory) { File outputDirectory = new File(OUTPUT_DIR); if (shouldFlushOutputDirectory) Util.flushDirectoryContent(outputDirectory); try { if (!outputDirectory.isDirectory()) { outputDirectory.mkdirs(); } PrintWriter sourceFileWriter; for (int i = 0; i < testFiles.length; i += 2) { String fileName = OUTPUT_DIR + File.separator + testFiles[i]; File file = new File(fileName), innerOutputDirectory = file .getParentFile(); if (!innerOutputDirectory.isDirectory()) { innerOutputDirectory.mkdirs(); } sourceFileWriter = new PrintWriter(new FileOutputStream(file)); sourceFileWriter.write(testFiles[i + 1]); sourceFileWriter.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException(e); } String printerWritersNameRoot = OUTPUT_DIR + File.separator + testName(); String outFileName = printerWritersNameRoot + "out.txt", errFileName = printerWritersNameRoot + "err.txt"; Main batchCompiler; try { batchCompiler = new Main(new PrintWriter(new FileOutputStream( outFileName)), new PrintWriter(new FileOutputStream( errFileName)), false); } catch (FileNotFoundException e) { System.out.println(getClass().getName() + '#' + getName()); e.printStackTrace(); throw new RuntimeException(e); } boolean compileOK; try { final String[] tokenizeCommandLine = Main.tokenize(commandLine); compileOK = batchCompiler.compile(tokenizeCommandLine); } catch (RuntimeException e) { compileOK = false; System.out.println(getClass().getName() + '#' + getName()); e.printStackTrace(); throw e; } String outOutputString = Util.fileContent(outFileName), errOutputString = Util.fileContent(errFileName); boolean compareOK = false; if (compileOK == shouldCompileOK) { compareOK = semiNormalizedComparison(expectedOutOutputString, outOutputString, outputDirNormalizer) && semiNormalizedComparison(expectedErrOutputString, errOutputString, outputDirNormalizer); } if (compileOK != shouldCompileOK || !compareOK) { System.out.println(getClass().getName() + '#' + getName()); for (int i = 0; i < testFiles.length; i += 2) { System.out.print(testFiles[i]); System.out.println(" ["); System.out.println(testFiles[i + 1]); System.out.println("]"); } } if (compileOK != shouldCompileOK) System.out.println(errOutputString); if (compileOK == shouldCompileOK && !compareOK) { System.out.println( "------------ [START OUT] ------------\n" + "------------- Expected: -------------\n" + expectedOutOutputString + "\n------------- but was: -------------\n" + outOutputString + "\n--------- (cut and paste:) ----------\n" + Util.displayString(outputDirNormalizer .normalized(outOutputString)) + "\n------------- [END OUT] -------------\n" + "------------ [START ERR] ------------\n" + "------------- Expected: -------------\n" + expectedErrOutputString + "\n------------- but was: -------------\n" + errOutputString + "\n--------- (cut and paste:) ----------\n" + Util.displayString(outputDirNormalizer .normalized(errOutputString)) + "\n------------- [END ERR] -------------\n"); } if (shouldCompileOK) assertTrue("Unexpected problems: " + errOutputString, compileOK); else assertTrue("Unexpected success: " + errOutputString, !compileOK); assertTrue("Unexpected output for invocation with arguments [" + commandLine + "]:\n--[START]--\n" + outOutputString + "\n" + errOutputString + "\n---[END]---\n", compareOK); } /** * Abstract normalizer for output comparison. This class merely embodies a * chain of responsibility, plus the signature of the method of interest * here, that is {@link #normalized(String) normalized}. */ private static abstract class Normalizer { private Normalizer nextInChain; Normalizer(Normalizer nextInChain) { this.nextInChain = nextInChain; } String normalized(String originalValue) { String result; if (nextInChain == null) result = Util.convertToIndependantLineDelimiter(originalValue); else result = nextInChain.normalized(originalValue); return result; } } /** * This normalizer replaces occurrences of a given string with a given * placeholder. */ private static class StringNormalizer extends Normalizer { private String match; private int matchLength; private String placeholder; StringNormalizer(Normalizer nextInChain, String match, String placeholder) { super(nextInChain); this.match = match; this.matchLength = match.length(); this.placeholder = placeholder; } String normalized(String originalValue) { String result; StringBuffer normalizedValueBuffer = new StringBuffer(originalValue); int nextOccurrenceIndex; while ((nextOccurrenceIndex = normalizedValueBuffer.indexOf(match)) != -1) normalizedValueBuffer.replace(nextOccurrenceIndex, nextOccurrenceIndex + matchLength, placeholder); result = super.normalized(normalizedValueBuffer.toString()); return result; } } /** * This normalizer replaces the whole classpaths section of a log file with * a normalized placeholder. */ private static class XMLClasspathsSectionNormalizer extends Normalizer { XMLClasspathsSectionNormalizer() { super(null); } XMLClasspathsSectionNormalizer(Normalizer nextInChain) { super(nextInChain); } String normalized(String originalValue) { String result; StringBuffer normalizedValueBuffer = new StringBuffer(originalValue); int classpathsStartTagStart = normalizedValueBuffer .indexOf(""), classpathsEndTagStart = normalizedValueBuffer .indexOf(""); if (classpathsStartTagStart != -1 && classpathsEndTagStart != -1 && classpathsStartTagStart < classpathsEndTagStart) normalizedValueBuffer.replace(classpathsStartTagStart + 12, classpathsEndTagStart, "NORMALIZED SECTION"); result = super.normalized(normalizedValueBuffer.toString()); return result; } } /** * This normalizer removes a selected range of lines from a log file. */ private static class LinesRangeNormalizer extends Normalizer { private int first, number; LinesRangeNormalizer() { super(null); first = number = 0; } LinesRangeNormalizer(Normalizer nextInChain) { super(nextInChain); first = number = 0; } /** * Make a new normalizer able to suppress a range of lines delimited by * "\n" sequences from a log file (or another string). * * @param nextInChain * the next normalizer in the chain of responsibility; pass * null if none is needed * @param firstLineToRemove * the index of the first line to remove, starting at 0 * @param linesNumber * the number or lines to remove; if 0, no other * transformation occurs than those operated by nextInChain * (if any) */ LinesRangeNormalizer(Normalizer nextInChain, int firstLineToRemove, int linesNumber) { super(nextInChain); first = firstLineToRemove; number = linesNumber >= 0 ? linesNumber : 0; } String normalized(String originalValue) { String result; if (number == 0 || originalValue.length() == 0) result = super.normalized(originalValue); else { final int START = 0, KEEPING = 1, KEEPING_R = 2, SKIPING = 3, SKIPING_R = 4, END = 5, ERROR = 6; int state = START, currentLineIndex = 0, currentCharIndex = 0, sourceLength; char currentChar = '\0'; if (first <= 0) state = SKIPING; else state = KEEPING; StringBuffer normalizedValueBuffer = new StringBuffer(), source = new StringBuffer( originalValue); sourceLength = source.length(); while (state != END && state != ERROR) { if (currentCharIndex < sourceLength) { currentChar = source.charAt(currentCharIndex++); switch (currentChar) { case '\r': switch (state) { case KEEPING: normalizedValueBuffer.append(currentChar); state = KEEPING_R; break; case SKIPING: state = SKIPING_R; break; default: state = ERROR; } break; case '\n': currentLineIndex++; switch (state) { case KEEPING: // tolerate Linux line delimiters case KEEPING_R: normalizedValueBuffer.append(currentChar); if (currentLineIndex == first) { state = SKIPING; } break; case SKIPING: // tolerate Linux line delimiters case SKIPING_R: // in effect, we tolerate too big first and number // values if (currentLineIndex >= first + number) { if (currentCharIndex < sourceLength) normalizedValueBuffer.append(source .substring(currentCharIndex)); state = END; } else { state = SKIPING; } break; default: state = ERROR; } break; default: switch (state) { case KEEPING: normalizedValueBuffer.append(currentChar); break; case SKIPING: break; default: state = ERROR; } } } else if (currentChar == '\n') state = END; else state = ERROR; } if (state == ERROR) normalizedValueBuffer .append("UNEXPECTED ERROR in LinesRangeNormalizer"); result = super.normalized(normalizedValueBuffer.toString()); } return result; } } /** * Normalizer instance that replaces occurrences of OUTPUT_DIR with * OUTPUT_DIR_PLACEHOLDER. */ private static Normalizer outputDirNormalizer = new StringNormalizer(null, OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER); /** * Normalizer instance for non XML log files. */ private static Normalizer textLogsNormalizer = new StringNormalizer( new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null, 0, 2)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER); /** * Normalizer instance for XML log files. */ private static Normalizer xmlLogsNormalizer = new StringNormalizer( new XMLClasspathsSectionNormalizer(new LinesRangeNormalizer(null, 1, 1)), OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER); /** * Return true if and only if the two strings passed as parameters compare * equal, modulo the transformation of the second string by a normalizer * passed in parameter. This is meant to erase the variations of subparts of * the compared strings in function of the test machine, the user account, * etc. * * @param keep * the first string to compare, gets compared as it is * @param normalize * the second string to compare, passed through the normalizer * before comparison * @param normalizer * the transformation applied to normalize * @return true if keep and normalize compare equal after normalize has been * normalized */ private boolean semiNormalizedComparison(String keep, String normalize, Normalizer normalizer) { if (keep == null) return normalize == null; if (normalize == null) return false; // return keep.equals(normalizer.normalized(normalize)); return equals(keep, normalizer.normalized(normalize)); } private static boolean equals(String a, String b) { StringBuffer aBuffer = new StringBuffer(a), bBuffer = new StringBuffer(b); int length = aBuffer.length(); if (length != bBuffer.length()) { System.err.println("a and b lengths differ"); return false; } for (int i = 0; i < length; i++) if (aBuffer.charAt(i) != bBuffer.charAt(i)) { int beforeStart = i - 5, beforeEnd = i - 1, afterStart = i + 1, afterEnd = i + 5; if (beforeStart < 0) { beforeStart = 0; if (beforeEnd < 0) beforeEnd = 0; } if (afterEnd >= length) { afterEnd = length - 1; if (afterStart >= length) afterStart = length - 1; } System.err.println("a and b differ at rank: " + i + " a: ..." + aBuffer.substring(beforeStart, beforeEnd) + "<" + aBuffer.charAt(i) + ">" + aBuffer.substring(afterStart, afterEnd) + "..." + " b: ..." + bBuffer.substring(beforeStart, beforeEnd) + "<" + bBuffer.charAt(i) + ">" + bBuffer.substring(afterStart, afterEnd) + "..."); return false; } return true; } public void test001() { String commandLine = "-classpath \"D:/a folder\";d:/jdk1.4/jre/lib/rt.jar -1.4 -preserveAllLocals -g -verbose d:/eclipse/workspaces/development2.0/plugins/Bar/src2/ -d d:/test"; String expected = " <-classpath> <-1.4> <-preserveAllLocals> <-g> <-verbose> <-d> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } public void test002() { String commandLine = "-classpath \"a folder\";\"b folder\""; String expected = " <-classpath> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } public void test003() { String commandLine = "-classpath \"a folder;b folder\""; String expected = " <-classpath> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } public void test004() { String commandLine = "\"d:/tmp A/\"A.java -classpath \"d:/tmp A\";d:/jars/rt.jar -nowarn -time -g -d d:/tmp"; String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } public void test005() { String commandLine = "\"d:/tmp A/\"A.java -classpath d:/jars/rt.jar;\"d:/tmp A\";\"toto\" -nowarn -time -g -d d:/tmp"; String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } public void test006() { String commandLine = "\"d:/tmp A/A.java\" -classpath d:/jars/rt.jar;\"d:/tmp A\";d:/tmpB/ -nowarn -time -g -d d:/tmp"; String expected = " <-classpath> <-nowarn> <-time> <-g> <-d> "; String[] args = Main.tokenize(commandLine); StringBuffer buffer = new StringBuffer(30); for (int i = 0; i < args.length; i++){ buffer.append(" <"+args[i]+">"); } String result = buffer.toString(); //System.out.println(Util.displayString(result, 2)); assertEquals("incorrect tokenized command line", expected, result); } // test the tester - runConformTest public void _test007(){ this.runConformTest( new String[] { "X.java", "import java.util.List;\n" + "\n" + "@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + ")\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " if (false) {\n" + " ;\n" + " } else {\n" + " }\n" + " // Zork z;\n" + " }\n" + "}" }, "\"" + OUTPUT_DIR + File.separator + "X.java\"" + " -1.5 -g -preserveAllLocals" + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar" + " -cp " + JRE_HOME_DIR + "/lib/jce.jar" + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"", "[1 .class file generated]\n", "----------\n" + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 1)\n" + " import java.util.List;\n" + " ^^^^^^^^^^^^^^\n" + "The import java.util.List is never used\n" + "----------\n" + "1 problem (1 warning)", true); } // test the tester - runNegativeTest public void _test008(){ this.runNegativeTest( new String[] { "X.java", "import java.util.List;\n" + "\n" + "@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + ")\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " if (false) {\n" + " ;\n" + " } else {\n" + " }\n" + " Zork z;\n" + " }\n" + "}" }, "\"" + OUTPUT_DIR + File.separator + "X.java\"" + " -1.5 -g -preserveAllLocals" + " -bootclasspath " + JRE_HOME_DIR + "/lib/rt.jar" + " -cp " + JRE_HOME_DIR + "/lib/jce.jar" + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"", "[1 .class file generated]\n", "----------\n" + "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 11)\n" + " Zork z;\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + "1 problem (1 error)", true); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=92398 -- a case that works, another that does not // revisit this test case depending on https://bugs.eclipse.org/bugs/show_bug.cgi?id=95349 public void _test009(){ this.runNegativeTest( new String[] { "X.java", "/** */\n" + "public class X {\n" + " OK1 ok1;\n" + " OK2 ok2;\n" + " Warn warn;\n" + " KO ko;\n" + " Zork z;\n" + "}", "OK1.java", "/** */\n" + "public class OK1 {\n" + " // empty\n" + "}", "OK2.java", "/** */\n" + "public class OK2 {\n" + " // empty\n" + "}", "Warn.java", "/** */\n" + "public class Warn {\n" + " // empty\n" + "}", "KO.java", "/** */\n" + "public class KO {\n" + " // empty\n" + "}", }, "\"" + OUTPUT_DIR + File.separator + "X.java\"" + " -1.5 -g -preserveAllLocals" + " -cp \"" + OUTPUT_DIR + "[+OK2" + File.pathSeparator + "~Warn" + File.pathSeparator + "-KO]\"" + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"", "[5 .class files generated]\n", "----------\n" + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 5)\n" + " Warn warn;\n" + " ^^^^\n" + "Discouraged access: Warn\n" + "----------\n" + "----------\n" + "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 6)\n" + " KO ko;\n" + " ^^\n" + "Access restriction: KO\n" + "----------\n" + "----------\n" + "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 7)\n" + " Zork z;\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + "3 problems (1 error, 2 warnings)", true); } // command line - no user classpath nor bootclasspath public void _test010(){ this.runConformTest( new String[] { "X.java", "import java.util.List;\n" + "\n" + "@SuppressWarnings(\"all\"//$NON-NLS-1$\n" + ")\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " if (false) {\n" + " ;\n" + " } else {\n" + " }\n" + " // Zork z;\n" + " }\n" + "}" }, "\"" + OUTPUT_DIR + File.separator + "X.java\"" + " -1.5 -g -preserveAllLocals" + " -verbose -warn:+deprecation,syntheticAccess,uselessTypeCheck,unsafe,finalBound,unusedLocal" + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"", "[1 .class file generated]\n", "----------\n" + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\n" + " (at line 1)\n" + " import java.util.List;\n" + " ^^^^^^^^^^^^^^\n" + "The import java.util.List is never used\n" + "----------\n" + "1 problem (1 warning)", true); } // command line - unusual classpath (ends with ';', still OK) public void test011(){ this.runConformTest( new String[] { "X.java", "/** */\n" + "public class X {\n" + "}", }, "\"" + OUTPUT_DIR + File.separator + "X.java\"" + " -1.5 -g -preserveAllLocals" + " -cp \"" + OUTPUT_DIR + "[+**/OK2;~**/Warn;-KO]" + "\"" + File.pathSeparator + " -proceedOnError -referenceInfo -d \"" + OUTPUT_DIR + "\"", "", "", true); } // command line - help public void _test012(){ final String expectedOutput = "{0}\n" + " \n" + " Usage: \n" + " If directories are specified, then their source contents are compiled.\n" + " Possible options are listed below. Options enabled by default are prefixed with \'\'+\'\'\n" + " \n" + " Classpath options:\n" + " -cp -classpath \n" + " specify location for application classes and sources. Each\n" + " directory or file can specify access rules for types between\n" + " \'\'[\'\' and \'\']\'\' (e.g. [-X.java] to deny access to type X)\n" + " -bootclasspath \n" + " specify location for system classes. Each directory or file can\n" + " specify access rules for types between \'\'[\'\' and \'\']\'\' (e.g. [-X.java]\n" + " to deny access to type X)\n" + " -sourcepath \n" + " specify location for application sources. Each directory or file can\n" + " specify access rules for types between \'\'[\'\' and \'\']\'\' (e.g. [-X.java]\n" + " to deny access to type X)\n" + " -extdirs \n" + " specify location for extension zip/jar files\n" + " -d destination directory (if omitted, no directory is created)\n" + " -d none generate no .class files\n" + " -encoding specify custom encoding for all sources. Each file/directory can override it\n" + " when suffixed with \'\'[\'\'\'\']\'\' (e.g. X.java[utf8])\n" + " \n" + " Compliance options:\n" + " -1.3 use 1.3 compliance level (implicit -source 1.3 -target 1.1)\n" + " -1.4 + use 1.4 compliance level (implicit -source 1.3 -target 1.2)\n" + " -1.5 use 1.5 compliance level (implicit -source 1.5 -target 1.5)\n" + " -source set source level: 1.3 to 1.5 (or 5 or 5.0)\n" + " -target set classfile target level: 1.1 to 1.5 (or 5 or 5.0)\n" + " \n" + " Warning options:\n" + " -deprecation + deprecation outside deprecated code\n" + " -nowarn disable all warnings\n" + " -warn:none disable all warnings\n" + " -warn: enable exactly the listed warnings\n" + " -warn:+ enable additional warnings\n" + " -warn:- disable specific warnings\n" + " allDeprecation deprecation including inside deprecated code\n" + " allJavadoc invalid or missing javadoc\n" + " assertIdentifier + \'\'assert\'\' used as identifier\n" + " boxing autoboxing conversion\n" + " charConcat + char[] in String concat\n" + " conditionAssign possible accidental boolean assignment\n" + " constructorName + method with constructor name\n" + " dep-ann missing @Deprecated annotation\n" + " deprecation + deprecation outside deprecated code\n" + " emptyBlock undocumented empty block\n" + " enumSwitch incomplete enum switch\n" + " fieldHiding field hiding another variable\n" + " finalBound type parameter with final bound\n" + " finally + finally block not completing normally\n" + " indirectStatic indirect reference to static member\n" + " intfAnnotation + annotation type used as super interface\n" + " intfNonInherited + interface non-inherited method compatibility\n" + " javadoc invalid javadoc\n" + " localHiding local variable hiding another variable\n" + " maskedCatchBlock + hidden catch block\n" + " nls string literal lacking non-nls tag //$NON-NLS-$\n" + " noEffectAssign + assignment without effect\n" + " null missing or redundant null check\n" + " over-ann missing @Override annotation\n" + " pkgDefaultMethod + attempt to override package-default method\n" + " semicolon unnecessary semicolon, empty statement\n" + " serial + missing serialVersionUID\n" + " suppress + enable @SuppressWarnings\n" + " unqualifiedField unqualified reference to field\n" + " unchecked + unchecked type operation\n" + " unusedArgument unread method parameter\n" + " unusedImport + unused import declaration\n" + " unusedLocal unread local variable\n" + " unusedPrivate unused private member declaration\n" + " unusedThrown unused declared thrown exception\n" + " unnecessaryElse unnecessary else clause\n" + " uselessTypeCheck unnecessary cast/instanceof operation\n" + " specialParamHiding constructor or setter parameter hiding another field\n" + " staticReceiver + non-static reference to static member\n" + " syntheticAccess synthetic access for innerclass\n" + " tasks() tasks identified by tags inside comments\n" + " typeHiding + type parameter hiding another type\n" + " varargsCast + varargs argument need explicit cast\n" + " warningToken + unhandled warning token in @SuppressWarnings\n" + " \n" + " Debug options:\n" + " -g[:lines,vars,source] custom debug info\n" + " -g:lines,source + both lines table and source debug info\n" + " -g all debug info\n" + " -g:none no debug info\n" + " -preserveAllLocals preserve unused local vars for debug purpose\n" + " \n" + " Ignored options:\n" + " -J