Copyright (c) 2000, 2019 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Tom Tromey - Contribution for bug 125961 Tom Tromey - Contribution for bug 159641 Benjamin Muskalla - Contribution for bug 239066 Stephan Herrmann - Contributions for bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used bug 295551 - Add option to automatically promote all warnings to errors bug 359721 - [options] add command line option for new warning token "resource" bug 365208 - [compiler][batch] command line options for annotation based null analysis bug 374605 - Unreasonable warning for enum-based switch statements bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set bug 388281 - [compiler][null] inheritance of null annotations as an option bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated Bug 440477 - [null] Infrastructure for feeding external annotations into compilation Bug 440687 - [compiler][batch][null] improve command line option for external annotations Bug 408815 - [batch][null] Add CLI option for COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS Jesper S Moller - Contributions for bug 407297 - [1.8][compiler] Control generation of parameter names by option Mat Booth - Contribution for bug 405176 Frits Jalvingh - fix for bug 533830.
/******************************************************************************* * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Tom Tromey - Contribution for bug 125961 * Tom Tromey - Contribution for bug 159641 * Benjamin Muskalla - Contribution for bug 239066 * Stephan Herrmann - Contributions for * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used * bug 295551 - Add option to automatically promote all warnings to errors * bug 359721 - [options] add command line option for new warning token "resource" * bug 365208 - [compiler][batch] command line options for annotation based null analysis * bug 374605 - Unreasonable warning for enum-based switch statements * bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set * bug 388281 - [compiler][null] inheritance of null annotations as an option * bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated * Bug 440477 - [null] Infrastructure for feeding external annotations into compilation * Bug 440687 - [compiler][batch][null] improve command line option for external annotations * Bug 408815 - [batch][null] Add CLI option for COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS * Jesper S Moller - Contributions for * bug 407297 - [1.8][compiler] Control generation of parameter names by option * Mat Booth - Contribution for bug 405176 * Frits Jalvingh - fix for bug 533830. *******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Path; import java.nio.file.Paths; import java.text.DateFormat; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.CompilationProgress; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.compiler.batch.BatchCompiler; import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.Compiler; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.jdt.internal.compiler.IProblemFactory; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; import org.eclipse.jdt.internal.compiler.batch.ModuleFinder.AddExport; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; import org.eclipse.jdt.internal.compiler.env.AccessRule; import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.env.IModule; import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport; import org.eclipse.jdt.internal.compiler.env.IUpdatableModule.UpdateKind; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.CompilerStats; import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding; import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.parser.Parser; import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter; import org.eclipse.jdt.internal.compiler.util.HashtableOfInt; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.Messages; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.compiler.util.Util; public class Main implements ProblemSeverities, SuffixConstants { public static class Logger { private PrintWriter err; private PrintWriter log; private Main main; private PrintWriter out; private HashMap<String, Object> parameters; int tagBits; private static final String CLASS = "class"; //$NON-NLS-1$ private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$ private static final String CLASSPATH = "classpath"; //$NON-NLS-1$ private static final String CLASSPATH_FILE = "FILE"; //$NON-NLS-1$ private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$ private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$ private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$ private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$ private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$ private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$ private static final String COMPILER = "compiler"; //$NON-NLS-1$ private static final String COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$ private static final String COMPILER_NAME = "name"; //$NON-NLS-1$ private static final String COMPILER_VERSION = "version"; //$NON-NLS-1$ public static final int EMACS = 2; private static final String ERROR = "ERROR"; //$NON-NLS-1$ private static final String ERROR_TAG = "error"; //$NON-NLS-1$ private static final String WARNING_TAG = "warning"; //$NON-NLS-1$ private static final String EXCEPTION = "exception"; //$NON-NLS-1$ private static final String EXTRA_PROBLEM_TAG = "extra_problem"; //$NON-NLS-1$ private static final String EXTRA_PROBLEMS = "extra_problems"; //$NON-NLS-1$ private static final HashtableOfInt FIELD_TABLE = new HashtableOfInt(); private static final String KEY = "key"; //$NON-NLS-1$ private static final String MESSAGE = "message"; //$NON-NLS-1$ private static final String NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$ private static final String NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$ private static final String NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$ private static final String NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$ private static final String NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$ private static final String NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$ private static final String NUMBER_OF_INFOS = "infos"; //$NON-NLS-1$ private static final String OPTION = "option"; //$NON-NLS-1$ private static final String OPTIONS = "options"; //$NON-NLS-1$ private static final String OUTPUT = "output"; //$NON-NLS-1$ private static final String PACKAGE = "package"; //$NON-NLS-1$ private static final String PATH = "path"; //$NON-NLS-1$ private static final String PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$ private static final String PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$ private static final String PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$ private static final String PROBLEM_CATEGORY_ID = "categoryID"; //$NON-NLS-1$ private static final String ID = "id"; //$NON-NLS-1$ private static final String PROBLEM_ID = "problemID"; //$NON-NLS-1$ private static final String PROBLEM_LINE = "line"; //$NON-NLS-1$ private static final String PROBLEM_OPTION_KEY = "optionKey"; //$NON-NLS-1$ private static final String PROBLEM_MESSAGE = "message"; //$NON-NLS-1$ private static final String PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$ private static final String PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$ private static final String PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$ private static final String PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$ private static final String PROBLEM_TAG = "problem"; //$NON-NLS-1$ private static final String PROBLEMS = "problems"; //$NON-NLS-1$ private static final String SOURCE = "source"; //$NON-NLS-1$ private static final String SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$ private static final String SOURCE_END = "sourceEnd"; //$NON-NLS-1$ private static final String SOURCE_START = "sourceStart"; //$NON-NLS-1$ private static final String SOURCES = "sources"; //$NON-NLS-1$ private static final String STATS = "stats"; //$NON-NLS-1$ private static final String TASK = "task"; //$NON-NLS-1$ private static final String TASKS = "tasks"; //$NON-NLS-1$ private static final String TIME = "time"; //$NON-NLS-1$ private static final String VALUE = "value"; //$NON-NLS-1$ private static final String WARNING = "WARNING"; //$NON-NLS-1$ private static final String INFO = "INFO"; //$NON-NLS-1$ public static final int XML = 1; private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.006 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_006.dtd\">"; //$NON-NLS-1$ static { try { Class<?> c = IProblem.class; Field[] fields = c.getFields(); for (int i = 0, max = fields.length; i < max; i++) { Field field = fields[i]; if (field.getType().equals(Integer.TYPE)) { Integer value = (Integer) field.get(null); int key2 = value.intValue() & IProblem.IgnoreCategoriesMask; if (key2 == 0) { key2 = Integer.MAX_VALUE; } Logger.FIELD_TABLE.put(key2, field.getName()); } } } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } } public Logger(Main main, PrintWriter out, PrintWriter err) { this.out = out; this.err = err; this.parameters = new HashMap<>(); this.main = main; } public String buildFileName( String outputPath, String relativeFileName) { char fileSeparatorChar = File.separatorChar; String fileSeparator = File.separator; outputPath = outputPath.replace('/', fileSeparatorChar); // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name StringBuffer outDir = new StringBuffer(outputPath); if (!outputPath.endsWith(fileSeparator)) { outDir.append(fileSeparator); } StringTokenizer tokenizer = new StringTokenizer(relativeFileName, fileSeparator); String token = tokenizer.nextToken(); while (tokenizer.hasMoreTokens()) { outDir.append(token).append(fileSeparator); token = tokenizer.nextToken(); } // token contains the last one return outDir.append(token).toString(); } public void close() { if (this.log != null) { if ((this.tagBits & Logger.XML) != 0) { endTag(Logger.COMPILER); flush(); } this.log.close(); } } /** * */ public void compiling() { printlnOut(this.main.bind("progress.compiling")); //$NON-NLS-1$ } private void endLoggingExtraProblems() { endTag(Logger.EXTRA_PROBLEMS); }
Used to stop logging problems. Only use in xml mode.
/** * Used to stop logging problems. * Only use in xml mode. */
private void endLoggingProblems() { endTag(Logger.PROBLEMS); } public void endLoggingSource() { if ((this.tagBits & Logger.XML) != 0) { endTag(Logger.SOURCE); } } public void endLoggingSources() { if ((this.tagBits & Logger.XML) != 0) { endTag(Logger.SOURCES); } } public void endLoggingTasks() { if ((this.tagBits & Logger.XML) != 0) { endTag(Logger.TASKS); } } private void endTag(String name) { if (this.log != null) { ((GenericXMLWriter) this.log).endTag(name, true, true); } } private String errorReportSource(CategorizedProblem problem, char[] unitSource, int bits) { //extra from the source the innacurate token //and "highlight" it using some underneath ^^^^^ //put some context around too. //this code assumes that the font used in the console is fixed size //sanity ..... int startPosition = problem.getSourceStart(); int endPosition = problem.getSourceEnd(); if (unitSource == null) { if (problem.getOriginatingFileName() != null) { try { unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null); } catch (IOException e) { // ignore; } } } int length; if ((startPosition > endPosition) || ((startPosition < 0) && (endPosition < 0)) || (unitSource == null) || (length = unitSource.length) == 0) return Messages.problem_noSourceInformation; StringBuffer errorBuffer = new StringBuffer(); if ((bits & Main.Logger.EMACS) == 0) { errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(problem.getSourceLineNumber()))); errorBuffer.append(Util.LINE_SEPARATOR); } errorBuffer.append('\t'); char c; final char SPACE = '\u0020'; final char MARK = '^'; final char TAB = '\t'; //the next code tries to underline the token..... //it assumes (for a good display) that token source does not //contain any \r \n. This is false on statements ! //(the code still works but the display is not optimal !) // expand to line limits int begin; int end; for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) { if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break; } for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) { if ((c = unitSource[end + 1]) == '\r' || c == '\n') break; } // trim left and right spaces/tabs while ((c = unitSource[begin]) == ' ' || c == '\t') begin++; //while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated // copy source errorBuffer.append(unitSource, begin, end-begin+1); errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$ // compute underline for (int i = begin; i <startPosition; i++) { errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE); } for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) { errorBuffer.append(MARK); } return errorBuffer.toString(); } private void extractContext(CategorizedProblem problem, char[] unitSource) { //sanity ..... int startPosition = problem.getSourceStart(); int endPosition = problem.getSourceEnd(); if (unitSource == null) { if (problem.getOriginatingFileName() != null) { try { unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null); } catch(IOException e) { // ignore } } } int length; if ((startPosition > endPosition) || ((startPosition < 0) && (endPosition < 0)) || (unitSource == null) || ((length = unitSource.length) <= 0) || (endPosition > length)) { this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation); this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$ this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$ printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true); return; } char c; //the next code tries to underline the token..... //it assumes (for a good display) that token source does not //contain any \r \n. This is false on statements ! //(the code still works but the display is not optimal !) // expand to line limits int begin, end; for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) { if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break; } for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) { if ((c = unitSource[end + 1]) == '\r' || c == '\n') break; } // trim left and right spaces/tabs while ((c = unitSource[begin]) == ' ' || c == '\t') begin++; while ((c = unitSource[end]) == ' ' || c == '\t') end--; // copy source StringBuffer buffer = new StringBuffer(); buffer.append(unitSource, begin, end - begin + 1); this.parameters.put(Logger.VALUE, String.valueOf(buffer)); this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin)); this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin)); printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true); } public void flush() { this.out.flush(); this.err.flush(); if (this.log != null) { this.log.flush(); } } private String getFieldName(int id) { int key2 = id & IProblem.IgnoreCategoriesMask; if (key2 == 0) { key2 = Integer.MAX_VALUE; } return (String) Logger.FIELD_TABLE.get(key2); } // find out an option name controlling a given problemID private String getProblemOptionKey(int problemID) { int irritant = ProblemReporter.getIrritant(problemID); return CompilerOptions.optionKeyFromIrritant(irritant); } public void logAverage() { Arrays.sort(this.main.compilerStats); long lineCount = this.main.compilerStats[0].lineCount; final int length = this.main.maxRepetition; long sum = 0; long parseSum = 0, resolveSum = 0, analyzeSum = 0, generateSum = 0; for (int i = 1, max = length - 1; i < max; i++) { CompilerStats stats = this.main.compilerStats[i]; sum += stats.elapsedTime(); parseSum += stats.parseTime; resolveSum += stats.resolveTime; analyzeSum += stats.analyzeTime; generateSum += stats.generateTime; } long time = sum / (length - 2); long parseTime = parseSum/(length - 2); long resolveTime = resolveSum/(length - 2); long analyzeTime = analyzeSum/(length - 2); long generateTime = generateSum/(length - 2); printlnOut(this.main.bind( "compile.averageTime", //$NON-NLS-1$ new String[] { String.valueOf(lineCount), String.valueOf(time), String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0), })); if ((this.main.timing & Main.TIMING_DETAILED) != 0) { printlnOut( this.main.bind("compile.detailedTime", //$NON-NLS-1$ new String[] { String.valueOf(parseTime), String.valueOf(((int) (parseTime * 1000.0 / time)) / 10.0), String.valueOf(resolveTime), String.valueOf(((int) (resolveTime * 1000.0 / time)) / 10.0), String.valueOf(analyzeTime), String.valueOf(((int) (analyzeTime * 1000.0 / time)) / 10.0), String.valueOf(generateTime), String.valueOf(((int) (generateTime * 1000.0 / time)) / 10.0), })); } } public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) { if ((this.tagBits & Logger.XML) != 0) { String fileName = null; if (generatePackagesStructure) { fileName = buildFileName(outputPath, relativeFileName); } else { char fileSeparatorChar = File.separatorChar; String fileSeparator = File.separator; // First we ensure that the outputPath exists outputPath = outputPath.replace('/', fileSeparatorChar); // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar); if (indexOfPackageSeparator == -1) { if (outputPath.endsWith(fileSeparator)) { fileName = outputPath + relativeFileName; } else { fileName = outputPath + fileSeparator + relativeFileName; } } else { int length = relativeFileName.length(); if (outputPath.endsWith(fileSeparator)) { fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length); } else { fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length); } } } File f = new File(fileName); try { this.parameters.put(Logger.PATH, f.getCanonicalPath()); printTag(Logger.CLASS_FILE, this.parameters, true, true); } catch (IOException e) { logNoClassFileCreated(outputPath, relativeFileName, e); } } } public void logClasspath(FileSystem.Classpath[] classpaths) { if (classpaths == null) return; if ((this.tagBits & Logger.XML) != 0) { final int length = classpaths.length; if (length != 0) { // generate xml output printTag(Logger.CLASSPATHS, null, true, false); for (int i = 0; i < length; i++) { String classpath = classpaths[i].getPath(); this.parameters.put(Logger.PATH, classpath); File f = new File(classpath); String id = null; if (f.isFile()) { int kind = Util.archiveFormat(classpath); switch (kind) { case Util.ZIP_FILE: id = Logger.CLASSPATH_JAR; break; default: id = Logger.CLASSPATH_FILE; break; } } else if (f.isDirectory()) { id = Logger.CLASSPATH_FOLDER; } if (id != null) { this.parameters.put(Logger.CLASSPATH_ID, id); printTag(Logger.CLASSPATH, this.parameters, true, true); } } endTag(Logger.CLASSPATHS); } } } public void logCommandLineArguments(String[] commandLineArguments) { if (commandLineArguments == null) return; if ((this.tagBits & Logger.XML) != 0) { final int length = commandLineArguments.length; if (length != 0) { // generate xml output printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false); for (int i = 0; i < length; i++) { this.parameters.put(Logger.VALUE, commandLineArguments[i]); printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true); } endTag(Logger.COMMAND_LINE_ARGUMENTS); } } }
Params:
  • e – the given exception to log
/** * @param e the given exception to log */
public void logException(Exception e) { StringWriter writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); e.printStackTrace(printWriter); printWriter.flush(); printWriter.close(); final String stackTrace = writer.toString(); if ((this.tagBits & Logger.XML) != 0) { LineNumberReader reader = new LineNumberReader(new StringReader(stackTrace)); String line; int i = 0; StringBuffer buffer = new StringBuffer(); String message = e.getMessage(); if (message != null) { buffer.append(message).append(Util.LINE_SEPARATOR); } try { while ((line = reader.readLine()) != null && i < 4) { buffer.append(line).append(Util.LINE_SEPARATOR); i++; } reader.close(); } catch (IOException e1) { // ignore } message = buffer.toString(); this.parameters.put(Logger.MESSAGE, message); this.parameters.put(Logger.CLASS, e.getClass()); printTag(Logger.EXCEPTION, this.parameters, true, true); } String message = e.getMessage(); if (message == null) { this.printlnErr(stackTrace); } else { this.printlnErr(message); } } private void logExtraProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount) { char[] originatingFileName = problem.getOriginatingFileName(); if (originatingFileName == null) { // simplified message output String severity = problem.isError() ? "requestor.extraerror" //$NON-NLS-1$ : problem.isInfo() ? "requestor.extrainfo" : "requestor.extrawarning"; //$NON-NLS-1$ //$NON-NLS-2$ printErr(this.main.bind( severity, Integer.toString(globalErrorCount))); printErr(" "); //$NON-NLS-1$ this.printlnErr(problem.getMessage()); } else { String fileName = new String(originatingFileName); if ((this.tagBits & Logger.EMACS) != 0) { String severity = problem.isError() ? "output.emacs.error" : //$NON-NLS-1$ problem.isInfo() ? "output.emacs.info" //$NON-NLS-1$ : "output.emacs.warning"; //$NON-NLS-1$ String result = fileName + ":" //$NON-NLS-1$ + problem.getSourceLineNumber() + ": " //$NON-NLS-1$ + this.main.bind(severity) + ": " //$NON-NLS-1$ + problem.getMessage(); this.printlnErr(result); final String errorReportSource = errorReportSource(problem, null, this.tagBits); this.printlnErr(errorReportSource); } else { if (localErrorCount == 0) { this.printlnErr("----------"); //$NON-NLS-1$ } String severity = problem.isError() ? "requestor.error" //$NON-NLS-1$ : problem.isInfo() ? "requestor.info" : "requestor.warning"; //$NON-NLS-1$ //$NON-NLS-2$ printErr(this.main.bind( severity, Integer.toString(globalErrorCount), fileName)); final String errorReportSource = errorReportSource(problem, null, 0); this.printlnErr(errorReportSource); this.printlnErr(problem.getMessage()); this.printlnErr("----------"); //$NON-NLS-1$ } } } public void loggingExtraProblems(Main currentMain) { ArrayList<CategorizedProblem> problems = currentMain.extraProblems; final int count = problems.size(); int localProblemCount = 0; if (count != 0) { int errors = 0; int warnings = 0; int infos = 0; for (int i = 0; i < count; i++) { CategorizedProblem problem = problems.get(i); if (problem != null) { currentMain.globalProblemsCount++; logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount); localProblemCount++; if (problem.isError()) { errors++; currentMain.globalErrorsCount++; } else if (problem.isInfo()) { currentMain.globalInfoCount++; infos++; } else { currentMain.globalWarningsCount++; warnings++; } } } if ((this.tagBits & Logger.XML) != 0) { if ((errors + warnings + infos) != 0) { startLoggingExtraProblems(count); for (int i = 0; i < count; i++) { CategorizedProblem problem = problems.get(i); if (problem!= null) { if (problem.getID() != IProblem.Task) { logXmlExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount); } } } endLoggingExtraProblems(); } } } } public void logUnavaibleAPT(String className) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$ printTag(Logger.ERROR_TAG, this.parameters, true, true); } this.printlnErr(this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$ } public void logIncorrectVMVersionForAnnotationProcessing() { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$ printTag(Logger.ERROR_TAG, this.parameters, true, true); } this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$ } /** * */ public void logNoClassFileCreated(String outputDir, String relativeFileName, IOException e) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$ new String[] { outputDir, relativeFileName, e.getMessage() })); printTag(Logger.ERROR_TAG, this.parameters, true, true); } this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$ new String[] { outputDir, relativeFileName, e.getMessage() })); }
Params:
  • exportedClassFilesCounter –
/** * @param exportedClassFilesCounter */
public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.VALUE, Integer.valueOf(exportedClassFilesCounter)); printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true); } if (exportedClassFilesCounter == 1) { printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$ } else { printlnOut(this.main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$ String.valueOf(exportedClassFilesCounter))); } }
Params:
  • options – the given compiler options
