org.eclipse.jdt.internal.compiler.batch.Main Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ecj Show documentation
Show all versions of ecj Show documentation
Eclipse Compiler for Java(TM)
/*******************************************************************************
* 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 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 = ""; //$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.
*/
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 = 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);
}
}
}
/**
* @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 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()
}));
}
/**
* @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)));
}
}
/**
* @param options the given compiler options
*/
public void logOptions(Map options) {
if ((this.tagBits & Logger.XML) != 0) {
printTag(Logger.OPTIONS, null, true, false);
final Set> entriesSet = options.entrySet();
Map.Entry[] entries = entriesSet.toArray(new Map.Entry[entriesSet.size()]);
Arrays.sort(entries, new Comparator>() {
@Override
public int compare(Map.Entry o1, Map.Entry o2) {
Map.Entry entry1 = o1;
Map.Entry entry2 = o2;
return entry1.getKey().compareTo(entry2.getKey());
}
});
for (int i = 0, max = entries.length; i < max; i++) {
Map.Entry 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);
}
}
/**
* @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);
}
/**
* @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;
}
/**
* @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('.');
}
/**
* @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)));
}
/**
* @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
* @param usage
*/
public void logUsage(String usage) {
printlnOut(usage);
}
/**
* 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
*/
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);
}
/**
* @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);
}
/**
* @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 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("");//$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.
*/
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
*/
public static class ResourceBundleFactory {
private static HashMap 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 annotationPaths;
protected boolean annotationsFromClasspath;
private List addonExports = Collections.EMPTY_LIST;
private List addonReads = Collections.EMPTY_LIST;
public Set rootModules = Collections.EMPTY_SET;
public Set 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 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 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 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 {@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 {@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 {@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 {@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 customDefaultOptions) {
this(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null /* progress */);
}
public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map 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 paths, String currentClasspathName,
ArrayList 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 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
*
*
* @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 bootclasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
String sourcepathClasspathArg = null;
String modulepathArg = null;
String moduleSourcepathArg = null;
ArrayList sourcepathClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
ArrayList classpaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
ArrayList extdirsClasspaths = null;
ArrayList 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 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();
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 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 opts = new HashMap(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 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[] entries = this.options.entrySet().toArray(new Map.Entry[this.options.size()]);
for (int i = 0, max = entries.length; i < max; i++) {
Map.Entry 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> entrySet = this.options.entrySet();
for (Entry 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 handleBootclasspath(ArrayList bootclasspaths, String customEncoding) {
final int bootclasspathsSize;
ArrayList 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 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 handleModulepath(String arg) {
ArrayList modulePaths = processModulePathEntries(arg);
ArrayList 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 handleModuleSourcepath(String arg) {
ArrayList modulePaths = processModulePathEntries(arg);
ArrayList 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 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 handleClasspath(ArrayList classpaths, String customEncoding) {
ArrayList 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 result = new ArrayList<>();
HashMap 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 linkedJars = current.fetchLinkedJars(problemReporter);
if (linkedJars != null) {
initial.addAll(0, linkedJars);
}
}
}
return result;
}
/*
* External API
*/
protected ArrayList handleEndorseddirs(ArrayList 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 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 handleExtdirs(ArrayList 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 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 {@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 {@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 customDefaultOptions) {
this.initialize(outWriter, errWriter, systemExit, customDefaultOptions, null /* progress */);
}
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map 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> iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) {
Map.Entry 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 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 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 processModulePathEntries(String arg) {
ArrayList 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 paths,
final String currentPath, String customEncoding, boolean isSourceOnly,
boolean rejectDestinationPathOnJars) {
String currentClasspathName = null;
String currentDestinationPath = null;
ArrayList currentRuleSpecs = new ArrayList<>(defaultSize);
StringTokenizer tokenizer = new StringTokenizer(currentPath,
File.pathSeparator + "[]", true); //$NON-NLS-1$
ArrayList 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 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.
*/
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 bootclasspaths,
String sourcepathClasspathArg,
ArrayList sourcepathClasspaths,
ArrayList classpaths,
String modulePath,
String moduleSourcepath,
ArrayList extdirsClasspaths,
ArrayList 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 allPaths = null;
long jdkLevel = validateClasspathOptions(bootclasspaths, endorsedDirClasspaths, extdirsClasspaths);
if (this.releaseVersion != null && this.complianceLevel < jdkLevel) {
// TODO: Revisit for access rules
allPaths = new ArrayList();
allPaths.add(
FileSystem.getOlderSystemRelease(this.javaHomeCache.getAbsolutePath(), this.releaseVersion, null));
} else {
allPaths = handleBootclasspath(bootclasspaths, customEncoding);
}
List cp = handleClasspath(classpaths, customEncoding);
List mp = handleModulepath(modulePath);
List msp = handleModuleSourcepath(moduleSourcepath);
ArrayList 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 extdirs = handleExtdirs(extdirsClasspaths);
List 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 bootclasspaths, ArrayList endorsedDirClasspaths, ArrayList 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$
}
}
}
}
}