/** * @param options the given compiler options */
public void logOptions(Map<String, String> options) { if ((this.tagBits & Logger.XML) != 0) { printTag(Logger.OPTIONS, null, true, false); final Set<Map.Entry<String, String>> entriesSet = options.entrySet(); Map.Entry<String, String>[] entries = entriesSet.toArray(new Map.Entry[entriesSet.size()]); Arrays.sort(entries, new Comparator<Map.Entry<String, String>>() { @Override public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { Map.Entry<String, String> entry1 = o1; Map.Entry<String, String> entry2 = o2; return entry1.getKey().compareTo(entry2.getKey()); } }); for (int i = 0, max = entries.length; i < max; i++) { Map.Entry<String, String> entry = entries[i]; String key = entry.getKey(); this.parameters.put(Logger.KEY, key); this.parameters.put(Logger.VALUE, entry.getValue()); printTag(Logger.OPTION, this.parameters, true, true); } endTag(Logger.OPTIONS); } }
Params:
  • error – the given error
/** * @param error the given error */
public void logPendingError(String error) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, error); printTag(Logger.ERROR_TAG, this.parameters, true, true); } this.printlnErr(error); }
Params:
  • message – the given message
/** * @param message the given message */
public void logWarning(String message) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, message); printTag(Logger.WARNING_TAG, this.parameters, true, true); } this.printlnOut(message); } private void logProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount, char[] unitSource) { if(problem instanceof DefaultProblem) { ((DefaultProblem) problem).reportError(); } if ((this.tagBits & Logger.EMACS) != 0) { String severity = problem.isError() ? "output.emacs.error" : //$NON-NLS-1$ problem.isInfo() ? "output.emacs.info" //$NON-NLS-1$ : "output.emacs.warning"; //$NON-NLS-1$ String result = (new String(problem.getOriginatingFileName()) + ":" //$NON-NLS-1$ + problem.getSourceLineNumber() + ": " //$NON-NLS-1$ + (this.main.bind(severity)) + ": " //$NON-NLS-1$ + problem.getMessage()); this.printlnErr(result); final String errorReportSource = errorReportSource(problem, unitSource, this.tagBits); if (errorReportSource.length() != 0) this.printlnErr(errorReportSource); } else { if (localErrorCount == 0) { this.printlnErr("----------"); //$NON-NLS-1$ } String severity = problem.isError() ? "requestor.error" : problem.isInfo() ? "requestor.info" : "requestor.warning"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ printErr(this.main.bind(severity, Integer.toString(globalErrorCount), new String(problem.getOriginatingFileName()))); try { final String errorReportSource = errorReportSource(problem, unitSource, 0); this.printlnErr(errorReportSource); this.printlnErr(problem.getMessage()); } catch (Exception e) { this.printlnErr(this.main.bind( "requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$ } this.printlnErr("----------"); //$NON-NLS-1$ } } public int logProblems(CategorizedProblem[] problems, char[] unitSource, Main currentMain) { final int count = problems.length; int localErrorCount = 0; int localProblemCount = 0; if (count != 0) { int errors = 0; int warnings = 0; int infos = 0; int tasks = 0; for (int i = 0; i < count; i++) { CategorizedProblem problem = problems[i]; if (problem != null) { currentMain.globalProblemsCount++; logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource); localProblemCount++; if (problem.isError()) { localErrorCount++; errors++; currentMain.globalErrorsCount++; } else if (problem.getID() == IProblem.Task) { currentMain.globalTasksCount++; tasks++; } else if (problem.isInfo()) { currentMain.globalInfoCount++; infos++; } else { currentMain.globalWarningsCount++; warnings++; } } } if ((this.tagBits & Logger.XML) != 0) { if ((errors + warnings + infos) != 0) { startLoggingProblems(errors, warnings, infos); for (int i = 0; i < count; i++) { CategorizedProblem problem = problems[i]; if (problem!= null) { if (problem.getID() != IProblem.Task) { logXmlProblem(problem, unitSource); } } } endLoggingProblems(); } if (tasks != 0) { startLoggingTasks(tasks); for (int i = 0; i < count; i++) { CategorizedProblem problem = problems[i]; if (problem!= null) { if (problem.getID() == IProblem.Task) { logXmlTask(problem, unitSource); } } } endLoggingTasks(); } } } return localErrorCount; }
Params:
  • globalProblemsCount –
  • globalErrorsCount –
  • globalWarningsCount –
/** * @param globalProblemsCount * @param globalErrorsCount * @param globalWarningsCount */
public void logProblemsSummary(int globalProblemsCount, int globalErrorsCount, int globalWarningsCount, int globalInfoCount, int globalTasksCount) { if ((this.tagBits & Logger.XML) != 0) { // generate xml this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(globalProblemsCount)); this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(globalErrorsCount)); this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(globalWarningsCount)); this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(globalInfoCount)); this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(globalTasksCount)); printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true); } if (globalProblemsCount == 1) { String message = null; if (globalErrorsCount == 1) { message = this.main.bind("compile.oneError"); //$NON-NLS-1$ } else if (globalInfoCount == 1) { message = this.main.bind("compile.oneInfo"); //$NON-NLS-1$ } else { message = this.main.bind("compile.oneWarning"); //$NON-NLS-1$ } printErr(this.main.bind("compile.oneProblem", message)); //$NON-NLS-1$ } else { String errorMessage = null; String warningMessage = null; String infoMessage = null; if (globalErrorsCount > 0) { if (globalErrorsCount == 1) { errorMessage = this.main.bind("compile.oneError"); //$NON-NLS-1$ } else { errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$ } } int warningsNumber = globalWarningsCount + globalTasksCount; if (warningsNumber > 0) { if (warningsNumber == 1) { warningMessage = this.main.bind("compile.oneWarning"); //$NON-NLS-1$ } else { warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$ } } if (globalInfoCount == 1) { infoMessage = this.main.bind("compile.oneInfo"); //$NON-NLS-1$ } else if (globalInfoCount > 1) { infoMessage = this.main.bind("compile.severalInfos", String.valueOf(warningsNumber)); //$NON-NLS-1$ } if (globalProblemsCount == globalInfoCount || globalProblemsCount == globalErrorsCount || globalProblemsCount == globalWarningsCount) { String msg = errorMessage != null ? errorMessage : warningMessage != null ? warningMessage : infoMessage; printErr(this.main.bind( "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$ String.valueOf(globalProblemsCount), msg)); } else { if (globalInfoCount == 0) { printErr(this.main.bind( "compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$ new String[] { String.valueOf(globalProblemsCount), errorMessage, warningMessage })); } else { if (errorMessage == null) { errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$ } if (warningMessage == null) { warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$ } printErr(this.main.bind( "compile.severalProblems", //$NON-NLS-1$ new String[] { String.valueOf(globalProblemsCount), errorMessage, warningMessage, infoMessage })); } } } if (this.main.failOnWarning && globalWarningsCount > 0) { printErr("\n"); //$NON-NLS-1$ printErr(this.main.bind("compile.failOnWarning")); //$NON-NLS-1$ } if ((this.tagBits & Logger.XML) == 0) { this.printlnErr(); } } /** * */ public void logProgress() { printOut('.'); }
Params:
  • i – the current repetition number
  • repetitions – the given number of repetitions
/** * @param i * the current repetition number * @param repetitions * the given number of repetitions */
public void logRepetition(int i, int repetitions) { printlnOut(this.main.bind("compile.repetition", //$NON-NLS-1$ String.valueOf(i + 1), String.valueOf(repetitions))); }
Params:
  • compilerStats –
/** * @param compilerStats */
public void logTiming(CompilerStats compilerStats) { long time = compilerStats.elapsedTime(); long lineCount = compilerStats.lineCount; if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.VALUE, Long.valueOf(time)); printTag(Logger.TIME, this.parameters, true, true); this.parameters.put(Logger.VALUE, Long.valueOf(lineCount)); printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true); } if (lineCount != 0) { printlnOut( this.main.bind("compile.instantTime", //$NON-NLS-1$ new String[] { String.valueOf(lineCount), String.valueOf(time), String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0), })); } else { printlnOut( this.main.bind("compile.totalTime", //$NON-NLS-1$ new String[] { String.valueOf(time), })); } if ((this.main.timing & Main.TIMING_DETAILED) != 0) { printlnOut( this.main.bind("compile.detailedTime", //$NON-NLS-1$ new String[] { String.valueOf(compilerStats.parseTime), String.valueOf(((int) (compilerStats.parseTime * 1000.0 / time)) / 10.0), String.valueOf(compilerStats.resolveTime), String.valueOf(((int) (compilerStats.resolveTime * 1000.0 / time)) / 10.0), String.valueOf(compilerStats.analyzeTime), String.valueOf(((int) (compilerStats.analyzeTime * 1000.0 / time)) / 10.0), String.valueOf(compilerStats.generateTime), String.valueOf(((int) (compilerStats.generateTime * 1000.0 / time)) / 10.0), })); } }
Print the usage of the compiler
Params:
  • usage –
/** * Print the usage of the compiler * @param usage */
public void logUsage(String usage) { printlnOut(usage); }
Print the version of the compiler in the log and/or the out field
/** * Print the version of the compiler in the log and/or the out field */
public void logVersion(final boolean printToOut) { if (this.log != null && (this.tagBits & Logger.XML) == 0) { final String version = this.main.bind("misc.version", //$NON-NLS-1$ new String[] { this.main.bind("compiler.name"), //$NON-NLS-1$ this.main.bind("compiler.version"), //$NON-NLS-1$ this.main.bind("compiler.copyright") //$NON-NLS-1$ } ); this.log.println("# " + version); //$NON-NLS-1$ if (printToOut) { this.out.println(version); this.out.flush(); } } else if (printToOut) { final String version = this.main.bind("misc.version", //$NON-NLS-1$ new String[] { this.main.bind("compiler.name"), //$NON-NLS-1$ this.main.bind("compiler.version"), //$NON-NLS-1$ this.main.bind("compiler.copyright") //$NON-NLS-1$ } ); this.out.println(version); this.out.flush(); } }
Print the usage of wrong JDK
/** * Print the usage of wrong JDK */
public void logWrongJDK() { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$ printTag(Logger.ERROR, this.parameters, true, true); } this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$ } private void logXmlExtraProblem(CategorizedProblem problem, int globalErrorCount, int localErrorCount) { final int sourceStart = problem.getSourceStart(); final int sourceEnd = problem.getSourceEnd(); boolean isError = problem.isError(); this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING)); this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber())); this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart)); this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd)); printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false); this.parameters.put(Logger.VALUE, problem.getMessage()); printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true); extractContext(problem, null); endTag(Logger.EXTRA_PROBLEM_TAG); }
Params:
  • problem – the given problem to log
  • unitSource – the given unit source
/** * @param problem * the given problem to log * @param unitSource * the given unit source */
private void logXmlProblem(CategorizedProblem problem, char[] unitSource) { final int sourceStart = problem.getSourceStart(); final int sourceEnd = problem.getSourceEnd(); final int id = problem.getID(); this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name this.parameters.put(Logger.PROBLEM_ID, Integer.valueOf(id)); // ID as numeric value boolean isError = problem.isError(); int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning; this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING)); this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber())); this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart)); this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd)); String problemOptionKey = getProblemOptionKey(id); if (problemOptionKey != null) { this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey); } int categoryID = ProblemReporter.getProblemCategory(severity, id); this.parameters.put(Logger.PROBLEM_CATEGORY_ID, Integer.valueOf(categoryID)); printTag(Logger.PROBLEM_TAG, this.parameters, true, false); this.parameters.put(Logger.VALUE, problem.getMessage()); printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true); extractContext(problem, unitSource); String[] arguments = problem.getArguments(); final int length = arguments.length; if (length != 0) { printTag(Logger.PROBLEM_ARGUMENTS, null, true, false); for (int i = 0; i < length; i++) { this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]); printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true); } endTag(Logger.PROBLEM_ARGUMENTS); } endTag(Logger.PROBLEM_TAG); }
Params:
  • problem – the given problem to log
  • unitSource – the given unit source
/** * @param problem * the given problem to log * @param unitSource * the given unit source */
private void logXmlTask(CategorizedProblem problem, char[] unitSource) { this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber())); this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(problem.getSourceStart())); this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(problem.getSourceEnd())); String problemOptionKey = getProblemOptionKey(problem.getID()); if (problemOptionKey != null) { this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey); } printTag(Logger.TASK, this.parameters, true, false); this.parameters.put(Logger.VALUE, problem.getMessage()); printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true); extractContext(problem, unitSource); endTag(Logger.TASK); } private void printErr(String s) { this.err.print(s); if ((this.tagBits & Logger.XML) == 0 && this.log != null) { this.log.print(s); } } private void printlnErr() { this.err.println(); if ((this.tagBits & Logger.XML) == 0 && this.log != null) { this.log.println(); } } private void printlnErr(String s) { this.err.println(s); if ((this.tagBits & Logger.XML) == 0 && this.log != null) { this.log.println(s); } } private void printlnOut(String s) { this.out.println(s); if ((this.tagBits & Logger.XML) == 0 && this.log != null) { this.log.println(s); } } /** * */ public void printNewLine() { this.out.println(); } private void printOut(char c) { this.out.print(c); } public void printStats() { final boolean isTimed = (this.main.timing & TIMING_ENABLED) != 0; if ((this.tagBits & Logger.XML) != 0) { printTag(Logger.STATS, null, true, false); } if (isTimed) { CompilerStats compilerStats = this.main.batchCompiler.stats; compilerStats.startTime = this.main.startTime; // also include batch initialization times compilerStats.endTime = System.currentTimeMillis(); // also include batch output times logTiming(compilerStats); } if (this.main.globalProblemsCount > 0) { logProblemsSummary(this.main.globalProblemsCount, this.main.globalErrorsCount, this.main.globalWarningsCount, this.main.globalInfoCount, this.main.globalTasksCount); } if (this.main.exportedClassFilesCounter != 0 && (this.main.showProgress || isTimed || this.main.verbose)) { logNumberOfClassFilesGenerated(this.main.exportedClassFilesCounter); } if ((this.tagBits & Logger.XML) != 0) { endTag(Logger.STATS); } } private void printTag(String name, HashMap<String, Object> params, boolean insertNewLine, boolean closeTag) { if (this.log != null) { ((GenericXMLWriter) this.log).printTag(name, this.parameters, true, insertNewLine, closeTag); } this.parameters.clear(); } public void setEmacs() { this.tagBits |= Logger.EMACS; } public void setLog(String logFileName) { final Date date = new Date(); final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault()); try { int index = logFileName.lastIndexOf('.'); if (index != -1) { if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$ this.log = new GenericXMLWriter(new OutputStreamWriter(new FileOutputStream(logFileName, false), Util.UTF_8), Util.LINE_SEPARATOR, true); this.tagBits |= Logger.XML; // insert time stamp as comment this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$ this.log.println(Logger.XML_DTD_DECLARATION); this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$ this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$ this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$ printTag(Logger.COMPILER, this.parameters, true, false); } else { this.log = new PrintWriter(new FileOutputStream(logFileName, false)); this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$ } } else { this.log = new PrintWriter(new FileOutputStream(logFileName, false)); this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$ } } catch (FileNotFoundException e) { throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLog", logFileName), e); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLogInvalidEncoding", logFileName), e); //$NON-NLS-1$ } } private void startLoggingExtraProblems(int count) { this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(count)); printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false); }
Used to start logging problems. Only use in xml mode.
/** * Used to start logging problems. * Only use in xml mode. */
private void startLoggingProblems(int errors, int warnings, int infos) { this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(errors + warnings)); this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(errors)); this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(warnings)); this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(infos)); printTag(Logger.PROBLEMS, this.parameters, true, false); } public void startLoggingSource(CompilationResult compilationResult) { if ((this.tagBits & Logger.XML) != 0) { ICompilationUnit compilationUnit = compilationResult.compilationUnit; if (compilationUnit != null) { char[] fileName = compilationUnit.getFileName(); File f = new File(new String(fileName)); if (fileName != null) { this.parameters.put(Logger.PATH, f.getAbsolutePath()); } char[][] packageName = compilationResult.packageName; if (packageName != null) { this.parameters.put( Logger.PACKAGE, new String(CharOperation.concatWith(packageName, File.separatorChar))); } CompilationUnit unit = (CompilationUnit) compilationUnit; String destinationPath = unit.destinationPath; if (destinationPath == null) { destinationPath = this.main.destinationPath; } if (destinationPath != null && destinationPath != NONE) { if (File.separatorChar == '/') { this.parameters.put(Logger.OUTPUT, destinationPath); } else { this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar)); } } } printTag(Logger.SOURCE, this.parameters, true, false); } } public void startLoggingSources() { if ((this.tagBits & Logger.XML) != 0) { printTag(Logger.SOURCES, null, true, false); } } public void startLoggingTasks(int tasks) { if ((this.tagBits & Logger.XML) != 0) { this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(tasks)); printTag(Logger.TASKS, this.parameters, true, false); } } }
Resource bundle factory to share bundles for the same locale
/** * Resource bundle factory to share bundles for the same locale */
public static class ResourceBundleFactory { private static HashMap<Locale, ResourceBundle> Cache = new HashMap<>(); public static synchronized ResourceBundle getBundle(Locale locale) { ResourceBundle bundle = Cache.get(locale); if (bundle == null) { bundle = ResourceBundle.getBundle(Main.bundleName, locale); Cache.put(locale, bundle); } return bundle; } } // used with -annotationpath to declare that annotations should be read from the classpath: private static final String ANNOTATION_SOURCE_CLASSPATH = "CLASSPATH"; //$NON-NLS-1$ // javadoc analysis tuning boolean enableJavadocOn; boolean warnJavadocOn; boolean warnAllJavadocOn; public Compiler batchCompiler; /* Bundle containing messages */ public ResourceBundle bundle; protected FileSystem.Classpath[] checkedClasspaths; // For single module mode protected IModule module; private String moduleVersion; // paths to external annotations: protected List<String> annotationPaths; protected boolean annotationsFromClasspath; private List<String> addonExports = Collections.EMPTY_LIST; private List<String> addonReads = Collections.EMPTY_LIST; public Set<String> rootModules = Collections.EMPTY_SET; public Set<String> limitedModules; public Locale compilerLocale; public CompilerOptions compilerOptions; // read-only public CompilationProgress progress; public String destinationPath; public String[] destinationPaths; // destination path for compilation units that get no more specific // one (through directory arguments or various classpath options); // coding is: // == null: unspecified, write class files close to their respective // source files; // == Main.NONE: absorbent element, do not output class files; // else: use as the path of the directory into which class files must // be written. protected boolean enablePreview; protected String releaseVersion; private boolean didSpecifySource; private boolean didSpecifyTarget; public String[] encodings; public int exportedClassFilesCounter; public String[] filenames; public String[] modNames; public String[] classNames; // overrides of destinationPath on a directory argument basis public int globalErrorsCount; public int globalProblemsCount; public int globalTasksCount; public int globalWarningsCount; public int globalInfoCount; private File javaHomeCache; private boolean javaHomeChecked = false; private boolean primaryNullAnnotationsSeen = false; public long lineCount0; public String log; public Logger logger; public int maxProblems; public Map<String, String> options; protected long complianceLevel; public char[][] ignoreOptionalProblemsFromFolders; protected PrintWriter out; public boolean proceed = true; public boolean proceedOnError = false; public boolean failOnWarning = false; public boolean produceRefInfo = false; public int currentRepetition, maxRepetition; public boolean showProgress = false; public long startTime; public ArrayList<String> pendingErrors; public boolean systemExitWhenFinished = true; public static final int TIMING_DISABLED = 0; public static final int TIMING_ENABLED = 1; public static final int TIMING_DETAILED = 2; public int timing = TIMING_DISABLED; public CompilerStats[] compilerStats; public boolean verbose = false; private String[] expandedCommandLine; private PrintWriter err; protected ArrayList<CategorizedProblem> extraProblems; public final static String bundleName = "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$ // two uses: recognize 'none' in options; code the singleton none // for the '-d none' option (wherever it may be found) public static final int DEFAULT_SIZE_CLASSPATH = 4; public static final String NONE = "none"; //$NON-NLS-1$
Deprecated:- use BatchCompiler.compile(String, PrintWriter, PrintWriter, CompilationProgress) instead e.g. BatchCompiler.compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err), null);
/** * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead * e.g. BatchCompiler.compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err), null); */
public static boolean compile(String commandLine) { return new Main(new PrintWriter(System.out), new PrintWriter(System.err), false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine)); }
Deprecated:- use BatchCompiler.compile(String, PrintWriter, PrintWriter, CompilationProgress) instead e.g. BatchCompiler.compile(commandLine, outWriter, errWriter, null);
/** * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead * e.g. BatchCompiler.compile(commandLine, outWriter, errWriter, null); */
public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter) { return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine)); } /* * Internal API for public API BatchCompiler#compile(String[], PrintWriter, PrintWriter, CompilationProgress) */ public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) { return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, progress).compile(commandLineArguments); } public static File[][] getLibrariesFiles(File[] files) { FilenameFilter filter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return Util.archiveFormat(name) > -1; } }; final int filesLength = files.length; File[][] result = new File[filesLength][]; for (int i = 0; i < filesLength; i++) { File currentFile = files[i]; if (currentFile.exists() && currentFile.isDirectory()) { result[i] = currentFile.listFiles(filter); } } return result; } public static void main(String[] argv) { new Main(new PrintWriter(System.out), new PrintWriter(System.err), true/*systemExit*/, null/*options*/, null/*progress*/).compile(argv); } public static String[] tokenize(String commandLine) { int count = 0; String[] arguments = new String[10]; StringTokenizer tokenizer = new StringTokenizer(commandLine, " \"", true); //$NON-NLS-1$ String token = Util.EMPTY_STRING; boolean insideQuotes = false; boolean startNewToken = true; // take care to quotes on the command line // 'xxx "aaa bbb";ccc yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" } // 'xxx "aaa bbb;ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" } // 'xxx "aaa bbb";"ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" } // 'xxx/"aaa bbb";"ccc" yyy' ---> {"xxx/aaa bbb;ccc", "yyy" } while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); if (token.equals(" ")) { //$NON-NLS-1$ if (insideQuotes) { arguments[count - 1] += token; startNewToken = false; } else { startNewToken = true; } } else if (token.equals("\"")) { //$NON-NLS-1$ if (!insideQuotes && startNewToken) { if (count == arguments.length) System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count); arguments[count++] = Util.EMPTY_STRING; } insideQuotes = !insideQuotes; startNewToken = false; } else { if (insideQuotes) { arguments[count - 1] += token; } else { if (token.length() > 0 && !startNewToken) { arguments[count - 1] += token; } else { if (count == arguments.length) System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count); String trimmedToken = token.trim(); if (trimmedToken.length() != 0) { arguments[count++] = trimmedToken; } } } startNewToken = false; } } System.arraycopy(arguments, 0, arguments = new String[count], 0, count); return arguments; }
Deprecated:- use Main(PrintWriter, PrintWriter, boolean, Map<String,String>, CompilationProgress) instead e.g. Main(outWriter, errWriter, systemExitWhenFinished, null, null)
/** * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead * e.g. Main(outWriter, errWriter, systemExitWhenFinished, null, null) */
public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) { this(outWriter, errWriter, systemExitWhenFinished, null /* options */, null /* progress */); }
Deprecated:- use Main(PrintWriter, PrintWriter, boolean, Map<String,String>, CompilationProgress) instead e.g. Main(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null)
/** * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead * e.g. Main(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null) */
public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map<String, String> customDefaultOptions) { this(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null /* progress */); } public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map<String, String> customDefaultOptions, CompilationProgress compilationProgress) { this.initialize(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, compilationProgress); this.relocalize(); } public void addExtraProblems(CategorizedProblem problem) { if (this.extraProblems == null) { this.extraProblems = new ArrayList<>(); } this.extraProblems.add(problem); } protected void addNewEntry(ArrayList<FileSystem.Classpath> paths, String currentClasspathName, ArrayList<String> currentRuleSpecs, String customEncoding, String destPath, boolean isSourceOnly, boolean rejectDestinationPathOnJars) { int rulesSpecsSize = currentRuleSpecs.size(); AccessRuleSet accessRuleSet = null; if (rulesSpecsSize != 0) { AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()]; boolean rulesOK = true; Iterator<String> i = currentRuleSpecs.iterator(); int j = 0; while (i.hasNext()) { String ruleSpec = i.next(); char key = ruleSpec.charAt(0); String pattern = ruleSpec.substring(1); if (pattern.length() > 0) { switch (key) { case '+': accessRules[j++] = new AccessRule(pattern .toCharArray(), 0); break; case '~': accessRules[j++] = new AccessRule(pattern .toCharArray(), IProblem.DiscouragedReference); break; case '-': accessRules[j++] = new AccessRule(pattern .toCharArray(), IProblem.ForbiddenReference); break; case '?': accessRules[j++] = new AccessRule(pattern .toCharArray(), IProblem.ForbiddenReference, true/*keep looking for accessible type*/); break; default: rulesOK = false; } } else { rulesOK = false; } } if (rulesOK) { accessRuleSet = new AccessRuleSet(accessRules, AccessRestriction.COMMAND_LINE, currentClasspathName); } else { if (currentClasspathName.length() != 0) { // we go on anyway addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$ } return; } } if (NONE.equals(destPath)) { destPath = NONE; // keep == comparison valid } if (rejectDestinationPathOnJars && destPath != null && Util.archiveFormat(currentClasspathName) > -1) { throw new IllegalArgumentException( this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$ currentClasspathName)); } FileSystem.Classpath currentClasspath = FileSystem.getClasspath( currentClasspathName, customEncoding, isSourceOnly, accessRuleSet, destPath, this.options, this.releaseVersion); if (currentClasspath != null) { paths.add(currentClasspath); } else if (currentClasspathName.length() != 0) { // we go on anyway addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$ } } void addPendingErrors(String message) { if (this.pendingErrors == null) { this.pendingErrors = new ArrayList<>(); } this.pendingErrors.add(message); } /* * Lookup the message with the given ID in this catalog */ public String bind(String id) { return bind(id, (String[]) null); } /* * Lookup the message with the given ID in this catalog and bind its * substitution locations with the given string. */ public String bind(String id, String binding) { return bind(id, new String[] { binding }); } /* * Lookup the message with the given ID in this catalog and bind its * substitution locations with the given strings. */ public String bind(String id, String binding1, String binding2) { return bind(id, new String[] { binding1, binding2 }); } /* * Lookup the message with the given ID in this catalog and bind its * substitution locations with the given string values. */ public String bind(String id, String[] arguments) { if (id == null) return "No message available"; //$NON-NLS-1$ String message = null; try { message = this.bundle.getString(id); } catch (MissingResourceException e) { // If we got an exception looking for the message, fail gracefully by just returning // the id we were looking for. In most cases this is semi-informative so is not too bad. return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$ } return MessageFormat.format(message, (Object[]) arguments); }
Return true if and only if the running VM supports the given minimal version.

This only checks the major version, since the minor version is always 0 (at least for the useful cases).

The given minimalSupportedVersion is one of the constants:

  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_8
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK9
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK10
  • org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK11
Params:
  • minimalSupportedVersion – the given minimal version
Returns:true if and only if the running VM supports the given minimal version, false otherwise
/** * Return true if and only if the running VM supports the given minimal version. * * <p>This only checks the major version, since the minor version is always 0 (at least for the useful cases).</p> * <p>The given minimalSupportedVersion is one of the constants:</p> * <ul> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_8</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK9</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK10</code></li> * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK11</code></li> * * </ul> * @param minimalSupportedVersion the given minimal version * @return true if and only if the running VM supports the given minimal version, false otherwise */
private boolean checkVMVersion(long minimalSupportedVersion) { // the format of this property is supposed to be xx.x where x are digits. String classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$ if (classFileVersion == null) { // by default we don't support a class file version we cannot recognize return false; } int index = classFileVersion.indexOf('.'); if (index == -1) { // by default we don't support a class file version we cannot recognize return false; } int majorVersion; try { majorVersion = Integer.parseInt(classFileVersion.substring(0, index)); } catch (NumberFormatException e) { // by default we don't support a class file version we cannot recognize return false; } return ClassFileConstants.getComplianceLevelForJavaVersion(majorVersion) >=minimalSupportedVersion; } /* * Low-level API performing the actual compilation */ public boolean compile(String[] argv) { // decode command line arguments try { configure(argv); if (this.progress != null) this.progress.begin(this.filenames == null ? 0 : this.filenames.length * this.maxRepetition); if (this.proceed) { // if (this.verbose) { // System.out.println(new CompilerOptions(this.options)); // } if (this.showProgress) this.logger.compiling(); for (this.currentRepetition = 0; this.currentRepetition < this.maxRepetition; this.currentRepetition++) { this.globalProblemsCount = 0; this.globalErrorsCount = 0; this.globalWarningsCount = 0; this.globalInfoCount = 0; this.globalTasksCount = 0; this.exportedClassFilesCounter = 0; if (this.maxRepetition > 1) { this.logger.flush(); this.logger.logRepetition(this.currentRepetition, this.maxRepetition); } // request compilation performCompilation(); } if (this.compilerStats != null) { this.logger.logAverage(); } if (this.showProgress) this.logger.printNewLine(); } if (this.systemExitWhenFinished) { this.logger.flush(); this.logger.close(); if (this.failOnWarning && this.globalWarningsCount > 0) { System.exit(-1); } System.exit(this.globalErrorsCount > 0 ? -1 : 0); } } catch (Exception e) { // internal compiler failure this.logger.logException(e); if (this.systemExitWhenFinished) { this.logger.flush(); this.logger.close(); System.exit(-1); } return false; } finally { this.logger.flush(); this.logger.close(); if (this.progress != null) this.progress.done(); } if (this.progress == null || !this.progress.isCanceled()) { if (this.failOnWarning && (this.globalWarningsCount > 0)) return false; if (this.globalErrorsCount == 0) return true; } return false; } /* Decode the command line arguments */ public void configure(String[] argv) { if ((argv == null) || (argv.length == 0)) { printUsage(); return; } final int INSIDE_CLASSPATH_start = 1; final int INSIDE_DESTINATION_PATH = 3; final int INSIDE_TARGET = 4; final int INSIDE_LOG = 5; final int INSIDE_REPETITION = 6; final int INSIDE_SOURCE = 7; final int INSIDE_DEFAULT_ENCODING = 8; final int INSIDE_BOOTCLASSPATH_start = 9; final int INSIDE_MAX_PROBLEMS = 11; final int INSIDE_EXT_DIRS = 12; final int INSIDE_SOURCE_PATH_start = 13; final int INSIDE_ENDORSED_DIRS = 15; final int INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH = 16; final int INSIDE_PROCESSOR_PATH_start = 17; final int INSIDE_PROCESSOR_start = 18; final int INSIDE_S_start = 19; final int INSIDE_CLASS_NAMES = 20; final int INSIDE_WARNINGS_PROPERTIES = 21; final int INSIDE_ANNOTATIONPATH_start = 22; final int INSIDE_MODULEPATH_start = 23; final int INSIDE_MODULESOURCEPATH_start = 24; final int INSIDE_ADD_EXPORTS = 25; final int INSIDE_ADD_READS = 26; final int INSIDE_SYSTEM = 27; final int INSIDE_PROCESSOR_MODULE_PATH_start = 28; final int INSIDE_ADD_MODULES = 29; final int INSIDE_RELEASE = 30; final int INSIDE_LIMIT_MODULES = 31; final int INSIDE_MODULE_VERSION = 32; final int DEFAULT = 0; ArrayList<String> bootclasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); String sourcepathClasspathArg = null; String modulepathArg = null; String moduleSourcepathArg = null; ArrayList<String> sourcepathClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); ArrayList<String> classpaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); ArrayList<String> extdirsClasspaths = null; ArrayList<String> endorsedDirClasspaths = null; this.annotationPaths = null; this.annotationsFromClasspath = false; int index = -1; int filesCount = 0; int classCount = 0; int argCount = argv.length; int mode = DEFAULT; this.maxRepetition = 0; boolean printUsageRequired = false; String usageSection = null; boolean printVersionRequired = false; boolean didSpecifyDeprecation = false; boolean didSpecifyCompliance = false; boolean didSpecifyDisabledAnnotationProcessing = false; String customEncoding = null; String customDestinationPath = null; String currentSourceDirectory = null; String currentArg = Util.EMPTY_STRING; String moduleName = null; Set<String> specifiedEncodings = null; // expand the command line if necessary boolean needExpansion = false; loop: for (int i = 0; i < argCount; i++) { if (argv[i].startsWith("@")) { //$NON-NLS-1$ needExpansion = true; break loop; } } String[] newCommandLineArgs = null; if (needExpansion) { newCommandLineArgs = new String[argCount]; index = 0; for (int i = 0; i < argCount; i++) { String[] newArgs = null; String arg = argv[i].trim(); if (arg.startsWith("@")) { //$NON-NLS-1$ try { LineNumberReader reader = new LineNumberReader(new StringReader(new String(Util.getFileCharContent(new File(arg.substring(1)), null)))); StringBuffer buffer = new StringBuffer(); String line; while((line = reader.readLine()) != null) { line = line.trim(); if (!line.startsWith("#")) { //$NON-NLS-1$ buffer.append(line).append(" "); //$NON-NLS-1$ } } newArgs = tokenize(buffer.toString()); } catch(IOException e) { throw new IllegalArgumentException( this.bind("configure.invalidexpansionargumentname", arg)); //$NON-NLS-1$ } } if (newArgs != null) { int newCommandLineArgsLength = newCommandLineArgs.length; int newArgsLength = newArgs.length; System.arraycopy(newCommandLineArgs, 0, (newCommandLineArgs = new String[newCommandLineArgsLength + newArgsLength - 1]), 0, index); System.arraycopy(newArgs, 0, newCommandLineArgs, index, newArgsLength); index += newArgsLength; } else { newCommandLineArgs[index++] = arg; } } index = -1; } else { newCommandLineArgs = argv; for (int i = 0; i < argCount; i++) { newCommandLineArgs[i] = newCommandLineArgs[i].trim(); } } argCount = newCommandLineArgs.length; this.expandedCommandLine = newCommandLineArgs; while (++index < argCount) { if (customEncoding != null) { throw new IllegalArgumentException( this.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$ } currentArg = newCommandLineArgs[index]; switch(mode) { case DEFAULT : if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$ switch (currentArg.length()) { case 7: disableAll(ProblemSeverities.Warning); break; case 8: throw new IllegalArgumentException(this.bind( "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ default: int foldersStart = currentArg.indexOf('[') + 1; int foldersEnd = currentArg.lastIndexOf(']'); if (foldersStart <= 8 || foldersEnd == -1 || foldersStart > foldersEnd || foldersEnd < currentArg.length() - 1) { throw new IllegalArgumentException(this.bind( "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ } String folders = currentArg.substring(foldersStart, foldersEnd); if (folders.length() > 0) { char[][] currentFolders = decodeIgnoreOptionalProblemsFromFolders(folders); if (this.ignoreOptionalProblemsFromFolders != null) { int length = this.ignoreOptionalProblemsFromFolders.length + currentFolders.length; char[][] tempFolders = new char[length][]; System.arraycopy(this.ignoreOptionalProblemsFromFolders, 0, tempFolders, 0, this.ignoreOptionalProblemsFromFolders.length); System.arraycopy(currentFolders, 0, tempFolders, this.ignoreOptionalProblemsFromFolders.length, currentFolders.length); this.ignoreOptionalProblemsFromFolders = tempFolders; } else { this.ignoreOptionalProblemsFromFolders = currentFolders; } } else { throw new IllegalArgumentException(this.bind( "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ } } mode = DEFAULT; continue; } if (currentArg.startsWith("[")) { //$NON-NLS-1$ throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } if (currentArg.endsWith("]")) { //$NON-NLS-1$ // look for encoding specification int encodingStart = currentArg.indexOf('[') + 1; if (encodingStart <= 1) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", currentArg)); //$NON-NLS-1$ } int encodingEnd = currentArg.length() - 1; if (encodingStart >= 1) { if (encodingStart < encodingEnd) { customEncoding = currentArg.substring(encodingStart, encodingEnd); try { // ensure encoding is supported new InputStreamReader(new ByteArrayInputStream(new byte[0]), customEncoding); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException( this.bind("configure.unsupportedEncoding", customEncoding), e); //$NON-NLS-1$ } } currentArg = currentArg.substring(0, encodingStart - 1); } } if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) { if (moduleName == null) { // If the module-info.java was supplied via command line, that will be the // de facto module for the other source files supplied via command line. // TODO: This needs revisit in case a source file specified in command line is // part of a --module-source-path IModule mod = extractModuleDesc(currentArg); if (mod != null) { moduleName = new String(mod.name()); this.module = mod; } } if (this.filenames == null) { this.filenames = new String[argCount - index]; this.encodings = new String[argCount - index]; this.modNames = new String[argCount - index]; this.destinationPaths = new String[argCount - index]; } else if (filesCount == this.filenames.length) { int length = this.filenames.length; System.arraycopy( this.filenames, 0, (this.filenames = new String[length + argCount - index]), 0, length); System.arraycopy( this.encodings, 0, (this.encodings = new String[length + argCount - index]), 0, length); System.arraycopy( this.destinationPaths, 0, (this.destinationPaths = new String[length + argCount - index]), 0, length); System.arraycopy( this.modNames, 0, (this.modNames = new String[length + argCount - index]), 0, length); } this.filenames[filesCount] = currentArg; this.modNames[filesCount] = moduleName; this.encodings[filesCount++] = customEncoding; // destination path cannot be specified upon an individual file customEncoding = null; mode = DEFAULT; continue; } if (currentArg.equals("-log")) { //$NON-NLS-1$ if (this.log != null) throw new IllegalArgumentException( this.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$ mode = INSIDE_LOG; continue; } if (currentArg.equals("-repeat")) { //$NON-NLS-1$ if (this.maxRepetition > 0) throw new IllegalArgumentException( this.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$ mode = INSIDE_REPETITION; continue; } if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$ if (this.maxProblems > 0) throw new IllegalArgumentException( this.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$ mode = INSIDE_MAX_PROBLEMS; continue; } if (currentArg.equals("--release")) { //$NON-NLS-1$ mode = INSIDE_RELEASE; continue; } if (currentArg.equals("-source")) { //$NON-NLS-1$ mode = INSIDE_SOURCE; continue; } if (currentArg.equals("-encoding")) { //$NON-NLS-1$ mode = INSIDE_DEFAULT_ENCODING; continue; } if (currentArg.equals("-1.3")) { //$NON-NLS-1$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3); mode = DEFAULT; continue; } if (currentArg.equals("-1.4")) { //$NON-NLS-1$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4); mode = DEFAULT; continue; } if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); mode = DEFAULT; continue; } if (currentArg.equals("-1.6") || currentArg.equals("-6") || currentArg.equals("-6.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); mode = DEFAULT; continue; } if (currentArg.equals("-1.7") || currentArg.equals("-7") || currentArg.equals("-7.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7); mode = DEFAULT; continue; } if (currentArg.equals("-1.8") || currentArg.equals("-8") || currentArg.equals("-8.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); mode = DEFAULT; continue; } if (currentArg.equals("-1.9") || currentArg.equals("-9") || currentArg.equals("-9.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9); mode = DEFAULT; continue; } if (currentArg.equals("-10") || currentArg.equals("-10.0")) { //$NON-NLS-1$ //$NON-NLS-2$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10); mode = DEFAULT; continue; } if (currentArg.equals("-11") || currentArg.equals("-11.0")) { //$NON-NLS-1$ //$NON-NLS-2$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); mode = DEFAULT; continue; } if (currentArg.equals("-12") || currentArg.equals("-12.0")) { //$NON-NLS-1$ //$NON-NLS-2$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); mode = DEFAULT; continue; } if (currentArg.equals("-13") || currentArg.equals("-13.0")) { //$NON-NLS-1$ //$NON-NLS-2$ if (didSpecifyCompliance) { throw new IllegalArgumentException( this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$ } didSpecifyCompliance = true; this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13); mode = DEFAULT; continue; } if (currentArg.equals("-d")) { //$NON-NLS-1$ if (this.destinationPath != null) { StringBuffer errorMessage = new StringBuffer(); errorMessage.append(currentArg); if ((index + 1) < argCount) { errorMessage.append(' '); errorMessage.append(newCommandLineArgs[index + 1]); } throw new IllegalArgumentException( this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$ } mode = INSIDE_DESTINATION_PATH; continue; } if (currentArg.equals("-classpath") //$NON-NLS-1$ || currentArg.equals("-cp")) { //$NON-NLS-1$ mode = INSIDE_CLASSPATH_start; continue; } if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$ if (bootclasspaths.size() > 0) { StringBuffer errorMessage = new StringBuffer(); errorMessage.append(currentArg); if ((index + 1) < argCount) { errorMessage.append(' '); errorMessage.append(newCommandLineArgs[index + 1]); } throw new IllegalArgumentException( this.bind("configure.duplicateBootClasspath", errorMessage.toString())); //$NON-NLS-1$ } mode = INSIDE_BOOTCLASSPATH_start; continue; } if (currentArg.equals("--enable-preview")) { //$NON-NLS-1$ this.enablePreview = true; mode = DEFAULT; continue; } if (currentArg.equals("--system")) { //$NON-NLS-1$ mode = INSIDE_SYSTEM; continue; } if (currentArg.equals("--module-path") || currentArg.equals("-p") || currentArg.equals("--processor-module-path")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ mode = INSIDE_MODULEPATH_start; continue; } if (currentArg.equals("--module-source-path")) { //$NON-NLS-1$ if (sourcepathClasspathArg != null) { throw new IllegalArgumentException(this.bind("configure.OneOfModuleOrSourcePath")); //$NON-NLS-1$ } mode = INSIDE_MODULESOURCEPATH_start; continue; } if (currentArg.equals("--add-exports")) { //$NON-NLS-1$ mode = INSIDE_ADD_EXPORTS; continue; } if (currentArg.equals("--add-reads")) { //$NON-NLS-1$ mode = INSIDE_ADD_READS; continue; } if (currentArg.equals("--add-modules")) { //$NON-NLS-1$ mode = INSIDE_ADD_MODULES; continue; } if (currentArg.equals("--limit-modules")) { //$NON-NLS-1$ mode = INSIDE_LIMIT_MODULES; continue; } if (currentArg.equals("--module-version")) { //$NON-NLS-1$ mode = INSIDE_MODULE_VERSION; continue; } if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$ if (sourcepathClasspathArg != null) { StringBuffer errorMessage = new StringBuffer(); errorMessage.append(currentArg); if ((index + 1) < argCount) { errorMessage.append(' '); errorMessage.append(newCommandLineArgs[index + 1]); } throw new IllegalArgumentException( this.bind("configure.duplicateSourcepath", errorMessage.toString())); //$NON-NLS-1$ } if (moduleSourcepathArg != null) { throw new IllegalArgumentException(this.bind("configure.OneOfModuleOrSourcePath")); //$NON-NLS-1$ } mode = INSIDE_SOURCE_PATH_start; continue; } if (currentArg.equals("-extdirs")) {//$NON-NLS-1$ if (extdirsClasspaths != null) { StringBuffer errorMessage = new StringBuffer(); errorMessage.append(currentArg); if ((index + 1) < argCount) { errorMessage.append(' '); errorMessage.append(newCommandLineArgs[index + 1]); } throw new IllegalArgumentException( this.bind("configure.duplicateExtDirs", errorMessage.toString())); //$NON-NLS-1$ } mode = INSIDE_EXT_DIRS; continue; } if (currentArg.equals("-endorseddirs")) { //$NON-NLS-1$ if (endorsedDirClasspaths != null) { StringBuffer errorMessage = new StringBuffer(); errorMessage.append(currentArg); if ((index + 1) < argCount) { errorMessage.append(' '); errorMessage.append(newCommandLineArgs[index + 1]); } throw new IllegalArgumentException( this.bind("configure.duplicateEndorsedDirs", errorMessage.toString())); //$NON-NLS-1$ } mode = INSIDE_ENDORSED_DIRS; continue; } if (currentArg.equals("-progress")) { //$NON-NLS-1$ mode = DEFAULT; this.showProgress = true; continue; } if (currentArg.startsWith("-proceedOnError")) { //$NON-NLS-1$ mode = DEFAULT; int length = currentArg.length(); if (length > 15) { if (currentArg.equals("-proceedOnError:Fatal")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.ENABLED); } else { throw new IllegalArgumentException( this.bind("configure.invalidWarningConfiguration", currentArg)); //$NON-NLS-1$ } } else { this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.DISABLED); } this.proceedOnError = true; continue; } if (currentArg.equals("-failOnWarning")) { //$NON-NLS-1$ mode = DEFAULT; this.failOnWarning = true; continue; } if (currentArg.equals("-time")) { //$NON-NLS-1$ mode = DEFAULT; this.timing = TIMING_ENABLED; continue; } if (currentArg.equals("-time:detail")) { //$NON-NLS-1$ mode = DEFAULT; this.timing = TIMING_ENABLED|TIMING_DETAILED; continue; } if (currentArg.equals("-version") //$NON-NLS-1$ || currentArg.equals("-v")) { //$NON-NLS-1$ this.logger.logVersion(true); this.proceed = false; return; } if (currentArg.equals("-showversion")) { //$NON-NLS-1$ printVersionRequired = true; mode = DEFAULT; continue; } if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$ didSpecifyDeprecation = true; this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); mode = DEFAULT; continue; } if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$ printUsageRequired = true; mode = DEFAULT; continue; } if (currentArg.equals("-help:warn") || //$NON-NLS-1$ currentArg.equals("-?:warn")) { //$NON-NLS-1$ printUsageRequired = true; usageSection = "misc.usage.warn"; //$NON-NLS-1$ continue; } if (currentArg.equals("-noExit")) { //$NON-NLS-1$ this.systemExitWhenFinished = false; mode = DEFAULT; continue; } if (currentArg.equals("-verbose")) { //$NON-NLS-1$ this.verbose = true; mode = DEFAULT; continue; } if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$ this.produceRefInfo = true; mode = DEFAULT; continue; } if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$ mode = DEFAULT; this.options.put( CompilerOptions.OPTION_InlineJsr, CompilerOptions.ENABLED); continue; } if (currentArg.equals("-parameters")) { //$NON-NLS-1$ mode = DEFAULT; this.options.put( CompilerOptions.OPTION_MethodParametersAttribute, CompilerOptions.GENERATE); continue; } if (currentArg.equals("-genericsignature")) { //$NON-NLS-1$ mode = DEFAULT; this.options.put( CompilerOptions.OPTION_LambdaGenericSignature, CompilerOptions.GENERATE); continue; } if (currentArg.startsWith("-g")) { //$NON-NLS-1$ mode = DEFAULT; String debugOption = currentArg; int length = currentArg.length(); if (length == 2) { this.options.put( CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); this.options.put( CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); this.options.put( CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); continue; } if (length > 3) { this.options.put( CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); this.options.put( CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); this.options.put( CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE); if (length == 7 && debugOption.equals("-g:" + NONE)) //$NON-NLS-1$ continue; StringTokenizer tokenizer = new StringTokenizer(debugOption.substring(3, debugOption.length()), ","); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (token.equals("vars")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); } else if (token.equals("lines")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); } else if (token.equals("source")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); } else { throw new IllegalArgumentException( this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$ } } continue; } throw new IllegalArgumentException( this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$ } if (currentArg.startsWith("-info")) { //$NON-NLS-1$ mode = DEFAULT; String infoOption = currentArg; int length = currentArg.length(); if (length == 10 && infoOption.equals("-info:" + NONE)) { //$NON-NLS-1$ disableAll(ProblemSeverities.Info); continue; } if (length <= 6) { throw new IllegalArgumentException( this.bind("configure.invalidInfoConfiguration", infoOption)); //$NON-NLS-1$ } int infoTokenStart; boolean isEnabling; switch (infoOption.charAt(6)) { case '+' : infoTokenStart = 7; isEnabling = true; break; case '-' : infoTokenStart = 7; isEnabling = false; // specified warnings are disabled break; default: disableAll(ProblemSeverities.Info); infoTokenStart = 6; isEnabling = true; } StringTokenizer tokenizer = new StringTokenizer(infoOption.substring(infoTokenStart, infoOption.length()), ","); //$NON-NLS-1$ int tokenCounter = 0; while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); tokenCounter++; switch(token.charAt(0)) { case '+' : isEnabling = true; token = token.substring(1); break; case '-' : isEnabling = false; token = token.substring(1); } handleInfoToken(token, isEnabling); } if (tokenCounter == 0) { throw new IllegalArgumentException( this.bind("configure.invalidInfoOption", currentArg)); //$NON-NLS-1$ } continue; } if (currentArg.startsWith("-warn")) { //$NON-NLS-1$ mode = DEFAULT; String warningOption = currentArg; int length = currentArg.length(); if (length == 10 && warningOption.equals("-warn:" + NONE)) { //$NON-NLS-1$ disableAll(ProblemSeverities.Warning); continue; } if (length <= 6) { throw new IllegalArgumentException( this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$ } int warnTokenStart; boolean isEnabling; switch (warningOption.charAt(6)) { case '+' : warnTokenStart = 7; isEnabling = true; break; case '-' : warnTokenStart = 7; isEnabling = false; // specified warnings are disabled break; default: disableAll(ProblemSeverities.Warning); warnTokenStart = 6; isEnabling = true; } StringTokenizer tokenizer = new StringTokenizer(warningOption.substring(warnTokenStart, warningOption.length()), ","); //$NON-NLS-1$ int tokenCounter = 0; if (didSpecifyDeprecation) { // deprecation could have also been set through -deprecation option this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); } while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); tokenCounter++; switch(token.charAt(0)) { case '+' : isEnabling = true; token = token.substring(1); break; case '-' : isEnabling = false; token = token.substring(1); } handleWarningToken(token, isEnabling); } if (tokenCounter == 0) { throw new IllegalArgumentException( this.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$ } continue; } if (currentArg.startsWith("-err")) { //$NON-NLS-1$ mode = DEFAULT; String errorOption = currentArg; int length = currentArg.length(); if (length <= 5) { throw new IllegalArgumentException( this.bind("configure.invalidErrorConfiguration", errorOption)); //$NON-NLS-1$ } int errorTokenStart; boolean isEnabling; switch (errorOption.charAt(5)) { case '+' : errorTokenStart = 6; isEnabling = true; break; case '-' : errorTokenStart = 6; isEnabling = false; // specified errors are disabled break; default: disableAll(ProblemSeverities.Error); errorTokenStart = 5; isEnabling = true; } StringTokenizer tokenizer = new StringTokenizer(errorOption.substring(errorTokenStart, errorOption.length()), ","); //$NON-NLS-1$ int tokenCounter = 0; while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); tokenCounter++; switch(token.charAt(0)) { case '+' : isEnabling = true; token = token.substring(1); break; case '-' : isEnabling = false; token = token.substring(1); break; } handleErrorToken(token, isEnabling); } if (tokenCounter == 0) { throw new IllegalArgumentException( this.bind("configure.invalidErrorOption", currentArg)); //$NON-NLS-1$ } continue; } if (currentArg.equals("-target")) { //$NON-NLS-1$ mode = INSIDE_TARGET; continue; } if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE); mode = DEFAULT; continue; } if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$ mode = DEFAULT; this.enableJavadocOn = true; continue; } if (currentArg.equals("-Xemacs")) { //$NON-NLS-1$ mode = DEFAULT; this.logger.setEmacs(); continue; } // annotation processing if (currentArg.startsWith("-A")) { //$NON-NLS-1$ mode = DEFAULT; continue; } if (currentArg.equals("-processorpath")) { //$NON-NLS-1$ mode = INSIDE_PROCESSOR_PATH_start; continue; } if (currentArg.equals("-processor")) { //$NON-NLS-1$ mode = INSIDE_PROCESSOR_start; continue; } if (currentArg.equals("--processor-module-path")) { //$NON-NLS-1$ mode = INSIDE_PROCESSOR_MODULE_PATH_start; continue; } if (currentArg.equals("-proc:only")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_GenerateClassFiles, CompilerOptions.DISABLED); mode = DEFAULT; continue; } if (currentArg.equals("-proc:none")) { //$NON-NLS-1$ didSpecifyDisabledAnnotationProcessing = true; this.options.put( CompilerOptions.OPTION_Process_Annotations, CompilerOptions.DISABLED); mode = DEFAULT; continue; } if (currentArg.equals("-s")) { //$NON-NLS-1$ mode = INSIDE_S_start; continue; } if (currentArg.equals("-XprintProcessorInfo") //$NON-NLS-1$ || currentArg.equals("-XprintRounds")) { //$NON-NLS-1$ mode = DEFAULT; continue; } // tolerated javac options - quietly filtered out if (currentArg.startsWith("-X")) { //$NON-NLS-1$ mode = DEFAULT; continue; } if (currentArg.startsWith("-J")) { //$NON-NLS-1$ mode = DEFAULT; continue; } if (currentArg.equals("-O")) { //$NON-NLS-1$ mode = DEFAULT; continue; } if (currentArg.equals("-classNames")) { //$NON-NLS-1$ mode = INSIDE_CLASS_NAMES; continue; } if (currentArg.equals("-properties")) { //$NON-NLS-1$ mode = INSIDE_WARNINGS_PROPERTIES; continue; } if (currentArg.equals("-missingNullDefault")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_ReportMissingNonNullByDefaultAnnotation, CompilerOptions.WARNING); continue; } if (currentArg.equals("-annotationpath")) { //$NON-NLS-1$ mode = INSIDE_ANNOTATIONPATH_start; continue; } break; case INSIDE_TARGET : if (this.didSpecifyTarget) { throw new IllegalArgumentException( this.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$ } if (this.releaseVersion != null) { throw new IllegalArgumentException( this.bind("configure.unsupportedWithRelease", "-target"));//$NON-NLS-1$ //$NON-NLS-2$ } this.didSpecifyTarget = true; if (currentArg.equals("1.1")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); } else if (currentArg.equals("1.2")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); } else if (currentArg.equals("1.3")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3); } else if (currentArg.equals("1.4")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } else if (currentArg.equals("1.9") || currentArg.equals("9") || currentArg.equals("9.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); } else if (currentArg.equals("10") || currentArg.equals("10.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); } else if (currentArg.equals("12") || currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); } else if (currentArg.equals("13") || currentArg.equals("13.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13); } else if (currentArg.equals("jsr14")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14); } else if (currentArg.equals("cldc1.1")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_CLDC1_1); this.options.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.ENABLED); }else { throw new IllegalArgumentException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$ } mode = DEFAULT; continue; case INSIDE_LOG : this.log = currentArg; mode = DEFAULT; continue; case INSIDE_REPETITION : try { this.maxRepetition = Integer.parseInt(currentArg); if (this.maxRepetition <= 0) { throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$ } } catch (NumberFormatException e) { throw new IllegalArgumentException(this.bind("configure.repetition", currentArg), e); //$NON-NLS-1$ } mode = DEFAULT; continue; case INSIDE_MAX_PROBLEMS : try { this.maxProblems = Integer.parseInt(currentArg); if (this.maxProblems <= 0) { throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$ } this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg); } catch (NumberFormatException e) { throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg), e); //$NON-NLS-1$ } mode = DEFAULT; continue; case INSIDE_RELEASE: // If release is < 9, the following are disallowed: // bootclasspath, -Xbootclasspath, -Xbootclasspath/a:, -Xbootclasspath/p:, // -endorseddirs, -Djava.endorsed.dirs, -extdirs, -Djava.ext.dirs // If release >= 9, the following are disallowed // --system and --upgrade-module-path // -source and -target are disallowed for any --release this.releaseVersion = currentArg; long releaseToJDKLevel = CompilerOptions.releaseToJDKLevel(currentArg); if (releaseToJDKLevel == 0) { throw new IllegalArgumentException( this.bind("configure.unsupportedReleaseVersion", currentArg)); //$NON-NLS-1$ } // Let's treat it as regular compliance mode this.complianceLevel = releaseToJDKLevel; String versionAsString = CompilerOptions.versionFromJdkLevel(releaseToJDKLevel); this.options.put(CompilerOptions.OPTION_Compliance, versionAsString); this.options.put(CompilerOptions.OPTION_Source, versionAsString); this.options.put(CompilerOptions.OPTION_TargetPlatform, versionAsString); mode = DEFAULT; continue; case INSIDE_SOURCE : if (this.didSpecifySource) { throw new IllegalArgumentException( this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$ } if (this.releaseVersion != null) { throw new IllegalArgumentException( this.bind("configure.unsupportedWithRelease", "-source"));//$NON-NLS-1$ //$NON-NLS-2$ } this.didSpecifySource = true; if (currentArg.equals("1.3")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); } else if (currentArg.equals("1.4")) { //$NON-NLS-1$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4); } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7); } else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); } else if (currentArg.equals("1.9") || currentArg.equals("9") || currentArg.equals("9.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9); } else if (currentArg.equals("10") || currentArg.equals("10.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); } else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); } else if (currentArg.equals("12") || currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); } else if (currentArg.equals("13") || currentArg.equals("13.0")) { //$NON-NLS-1$//$NON-NLS-2$ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13); } else { throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$ } mode = DEFAULT; continue; case INSIDE_DEFAULT_ENCODING : if (specifiedEncodings != null) { // check already defined encoding if (!specifiedEncodings.contains(currentArg)) { if (specifiedEncodings.size() > 1) { this.logger.logWarning( this.bind("configure.differentencodings", //$NON-NLS-1$ currentArg, getAllEncodings(specifiedEncodings))); } else { this.logger.logWarning( this.bind("configure.differentencoding", //$NON-NLS-1$ currentArg, getAllEncodings(specifiedEncodings))); } } } else { specifiedEncodings = new HashSet<>(); } try { // ensure encoding is supported new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException( this.bind("configure.unsupportedEncoding", currentArg), e); //$NON-NLS-1$ } specifiedEncodings.add(currentArg); this.options.put(CompilerOptions.OPTION_Encoding, currentArg); mode = DEFAULT; continue; case INSIDE_DESTINATION_PATH : setDestinationPath(currentArg.equals(NONE) ? NONE : currentArg); mode = DEFAULT; continue; case INSIDE_SYSTEM: mode = DEFAULT; setJavaHome(currentArg); continue; case INSIDE_MODULEPATH_start: mode = DEFAULT; String[] modulepaths = new String[1]; index += processPaths(newCommandLineArgs, index, currentArg, modulepaths); modulepathArg = modulepaths[0]; continue; case INSIDE_MODULESOURCEPATH_start: mode = DEFAULT; String[] moduleSourcepaths = new String[1]; index += processPaths(newCommandLineArgs, index, currentArg, moduleSourcepaths); moduleSourcepathArg = moduleSourcepaths[0]; continue; case INSIDE_ADD_EXPORTS: mode = DEFAULT; // TODO: better to validate the option before processing it further? if (this.addonExports == Collections.EMPTY_LIST) { this.addonExports = new ArrayList<>(); } this.addonExports.add(currentArg); continue; case INSIDE_ADD_READS: mode = DEFAULT; if (this.addonReads == Collections.EMPTY_LIST) { this.addonReads = new ArrayList<>(); } this.addonReads.add(currentArg); continue; case INSIDE_ADD_MODULES: mode = DEFAULT; if (this.rootModules == Collections.EMPTY_SET) { this.rootModules = new HashSet<>(); } StringTokenizer tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) { this.rootModules.add(tokenizer.nextToken().trim()); } continue; case INSIDE_LIMIT_MODULES: mode = DEFAULT; tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) { if (this.limitedModules == null) { this.limitedModules = new HashSet<>(); } this.limitedModules.add(tokenizer.nextToken().trim()); } continue; case INSIDE_MODULE_VERSION: mode = DEFAULT; this.moduleVersion = validateModuleVersion(currentArg); continue; case INSIDE_CLASSPATH_start: mode = DEFAULT; index += processPaths(newCommandLineArgs, index, currentArg, classpaths); continue; case INSIDE_BOOTCLASSPATH_start: mode = DEFAULT; index += processPaths(newCommandLineArgs, index, currentArg, bootclasspaths); continue; case INSIDE_SOURCE_PATH_start: mode = DEFAULT; String[] sourcePaths = new String[1]; index += processPaths(newCommandLineArgs, index, currentArg, sourcePaths); sourcepathClasspathArg = sourcePaths[0]; continue; case INSIDE_EXT_DIRS: if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$ throw new IllegalArgumentException( this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$ "-extdir")); //$NON-NLS-1$ } tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false); extdirsClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); while (tokenizer.hasMoreTokens()) extdirsClasspaths.add(tokenizer.nextToken()); mode = DEFAULT; continue; case INSIDE_ENDORSED_DIRS: if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$ throw new IllegalArgumentException( this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$ "-endorseddirs")); //$NON-NLS-1$ } tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false); endorsedDirClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); while (tokenizer.hasMoreTokens()) endorsedDirClasspaths.add(tokenizer.nextToken()); mode = DEFAULT; continue; case INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH: if (currentArg.endsWith("]")) { //$NON-NLS-1$ customDestinationPath = currentArg.substring(0, currentArg.length() - 1); } else { throw new IllegalArgumentException( this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$ "[-d " + currentArg)); //$NON-NLS-1$ } break; case INSIDE_PROCESSOR_PATH_start : // nothing to do here. This is consumed again by the AnnotationProcessorManager mode = DEFAULT; continue; case INSIDE_PROCESSOR_start : // nothing to do here. This is consumed again by the AnnotationProcessorManager mode = DEFAULT; continue; case INSIDE_PROCESSOR_MODULE_PATH_start : mode = DEFAULT; continue; case INSIDE_S_start : // nothing to do here. This is consumed again by the AnnotationProcessorManager mode = DEFAULT; continue; case INSIDE_CLASS_NAMES : tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$ if (this.classNames == null) { this.classNames = new String[DEFAULT_SIZE_CLASSPATH]; } while (tokenizer.hasMoreTokens()) { if (this.classNames.length == classCount) { // resize System.arraycopy( this.classNames, 0, (this.classNames = new String[classCount * 2]), 0, classCount); } this.classNames[classCount++] = tokenizer.nextToken(); } mode = DEFAULT; continue; case INSIDE_WARNINGS_PROPERTIES : initializeWarnings(currentArg); mode = DEFAULT; continue; case INSIDE_ANNOTATIONPATH_start: mode = DEFAULT; if (currentArg.isEmpty() || currentArg.charAt(0) == '-') throw new IllegalArgumentException(this.bind("configure.missingAnnotationPath", currentArg)); //$NON-NLS-1$ if (ANNOTATION_SOURCE_CLASSPATH.equals(currentArg)) { this.annotationsFromClasspath = true; } else { if (this.annotationPaths == null) this.annotationPaths = new ArrayList<String>(); StringTokenizer tokens = new StringTokenizer(currentArg, File.pathSeparator); while (tokens.hasMoreTokens()) this.annotationPaths.add(tokens.nextToken()); } continue; } // default is input directory, if no custom destination path exists if (customDestinationPath == null) { if (File.separatorChar != '/') { currentArg = currentArg.replace('/', File.separatorChar); } if (currentArg.endsWith("[-d")) { //$NON-NLS-1$ currentSourceDirectory = currentArg.substring(0, currentArg.length() - 3); mode = INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH; continue; } currentSourceDirectory = currentArg; } File dir = new File(currentSourceDirectory); if (!dir.isDirectory()) { throw new IllegalArgumentException( this.bind("configure.unrecognizedOption", currentSourceDirectory)); //$NON-NLS-1$ } String[] result = FileFinder.find(dir, SuffixConstants.SUFFIX_STRING_java); if (NONE.equals(customDestinationPath)) { customDestinationPath = NONE; // ensure == comparison } if (this.filenames != null) { // some source files were specified explicitly int length = result.length; System.arraycopy( this.filenames, 0, (this.filenames = new String[length + filesCount]), 0, filesCount); System.arraycopy( this.encodings, 0, (this.encodings = new String[length + filesCount]), 0, filesCount); System.arraycopy( this.destinationPaths, 0, (this.destinationPaths = new String[length + filesCount]), 0, filesCount); System.arraycopy( this.modNames, 0, (this.modNames = new String[length + filesCount]), 0, filesCount); System.arraycopy(result, 0, this.filenames, filesCount, length); for (int i = 0; i < length; i++) { this.encodings[filesCount + i] = customEncoding; this.destinationPaths[filesCount + i] = customDestinationPath; this.modNames[filesCount + i] = moduleName; } filesCount += length; customEncoding = null; customDestinationPath = null; currentSourceDirectory = null; } else { this.filenames = result; filesCount = this.filenames.length; this.encodings = new String[filesCount]; this.destinationPaths = new String[filesCount]; this.modNames = new String[filesCount]; for (int i = 0; i < filesCount; i++) { this.encodings[i] = customEncoding; this.destinationPaths[i] = customDestinationPath; } customEncoding = null; customDestinationPath = null; currentSourceDirectory = null; } mode = DEFAULT; continue; } if (this.enablePreview) { this.options.put( CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); } // set DocCommentSupport, with appropriate side effects on defaults if // javadoc is not enabled if (this.enableJavadocOn) { this.options.put( CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); } else if (this.warnJavadocOn || this.warnAllJavadocOn) { this.options.put( CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); // override defaults: references that are embedded in javadoc are ignored // from the perspective of parameters and thrown exceptions usage this.options.put( CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference, CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference, CompilerOptions.DISABLED); } // configure warnings for javadoc contents if (this.warnJavadocOn) { this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTags, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, CompilerOptions.PRIVATE); } if (printUsageRequired || (filesCount == 0 && classCount == 0)) { if (usageSection == null) { printUsage(); // default } else { printUsage(usageSection); } this.proceed = false; return; } if (this.log != null) { this.logger.setLog(this.log); } else { this.showProgress = false; } this.logger.logVersion(printVersionRequired); validateOptions(didSpecifyCompliance); // Enable annotation processing by default in batch mode when compliance is at least 1.6 // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=185768 if (!didSpecifyDisabledAnnotationProcessing && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) >= ClassFileConstants.JDK1_6) { this.options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED); } this.logger.logCommandLineArguments(newCommandLineArgs); this.logger.logOptions(this.options); if (this.maxRepetition == 0) { this.maxRepetition = 1; } if (this.maxRepetition >= 3 && (this.timing & TIMING_ENABLED) != 0) { this.compilerStats = new CompilerStats[this.maxRepetition]; } if (filesCount != 0) { System.arraycopy( this.filenames, 0, (this.filenames = new String[filesCount]), 0, filesCount); } if (classCount != 0) { System.arraycopy( this.classNames, 0, (this.classNames = new String[classCount]), 0, classCount); } setPaths(bootclasspaths, sourcepathClasspathArg, sourcepathClasspaths, classpaths, modulepathArg, moduleSourcepathArg, extdirsClasspaths, endorsedDirClasspaths, customEncoding); if (specifiedEncodings != null && specifiedEncodings.size() > 1) { this.logger.logWarning(this.bind("configure.multipleencodings", //$NON-NLS-1$ this.options.get(CompilerOptions.OPTION_Encoding), getAllEncodings(specifiedEncodings))); } if (this.pendingErrors != null) { for (Iterator<String> iterator = this.pendingErrors.iterator(); iterator.hasNext(); ) { String message = iterator.next(); this.logger.logPendingError(message); } this.pendingErrors = null; } } private String validateModuleVersion(String versionString) { try { Class<?> versionClass = Class.forName("java.lang.module.ModuleDescriptor$Version"); //$NON-NLS-1$ Method method = versionClass.getMethod("parse", String.class); //$NON-NLS-1$ try { method.invoke(null, versionString); } catch (InvocationTargetException e) { if (e.getCause() instanceof IllegalArgumentException) throw (IllegalArgumentException) e.getCause(); } } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException e) { this.logger.logWarning(this.bind("configure.no.ModuleDescriptorVersionparse")); //$NON-NLS-1$ } return versionString; } private Parser getNewParser() { return new Parser(new ProblemReporter(getHandlingPolicy(), new CompilerOptions(this.options), getProblemFactory()), false); } private IModule extractModuleDesc(String fileName) { IModule mod = null; // this.options may not be completely populated yet, and definitely not // validated. Make sure the source level is set for the parser Map<String,String> opts = new HashMap<String, String>(this.options); opts.put(CompilerOptions.OPTION_Source, this.options.get(CompilerOptions.OPTION_Compliance)); Parser parser = new Parser(new ProblemReporter(getHandlingPolicy(), new CompilerOptions(opts), getProblemFactory()), false); if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_JAVA)) { ICompilationUnit cu = new CompilationUnit(null, fileName, null); CompilationResult compilationResult = new CompilationResult(cu, 0, 1, 10); CompilationUnitDeclaration unit = parser.parse(cu, compilationResult); if (unit.isModuleInfo() && unit.moduleDeclaration != null) { mod = new BasicModule(unit.moduleDeclaration, null); } } else if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_CLASS)) { try { ClassFileReader reader = ClassFileReader.read(fileName); // Check the absolute path? mod = reader.getModuleDeclaration(); } catch (ClassFormatException | IOException e) { e.printStackTrace(); throw new IllegalArgumentException( this.bind("configure.invalidModuleDescriptor", fileName)); //$NON-NLS-1$ } } return mod; } private static char[][] decodeIgnoreOptionalProblemsFromFolders(String folders) { StringTokenizer tokenizer = new StringTokenizer(folders, File.pathSeparator); char[][] result = new char[tokenizer.countTokens()][]; int count = 0; while (tokenizer.hasMoreTokens()) { String fileName = tokenizer.nextToken(); // relative folder names are created relative to the current user dir File file = new File(fileName); if (file.exists()) { // if the file exists, we should try to use its canonical path try { result[count++] = file.getCanonicalPath().toCharArray(); } catch (IOException e) { // if we got exception during canonicalization, fall back to the name that was specified result[count++] = fileName.toCharArray(); } } else { // if the file does not exist, use the name that was specified result[count++] = fileName.toCharArray(); } } return result; } private static String getAllEncodings(Set<String> encodings) { int size = encodings.size(); String[] allEncodings = new String[size]; encodings.toArray(allEncodings); Arrays.sort(allEncodings); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < size; i++) { if (i > 0) { buffer.append(", "); //$NON-NLS-1$ } buffer.append(allEncodings[i]); } return String.valueOf(buffer); } @SuppressWarnings("rawtypes") private void initializeWarnings(String propertiesFile) { File file = new File(propertiesFile); if (!file.exists()) { throw new IllegalArgumentException(this.bind("configure.missingwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$ } BufferedInputStream stream = null; Properties properties = null; try { stream = new BufferedInputStream(new FileInputStream(propertiesFile)); properties = new Properties(); properties.load(stream); } catch(IOException e) { e.printStackTrace(); throw new IllegalArgumentException(this.bind("configure.ioexceptionwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$ } finally { if (stream != null) { try { stream.close(); } catch(IOException e) { // ignore } } } for(Iterator iterator = properties.entrySet().iterator(); iterator.hasNext(); ) { Map.Entry entry = (Map.Entry) iterator.next(); final String key = entry.getKey().toString(); if (key.startsWith("org.eclipse.jdt.core.compiler.")) { //$NON-NLS-1$ this.options.put(key, entry.getValue().toString()); } } // when using a properties file mimic relevant defaults from JavaCorePreferenceInitializer: if (!properties.containsKey(CompilerOptions.OPTION_LocalVariableAttribute)) { this.options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); } if (!properties.containsKey(CompilerOptions.OPTION_PreserveUnusedLocal)) { this.options.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE); } if (!properties.containsKey(CompilerOptions.OPTION_DocCommentSupport)) { this.options.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); } if (!properties.containsKey(CompilerOptions.OPTION_ReportForbiddenReference)) { this.options.put(CompilerOptions.OPTION_ReportForbiddenReference, CompilerOptions.ERROR); } } protected void enableAll(int severity) { String newValue = null; switch(severity) { case ProblemSeverities.Error : newValue = CompilerOptions.ERROR; break; case ProblemSeverities.Warning : newValue = CompilerOptions.WARNING; break; } Map.Entry<String, String>[] entries = this.options.entrySet().toArray(new Map.Entry[this.options.size()]); for (int i = 0, max = entries.length; i < max; i++) { Map.Entry<String, String> entry = entries[i]; if (entry.getValue().equals(CompilerOptions.IGNORE)) { this.options.put(entry.getKey(), newValue); } } this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING); } protected void disableAll(int severity) { String checkedValue = null; switch(severity) { case ProblemSeverities.Error : checkedValue = CompilerOptions.ERROR; break; case ProblemSeverities.Warning : checkedValue = CompilerOptions.WARNING; break; case ProblemSeverities.Info : checkedValue = CompilerOptions.INFO; break; } Set<Entry<String, String>> entrySet = this.options.entrySet(); for (Entry<String, String> entry : entrySet) { if (entry.getValue().equals(checkedValue)) { this.options.put(entry.getKey(), CompilerOptions.IGNORE); } } if (severity == ProblemSeverities.Warning) { disableAll(ProblemSeverities.Info); } } public String extractDestinationPathFromSourceFile(CompilationResult result) { ICompilationUnit compilationUnit = result.compilationUnit; if (compilationUnit != null) { char[] fileName = compilationUnit.getFileName(); int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName); if (lastIndex != -1) { final String outputPathName = new String(fileName, 0, lastIndex); final File output = new File(outputPathName); if (output.exists() && output.isDirectory()) { return outputPathName; } } } return System.getProperty("user.dir"); //$NON-NLS-1$ } /* * Answer the component to which will be handed back compilation results from the compiler */ public ICompilerRequestor getBatchRequestor() { return new BatchCompilerRequestor(this); } /* * Build the set of compilation source units */ public CompilationUnit[] getCompilationUnits() { int fileCount = this.filenames.length; CompilationUnit[] units = new CompilationUnit[fileCount]; HashtableOfObject knownFileNames = new HashtableOfObject(fileCount); String defaultEncoding = this.options.get(CompilerOptions.OPTION_Encoding); if (Util.EMPTY_STRING.equals(defaultEncoding)) defaultEncoding = null; for (int round = 0; round < 2; round++) { for (int i = 0; i < fileCount; i++) { char[] charName = this.filenames[i].toCharArray(); boolean isModuleInfo = CharOperation.endsWith(charName, TypeConstants.MODULE_INFO_FILE_NAME); if (isModuleInfo == (round==0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModCU well in time) if (knownFileNames.get(charName) != null) throw new IllegalArgumentException(this.bind("unit.more", this.filenames[i])); //$NON-NLS-1$ knownFileNames.put(charName, charName); File file = new File(this.filenames[i]); if (!file.exists()) throw new IllegalArgumentException(this.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$ String encoding = this.encodings[i]; if (encoding == null) encoding = defaultEncoding; String fileName; try { fileName = file.getCanonicalPath(); } catch (IOException e) { // if we got exception during canonicalization, fall back to the name that was specified fileName = this.filenames[i]; } units[i] = new CompilationUnit(null, fileName, encoding, this.destinationPaths[i], shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()), this.modNames[i]); } } } return units; } /* * Low-level API performing the actual compilation */ public IErrorHandlingPolicy getHandlingPolicy() { // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match) return new IErrorHandlingPolicy() { @Override public boolean proceedOnErrors() { return Main.this.proceedOnError; // stop if there are some errors } @Override public boolean stopOnFirstError() { return false; } @Override public boolean ignoreAllErrors() { return false; } }; } private void setJavaHome(String javaHome) { File release = new File(javaHome, "release"); //$NON-NLS-1$ Properties prop = new Properties(); try { prop.load(new FileReader(release)); String ver = prop.getProperty("JAVA_VERSION"); //$NON-NLS-1$ if (ver != null) ver = ver.replace("\"", ""); //$NON-NLS-1$//$NON-NLS-2$ this.javaHomeCache = new File(javaHome); this.javaHomeChecked = true; } catch (IOException e) { throw new IllegalArgumentException(this.bind("configure.invalidSystem", javaHome)); //$NON-NLS-1$ } } /* * External API */ public File getJavaHome() { if (!this.javaHomeChecked) { this.javaHomeChecked = true; this.javaHomeCache = Util.getJavaHome(); } return this.javaHomeCache; } public FileSystem getLibraryAccess() { FileSystem nameEnvironment = new FileSystem(this.checkedClasspaths, this.filenames, this.annotationsFromClasspath && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis)), this.limitedModules); nameEnvironment.module = this.module; processAddonModuleOptions(nameEnvironment); return nameEnvironment; } /* * Low-level API performing the actual compilation */ public IProblemFactory getProblemFactory() { return new DefaultProblemFactory(this.compilerLocale); } /* * External API */ protected ArrayList<Classpath> handleBootclasspath(ArrayList<String> bootclasspaths, String customEncoding) { final int bootclasspathsSize; ArrayList<Classpath> result = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); if ((bootclasspaths != null) && ((bootclasspathsSize = bootclasspaths.size()) != 0)) { result = new ArrayList<>(bootclasspathsSize); for (String path : bootclasspaths) { processPathEntries(DEFAULT_SIZE_CLASSPATH, result, path, customEncoding, false, true); } } else { try { Util.collectVMBootclasspath(result, this.javaHomeCache); } catch(IllegalStateException e) { throw new IllegalArgumentException(this.bind("configure.invalidSystem", this.javaHomeCache.toString())); //$NON-NLS-1$ } } return result; } private void processAddonModuleOptions(FileSystem env) { Map<String, IPackageExport[]> exports = new HashMap<>(); for (String option : this.addonExports) { AddExport addExport = ModuleFinder.extractAddonExport(option); if (addExport != null) { String modName = addExport.sourceModuleName; IPackageExport export = addExport.export; IPackageExport[] existing = exports.get(modName); if (existing == null) { existing = new IPackageExport[1]; existing[0] = export; exports.put(modName, existing); } else { for (IPackageExport iPackageExport : existing) { if (CharOperation.equals(iPackageExport.name(), export.name())) { throw new IllegalArgumentException(this.bind("configure.duplicateExport")); //$NON-NLS-1$ } } IPackageExport[] updated = new IPackageExport[existing.length + 1]; System.arraycopy(existing, 0, updated, 0, existing.length); updated[existing.length] = export; exports.put(modName, updated); } env.addModuleUpdate(modName, m -> m.addExports(export.name(), export.targets()), UpdateKind.PACKAGE); } else { throw new IllegalArgumentException(this.bind("configure.invalidModuleOption", "--add-exports " + option)); //$NON-NLS-1$ //$NON-NLS-2$ } } for (String option : this.addonReads) { String[] result = ModuleFinder.extractAddonRead(option); if (result != null && result.length == 2) { env.addModuleUpdate(result[0], m -> m.addReads(result[1].toCharArray()), UpdateKind.MODULE); } else { throw new IllegalArgumentException(this.bind("configure.invalidModuleOption", "--add-reads " + option)); //$NON-NLS-1$ //$NON-NLS-2$ } } } protected ArrayList<FileSystem.Classpath> handleModulepath(String arg) { ArrayList<String> modulePaths = processModulePathEntries(arg); ArrayList<Classpath> result = new ArrayList<>(); if ((modulePaths != null && modulePaths.size() > 0)) { for (String path : modulePaths) { File file = new File(path); if (file.isDirectory()) { result.addAll( ModuleFinder.findModules(file, null, getNewParser(), this.options, true, this.releaseVersion)); } else { Classpath modulePath = ModuleFinder.findModule(file, null, getNewParser(), this.options, true, this.releaseVersion); if (modulePath != null) result.add(modulePath); } } } // TODO: What about chained jars from MANIFEST.MF? Check with spec return result; } protected ArrayList<FileSystem.Classpath> handleModuleSourcepath(String arg) { ArrayList<String> modulePaths = processModulePathEntries(arg); ArrayList<FileSystem.Classpath> result = new ArrayList<>(); if ((modulePaths != null) && (modulePaths.size() != 0)) { if (this.destinationPath == null) { addPendingErrors(this.bind("configure.missingDestinationPath"));//$NON-NLS-1$ } String[] paths = new String[modulePaths.size()]; modulePaths.toArray(paths); for (int i = 0; i < paths.length; i++) { File dir = new File(paths[i]); if (dir.isDirectory()) { // 1. Create FileSystem.Classpath for each module // 2. Iterator each module in case of directory for source files and add to this.fileNames List<Classpath> modules = ModuleFinder.findModules(dir, this.destinationPath, getNewParser(), this.options, false, this.releaseVersion); for (Classpath classpath : modules) { result.add(classpath); Path modLocation = Paths.get(classpath.getPath()).toAbsolutePath(); String destPath = classpath.getDestinationPath(); IModule mod = classpath.getModule(); String moduleName = mod == null ? null : new String(mod.name()); for(int j = 0; j < this.filenames.length; j++) { Path filePath; try { // Get canonical path just as the classpath location is stored with the same. // To avoid mismatch of /USER_JAY and /USE~1 in windows systems. filePath = new File(this.filenames[j]).getCanonicalFile().toPath(); if (filePath.startsWith(modLocation)) { this.modNames[j] = moduleName; this.destinationPaths[j] = destPath; } } catch (IOException e) { // Files doesn't exist and perhaps doesn't belong in a module, move on to other files // Use empty module name to distinguish from missing module case this.modNames[j] = ""; //$NON-NLS-1$ } } } } } for(int j = 0; j < this.filenames.length; j++) { if (this.modNames[j] == null) { throw new IllegalArgumentException(this.bind("configure.notOnModuleSourcePath", new String[] {this.filenames[j]})); //$NON-NLS-1$ } } } return result; } /* * External API */ protected ArrayList<FileSystem.Classpath> handleClasspath(ArrayList<String> classpaths, String customEncoding) { ArrayList<FileSystem.Classpath> initial = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); if (classpaths != null && classpaths.size() > 0) { for (String path : classpaths) { processPathEntries(DEFAULT_SIZE_CLASSPATH, initial, path, customEncoding, false, true); } } else { // no user classpath specified. String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$ if ((classProp == null) || (classProp.length() == 0)) { addPendingErrors(this.bind("configure.noClasspath")); //$NON-NLS-1$ final Classpath classpath = FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, null, this.options, this.releaseVersion);//$NON-NLS-1$ if (classpath != null) { initial.add(classpath); } } else { StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator); String token; while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); FileSystem.Classpath currentClasspath = FileSystem .getClasspath(token, customEncoding, null, this.options, this.releaseVersion); if (currentClasspath != null) { initial.add(currentClasspath); } else if (token.length() != 0) { addPendingErrors(this.bind("configure.incorrectClasspath", token));//$NON-NLS-1$ } } } } ArrayList<Classpath> result = new ArrayList<>(); HashMap<String, Classpath> knownNames = new HashMap<>(); FileSystem.ClasspathSectionProblemReporter problemReporter = new FileSystem.ClasspathSectionProblemReporter() { @Override public void invalidClasspathSection(String jarFilePath) { addPendingErrors(bind("configure.invalidClasspathSection", jarFilePath)); //$NON-NLS-1$ } @Override public void multipleClasspathSections(String jarFilePath) { addPendingErrors(bind("configure.multipleClasspathSections", jarFilePath)); //$NON-NLS-1$ } }; while (! initial.isEmpty()) { Classpath current = initial.remove(0); String currentPath = current.getPath(); if (knownNames.get(currentPath) == null) { knownNames.put(currentPath, current); result.add(current); List<Classpath> linkedJars = current.fetchLinkedJars(problemReporter); if (linkedJars != null) { initial.addAll(0, linkedJars); } } } return result; } /* * External API */ protected ArrayList<FileSystem.Classpath> handleEndorseddirs(ArrayList<String> endorsedDirClasspaths) { final File javaHome = getJavaHome(); /* * Feed endorsedDirClasspath according to: * - -endorseddirs first if present; * - else java.endorsed.dirs if defined; * - else default extensions directory for the platform. (/lib/endorsed) */ if (endorsedDirClasspaths == null) { endorsedDirClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); String endorsedDirsStr = System.getProperty("java.endorsed.dirs"); //$NON-NLS-1$ if (endorsedDirsStr == null) { if (javaHome != null) { endorsedDirClasspaths.add(javaHome.getAbsolutePath() + "/lib/endorsed"); //$NON-NLS-1$ } } else { StringTokenizer tokenizer = new StringTokenizer(endorsedDirsStr, File.pathSeparator); while (tokenizer.hasMoreTokens()) { endorsedDirClasspaths.add(tokenizer.nextToken()); } } } /* * Feed extdirsClasspath with the entries found into the directories listed by * extdirsNames. */ if (endorsedDirClasspaths.size() != 0) { ArrayList<FileSystem.Classpath> result = new ArrayList<>(); File[] directoriesToCheck = new File[endorsedDirClasspaths.size()]; for (int i = 0; i < directoriesToCheck.length; i++) directoriesToCheck[i] = new File(endorsedDirClasspaths.get(i)); File[][] endorsedDirsJars = getLibrariesFiles(directoriesToCheck); if (endorsedDirsJars != null) { for (int i = 0, max = endorsedDirsJars.length; i < max; i++) { File[] current = endorsedDirsJars[i]; if (current != null) { for (int j = 0, max2 = current.length; j < max2; j++) { FileSystem.Classpath classpath = FileSystem.getClasspath( current[j].getAbsolutePath(), null, null, this.options, this.releaseVersion); if (classpath != null) { result.add(classpath); } } } else if (directoriesToCheck[i].isFile()) { addPendingErrors( this.bind( "configure.incorrectEndorsedDirsEntry", //$NON-NLS-1$ directoriesToCheck[i].getAbsolutePath())); } } } return result; } return FileSystem.EMPTY_CLASSPATH; } /* * External API * Handle extdirs processing */ protected ArrayList<FileSystem.Classpath> handleExtdirs(ArrayList<String> extdirsClasspaths) { final File javaHome = getJavaHome(); /* * Feed extDirClasspath according to: * - -extdirs first if present; * - else java.ext.dirs if defined; * - else default extensions directory for the platform. */ if (extdirsClasspaths == null) { extdirsClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH); String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$ if (extdirsStr == null) { extdirsClasspaths.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$ } else { StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator); while (tokenizer.hasMoreTokens()) extdirsClasspaths.add(tokenizer.nextToken()); } } /* * Feed extdirsClasspath with the entries found into the directories listed by * extdirsNames. */ if (extdirsClasspaths.size() != 0) { ArrayList<FileSystem.Classpath> result = new ArrayList<>(); File[] directoriesToCheck = new File[extdirsClasspaths.size()]; for (int i = 0; i < directoriesToCheck.length; i++) directoriesToCheck[i] = new File(extdirsClasspaths.get(i)); File[][] extdirsJars = getLibrariesFiles(directoriesToCheck); if (extdirsJars != null) { for (int i = 0, max = extdirsJars.length; i < max; i++) { File[] current = extdirsJars[i]; if (current != null) { for (int j = 0, max2 = current.length; j < max2; j++) { FileSystem.Classpath classpath = FileSystem.getClasspath( current[j].getAbsolutePath(), null, null, this.options, this.releaseVersion); if (classpath != null) { result.add(classpath); } } } else if (directoriesToCheck[i].isFile()) { addPendingErrors(this.bind( "configure.incorrectExtDirsEntry", //$NON-NLS-1$ directoriesToCheck[i].getAbsolutePath())); } } } return result; } return FileSystem.EMPTY_CLASSPATH; } /* * External API * Handle a single warning token. */ protected void handleInfoToken(String token, boolean isEnabling) { handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Info); } protected void handleWarningToken(String token, boolean isEnabling) { handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Warning); } protected void handleErrorToken(String token, boolean isEnabling) { handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Error); } private void setSeverity(String compilerOptions, int severity, boolean isEnabling) { if (isEnabling) { switch(severity) { case ProblemSeverities.Error : this.options.put(compilerOptions, CompilerOptions.ERROR); break; case ProblemSeverities.Warning : this.options.put(compilerOptions, CompilerOptions.WARNING); break; case ProblemSeverities.Info : this.options.put(compilerOptions, CompilerOptions.INFO); break; default: this.options.put(compilerOptions, CompilerOptions.IGNORE); } } else { switch(severity) { case ProblemSeverities.Error : String currentValue = this.options.get(compilerOptions); if (CompilerOptions.ERROR.equals(currentValue)) { this.options.put(compilerOptions, CompilerOptions.IGNORE); } break; case ProblemSeverities.Warning : currentValue = this.options.get(compilerOptions); if (CompilerOptions.WARNING.equals(currentValue)) { this.options.put(compilerOptions, CompilerOptions.IGNORE); } break; case ProblemSeverities.Info : currentValue = this.options.get(compilerOptions); if (CompilerOptions.INFO.equals(currentValue)) { this.options.put(compilerOptions, CompilerOptions.IGNORE); } break; default: this.options.put(compilerOptions, CompilerOptions.IGNORE); } } } private void handleErrorOrWarningToken(String token, boolean isEnabling, int severity) { if (token.length() == 0) return; switch(token.charAt(0)) { case 'a' : if (token.equals("allDeprecation")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportTerminalDeprecation, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("allJavadoc")) { //$NON-NLS-1$ this.warnAllJavadocOn = this.warnJavadocOn = isEnabling; setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling); return; } else if (token.equals("assertIdentifier")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportAssertIdentifier, severity, isEnabling); return; } else if (token.equals("allDeadCode")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("allOver-ann")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("all-static-method")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, severity, isEnabling); return; } else if (token.equals("all")) { //$NON-NLS-1$ if (isEnabling) { enableAll(severity); } else { disableAll(severity); } return; } break; case 'b' : if (token.equals("boxing")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportAutoboxing, severity, isEnabling); return; } break; case 'c' : if (token.equals("constructorName")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMethodWithConstructorName, severity, isEnabling); return; } else if (token.equals("conditionAssign")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, severity, isEnabling); return; } else if (token.equals("compareIdentical")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportComparingIdentical, severity, isEnabling); return; } else if (token.equals("charConcat") /*|| token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling); return; } break; case 'd' : if (token.equals("deprecation")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); return; } else if (token.equals("dep-ann")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation, severity, isEnabling); return; } else if (token.equals("discouraged")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDiscouragedReference, severity, isEnabling); return; } else if (token.equals("deadCode")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.DISABLED); return; } break; case 'e' : if (token.equals("enumSwitch")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling); return; } else if (token.equals("enumSwitchPedantic")) { //$NON-NLS-1$ if (isEnabling) { switch (severity) { case ProblemSeverities.Error: setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling); break; case ProblemSeverities.Warning: if (CompilerOptions.IGNORE.equals(this.options.get(CompilerOptions.OPTION_ReportIncompleteEnumSwitch))) { setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling); } break; default: // no severity update } } this.options.put(CompilerOptions.OPTION_ReportMissingEnumCaseDespiteDefault, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("emptyBlock")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, severity, isEnabling); return; } else if (token.equals("enumIdentifier")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportEnumIdentifier, severity, isEnabling); return; } else if (token.equals("exports")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportAPILeak, severity, isEnabling); return; } break; case 'f' : if (token.equals("fieldHiding")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling); return; } else if (token.equals("finalBound")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportFinalParameterBound, severity, isEnabling); return; } else if (token.equals("finally")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, severity, isEnabling); return; } else if (token.equals("forbidden")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportForbiddenReference, severity, isEnabling); return; } else if (token.equals("fallthrough")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportFallthroughCase, severity, isEnabling); return; } break; case 'h' : if (token.equals("hiding")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling); return; } else if (token.equals("hashCode")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingHashCodeMethod, severity, isEnabling); return; } break; case 'i' : if (token.equals("indirectStatic")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling); return; } else if (token.equals("inheritNullAnnot")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_InheritNullAnnotations, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, severity, isEnabling); return; } else if (token.equals("intfAnnotation")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportAnnotationSuperInterface, severity, isEnabling); return; } else if (token.equals("intfRedundant") /*|| token.equals("redundantSuperinterface")*/) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling); return; } else if (token.equals("includeAssertNull")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_IncludeNullInfoFromAsserts, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("invalidJavadoc")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTags, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); if (isEnabling) { this.options.put( CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, CompilerOptions.PRIVATE); } return; } else if (token.equals("invalidJavadocTag")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTags, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("invalidJavadocTagDep")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("invalidJavadocTagNotVisible")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.startsWith("invalidJavadocTagVisibility")) { //$NON-NLS-1$ int start = token.indexOf('('); int end = token.indexOf(')'); String visibility = null; if (isEnabling && start >= 0 && end >= 0 && start < end){ visibility = token.substring(start+1, end).trim(); } if (visibility != null && visibility.equals(CompilerOptions.PUBLIC) || visibility.equals(CompilerOptions.PRIVATE) || visibility.equals(CompilerOptions.PROTECTED) || visibility.equals(CompilerOptions.DEFAULT)) { this.options.put( CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, visibility); return; } else { throw new IllegalArgumentException(this.bind("configure.invalidJavadocTagVisibility", token)); //$NON-NLS-1$ } } break; case 'j' : if (token.equals("javadoc")) {//$NON-NLS-1$ this.warnJavadocOn = isEnabling; setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling); return; } break; case 'l' : if (token.equals("localHiding")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling); return; } break; case 'm' : if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling); return; } else if (token.equals("missingJavadocTags")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); if (isEnabling) { this.options.put( CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, CompilerOptions.PRIVATE); } return; } else if (token.equals("missingJavadocTagsOverriding")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("missingJavadocTagsMethod")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.startsWith("missingJavadocTagsVisibility")) { //$NON-NLS-1$ int start = token.indexOf('('); int end = token.indexOf(')'); String visibility = null; if (isEnabling && start >= 0 && end >= 0 && start < end){ visibility = token.substring(start+1, end).trim(); } if (visibility != null && visibility.equals(CompilerOptions.PUBLIC) || visibility.equals(CompilerOptions.PRIVATE) || visibility.equals(CompilerOptions.PROTECTED) || visibility.equals(CompilerOptions.DEFAULT)) { this.options.put( CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, visibility); return; } else { throw new IllegalArgumentException(this.bind("configure.missingJavadocTagsVisibility", token)); //$NON-NLS-1$ } } else if (token.equals("missingJavadocComments")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); if (isEnabling) { this.options.put( CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility, CompilerOptions.PRIVATE); } return; } else if (token.equals("missingJavadocCommentsOverriding")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.startsWith("missingJavadocCommentsVisibility")) { //$NON-NLS-1$ int start = token.indexOf('('); int end = token.indexOf(')'); String visibility = null; if (isEnabling && start >= 0 && end >= 0 && start < end){ visibility = token.substring(start+1, end).trim(); } if (visibility != null && visibility.equals(CompilerOptions.PUBLIC) || visibility.equals(CompilerOptions.PRIVATE) || visibility.equals(CompilerOptions.PROTECTED) || visibility.equals(CompilerOptions.DEFAULT)) { this.options.put( CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility, visibility); return; } else { throw new IllegalArgumentException(this.bind("configure.missingJavadocCommentsVisibility", token)); //$NON-NLS-1$ } } else if (token.equals("module")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnstableAutoModuleName, severity, isEnabling); return; } break; case 'n' : if (token.equals("nls")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, severity, isEnabling); return; } else if (token.equals("noEffectAssign")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNoEffectAssignment, severity, isEnabling); return; } else if (/*token.equals("charConcat") ||*/ token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling); return; } else if (token.equals("null")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, severity, isEnabling); return; } else if (token.equals("nullDereference")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling); if (!isEnabling) { setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, ProblemSeverities.Ignore, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling); } return; }else if (token.equals("nullAnnotConflict")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling); return; } else if (token.equals("nullAnnotRedundant")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling); return; } else if (token.startsWith("nullAnnot")) { //$NON-NLS-1$ String annotationNames = Util.EMPTY_STRING; int start = token.indexOf('('); int end = token.indexOf(')'); String nonNullAnnotName = null, nullableAnnotName = null, nonNullByDefaultAnnotName = null; if (isEnabling && start >= 0 && end >= 0 && start < end){ boolean isPrimarySet = !this.primaryNullAnnotationsSeen; annotationNames = token.substring(start+1, end).trim(); int separator1 = annotationNames.indexOf('|'); if (separator1 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ nullableAnnotName = annotationNames.substring(0, separator1).trim(); if (isPrimarySet && nullableAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ int separator2 = annotationNames.indexOf('|', separator1 + 1); if (separator2 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ nonNullAnnotName = annotationNames.substring(separator1 + 1, separator2).trim(); if (isPrimarySet && nonNullAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ nonNullByDefaultAnnotName = annotationNames.substring(separator2 + 1).trim(); if (isPrimarySet && nonNullByDefaultAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ if (isPrimarySet) { this.primaryNullAnnotationsSeen = true; this.options.put(CompilerOptions.OPTION_NullableAnnotationName, nullableAnnotName); this.options.put(CompilerOptions.OPTION_NonNullAnnotationName, nonNullAnnotName); this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationName, nonNullByDefaultAnnotName); } else { if (nullableAnnotName.length() > 0) { String nullableList = this.options.get(CompilerOptions.OPTION_NullableAnnotationSecondaryNames); nullableList = nullableList.isEmpty() ? nullableAnnotName : nullableList + ',' + nullableAnnotName; this.options.put(CompilerOptions.OPTION_NullableAnnotationSecondaryNames, nullableList); } if (nonNullAnnotName.length() > 0) { String nonnullList = this.options.get(CompilerOptions.OPTION_NonNullAnnotationSecondaryNames); nonnullList = nonnullList.isEmpty() ? nonNullAnnotName : nonnullList + ',' + nonNullAnnotName; this.options.put(CompilerOptions.OPTION_NonNullAnnotationSecondaryNames, nonnullList); } if (nonNullByDefaultAnnotName.length() > 0) { String nnbdList = this.options.get(CompilerOptions.OPTION_NonNullByDefaultAnnotationSecondaryNames); nnbdList = nnbdList.isEmpty() ? nonNullByDefaultAnnotName : nnbdList + ',' + nonNullByDefaultAnnotName; this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationSecondaryNames, nnbdList); } } } this.options.put( CompilerOptions.OPTION_AnnotationBasedNullAnalysis, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); setSeverity(CompilerOptions.OPTION_ReportNullSpecViolation, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling); return; } else if (token.equals("nullUncheckedConversion")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling); return; } else if (token.equals("nonnullNotRepeated")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNonnullParameterAnnotationDropped, severity, isEnabling); return; } break; case 'o' : if (token.equals("over-sync") /*|| token.equals("syncOverride")*/) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling); return; } else if (token.equals("over-ann")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation, CompilerOptions.DISABLED); return; } break; case 'p' : if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, severity, isEnabling); return; } else if (token.equals("paramAssign")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportParameterAssignment, severity, isEnabling); return; } break; case 'r' : if (token.equals("raw")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportRawTypeReference, severity, isEnabling); return; } else if (/*token.equals("intfRedundant") ||*/ token.equals("redundantSuperinterface")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling); return; } else if (token.equals("resource")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnclosedCloseable, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, severity, isEnabling); return; } else if (token.equals("removal")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportTerminalDeprecation, severity, isEnabling); this.options.put( CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); return; } break; case 's' : if (token.equals("specialParamHiding")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportSpecialParameterHidingField, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("syntheticAccess") || token.equals("synthetic-access")) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, severity, isEnabling); return; } else if (token.equals("staticReceiver")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling); return; } else if (/*token.equals("over-sync") ||*/ token.equals("syncOverride")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling); return; } else if (token.equals("semicolon")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportEmptyStatement, severity, isEnabling); return; } else if (token.equals("serial")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingSerialVersion, severity, isEnabling); return; } else if (token.equals("suppress")) {//$NON-NLS-1$ switch(severity) { case ProblemSeverities.Warning : this.options.put( CompilerOptions.OPTION_SuppressWarnings, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.DISABLED); break; case ProblemSeverities.Error : this.options.put( CompilerOptions.OPTION_SuppressWarnings, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); this.options.put( CompilerOptions.OPTION_SuppressOptionalErrors, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); } return; } else if (token.equals("static-access")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling); return; } else if (token.equals("super")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, severity, isEnabling); return; } else if (token.equals("static-method")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling); return; } else if (token.equals("switchDefault")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportMissingDefaultCase, severity, isEnabling); return; } else if (token.equals("syntacticAnalysis")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_SyntacticNullAnalysisForFields, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } break; case 't' : if (token.startsWith("tasks")) { //$NON-NLS-1$ String taskTags = Util.EMPTY_STRING; int start = token.indexOf('('); int end = token.indexOf(')'); if (start >= 0 && end >= 0 && start < end){ taskTags = token.substring(start+1, end).trim(); taskTags = taskTags.replace('|',','); } if (taskTags.length() == 0){ throw new IllegalArgumentException(this.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$ } this.options.put( CompilerOptions.OPTION_TaskTags, isEnabling ? taskTags : Util.EMPTY_STRING); setSeverity(CompilerOptions.OPTION_ReportTasks, severity, isEnabling); return; } else if (token.equals("typeHiding")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling); return; } break; case 'u' : if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling); return; } else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling); return; } else if (token.equals("unusedExceptionParam")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedExceptionParameter, severity, isEnabling); return; } else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling); return; } else if (token.equals("unusedAllocation")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity, isEnabling); return; } else if (token.equals("unusedPrivate")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling); return; } else if (token.equals("unusedLabel")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling); return; } else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, severity, isEnabling); return; } else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportUncheckedTypeOperation, severity, isEnabling); return; } else if (token.equals("unlikelyCollectionMethodArgumentType")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnlikelyCollectionMethodArgumentType, severity, isEnabling); return; } else if (token.equals("unlikelyEqualsArgumentType")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnlikelyEqualsArgumentType, severity, isEnabling); return; } else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnnecessaryElse, severity, isEnabling); return; } else if (token.equals("unusedThrown")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling); return; } else if (token.equals("unusedThrownWhenOverriding")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unusedThrownIncludeDocComment")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unusedThrownExemptExceptionThrowable")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unqualifiedField") || token.equals("unqualified-field-access")) { //$NON-NLS-1$ //$NON-NLS-2$ setSeverity(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, severity, isEnabling); return; } else if (token.equals("unused")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedExceptionParameter, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity,isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity,isEnabling); return; } else if (token.equals("unusedParam")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling); return; } else if (token.equals("unusedTypeParameter")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity, isEnabling); return; } else if (token.equals("unusedParamIncludeDoc")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unusedParamOverriding")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unusedParamImplementing")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } else if (token.equals("unusedTypeArgs")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling); return; } else if (token.equals("unavoidableGenericProblems")) { //$NON-NLS-1$ this.options.put( CompilerOptions.OPTION_ReportUnavoidableGenericTypeProblems, isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); return; } break; case 'v' : if (token.equals("varargsCast")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportVarargsArgumentNeedCast, severity, isEnabling); return; } break; case 'w' : if (token.equals("warningToken")) {//$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnhandledWarningToken, severity, isEnabling); setSeverity(CompilerOptions.OPTION_ReportUnusedWarningToken, severity, isEnabling); return; } break; } String message = null; switch(severity) { case ProblemSeverities.Info: message = this.bind("configure.invalidInfo", token); //$NON-NLS-1$ break; case ProblemSeverities.Warning : message = this.bind("configure.invalidWarning", token); //$NON-NLS-1$ break; case ProblemSeverities.Error : message = this.bind("configure.invalidError", token); //$NON-NLS-1$ } addPendingErrors(message); }
Deprecated:- use initialize(PrintWriter, PrintWriter, boolean, Map<String,String>, CompilationProgress) instead e.g. initialize(outWriter, errWriter, systemExit, null, null)
/** * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead * e.g. initialize(outWriter, errWriter, systemExit, null, null) */
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit) { this.initialize(outWriter, errWriter, systemExit, null /* options */, null /* progress */); }
Deprecated:- use initialize(PrintWriter, PrintWriter, boolean, Map<String,String>, CompilationProgress) instead e.g. initialize(outWriter, errWriter, systemExit, customDefaultOptions, null)
/** * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead * e.g. initialize(outWriter, errWriter, systemExit, customDefaultOptions, null) */
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map<String, String> customDefaultOptions) { this.initialize(outWriter, errWriter, systemExit, customDefaultOptions, null /* progress */); } protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map<String, String> customDefaultOptions, CompilationProgress compilationProgress) { this.logger = new Logger(this, outWriter, errWriter); this.proceed = true; this.out = outWriter; this.err = errWriter; this.systemExitWhenFinished = systemExit; this.options = new CompilerOptions().getMap(); this.ignoreOptionalProblemsFromFolders = null; this.progress = compilationProgress; if (customDefaultOptions != null) { this.didSpecifySource = customDefaultOptions.get(CompilerOptions.OPTION_Source) != null; this.didSpecifyTarget = customDefaultOptions.get(CompilerOptions.OPTION_TargetPlatform) != null; for (Iterator<Map.Entry<String, String>> iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) { Map.Entry<String, String> entry = iter.next(); this.options.put(entry.getKey(), entry.getValue()); } } else { this.didSpecifySource = false; this.didSpecifyTarget = false; } this.classNames = null; } protected void initializeAnnotationProcessorManager() { String className = "org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"; //$NON-NLS-1$ try { Class<?> c = Class.forName(className); AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance(); annotationManager.configure(this, this.expandedCommandLine); annotationManager.setErr(this.err); annotationManager.setOut(this.out); this.batchCompiler.annotationProcessorManager = annotationManager; } catch (ClassNotFoundException | InstantiationException e) { this.logger.logUnavaibleAPT(className); throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation(); } catch (IllegalAccessException e) { // should not happen throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation(); } catch(UnsupportedClassVersionError e) { // report a warning this.logger.logIncorrectVMVersionForAnnotationProcessing(); } } private static boolean isParentOf(char[] folderName, char[] fileName) { if (folderName.length >= fileName.length) { return false; } if (fileName[folderName.length] != '\\' && fileName[folderName.length] != '/') { return false; } for (int i = folderName.length - 1; i >= 0; i--) { if (folderName[i] != fileName[i]) { return false; } } return true; } // Dump classfiles onto disk for all compilation units that where successful // and do not carry a -d none spec, either directly or inherited from Main. public void outputClassFiles(CompilationResult unitResult) { if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) { ClassFile[] classFiles = unitResult.getClassFiles(); String currentDestinationPath = null; boolean generateClasspathStructure = false; CompilationUnit compilationUnit = (CompilationUnit) unitResult.compilationUnit; if (compilationUnit.destinationPath == null) { if (this.destinationPath == null) { currentDestinationPath = extractDestinationPathFromSourceFile(unitResult); } else if (this.destinationPath != NONE) { currentDestinationPath = this.destinationPath; generateClasspathStructure = true; } // else leave currentDestinationPath null } else if (compilationUnit.destinationPath != NONE) { currentDestinationPath = compilationUnit.destinationPath; generateClasspathStructure = true; } // else leave currentDestinationPath null if (currentDestinationPath != null) { for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) { // retrieve the key and the corresponding classfile ClassFile classFile = classFiles[i]; char[] filename = classFile.fileName(); int length = filename.length; char[] relativeName = new char[length + 6]; System.arraycopy(filename, 0, relativeName, 0, length); System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6); CharOperation.replace(relativeName, '/', File.separatorChar); String relativeStringName = new String(relativeName); try { if (this.compilerOptions.verbose) this.out.println( Messages.bind( Messages.compilation_write, new String[] { String.valueOf(this.exportedClassFilesCounter+1), relativeStringName })); Util.writeToDisk( generateClasspathStructure, currentDestinationPath, relativeStringName, classFile); this.logger.logClassFile( generateClasspathStructure, currentDestinationPath, relativeStringName); this.exportedClassFilesCounter++; } catch (IOException e) { this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e); } } this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles); } } } /* * Low-level API performing the actual compilation */ public void performCompilation() { this.startTime = System.currentTimeMillis(); FileSystem environment = getLibraryAccess(); try { this.compilerOptions = new CompilerOptions(this.options); this.compilerOptions.performMethodsFullRecovery = false; this.compilerOptions.performStatementsRecovery = false; this.batchCompiler = new Compiler( environment, getHandlingPolicy(), this.compilerOptions, getBatchRequestor(), getProblemFactory(), this.out, this.progress); this.batchCompiler.remainingIterations = this.maxRepetition-this.currentRepetition/*remaining iterations including this one*/; // temporary code to allow the compiler to revert to a single thread String setting = System.getProperty("jdt.compiler.useSingleThread"); //$NON-NLS-1$ this.batchCompiler.useSingleThread = setting != null && setting.equals("true"); //$NON-NLS-1$ if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6 && this.compilerOptions.processAnnotations) { if (checkVMVersion(ClassFileConstants.JDK1_6)) { initializeAnnotationProcessorManager(); if (this.classNames != null) { this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment)); } } else { // report a warning this.logger.logIncorrectVMVersionForAnnotationProcessing(); } if (checkVMVersion(ClassFileConstants.JDK9)) { initRootModules(this.batchCompiler.lookupEnvironment, environment); } } // set the non-externally configurable options. this.compilerOptions.verbose = this.verbose; this.compilerOptions.produceReferenceInfo = this.produceRefInfo; try { this.logger.startLoggingSources(); this.batchCompiler.compile(getCompilationUnits()); } finally { this.logger.endLoggingSources(); } if (this.extraProblems != null) { loggingExtraProblems(); this.extraProblems = null; } if (this.compilerStats != null) { this.compilerStats[this.currentRepetition] = this.batchCompiler.stats; } this.logger.printStats(); } finally { // cleanup environment.cleanup(); } } protected void loggingExtraProblems() { this.logger.loggingExtraProblems(this); } public void printUsage() { printUsage("misc.usage"); //$NON-NLS-1$ } private void printUsage(String sectionID) { this.logger.logUsage( this.bind( sectionID, new String[] { System.getProperty("path.separator"), //$NON-NLS-1$ this.bind("compiler.name"), //$NON-NLS-1$ this.bind("compiler.version"), //$NON-NLS-1$ this.bind("compiler.copyright") //$NON-NLS-1$ })); this.logger.flush(); } private void initRootModules(LookupEnvironment environment, FileSystem fileSystem) { Map<String, String> map = new HashMap<>(); for (String m : this.rootModules) { ModuleBinding mod = environment.getModule(m.toCharArray()); if (mod == null) { throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$ } PackageBinding[] exports = mod.getExports(); for (PackageBinding packageBinding : exports) { String qName = CharOperation.toString(packageBinding.compoundName); String existing = map.get(qName); if (existing != null) { throw new IllegalArgumentException(this.bind("configure.packageConflict", new String[] {qName, existing, m})); //$NON-NLS-1$ // report an error and bail out } map.put(qName, m); } } if (this.limitedModules != null) { for (String m : this.limitedModules) { ModuleBinding mod = environment.getModule(m.toCharArray()); if (mod == null) { throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$ } } } environment.moduleVersion = this.moduleVersion; } private ReferenceBinding[] processClassNames(LookupEnvironment environment) { // check for .class file presence in case of apt processing int length = this.classNames.length; ReferenceBinding[] referenceBindings = new ReferenceBinding[length]; ModuleBinding[] modules = new ModuleBinding[length]; Set<ModuleBinding> modSet = new HashSet<>(); String[] typeNames = new String[length]; if (this.complianceLevel <= ClassFileConstants.JDK1_8) { typeNames = this.classNames; } else { for (int i = 0; i < length; i++) { String currentName = this.classNames[i]; int idx = currentName.indexOf('/'); ModuleBinding mod = null; if (idx > 0) { String m = currentName.substring(0, idx); mod = environment.getModule(m.toCharArray()); if (mod == null) { throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$ } modules[i] = mod; modSet.add(mod); currentName = currentName.substring(idx + 1); } typeNames[i] = currentName; } } for (int i = 0; i < length; i++) { char[][] compoundName = null; String cls = typeNames[i]; if (cls.indexOf('.') != -1) { // consider names with '.' as fully qualified names char[] typeName = cls.toCharArray(); compoundName = CharOperation.splitOn('.', typeName); } else { compoundName = new char[][] { cls.toCharArray() }; } ModuleBinding mod = modules[i]; ReferenceBinding type = mod != null ? environment.getType(compoundName, mod) : environment.getType(compoundName); if (type != null && type.isValidBinding()) { if (type.isBinaryBinding()) { referenceBindings[i] = type; type.superclass(); } } else { throw new IllegalArgumentException( this.bind("configure.invalidClassName", this.classNames[i]));//$NON-NLS-1$ } } return referenceBindings; } private ArrayList<String> processModulePathEntries(String arg) { ArrayList<String> paths = new ArrayList<>(); if (arg == null) return paths; StringTokenizer tokenizer = new StringTokenizer(arg, File.pathSeparator, false); while (tokenizer.hasMoreTokens()) { paths.add(tokenizer.nextToken()); } return paths; } /* * External API */ public void processPathEntries(final int defaultSize, final ArrayList<FileSystem.Classpath> paths, final String currentPath, String customEncoding, boolean isSourceOnly, boolean rejectDestinationPathOnJars) { String currentClasspathName = null; String currentDestinationPath = null; ArrayList<String> currentRuleSpecs = new ArrayList<>(defaultSize); StringTokenizer tokenizer = new StringTokenizer(currentPath, File.pathSeparator + "[]", true); //$NON-NLS-1$ ArrayList<String> tokens = new ArrayList<>(); while (tokenizer.hasMoreTokens()) { tokens.add(tokenizer.nextToken()); } // state machine final int start = 0; final int readyToClose = 1; // 'path' 'path1[rule];path2' final int readyToCloseEndingWithRules = 2; // 'path[rule]' 'path1;path2[rule]' final int readyToCloseOrOtherEntry = 3; // 'path[rule];' 'path;' 'path1;path2;' final int rulesNeedAnotherRule = 4; // 'path[rule1;' final int rulesStart = 5; // 'path[' 'path1;path2[' final int rulesReadyToClose = 6; // 'path[rule' 'path[rule1;rule2' final int destinationPathReadyToClose = 7; // 'path[-d bin' final int readyToCloseEndingWithDestinationPath = 8; // 'path[-d bin]' 'path[rule][-d bin]' final int destinationPathStart = 9; // 'path[rule][' final int bracketOpened = 10; // '.*[.*' final int bracketClosed = 11; // '.*([.*])+' final int error = 99; int state = start; String token = null; int cursor = 0, tokensNb = tokens.size(), bracket = -1; while (cursor < tokensNb && state != error) { token = tokens.get(cursor++); if (token.equals(File.pathSeparator)) { switch (state) { case start: case readyToCloseOrOtherEntry: case bracketOpened: break; case readyToClose: case readyToCloseEndingWithRules: case readyToCloseEndingWithDestinationPath: state = readyToCloseOrOtherEntry; addNewEntry(paths, currentClasspathName, currentRuleSpecs, customEncoding, currentDestinationPath, isSourceOnly, rejectDestinationPathOnJars); currentRuleSpecs.clear(); break; case rulesReadyToClose: state = rulesNeedAnotherRule; break; case destinationPathReadyToClose: throw new IllegalArgumentException( this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$ currentPath)); case bracketClosed: cursor = bracket + 1; state = rulesStart; break; default: state = error; } } else if (token.equals("[")) { //$NON-NLS-1$ switch (state) { case start: currentClasspathName = ""; //$NON-NLS-1$ //$FALL-THROUGH$ case readyToClose: bracket = cursor - 1; //$FALL-THROUGH$ case bracketClosed: state = bracketOpened; break; case readyToCloseEndingWithRules: state = destinationPathStart; break; case readyToCloseEndingWithDestinationPath: state = rulesStart; break; case bracketOpened: default: state = error; } } else if (token.equals("]")) { //$NON-NLS-1$ switch (state) { case rulesReadyToClose: state = readyToCloseEndingWithRules; break; case destinationPathReadyToClose: state = readyToCloseEndingWithDestinationPath; break; case bracketOpened: state = bracketClosed; break; case bracketClosed: default: state = error; } } else { // regular word switch (state) { case start: case readyToCloseOrOtherEntry: state = readyToClose; currentClasspathName = token; break; case rulesStart: if (token.startsWith("-d ")) { //$NON-NLS-1$ if (currentDestinationPath != null) { throw new IllegalArgumentException( this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$ currentPath)); } currentDestinationPath = token.substring(3).trim(); state = destinationPathReadyToClose; break; } // else we proceed with a rule //$FALL-THROUGH$ case rulesNeedAnotherRule: if (currentDestinationPath != null) { throw new IllegalArgumentException( this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$ currentPath)); } state = rulesReadyToClose; currentRuleSpecs.add(token); break; case destinationPathStart: if (!token.startsWith("-d ")) { //$NON-NLS-1$ state = error; } else { currentDestinationPath = token.substring(3).trim(); state = destinationPathReadyToClose; } break; case bracketClosed: for (int i = bracket; i < cursor ; i++) { currentClasspathName += tokens.get(i); } state = readyToClose; break; case bracketOpened: break; default: state = error; } } if (state == bracketClosed && cursor == tokensNb) { cursor = bracket + 1; state = rulesStart; } } switch(state) { case readyToCloseOrOtherEntry: break; case readyToClose: case readyToCloseEndingWithRules: case readyToCloseEndingWithDestinationPath: addNewEntry(paths, currentClasspathName, currentRuleSpecs, customEncoding, currentDestinationPath, isSourceOnly, rejectDestinationPathOnJars); break; case bracketOpened: case bracketClosed: default : // we go on anyway if (currentPath.length() != 0) { addPendingErrors(this.bind("configure.incorrectClasspath", currentPath));//$NON-NLS-1$ } } } private int processPaths(String[] args, int index, String currentArg, ArrayList<String> paths) { int localIndex = index; int count = 0; for (int i = 0, max = currentArg.length(); i < max; i++) { switch(currentArg.charAt(i)) { case '[' : count++; break; case ']' : count--; break; } } if (count == 0) { paths.add(currentArg); } else if (count > 1) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } else { StringBuffer currentPath = new StringBuffer(currentArg); while (true) { if (localIndex >= args.length) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } localIndex++; String nextArg = args[localIndex]; for (int i = 0, max = nextArg.length(); i < max; i++) { switch(nextArg.charAt(i)) { case '[' : if (count > 1) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ nextArg)); } count++; break; case ']' : count--; break; } } if (count == 0) { currentPath.append(' '); currentPath.append(nextArg); paths.add(currentPath.toString()); return localIndex - index; } else if (count < 0) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ nextArg)); } else { currentPath.append(' '); currentPath.append(nextArg); } } } return localIndex - index; } private int processPaths(String[] args, int index, String currentArg, String[] paths) { int localIndex = index; int count = 0; for (int i = 0, max = currentArg.length(); i < max; i++) { switch(currentArg.charAt(i)) { case '[' : count++; break; case ']' : count--; break; } } if (count == 0) { paths[0] = currentArg; } else { StringBuffer currentPath = new StringBuffer(currentArg); while (true) { localIndex++; if (localIndex >= args.length) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } String nextArg = args[localIndex]; for (int i = 0, max = nextArg.length(); i < max; i++) { switch(nextArg.charAt(i)) { case '[' : if (count > 1) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } count++; break; case ']' : count--; break; } } if (count == 0) { currentPath.append(' '); currentPath.append(nextArg); paths[0] = currentPath.toString(); return localIndex - index; } else if (count < 0) { throw new IllegalArgumentException( this.bind("configure.unexpectedBracket", //$NON-NLS-1$ currentArg)); } else { currentPath.append(' '); currentPath.append(nextArg); } } } return localIndex - index; }
Creates a NLS catalog for the given locale.
/** * Creates a NLS catalog for the given locale. */
public void relocalize() { relocalize(Locale.getDefault()); } private void relocalize(Locale locale) { this.compilerLocale = locale; try { this.bundle = ResourceBundleFactory.getBundle(locale); } catch(MissingResourceException e) { System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$ throw e; } } /* * External API */ public void setDestinationPath(String dest) { this.destinationPath = dest; } /* * External API */ public void setLocale(Locale locale) { relocalize(locale); } /* * External API */ protected void setPaths(ArrayList<String> bootclasspaths, String sourcepathClasspathArg, ArrayList<String> sourcepathClasspaths, ArrayList<String> classpaths, String modulePath, String moduleSourcepath, ArrayList<String> extdirsClasspaths, ArrayList<String> endorsedDirClasspaths, String customEncoding) { if (this.complianceLevel == 0) { String version = this.options.get(CompilerOptions.OPTION_Compliance); this.complianceLevel = CompilerOptions.versionToJdkLevel(version); } // process bootclasspath, classpath and sourcepaths ArrayList<Classpath> allPaths = null; long jdkLevel = validateClasspathOptions(bootclasspaths, endorsedDirClasspaths, extdirsClasspaths); if (this.releaseVersion != null && this.complianceLevel < jdkLevel) { // TODO: Revisit for access rules allPaths = new ArrayList<Classpath>(); allPaths.add( FileSystem.getOlderSystemRelease(this.javaHomeCache.getAbsolutePath(), this.releaseVersion, null)); } else { allPaths = handleBootclasspath(bootclasspaths, customEncoding); } List<FileSystem.Classpath> cp = handleClasspath(classpaths, customEncoding); List<FileSystem.Classpath> mp = handleModulepath(modulePath); List<FileSystem.Classpath> msp = handleModuleSourcepath(moduleSourcepath); ArrayList<FileSystem.Classpath> sourcepaths = new ArrayList<>(); if (sourcepathClasspathArg != null) { processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepaths, sourcepathClasspathArg, customEncoding, true, false); } /* * Feed endorsedDirClasspath according to: * - -extdirs first if present; * - else java.ext.dirs if defined; * - else default extensions directory for the platform. */ List<FileSystem.Classpath> extdirs = handleExtdirs(extdirsClasspaths); List<FileSystem.Classpath> endorsed = handleEndorseddirs(endorsedDirClasspaths); /* * Concatenate classpath entries * We put the bootclasspath at the beginning of the classpath * entries, followed by the extension libraries, followed by * the sourcepath followed by the classpath. All classpath * entries are searched for both sources and binaries except * the sourcepath entries which are searched for sources only. */ allPaths.addAll(0, endorsed); allPaths.addAll(extdirs); allPaths.addAll(sourcepaths); allPaths.addAll(cp); allPaths.addAll(mp); allPaths.addAll(msp); allPaths = FileSystem.ClasspathNormalizer.normalize(allPaths); this.checkedClasspaths = new FileSystem.Classpath[allPaths.size()]; allPaths.toArray(this.checkedClasspaths); this.logger.logClasspath(this.checkedClasspaths); if (this.annotationPaths != null && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis))) { for (FileSystem.Classpath c : this.checkedClasspaths) { if (c instanceof ClasspathJar) ((ClasspathJar) c).annotationPaths = this.annotationPaths; else if (c instanceof ClasspathJrt) ((ClasspathJrt) c).annotationPaths = this.annotationPaths; } } } protected final static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) { if (folderNames == null || fileName == null) { return false; } for (int i = 0, max = folderNames.length; i < max; i++) { char[] folderName = folderNames[i]; if (isParentOf(folderName, fileName)) { return true; } } return false; } protected long validateClasspathOptions(ArrayList<String> bootclasspaths, ArrayList<String> endorsedDirClasspaths, ArrayList<String> extdirsClasspaths) { if (this.complianceLevel > ClassFileConstants.JDK1_8) { if (bootclasspaths != null && bootclasspaths.size() > 0) throw new IllegalArgumentException( this.bind("configure.unsupportedOption", "-bootclasspath")); //$NON-NLS-1$ //$NON-NLS-2$ if (extdirsClasspaths != null && extdirsClasspaths.size() > 0) throw new IllegalArgumentException( this.bind("configure.unsupportedOption", "-extdirs")); //$NON-NLS-1$ //$NON-NLS-2$ if (endorsedDirClasspaths != null && endorsedDirClasspaths.size() > 0) throw new IllegalArgumentException( this.bind("configure.unsupportedOption", "-endorseddirs")); //$NON-NLS-1$ //$NON-NLS-2$ } long jdkLevel = Util.getJDKLevel(getJavaHome()); if (jdkLevel < ClassFileConstants.JDK9 && this.releaseVersion != null) { throw new IllegalArgumentException( this.bind("configure.unsupportedReleaseOption")); //$NON-NLS-1$ } return jdkLevel; } protected void validateOptions(boolean didSpecifyCompliance) { if (didSpecifyCompliance) { String version = this.options.get(CompilerOptions.OPTION_Compliance); if (this.releaseVersion != null) { throw new IllegalArgumentException( this.bind("configure.unsupportedWithRelease", version));//$NON-NLS-1$ } if (CompilerOptions.VERSION_1_3.equals(version)) { if (!this.didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); } else if (CompilerOptions.VERSION_1_4.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); } else if (CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); } } else if (CompilerOptions.VERSION_1_5.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); } } else if (CompilerOptions.VERSION_1_6.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } } else if (CompilerOptions.VERSION_1_7.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (CompilerOptions.VERSION_1_7.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } } else if (CompilerOptions.VERSION_1_8.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (CompilerOptions.VERSION_1_7.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } else if (CompilerOptions.VERSION_1_8.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } } else if (CompilerOptions.VERSION_9.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (CompilerOptions.VERSION_1_7.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } else if (CompilerOptions.VERSION_1_8.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } else if (CompilerOptions.VERSION_9.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); } } else if (CompilerOptions.VERSION_10.equals(version)) { if (this.didSpecifySource) { Object source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (CompilerOptions.VERSION_1_7.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } else if (CompilerOptions.VERSION_1_8.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } else if (CompilerOptions.VERSION_9.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); } else if (CompilerOptions.VERSION_10.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } } else { this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } } else { if (!this.didSpecifyTarget) { if (this.didSpecifySource) { String source = this.options.get(CompilerOptions.OPTION_Source); if (CompilerOptions.VERSION_1_3.equals(source) || CompilerOptions.VERSION_1_4.equals(source)) { if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(source) || CompilerOptions.VERSION_1_6.equals(source)) { this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else { // 1.3 is the lowest version that can be specified as -source // The following check will ensure '0' is ignored. if (CompilerOptions.versionToJdkLevel(source) >= ClassFileConstants.JDK1_7) this.options.put(CompilerOptions.OPTION_TargetPlatform, source); } } else { if (CompilerOptions.versionToJdkLevel(version) > ClassFileConstants.JDK10) { this.options.put(CompilerOptions.OPTION_Source, version); this.options.put(CompilerOptions.OPTION_TargetPlatform, version); } } } } } else if (this.didSpecifySource) { String version = this.options.get(CompilerOptions.OPTION_Source); // default is source 1.3 target 1.2 and compliance 1.4 if (CompilerOptions.VERSION_1_4.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (CompilerOptions.VERSION_1_5.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); } else if (CompilerOptions.VERSION_1_6.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); } else if (CompilerOptions.VERSION_1_7.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); } else if (CompilerOptions.VERSION_1_8.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); } else if (CompilerOptions.VERSION_9.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); } else if (CompilerOptions.VERSION_10.equals(version)) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); } else { if (CompilerOptions.versionToJdkLevel(version) > ClassFileConstants.JDK10) { if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, version); if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, version); } } } final String sourceVersion = this.options.get(CompilerOptions.OPTION_Source); if (this.complianceLevel == 0) { final String compliance = this.options.get(CompilerOptions.OPTION_Compliance); this.complianceLevel = CompilerOptions.versionToJdkLevel(compliance); } if (sourceVersion.equals(CompilerOptions.VERSION_10) && this.complianceLevel < ClassFileConstants.JDK10) { // compliance must be 10 if source is 10 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_10)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_9) && this.complianceLevel < ClassFileConstants.JDK9) { // compliance must be 9 if source is 9 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_9)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_8) && this.complianceLevel < ClassFileConstants.JDK1_8) { // compliance must be 1.8 if source is 1.8 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_8)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_7) && this.complianceLevel < ClassFileConstants.JDK1_7) { // compliance must be 1.7 if source is 1.7 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_7)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_6) && this.complianceLevel < ClassFileConstants.JDK1_6) { // compliance must be 1.6 if source is 1.6 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_5) && this.complianceLevel < ClassFileConstants.JDK1_5) { // compliance must be 1.5 if source is 1.5 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4) && this.complianceLevel < ClassFileConstants.JDK1_4) { // compliance must be 1.4 if source is 1.4 throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$ } else { long ver = CompilerOptions.versionToJdkLevel(sourceVersion); if(this.complianceLevel < ver) throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), sourceVersion)); //$NON-NLS-1$ } if (this.enablePreview && this.complianceLevel != ClassFileConstants.getLatestJDKLevel()) { throw new IllegalArgumentException(this.bind("configure.unsupportedPreview")); //$NON-NLS-1$ } // check and set compliance/source/target compatibilities if (this.didSpecifyTarget) { final String targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform); // tolerate jsr14 target if (CompilerOptions.VERSION_JSR14.equals(targetVersion)) { // expecting source >= 1.5 if (CompilerOptions.versionToJdkLevel(sourceVersion) < ClassFileConstants.JDK1_5) { throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForGenericSource", targetVersion, sourceVersion)); //$NON-NLS-1$ } } else if (CompilerOptions.VERSION_CLDC1_1.equals(targetVersion)) { if (this.didSpecifySource && CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4) { throw new IllegalArgumentException(this.bind("configure.incompatibleSourceForCldcTarget", targetVersion, sourceVersion)); //$NON-NLS-1$ } if (this.complianceLevel >= ClassFileConstants.JDK1_5) { throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForCldcTarget", targetVersion, sourceVersion)); //$NON-NLS-1$ } } else { // target must be 1.8 if source is 1.8 if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_8 && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_8){ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_8)); //$NON-NLS-1$ } // target must be 1.7 if source is 1.7 if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_7 && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_7){ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_7)); //$NON-NLS-1$ } // target must be 1.6 if source is 1.6 if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6 && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_6)); //$NON-NLS-1$ } // target must be 1.5 if source is 1.5 if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_5 && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_5){ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_5)); //$NON-NLS-1$ } // target must be 1.4 if source is 1.4 if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4 && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_4){ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_4)); //$NON-NLS-1$ } // target cannot be greater than compliance level if (this.complianceLevel < CompilerOptions.versionToJdkLevel(targetVersion)){ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForTarget", this.options.get(CompilerOptions.OPTION_Compliance), targetVersion)); //$NON-NLS-1$ } } } } }