| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.compiler.batch; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.LineNumberReader; |
| import java.io.PrintWriter; |
| import java.io.StringReader; |
| import java.io.UnsupportedEncodingException; |
| import java.lang.reflect.Field; |
| import java.text.MessageFormat; |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.MissingResourceException; |
| import java.util.ResourceBundle; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| import org.eclipse.jdt.core.compiler.IProblem; |
| 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.classfmt.ClassFileConstants; |
| 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.INameEnvironment; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; |
| import org.eclipse.jdt.internal.compiler.util.Messages; |
| import org.eclipse.jdt.internal.compiler.util.SuffixConstants; |
| import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; |
| import org.eclipse.jdt.internal.compiler.util.Util; |
| |
| public class Main implements ProblemSeverities, SuffixConstants { |
| |
| public static class Logger { |
| 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_ID = "id"; //$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_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_VERSION = "version"; //$NON-NLS-1$ |
| private static final String COMPILER_NAME = "name"; //$NON-NLS-1$ |
| private static final String EXCEPTION = "exception"; //$NON-NLS-1$ |
| private static final String ERROR = "ERROR"; //$NON-NLS-1$ |
| private static final String ERROR_TAG = "error"; //$NON-NLS-1$ |
| 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 OPTION = "option"; //$NON-NLS-1$ |
| private static final String OPTIONS = "options"; //$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_ID = "id"; //$NON-NLS-1$ |
| private static final String PROBLEM_LINE = "line"; //$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_START = "charStart"; //$NON-NLS-1$ |
| private static final String PROBLEM_SOURCE_END = "charEnd"; //$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 XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$ |
| private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler SYSTEM \"compiler.dtd\">"; //$NON-NLS-1$ |
| |
| private static final HashMap FIELD_TABLE = new HashMap(); |
| static { |
| try { |
| Class c = IProblem.class; |
| Field[] fields = c.getFields(); |
| for (int i = 0, max = fields.length; i < max; i++) { |
| Field field = fields[i]; |
| FIELD_TABLE.put(field.get(null), field.getName()); |
| } |
| } catch (SecurityException e) { |
| e.printStackTrace(); |
| } catch (IllegalArgumentException e) { |
| e.printStackTrace(); |
| } catch (IllegalAccessException e) { |
| e.printStackTrace(); |
| } |
| } |
| private static void appendEscapedChar(StringBuffer buffer, char c) { |
| String replacement= getReplacement(c); |
| if (replacement != null) { |
| buffer.append('&'); |
| buffer.append(replacement); |
| buffer.append(';'); |
| } else { |
| buffer.append(c); |
| } |
| } |
| private static String getEscaped(String s) { |
| StringBuffer result= new StringBuffer(s.length() + 10); |
| for (int i= 0; i < s.length(); ++i) |
| appendEscapedChar(result, s.charAt(i)); |
| return result.toString(); |
| } |
| private static String getReplacement(char c) { |
| // Encode special XML characters into the equivalent character references. |
| // These five are defined by default for all XML documents. |
| switch (c) { |
| case '<' : |
| return "lt"; //$NON-NLS-1$ |
| case '>' : |
| return "gt"; //$NON-NLS-1$ |
| case '"' : |
| return "quot"; //$NON-NLS-1$ |
| case '\'' : |
| return "apos"; //$NON-NLS-1$ |
| case '&' : |
| return "amp"; //$NON-NLS-1$ |
| } |
| return null; |
| } |
| private PrintWriter err; |
| boolean isXml; |
| private PrintWriter log; |
| private PrintWriter out; |
| private int tab; |
| private HashMap parameters; |
| |
| public Logger(PrintWriter out, PrintWriter err) { |
| this.out = out; |
| this.err = err; |
| this.isXml = false; |
| this.parameters = new HashMap(); |
| } |
| |
| 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.isXml) { |
| this.endTag(COMPILER); |
| this.flush(); |
| } |
| this.log.close(); |
| } |
| } |
| |
| /** |
| * |
| */ |
| public void compiling() { |
| this.printlnOut(Main.bind("progress.compiling")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Used to stop logging problems. |
| * Only use in xml mode. |
| */ |
| private void endLoggingProblems() { |
| this.endTag(PROBLEMS); |
| } |
| public void endLoggingSource() { |
| if (this.isXml) { |
| this.endTag(SOURCE); |
| } |
| } |
| public void endLoggingSources() { |
| if (this.isXml) { |
| this.endTag(SOURCES); |
| } |
| } |
| public void endLoggingTasks() { |
| if (this.isXml) { |
| this.endTag(TASKS); |
| } |
| } |
| public void endTag(String name) { |
| tab--; |
| this.printTag('/' + name, null, true, false); |
| this.tab--; |
| } |
| |
| private void extractContext(IProblem problem, char[] unitSource) { |
| //sanity ..... |
| int startPosition = problem.getSourceStart(); |
| int endPosition = problem.getSourceEnd(); |
| if ((startPosition > endPosition) |
| || ((startPosition < 0) && (endPosition < 0))) { |
| this.parameters.put(VALUE, Messages.problem_noSourceInformation); |
| this.parameters.put(SOURCE_START, "-1"); //$NON-NLS-1$ |
| this.parameters.put(SOURCE_END, "-1"); //$NON-NLS-1$ |
| 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 length = unitSource.length, 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(VALUE, String.valueOf(buffer)); |
| this.parameters.put(SOURCE_START, Integer.toString(startPosition - begin)); |
| this.parameters.put(SOURCE_END, Integer.toString(endPosition - begin)); |
| } |
| |
| private String getFieldName(int id) { |
| return (String) FIELD_TABLE.get(new Integer(id)); |
| } |
| |
| public void flush() { |
| this.out.flush(); |
| this.err.flush(); |
| if (this.log != null) { |
| this.log.flush(); |
| } |
| } |
| public void logAverage(long[] times, long lineCount) { |
| Arrays.sort(times); |
| final int length = times.length; |
| long sum = 0; |
| for (int i = 1, max = length - 1; i < max; i++) { |
| sum += times[i]; |
| } |
| long time = sum / (length - 2); |
| this.printlnOut(Main.bind( |
| "compile.averageTime", //$NON-NLS-1$ |
| new String[] { |
| String.valueOf(lineCount), |
| String.valueOf(time), |
| String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) })); |
| } |
| public void logClasspath(FileSystem.Classpath[] classpaths) { |
| if (classpaths == null) return; |
| if (this.isXml) { |
| final int length = classpaths.length; |
| if (length != 0) { |
| // generate xml output |
| this.printTag(CLASSPATHS, null, true, false); |
| for (int i = 0; i < length; i++) { |
| this.parameters.clear(); |
| String classpath = classpaths[i].getPath(); |
| parameters.put(PATH, classpath); |
| File f = new File(classpath); |
| String id = null; |
| if (f.isFile()) { |
| if (Util.isArchiveFileName(classpath)) { |
| id = CLASSPATH_JAR; |
| } else { |
| id = CLASSPATH_FILE; |
| } |
| } else if (f.isDirectory()) { |
| id = CLASSPATH_FOLDER; |
| } |
| if (id != null) { |
| this.parameters.put(CLASSPATH_ID, id); |
| this.printTag(CLASSPATH, parameters, true, true); |
| } |
| } |
| this.endTag(CLASSPATHS); |
| } |
| } |
| |
| } |
| |
| public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) { |
| if (this.isXml) { |
| 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.clear(); |
| this.parameters.put(PATH, f.getCanonicalPath()); |
| this.printTag(CLASS_FILE, this.parameters, true, true); |
| } catch (IOException e) { |
| this.logNoClassFileCreated(fileName); |
| } |
| } |
| } |
| |
| public void logCommandLineArguments(String[] commandLineArguments) { |
| if (commandLineArguments == null) return; |
| if (this.isXml) { |
| final int length = commandLineArguments.length; |
| if (length != 0) { |
| // generate xml output |
| this.printTag(COMMAND_LINE_ARGUMENTS, null, true, false); |
| parameters.clear(); |
| for (int i = 0; i < length; i++) { |
| parameters.put(VALUE, commandLineArguments[i]); |
| this.printTag(COMMAND_LINE_ARGUMENT, parameters, true, true); |
| } |
| this.endTag(COMMAND_LINE_ARGUMENTS); |
| } |
| } |
| } |
| |
| /** |
| * @param e the given exception to log |
| */ |
| public void logException(Exception e) { |
| final String message = e.getMessage(); |
| if (isXml) { |
| parameters.clear(); |
| parameters.put(MESSAGE, message); |
| parameters.put(CLASS, e.getClass()); |
| this.printTag(EXCEPTION, parameters, true, true); |
| } |
| this.printlnErr(message); |
| } |
| |
| /** |
| * @param wrongClasspath |
| * the given wrong classpath entry |
| */ |
| public void logIncorrectClasspath(String wrongClasspath) { |
| if (isXml) { |
| this.parameters.clear(); |
| this.parameters.put(MESSAGE, Main.bind("configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$ |
| this.printTag(ERROR_TAG, this.parameters, true, true); |
| } |
| this.printlnErr(Main.bind( |
| "configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * |
| */ |
| public void logNoClassFileCreated(String fileName) { |
| if (isXml) { |
| this.parameters.clear(); |
| this.parameters.put(MESSAGE, Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$ |
| this.printTag(ERROR_TAG, this.parameters, true, true); |
| } |
| this.printlnErr(Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$ |
| } |
| |
| public void logNoClasspath() { |
| if (isXml) { |
| this.parameters.clear(); |
| this.parameters.put(MESSAGE, Main.bind("configure.noClasspath")); //$NON-NLS-1$ |
| this.printTag(ERROR_TAG, this.parameters, true, true); |
| } |
| this.printlnErr(Main.bind("configure.noClasspath")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param exportedClassFilesCounter |
| */ |
| public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) { |
| if (isXml) { |
| this.parameters.clear(); |
| this.parameters.put(VALUE, new Integer(exportedClassFilesCounter)); |
| this.printTag(NUMBER_OF_CLASSFILES, this.parameters, true, true); |
| } |
| if (exportedClassFilesCounter == 1) { |
| this.printlnOut(Main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$ |
| } else { |
| this.printlnOut(Main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$ |
| String.valueOf(exportedClassFilesCounter))); |
| } |
| } |
| |
| /** |
| * @param options the given compiler options |
| */ |
| public void logOptions(Map options) { |
| if (this.isXml) { |
| this.printTag(OPTIONS, null, true, false); |
| final Set keySet = options.keySet(); |
| Object[] keys = keySet.toArray(); |
| Arrays.sort(keys); |
| for (int i = 0, max = keys.length; i < max; i++) { |
| this.parameters.clear(); |
| Object key = keys[i]; |
| this.parameters.put(KEY, key); |
| this.parameters.put(VALUE, options.get(key)); |
| this.printTag(OPTION, this.parameters, true, true); |
| } |
| this.endTag(OPTIONS); |
| } |
| } |
| |
| private void logProblem(IProblem problem, int localErrorCount, |
| int globalErrorCount, char[] unitSource) { |
| if (localErrorCount == 0) { |
| this.printlnErr("----------"); //$NON-NLS-1$ |
| } |
| this.printlnErr(problem.isError() ? |
| Main.bind( |
| "requestor.error", //$NON-NLS-1$ |
| Integer.toString(globalErrorCount), |
| new String(problem.getOriginatingFileName())) |
| : Main.bind( |
| "requestor.warning", //$NON-NLS-1$ |
| Integer.toString(globalErrorCount), |
| new String(problem.getOriginatingFileName()))); |
| try { |
| this.printlnErr(((DefaultProblem) problem).errorReportSource(unitSource)); |
| this.printlnErr(problem.getMessage()); |
| } catch (Exception e) { |
| this.printlnErr(Main.bind( |
| "requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$ |
| } |
| this.printlnErr("----------"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param globalProblemsCount |
| * @param globalErrorsCount |
| * @param globalWarningsCount |
| */ |
| public void logProblemsSummary(int globalProblemsCount, |
| int globalErrorsCount, int globalWarningsCount, int globalTasksCount) { |
| if (this.isXml) { |
| // generate xml |
| parameters.clear(); |
| parameters.put(NUMBER_OF_PROBLEMS, new Integer(globalProblemsCount)); |
| parameters.put(NUMBER_OF_ERRORS, new Integer(globalErrorsCount)); |
| parameters.put(NUMBER_OF_WARNINGS, new Integer(globalWarningsCount)); |
| parameters.put(NUMBER_OF_TASKS, new Integer(globalTasksCount)); |
| this.printTag(PROBLEM_SUMMARY, parameters, true, true); |
| } |
| if (globalProblemsCount == 1) { |
| String message = null; |
| if (globalErrorsCount == 1) { |
| message = Main.bind("compile.oneError"); //$NON-NLS-1$ |
| } else { |
| message = Main.bind("compile.oneWarning"); //$NON-NLS-1$ |
| } |
| this.printErr(Main.bind("compile.oneProblem", message)); //$NON-NLS-1$ |
| } else { |
| String errorMessage = null; |
| String warningMessage = null; |
| if (globalErrorsCount > 0) { |
| if (globalErrorsCount == 1) { |
| errorMessage = Main.bind("compile.oneError"); //$NON-NLS-1$ |
| } else { |
| errorMessage = Main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$ |
| } |
| } |
| int warningsNumber = globalWarningsCount + globalTasksCount; |
| if (warningsNumber > 0) { |
| if (warningsNumber == 1) { |
| warningMessage = Main.bind("compile.oneWarning"); //$NON-NLS-1$ |
| } else { |
| warningMessage = Main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$ |
| } |
| } |
| if (errorMessage == null || warningMessage == null) { |
| if (errorMessage == null) { |
| this.printErr(Main.bind( |
| "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$ |
| String.valueOf(globalProblemsCount), |
| warningMessage)); |
| } else { |
| this.printErr(Main.bind( |
| "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$ |
| String.valueOf(globalProblemsCount), |
| errorMessage)); |
| } |
| } else { |
| this.printErr(Main.bind( |
| "compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$ |
| new String[] { |
| String.valueOf(globalProblemsCount), |
| errorMessage, |
| warningMessage |
| })); |
| } |
| } |
| } |
| |
| public int logProblems(IProblem[] problems, char[] unitSource, Main currentMain) { |
| final int count = problems.length; |
| int localErrorCount = 0; |
| int localProblemCount = 0; |
| if (count != 0) { |
| if (this.isXml) { |
| int errors = 0; |
| int warnings = 0; |
| int tasks = 0; |
| for (int i = 0; i < count; i++) { |
| IProblem problem = problems[i]; |
| if (problem != null) { |
| currentMain.globalProblemsCount++; |
| this.logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource); |
| localProblemCount++; |
| if (problem.isError()) { |
| localErrorCount++; |
| errors++; |
| currentMain.globalErrorsCount++; |
| } else if (problem.getID() == IProblem.Task) { |
| currentMain.globalTasksCount++; |
| tasks++; |
| } else { |
| currentMain.globalWarningsCount++; |
| warnings++; |
| } |
| } |
| } |
| if ((errors + warnings) != 0) { |
| this.startLoggingProblems(errors, warnings); |
| for (int i = 0; i < count; i++) { |
| IProblem problem = problems[i]; |
| if (problem!= null) { |
| if (problem.getID() != IProblem.Task) { |
| this.logXmlProblem(problem, unitSource); |
| } |
| } |
| } |
| this.endLoggingProblems(); |
| } |
| if (tasks != 0) { |
| this.startLoggingTasks(tasks); |
| for (int i = 0; i < count; i++) { |
| IProblem problem = problems[i]; |
| if (problem!= null) { |
| if (problem.getID() == IProblem.Task) { |
| this.logXmlTask(problem, unitSource); |
| } |
| } |
| } |
| this.endLoggingTasks(); |
| } |
| } else { |
| for (int i = 0; i < count; i++) { |
| if (problems[i] != null) { |
| currentMain.globalProblemsCount++; |
| this.logProblem(problems[i], localProblemCount, currentMain.globalProblemsCount, unitSource); |
| localProblemCount++; |
| if (problems[i].isError()) { |
| localErrorCount++; |
| currentMain.globalErrorsCount++; |
| } else { |
| currentMain.globalWarningsCount++; |
| } |
| } |
| } |
| } |
| } |
| return localErrorCount; |
| } |
| |
| /** |
| * |
| */ |
| public void logProgress() { |
| this.printOut('.'); |
| } |
| |
| /** |
| * @param i |
| * the current repetition number |
| * @param repetitions |
| * the given number of repetitions |
| */ |
| public void logRepetition(int i, int repetitions) { |
| this.printlnOut(Main.bind("compile.repetition", //$NON-NLS-1$ |
| String.valueOf(i + 1), String.valueOf(repetitions))); |
| } |
| |
| public void printStats(Main main) { |
| final boolean isTimed = main.timing; |
| if (isXml) { |
| this.printTag(STATS, null, true, false); |
| } |
| if (isTimed) { |
| long time = System.currentTimeMillis() - main.startTime; |
| this.logTiming(time, main.lineCount); |
| if (main.times != null) { |
| main.times[main.timesCounter++] = time; |
| } |
| } |
| if (main.globalProblemsCount > 0) { |
| this.logProblemsSummary(main.globalProblemsCount, main.globalErrorsCount, main.globalWarningsCount, main.globalTasksCount); |
| } |
| if (main.exportedClassFilesCounter != 0 |
| && (main.showProgress || isTimed || main.verbose)) { |
| this.logNumberOfClassFilesGenerated(main.exportedClassFilesCounter); |
| } |
| if (isXml) { |
| this.endTag(STATS); |
| } |
| } |
| /** |
| * @param time |
| * @param lineCount |
| */ |
| public void logTiming(long time, long lineCount) { |
| if (isXml) { |
| this.parameters.clear(); |
| this.parameters.put(VALUE, new Long(time)); |
| this.printTag(TIME, this.parameters, true, true); |
| this.parameters.clear(); |
| this.parameters.put(VALUE, new Long(lineCount)); |
| this.printTag(NUMBER_OF_LINES, this.parameters, true, true); |
| } |
| if (lineCount != 0) { |
| this.printlnOut(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 { |
| this.printlnOut(Main.bind("compile.totalTime", String.valueOf(time))); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Print the usage of the compiler |
| * @param usage |
| */ |
| public void logUsage(String usage) { |
| this.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.isXml) { |
| final String version = Main.bind("misc.version", //$NON-NLS-1$ |
| new String[] { |
| Main.bind("compiler.name"), //$NON-NLS-1$ |
| Main.bind("compiler.version"), //$NON-NLS-1$ |
| 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 = Main.bind("misc.version", //$NON-NLS-1$ |
| new String[] { |
| Main.bind("compiler.name"), //$NON-NLS-1$ |
| Main.bind("compiler.version"), //$NON-NLS-1$ |
| Main.bind("compiler.copyright") //$NON-NLS-1$ |
| } |
| ); |
| this.out.println(version); |
| this.out.flush(); |
| } |
| } |
| |
| /** |
| * Print the usage of wrong JDK |
| */ |
| public void logWrongJDK() { |
| if (isXml) { |
| parameters.clear(); |
| parameters.put(MESSAGE, Main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$ |
| this.printTag(ERROR, parameters, true, true); |
| } |
| this.printlnErr(Main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param problem |
| * the given problem to log |
| * @param unitSource |
| * the given unit source |
| */ |
| private void logXmlProblem(IProblem problem, char[] unitSource) { |
| final int sourceStart = problem.getSourceStart(); |
| final int sourceEnd = problem.getSourceEnd(); |
| this.parameters.clear(); |
| this.parameters.put(PROBLEM_ID, getFieldName(problem.getID())); |
| this.parameters.put(PROBLEM_SEVERITY, problem.isError() ? ERROR : WARNING); |
| this.parameters.put(PROBLEM_LINE, new Integer(problem.getSourceLineNumber())); |
| this.parameters.put(PROBLEM_SOURCE_START, new Integer(sourceStart)); |
| this.parameters.put(PROBLEM_SOURCE_END, new Integer(sourceEnd)); |
| this.printTag(PROBLEM_TAG, parameters, true, false); |
| this.parameters.clear(); |
| this.parameters.put(VALUE, problem.getMessage()); |
| this.printTag(PROBLEM_MESSAGE, parameters, true, true); |
| this.parameters.clear(); |
| extractContext(problem, unitSource); |
| this.printTag(SOURCE_CONTEXT, this.parameters, true, true); |
| String[] arguments = problem.getArguments(); |
| final int length = arguments.length; |
| if (length != 0) { |
| this.printTag(PROBLEM_ARGUMENTS, null, true, false); |
| this.parameters.clear(); |
| for (int i = 0; i < length; i++) { |
| this.parameters.put(PROBLEM_ARGUMENT_VALUE, arguments[i]); |
| this.printTag(PROBLEM_ARGUMENT, this.parameters, true, true); |
| } |
| this.endTag(PROBLEM_ARGUMENTS); |
| } |
| this.endTag(PROBLEM_TAG); |
| } |
| /** |
| * @param problem |
| * the given problem to log |
| * @param unitSource |
| * the given unit source |
| */ |
| private void logXmlTask(IProblem problem, char[] unitSource) { |
| this.parameters.clear(); |
| this.parameters.put(PROBLEM_LINE, new Integer(problem.getSourceLineNumber())); |
| this.parameters.put(PROBLEM_SOURCE_START, new Integer(problem.getSourceStart())); |
| this.parameters.put(PROBLEM_SOURCE_END, new Integer(problem.getSourceEnd())); |
| this.printTag(TASK, this.parameters, true, false); |
| this.parameters.clear(); |
| this.parameters.put(VALUE, problem.getMessage()); |
| this.printTag(PROBLEM_MESSAGE, this.parameters, true, true); |
| this.parameters.clear(); |
| extractContext(problem, unitSource); |
| this.printTag(SOURCE_CONTEXT, this.parameters, true, true); |
| this.endTag(TASK); |
| } |
| private void printErr(String s) { |
| this.err.print(s); |
| if (!this.isXml && this.log != null) { |
| this.log.print(s); |
| } |
| } |
| |
| private void printlnErr(String s) { |
| this.err.println(s); |
| if (!this.isXml && this.log != null) { |
| this.log.println(s); |
| } |
| } |
| |
| private void printlnOut(String s) { |
| this.out.println(s); |
| if (!this.isXml && this.log != null) { |
| this.log.println(s); |
| } |
| } |
| |
| /** |
| * |
| */ |
| public void printNewLine() { |
| this.out.println(); |
| } |
| |
| private void printOut(char c) { |
| this.out.print(c); |
| } |
| public void printTag(String name, HashMap params, boolean insertNewLine, boolean closeTag) { |
| for (int i= this.tab; i > 0; i--) this.log.print('\t'); |
| StringBuffer buffer= new StringBuffer(); |
| buffer.append("<"); //$NON-NLS-1$ |
| buffer.append(name); |
| if (params != null) { |
| for (Enumeration enumeration = Collections.enumeration(params.keySet()); enumeration.hasMoreElements();) { |
| buffer.append(" "); //$NON-NLS-1$ |
| String key= (String) enumeration.nextElement(); |
| buffer.append(key); |
| buffer.append("=\""); //$NON-NLS-1$ |
| buffer.append(getEscaped(String.valueOf(params.get(key)))); |
| buffer.append("\""); //$NON-NLS-1$ |
| } |
| } |
| if (closeTag) { |
| buffer.append("/>"); //$NON-NLS-1$ |
| } else { |
| buffer.append(">"); //$NON-NLS-1$ |
| this.tab++; |
| } |
| if (insertNewLine) { |
| this.log.println(String.valueOf(buffer)); |
| } else { |
| this.log.print(String.valueOf(buffer)); |
| } |
| } |
| |
| public void setLog(String logFileName) throws InvalidInputException { |
| final Date date = new Date(); |
| final SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM yyyy HH:mm:ss", Locale.getDefault());//$NON-NLS-1$ |
| try { |
| this.log = new PrintWriter(new FileOutputStream(logFileName, false)); |
| int index = logFileName.lastIndexOf('.'); |
| if (index != -1) { |
| if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$ |
| this.isXml = true; |
| this.log.println(XML_HEADER); |
| // insert time stamp as comment |
| this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$ |
| this.log.println(XML_DTD_DECLARATION); |
| this.tab = 0; |
| parameters.clear(); |
| parameters.put(COMPILER_NAME, Main.bind("compiler.name")); //$NON-NLS-1$ |
| parameters.put(COMPILER_VERSION, Main.bind("compiler.version")); //$NON-NLS-1$ |
| parameters.put(COMPILER_COPYRIGHT, Main.bind("compiler.copyright")); //$NON-NLS-1$ |
| this.printTag(COMPILER, parameters, true, false); |
| } else { |
| this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$ |
| } |
| } else { |
| this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$ |
| } |
| } catch (FileNotFoundException e) { |
| throw new InvalidInputException(Main.bind("configure.cannotOpenLog")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Used to start logging problems. |
| * Only use in xml mode. |
| */ |
| private void startLoggingProblems(int errors, int warnings) { |
| parameters.clear(); |
| parameters.put(NUMBER_OF_PROBLEMS, new Integer(errors + warnings)); |
| parameters.put(NUMBER_OF_ERRORS, new Integer(errors)); |
| parameters.put(NUMBER_OF_WARNINGS, new Integer(warnings)); |
| this.printTag(PROBLEMS, this.parameters, true, false); |
| } |
| public void startLoggingSource(CompilationResult compilationResult) { |
| if (this.isXml) { |
| ICompilationUnit compilationUnit = compilationResult.compilationUnit; |
| char[] fileName = compilationUnit.getFileName(); |
| File f = new File(new String(fileName)); |
| if (fileName != null) { |
| this.parameters.clear(); |
| if (compilationUnit != null) { |
| this.parameters.put(PATH, f.getAbsolutePath()); |
| } |
| } |
| this.printTag(SOURCE, this.parameters, true, false); |
| } |
| } |
| public void startLoggingSources() { |
| if (this.isXml) { |
| this.printTag(SOURCES, null, true, false); |
| } |
| } |
| public void startLoggingTasks(int tasks) { |
| if (this.isXml) { |
| parameters.clear(); |
| parameters.put(NUMBER_OF_TASKS, new Integer(tasks)); |
| this.printTag(TASKS, this.parameters, true, false); |
| } |
| } |
| } |
| static { |
| relocalize(); |
| } |
| |
| /* Bundle containing messages */ |
| public static ResourceBundle bundle; |
| public final static String bundleName = |
| "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$ |
| |
| FileSystem.Classpath[] checkedClasspaths; |
| public String destinationPath; |
| public String[] encodings; |
| public Logger logger; |
| public int exportedClassFilesCounter; |
| public String[] filenames; |
| public boolean generatePackagesStructure; |
| public int globalErrorsCount; |
| public int globalTasksCount; |
| public int globalProblemsCount; |
| public int globalWarningsCount; |
| public long lineCount; |
| public String log; |
| |
| public boolean noWarn = false; |
| |
| public Map options; |
| public CompilerOptions compilerOptions; // read-only |
| |
| public boolean proceed = true; |
| public boolean proceedOnError = false; |
| public boolean produceRefInfo = false; |
| public int repetitions; |
| public int maxProblems; |
| public boolean showProgress = false; |
| public boolean systemExitWhenFinished = true; |
| public long startTime; |
| public boolean timing = false; |
| public long[] times; |
| public int timesCounter; |
| public boolean verbose = false; |
| |
| public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) { |
| this(outWriter, errWriter, systemExitWhenFinished, null); |
| } |
| |
| public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions) { |
| this.logger = new Logger(outWriter, errWriter); |
| this.systemExitWhenFinished = systemExitWhenFinished; |
| this.options = new CompilerOptions().getMap(); |
| if (customDefaultOptions != null) { |
| for (Iterator iter = customDefaultOptions.keySet().iterator(); iter.hasNext();) { |
| Object key = iter.next(); |
| this.options.put(key, customDefaultOptions.get(key)); |
| } |
| } |
| } |
| |
| /* |
| * Lookup the message with the given ID in this catalog |
| */ |
| public static 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 static 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 static 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 static String bind(String id, String[] arguments) { |
| if (id == null) |
| return "No message available"; //$NON-NLS-1$ |
| String message = null; |
| try { |
| message = 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: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$ |
| } |
| return MessageFormat.format(message, arguments); |
| } |
| |
| /* |
| * Internal IDE API |
| */ |
| public static boolean compile(String commandLine) { |
| |
| return compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err)); |
| } |
| |
| /* |
| * Internal IDE API for test harness purpose |
| */ |
| public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter) { |
| |
| return new Main(outWriter, errWriter, false).compile(tokenize(commandLine)); |
| } |
| |
| /* |
| * External API |
| */ |
| |
| public static void main(String[] argv) { |
| new Main(new PrintWriter(System.out), new PrintWriter(System.err), true).compile(argv); |
| } |
| |
| /** |
| * Creates a NLS catalog for the given locale. |
| */ |
| public static void relocalize() { |
| try { |
| bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault()); |
| } catch(MissingResourceException e) { |
| System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$ |
| throw e; |
| } |
| } |
| |
| 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 = ""; //$NON-NLS-1$ |
| 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++] = ""; //$NON-NLS-1$ |
| } |
| 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; |
| } |
| |
| /* |
| * Low-level API performing the actual compilation |
| */ |
| public boolean compile(String[] argv) { |
| |
| // decode command line arguments |
| try { |
| configure(argv); |
| if (this.proceed) { |
| // if (this.verbose) { |
| // System.out.println(new CompilerOptions(this.options)); |
| // } |
| if (this.showProgress) this.logger.compiling(); |
| for (int i = 0; i < this.repetitions; i++) { |
| this.globalProblemsCount = 0; |
| this.globalErrorsCount = 0; |
| this.globalWarningsCount = 0; |
| this.globalTasksCount = 0; |
| this.lineCount = 0; |
| this.exportedClassFilesCounter = 0; |
| |
| if (this.repetitions > 1) { |
| this.logger.flush(); |
| this.logger.logRepetition(i, this.repetitions); |
| } |
| // request compilation |
| performCompilation(); |
| } |
| if (this.times != null) { |
| this.logger.logAverage(this.times, this.lineCount); |
| } |
| if (this.showProgress) this.logger.printNewLine(); |
| } |
| if (this.systemExitWhenFinished) { |
| this.logger.flush(); |
| this.logger.close(); |
| System.exit(this.globalErrorsCount > 0 ? -1 : 0); |
| } |
| } catch (InvalidInputException e) { |
| this.logger.logException(e); |
| if (this.systemExitWhenFinished) { |
| this.logger.flush(); |
| this.logger.close(); |
| System.exit(-1); |
| } |
| return false; |
| } catch (RuntimeException e) { // internal compiler failure |
| if (this.systemExitWhenFinished) { |
| this.logger.flush(); |
| this.logger.close(); |
| System.exit(-1); |
| } |
| return false; |
| } finally { |
| this.logger.flush(); |
| this.logger.close(); |
| } |
| if (this.globalErrorsCount == 0) |
| return true; |
| return false; |
| } |
| |
| /* |
| Decode the command line arguments |
| */ |
| public void configure(String[] argv) throws InvalidInputException { |
| |
| if ((argv == null) || (argv.length == 0)) { |
| printUsage(); |
| return; |
| } |
| final int InsideClasspath = 1; |
| final int InsideDestinationPath = 2; |
| final int TargetSetting = 4; |
| final int InsideLog = 8; |
| final int InsideRepetition = 16; |
| final int InsideSource = 32; |
| final int InsideDefaultEncoding = 64; |
| final int InsideBootClasspath = 128; |
| final int InsideMaxProblems = 256; |
| final int InsideExtdirs = 512; |
| final int InsideSourcepath = 1024; |
| |
| final int Default = 0; |
| int DEFAULT_SIZE_CLASSPATH = 4; |
| ArrayList bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH), |
| extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH), |
| extdirsNames = new ArrayList(DEFAULT_SIZE_CLASSPATH), |
| sourcepathClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH), |
| classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH); |
| String currentClasspathName = null; |
| ArrayList currentRuleSpecs = new ArrayList(DEFAULT_SIZE_CLASSPATH); |
| int index = -1, filesCount = 0, argCount = argv.length; |
| int mode = Default; |
| this.repetitions = 0; |
| boolean printUsageRequired = false; |
| boolean printVersionRequired = false; |
| |
| boolean didSpecifySource = false; |
| boolean didSpecifyCompliance = false; |
| boolean didSpecifyDefaultEncoding = false; |
| boolean didSpecifyTarget = false; |
| boolean didSpecifyDeprecation = false; |
| boolean didSpecifyWarnings = false; |
| boolean useEnableJavadoc = false; |
| |
| String customEncoding = null; |
| String currentArg = ""; //$NON-NLS-1$ |
| |
| // 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 InvalidInputException( |
| Main.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; |
| while (++index < argCount) { |
| |
| if (customEncoding != null) { |
| throw new InvalidInputException( |
| Main.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$ |
| } |
| |
| currentArg = newCommandLineArgs[index]; |
| |
| customEncoding = null; |
| if (currentArg.endsWith("]") && !(mode == InsideBootClasspath || mode == InsideClasspath || //$NON-NLS-1$ |
| mode == InsideSourcepath) ) { |
| // look for encoding specification |
| int encodingStart = currentArg.indexOf('[') + 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 InvalidInputException( |
| Main.bind("configure.unsupportedEncoding", customEncoding)); //$NON-NLS-1$ |
| } |
| } |
| currentArg = currentArg.substring(0, encodingStart - 1); |
| } |
| } |
| |
| if (currentArg.endsWith(SUFFIX_STRING_java)) { |
| if (this.filenames == null) { |
| this.filenames = new String[argCount - index]; |
| this.encodings = 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); |
| } |
| this.filenames[filesCount] = currentArg; |
| this.encodings[filesCount++] = customEncoding; |
| customEncoding = null; |
| mode = Default; |
| continue; |
| } |
| if (currentArg.equals("-log")) { //$NON-NLS-1$ |
| if (this.log != null) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$ |
| mode = InsideLog; |
| continue; |
| } |
| if (currentArg.equals("-repeat")) { //$NON-NLS-1$ |
| if (this.repetitions > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$ |
| mode = InsideRepetition; |
| continue; |
| } |
| if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$ |
| if (this.maxProblems > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$ |
| mode = InsideMaxProblems; |
| continue; |
| } |
| if (currentArg.equals("-source")) { //$NON-NLS-1$ |
| mode = InsideSource; |
| continue; |
| } |
| if (currentArg.equals("-encoding")) { //$NON-NLS-1$ |
| mode = InsideDefaultEncoding; |
| continue; |
| } |
| if (currentArg.equals("-1.3")) { //$NON-NLS-1$ |
| if (didSpecifyCompliance) { |
| throw new InvalidInputException( |
| Main.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 InvalidInputException( |
| Main.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 InvalidInputException( |
| Main.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 InvalidInputException( |
| Main.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("-d")) { //$NON-NLS-1$ |
| if (this.destinationPath != null) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateOutputPath", currentArg)); //$NON-NLS-1$ |
| mode = InsideDestinationPath; |
| this.generatePackagesStructure = true; |
| continue; |
| } |
| if (currentArg.equals("-classpath") //$NON-NLS-1$ |
| || currentArg.equals("-cp")) { //$NON-NLS-1$ |
| mode = InsideClasspath; |
| continue; |
| } |
| if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$ |
| if (bootclasspaths.size() > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateBootClasspath", currentArg)); //$NON-NLS-1$ |
| mode = InsideBootClasspath; |
| continue; |
| } |
| if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$ |
| if (sourcepathClasspaths.size() > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateSourcepath", currentArg)); //$NON-NLS-1$ |
| mode = InsideSourcepath; |
| continue; |
| } |
| if (currentArg.equals("-extdirs")) {//$NON-NLS-1$ |
| if (extdirsNames.size() > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateExtdirs", currentArg)); //$NON-NLS-1$ |
| mode = InsideExtdirs; |
| continue; |
| } |
| if (currentArg.equals("-progress")) { //$NON-NLS-1$ |
| mode = Default; |
| this.showProgress = true; |
| continue; |
| } |
| if (currentArg.equals("-proceedOnError")) { //$NON-NLS-1$ |
| mode = Default; |
| this.proceedOnError = true; |
| continue; |
| } |
| if (currentArg.equals("-time")) { //$NON-NLS-1$ |
| mode = Default; |
| this.timing = true; |
| 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; |
| continue; |
| } |
| if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$ |
| didSpecifyDeprecation = true; |
| this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); |
| continue; |
| } |
| if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| printUsageRequired = true; |
| continue; |
| } |
| if (currentArg.equals("-noExit")) { //$NON-NLS-1$ |
| mode = Default; |
| this.systemExitWhenFinished = false; |
| continue; |
| } |
| if (currentArg.equals("-verbose")) { //$NON-NLS-1$ |
| mode = Default; |
| this.verbose = true; |
| continue; |
| } |
| if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$ |
| mode = Default; |
| this.produceRefInfo = true; |
| continue; |
| } |
| if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$ |
| mode = Default; |
| this.options.put( |
| CompilerOptions.OPTION_InlineJsr, |
| CompilerOptions.ENABLED); |
| 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 InvalidInputException( |
| Main.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$ |
| } |
| } |
| continue; |
| } |
| throw new InvalidInputException( |
| Main.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$ |
| } |
| if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$ |
| disableWarnings(); |
| mode = Default; |
| 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$ |
| disableWarnings(); |
| continue; |
| } |
| if (length <= 6) { |
| throw new InvalidInputException( |
| Main.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; // mentionned warnings are disabled |
| break; |
| default: |
| warnTokenStart = 6; |
| // clear default warning level |
| // but allow multiple warning option on the command line |
| if (!didSpecifyWarnings) disableWarnings(); |
| 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++; |
| if (token.equals("constructorName")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportMethodWithConstructorName, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportHiddenCatchBlock, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("deprecation")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, |
| CompilerOptions.DISABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, |
| CompilerOptions.DISABLED); |
| } else if (token.equals("allDeprecation")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, |
| isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, |
| isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); |
| } else if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedLocal, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedParameter, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedImport, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unusedPrivate")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedPrivateMember, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unusedLabel")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedLabel, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("localHiding")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportLocalVariableHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("fieldHiding")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportFieldHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("specialParamHiding")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportSpecialParameterHidingField, |
| isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); |
| } else if (token.equals("conditionAssign")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("syntheticAccess") //$NON-NLS-1$ |
| || token.equals("synthetic-access")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportSyntheticAccessEmulation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("nls")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("staticReceiver")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNonStaticAccessToStatic, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("indirectStatic")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportIndirectStaticAccess, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("noEffectAssign")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNoEffectAssignment, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("charConcat") || token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNoImplicitStringConversion, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("semicolon")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportEmptyStatement, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("serial")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingSerialVersion, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("emptyBlock")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUncheckedTypeOperation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("raw")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportRawTypeReference, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("finalBound")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportFinalParameterBound, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("suppress")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_SuppressWarnings, |
| isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); |
| } else if (token.equals("warningToken")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnhandledWarningToken, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnnecessaryElse, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("javadoc")) {//$NON-NLS-1$ |
| if (!useEnableJavadoc) { |
| this.options.put( |
| CompilerOptions.OPTION_DocCommentSupport, |
| isEnabling ? CompilerOptions.ENABLED: CompilerOptions.DISABLED); |
| } |
| // if disabling then it's not necessary to set other javadoc options |
| if (isEnabling) { |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadoc, |
| CompilerOptions.WARNING); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTags, |
| CompilerOptions.ENABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, |
| CompilerOptions.DISABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, |
| CompilerOptions.DISABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, |
| CompilerOptions.PRIVATE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingJavadocTags, |
| CompilerOptions.WARNING); |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, |
| CompilerOptions.PRIVATE); |
| } |
| } else if (token.equals("allJavadoc")) { //$NON-NLS-1$ |
| if (!useEnableJavadoc) { |
| this.options.put( |
| CompilerOptions.OPTION_DocCommentSupport, |
| isEnabling ? CompilerOptions.ENABLED: CompilerOptions.DISABLED); |
| } |
| // if disabling then it's not necessary to set other javadoc options |
| if (isEnabling) { |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadoc, |
| CompilerOptions.WARNING); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTags, |
| CompilerOptions.ENABLED); |
| this.options.put( |
| CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, |
| CompilerOptions.PRIVATE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingJavadocTags, |
| CompilerOptions.WARNING); |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, |
| CompilerOptions.PRIVATE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingJavadocComments, |
| CompilerOptions.WARNING); |
| } |
| } else if (token.startsWith("tasks")) { //$NON-NLS-1$ |
| String taskTags = ""; //$NON-NLS-1$ |
| 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 InvalidInputException(Main.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$ |
| } |
| this.options.put( |
| CompilerOptions.OPTION_TaskTags, |
| isEnabling ? taskTags : ""); //$NON-NLS-1$ |
| } else if (token.equals("assertIdentifier")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportAssertIdentifier, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("enumIdentifier")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportEnumIdentifier, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("finally")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unusedThrown")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unqualifiedField") //$NON-NLS-1$ |
| || token.equals("unqualified-field-access")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("typeHiding")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportTypeParameterHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("varargsCast")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportVarargsArgumentNeedCast, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("null")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNullReference, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("boxing")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportAutoboxing, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("over-ann")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingOverrideAnnotation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("dep-ann")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("intfAnnotation")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportAnnotationSuperInterface, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("enumSwitch") //$NON-NLS-1$ |
| || token.equals("incomplete-switch")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportIncompleteEnumSwitch, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("hiding")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportHiddenCatchBlock, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportLocalVariableHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportFieldHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportTypeParameterHiding, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("static-access")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportNonStaticAccessToStatic, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportIndirectStaticAccess, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else if (token.equals("unused")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedLocal, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedParameter, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedImport, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedPrivateMember, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| this.options.put( |
| CompilerOptions.OPTION_ReportUnusedLabel, |
| isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); |
| } else { |
| throw new InvalidInputException(Main.bind("configure.invalidWarning", token)); //$NON-NLS-1$ |
| } |
| } |
| if (tokenCounter == 0) |
| throw new InvalidInputException( |
| Main.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$ |
| didSpecifyWarnings = true; |
| continue; |
| } |
| if (currentArg.equals("-target")) { //$NON-NLS-1$ |
| mode = TargetSetting; |
| continue; |
| } |
| if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_PreserveUnusedLocal, |
| CompilerOptions.PRESERVE); |
| continue; |
| } |
| if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$ |
| this.options.put( |
| CompilerOptions.OPTION_DocCommentSupport, |
| CompilerOptions.ENABLED); |
| useEnableJavadoc = true; |
| 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("-sourcepath")) {//$NON-NLS-1$ |
| if (sourcepathClasspaths.size() > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateSourcepath", currentArg)); //$NON-NLS-1$ |
| mode = InsideSourcepath; |
| continue; |
| } |
| if (currentArg.equals("-extdirs")) {//$NON-NLS-1$ |
| if (extdirsNames.size() > 0) |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateExtdirs", currentArg)); //$NON-NLS-1$ |
| mode = InsideExtdirs; |
| continue; |
| } |
| |
| if (mode == TargetSetting) { |
| if (didSpecifyTarget) { |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$ |
| } |
| 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); |
| if (didSpecifyCompliance && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) < ClassFileConstants.JDK1_4) { |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$ |
| } |
| this.options.put(CompilerOptions.OPTION_Compliance, 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); |
| if (didSpecifyCompliance && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) < ClassFileConstants.JDK1_5) { |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$ |
| } |
| this.options.put(CompilerOptions.OPTION_Compliance, 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); |
| if (didSpecifyCompliance && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) < ClassFileConstants.JDK1_6) { |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$ |
| } |
| this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); |
| } else { |
| throw new InvalidInputException(Main.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$ |
| } |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideLog) { |
| this.log = currentArg; |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideRepetition) { |
| try { |
| this.repetitions = Integer.parseInt(currentArg); |
| if (this.repetitions <= 0) { |
| throw new InvalidInputException(Main.bind("configure.repetition", currentArg)); //$NON-NLS-1$ |
| } |
| } catch (NumberFormatException e) { |
| throw new InvalidInputException(Main.bind("configure.repetition", currentArg)); //$NON-NLS-1$ |
| } |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideMaxProblems) { |
| try { |
| this.maxProblems = Integer.parseInt(currentArg); |
| if (this.maxProblems <= 0) { |
| throw new InvalidInputException(Main.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$ |
| } |
| this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg); |
| } catch (NumberFormatException e) { |
| throw new InvalidInputException(Main.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$ |
| } |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideSource) { |
| if (didSpecifySource) { |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$ |
| } |
| 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 { |
| throw new InvalidInputException(Main.bind("configure.source", currentArg)); //$NON-NLS-1$ |
| } |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideDefaultEncoding) { |
| if (didSpecifyDefaultEncoding) { |
| throw new InvalidInputException( |
| Main.bind("configure.duplicateDefaultEncoding", currentArg)); //$NON-NLS-1$ |
| } |
| try { // ensure encoding is supported |
| new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg); |
| } catch (UnsupportedEncodingException e) { |
| throw new InvalidInputException( |
| Main.bind("configure.unsupportedEncoding", currentArg)); //$NON-NLS-1$ |
| } |
| this.options.put(CompilerOptions.OPTION_Encoding, currentArg); |
| didSpecifyDefaultEncoding = true; |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideDestinationPath) { |
| this.destinationPath = currentArg; |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideClasspath || mode == InsideBootClasspath || mode == InsideSourcepath) { |
| StringTokenizer tokenizer = new StringTokenizer(currentArg, |
| File.pathSeparator + "[]", true); //$NON-NLS-1$ |
| // 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 error = 99; |
| int state = start; |
| String token = null; |
| while (tokenizer.hasMoreTokens()) { |
| token = tokenizer.nextToken(); |
| if (token.equals(File.pathSeparator)) { |
| switch (state) { |
| case start: |
| break; |
| case readyToClose: |
| case readyToCloseEndingWithRules: |
| case readyToCloseOrOtherEntry: |
| state = readyToCloseOrOtherEntry; |
| addNewEntry(InsideClasspath, InsideSourcepath, bootclasspaths, classpaths, sourcepathClasspaths, currentClasspathName, currentRuleSpecs, mode, customEncoding); |
| break; |
| case rulesReadyToClose: |
| state = rulesNeedAnotherRule; |
| break; |
| default: |
| state = error; |
| } |
| } else if (token.equals("[")) { //$NON-NLS-1$ |
| switch (state) { |
| case readyToClose: |
| state = rulesStart; |
| break; |
| default: |
| state = error; |
| } |
| } else if (token.equals("]")) { //$NON-NLS-1$ |
| switch (state) { |
| case rulesReadyToClose: |
| state = readyToCloseEndingWithRules; |
| break; |
| default: |
| state = error; |
| } |
| |
| } else { |
| // regular word |
| switch (state) { |
| case start: |
| case readyToCloseOrOtherEntry: |
| state = readyToClose; |
| currentClasspathName = token; |
| break; |
| case rulesNeedAnotherRule: |
| case rulesStart: |
| state = rulesReadyToClose; |
| currentRuleSpecs.add(token); |
| break; |
| default: |
| state = error; |
| } |
| } |
| } |
| switch(state) { |
| case readyToClose : |
| case readyToCloseEndingWithRules : |
| case readyToCloseOrOtherEntry : |
| addNewEntry(InsideClasspath, InsideSourcepath, bootclasspaths, classpaths, sourcepathClasspaths, currentClasspathName, currentRuleSpecs, mode, customEncoding); |
| break; |
| default : |
| // we go on anyway |
| this.logger.logIncorrectClasspath(currentArg); |
| } |
| mode = Default; |
| continue; |
| } |
| if (mode == InsideExtdirs) { |
| StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false); |
| while (tokenizer.hasMoreTokens()) |
| extdirsNames.add(tokenizer.nextToken()); |
| if (extdirsNames.size() == 0) // empty entry |
| extdirsNames.add(""); //$NON-NLS-1$ |
| mode = Default; |
| continue; |
| } |
| |
| //default is input directory |
| currentArg = currentArg.replace('/', File.separatorChar); |
| if (currentArg.endsWith(File.separator)) |
| currentArg = |
| currentArg.substring(0, currentArg.length() - File.separator.length()); |
| File dir = new File(currentArg); |
| if (!dir.isDirectory()) |
| throw new InvalidInputException( |
| Main.bind("configure.directoryNotExist", currentArg)); //$NON-NLS-1$ |
| FileFinder finder = new FileFinder(); |
| try { |
| finder.find(dir, SUFFIX_STRING_JAVA, this.verbose); |
| } catch (Exception e) { |
| throw new InvalidInputException(Main.bind("configure.IOError", currentArg)); //$NON-NLS-1$ |
| } |
| if (this.filenames != null) { |
| // some source files were specified explicitly |
| String results[] = finder.resultFiles; |
| int length = results.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(results, 0, this.filenames, filesCount, length); |
| for (int i = 0; i < length; i++) { |
| this.encodings[filesCount + i] = customEncoding; |
| } |
| filesCount += length; |
| customEncoding = null; |
| } else { |
| this.filenames = finder.resultFiles; |
| filesCount = this.filenames.length; |
| this.encodings = new String[filesCount]; |
| for (int i = 0; i < filesCount; i++) { |
| this.encodings[i] = customEncoding; |
| } |
| customEncoding = null; |
| } |
| mode = Default; |
| continue; |
| } |
| |
| |
| if (this.log != null) { |
| this.logger.setLog(this.log); |
| } else { |
| this.showProgress = false; |
| } |
| this.logger.logVersion(printVersionRequired); |
| |
| if (printUsageRequired || filesCount == 0) { |
| printUsage(); |
| this.proceed = false; |
| return; |
| } |
| |
| if (filesCount != 0) |
| System.arraycopy( |
| this.filenames, |
| 0, |
| (this.filenames = new String[filesCount]), |
| 0, |
| filesCount); |
| if (classpaths.size() == 0) { |
| // no user classpath specified. |
| String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$ |
| if ((classProp == null) || (classProp.length() == 0)) { |
| this.logger.logNoClasspath(); |
| classpaths.add(FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, 0, null));//$NON-NLS-1$ |
| } else { |
| StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator); |
| String token; |
| while (tokenizer.hasMoreTokens()) { |
| token = tokenizer.nextToken(); |
| FileSystem.Classpath currentClasspath = FileSystem |
| .getClasspath(token, customEncoding, 0, null); |
| if (currentClasspath != null) { |
| classpaths.add(currentClasspath); |
| } else { |
| this.logger.logIncorrectClasspath(token); |
| // should not happen - we go on anyway |
| } |
| } |
| } |
| } |
| |
| final File javaHome = getJavaHome(); |
| if (bootclasspaths.size() == 0) { |
| /* no bootclasspath specified |
| * we can try to retrieve the default librairies of the VM used to run |
| * the batch compiler |
| */ |
| String javaversion = System.getProperty("java.version");//$NON-NLS-1$ |
| if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$ |
| this.logger.logWrongJDK(); |
| this.proceed = false; |
| return; |
| } |
| |
| /* |
| * Handle >= JDK 1.2.2 settings: retrieve rt.jar |
| */ |
| if (javaHome != null) { |
| File[] directoriesToCheck = null; |
| if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$ |
| directoriesToCheck = new File[] { |
| new File(javaHome, "../Classes"), //$NON-NLS-1$ |
| }; |
| } else { |
| directoriesToCheck = new File[] { |
| new File(javaHome, "lib") //$NON-NLS-1$ |
| }; |
| } |
| File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck); |
| if (systemLibrariesJars != null) { |
| for (int i = 0, max = systemLibrariesJars.length; i < max; i++) { |
| File[] current = systemLibrariesJars[i]; |
| if (current != null) { |
| for (int j = 0, max2 = current.length; j < max2; j++) { |
| FileSystem.Classpath classpath = |
| FileSystem.getClasspath( |
| current[j].getAbsolutePath(), |
| null, 0, null); |
| if (classpath != null) { |
| bootclasspaths.add(classpath); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * Feed extdirsNames according to: |
| * - -extdirs first if present; |
| * - else java.ext.dirs if defined; |
| * - else default extensions directory for the platform. |
| */ |
| if (extdirsNames.size() == 0) { |
| String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$ |
| if (extdirsStr == null) { |
| extdirsNames.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$ |
| } |
| else { |
| StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator); |
| while (tokenizer.hasMoreTokens()) |
| extdirsNames.add(tokenizer.nextToken()); |
| } |
| } |
| |
| /* |
| * Feed extdirsClasspath with the entries found into the directories listed by |
| * extdirsNames. |
| */ |
| if (extdirsNames.size() != 0) { |
| File[] directoriesToCheck = new File[extdirsNames.size()]; |
| for (int i = 0; i < directoriesToCheck.length; i++) |
| directoriesToCheck[i] = new File((String) extdirsNames.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, 0, null); |
| if (classpath != null) { |
| extdirsClasspaths.add(classpath); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * 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. |
| */ |
| bootclasspaths.addAll(extdirsClasspaths); |
| bootclasspaths.addAll(sourcepathClasspaths); |
| bootclasspaths.addAll(classpaths); |
| classpaths = bootclasspaths; |
| this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()]; |
| classpaths.toArray(this.checkedClasspaths); |
| if (this.destinationPath == null) { |
| this.generatePackagesStructure = false; |
| } else if ("none".equals(this.destinationPath)) { //$NON-NLS-1$ |
| this.destinationPath = null; |
| } |
| |
| if (didSpecifyCompliance) { |
| Object version = this.options.get(CompilerOptions.OPTION_Compliance); |
| if (CompilerOptions.VERSION_1_3.equals(version)) { |
| if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); |
| if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); |
| } else if (CompilerOptions.VERSION_1_4.equals(version)) { |
| if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); |
| if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); |
| } else if (CompilerOptions.VERSION_1_5.equals(version)) { |
| if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); |
| if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); |
| } else if (CompilerOptions.VERSION_1_6.equals(version)) { |
| if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); |
| if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); |
| } |
| } |
| if (didSpecifySource) { |
| Object 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 (!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 (!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 (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); |
| } |
| } |
| |
| // check and set compliance/source/target compatibilities |
| final Object sourceVersion = this.options.get(CompilerOptions.OPTION_Source); |
| final Object compliance = this.options.get(CompilerOptions.OPTION_Compliance); |
| if (didSpecifyTarget) { |
| // target must be 1.6 if source is 1.6 |
| final Object targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform); |
| if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6 |
| && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){ |
| throw new InvalidInputException(Main.bind("configure.incompatibleTargetForSource", (String)this.options.get(CompilerOptions.OPTION_TargetPlatform), 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 InvalidInputException(Main.bind("configure.incompatibleTargetForSource", (String)this.options.get(CompilerOptions.OPTION_TargetPlatform), 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 InvalidInputException(Main.bind("configure.incompatibleTargetForSource", (String)this.options.get(CompilerOptions.OPTION_TargetPlatform), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$ |
| } |
| // target cannot be greater than compliance level |
| if (CompilerOptions.versionToJdkLevel(compliance) < CompilerOptions.versionToJdkLevel(targetVersion)){ |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), (String)this.options.get(CompilerOptions.OPTION_TargetPlatform))); //$NON-NLS-1$ |
| } |
| } |
| |
| if (sourceVersion.equals(CompilerOptions.VERSION_1_6) |
| && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_6) { |
| // compliance must be 1.6 if source is 1.6 |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$ |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_5) |
| && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_5) { |
| // compliance must be 1.5 if source is 1.5 |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$ |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4) |
| && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_4) { |
| // compliance must be 1.4 if source is 1.4 |
| throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$ |
| } |
| // set default target according to compliance & sourcelevel. |
| if (!didSpecifyTarget) { |
| if (compliance.equals(CompilerOptions.VERSION_1_3)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); |
| } else if (compliance.equals(CompilerOptions.VERSION_1_4)) { |
| if (sourceVersion.equals(CompilerOptions.VERSION_1_3)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); |
| } |
| } else if (compliance.equals(CompilerOptions.VERSION_1_5)) { |
| if (sourceVersion.equals(CompilerOptions.VERSION_1_3)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); |
| } |
| } else if (compliance.equals(CompilerOptions.VERSION_1_6)) { |
| if (sourceVersion.equals(CompilerOptions.VERSION_1_3)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); |
| } else if (sourceVersion.equals(CompilerOptions.VERSION_1_6)) { |
| this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); |
| } |
| } |
| } |
| this.logger.logCommandLineArguments(newCommandLineArgs); |
| this.logger.logOptions(this.options); |
| this.logger.logClasspath(this.checkedClasspaths); |
| if (this.repetitions == 0) { |
| this.repetitions = 1; |
| } |
| if (this.repetitions >= 3 && this.timing) { |
| this.times = new long[this.repetitions]; |
| this.timesCounter = 0; |
| } |
| } |
| |
| private void addNewEntry(final int InsideClasspath, final int InsideSourcepath, ArrayList bootclasspaths, ArrayList classpaths,ArrayList sourcepathClasspaths, String currentClasspathName, ArrayList currentRuleSpecs, int mode, String customEncoding) { |
| AccessRule[] accessRules = new AccessRule[currentRuleSpecs |
| .size()]; |
| boolean rulesOK = true; |
| Iterator i = currentRuleSpecs.iterator(); |
| int j = 0; |
| while (i.hasNext()) { |
| String ruleSpec = (String) 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(), -1); |
| break; |
| case '~': |
| accessRules[j++] = new AccessRule(pattern |
| .toCharArray(), |
| IProblem.DiscouragedReference); |
| break; |
| case '-': |
| accessRules[j++] = new AccessRule(pattern |
| .toCharArray(), |
| IProblem.ForbiddenReference); |
| break; |
| default: |
| rulesOK = false; |
| } |
| } else { |
| rulesOK = false; |
| } |
| } |
| if (rulesOK) { |
| AccessRuleSet accessRuleSet = new AccessRuleSet( |
| accessRules, "{0}"); //$NON-NLS-1$ |
| FileSystem.Classpath currentClasspath = FileSystem |
| .getClasspath(currentClasspathName, |
| customEncoding, 0, accessRuleSet); |
| if (currentClasspath != null) { |
| if (mode == InsideClasspath) { |
| classpaths.add(currentClasspath); |
| } else if (mode == InsideSourcepath) { |
| if (currentClasspath instanceof ClasspathDirectory) { |
| ((ClasspathDirectory) currentClasspath).mode = |
| ClasspathDirectory.SOURCE; |
| // TODO may consider adding this attribute to other classpath natures |
| } |
| sourcepathClasspaths.add(currentClasspath); |
| } else { // inside bootclasspath |
| bootclasspaths.add(currentClasspath); |
| } |
| } else { |
| this.logger.logIncorrectClasspath(currentClasspathName); |
| // we go on anyway |
| } |
| } else { |
| this.logger.logIncorrectClasspath(currentClasspathName); |
| // we go on anyway |
| } |
| } |
| |
| private File javaHomeCache; |
| private boolean javaHomeChecked; |
| private File getJavaHome() { |
| if (!javaHomeChecked) { |
| javaHomeChecked = true; |
| String javaHome = System.getProperty("java.home");//$NON-NLS-1$ |
| if (javaHome != null) { |
| javaHomeCache = new File(javaHome); |
| if (!javaHomeCache.exists()) |
| javaHomeCache = null; |
| } |
| } |
| return javaHomeCache; |
| } |
| |
| private void disableWarnings() { |
| Object[] entries = this.options.entrySet().toArray(); |
| for (int i = 0, max = entries.length; i < max; i++) { |
| Map.Entry entry = (Map.Entry) entries[i]; |
| if (!(entry.getKey() instanceof String)) |
| continue; |
| if (!(entry.getValue() instanceof String)) |
| continue; |
| if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) { |
| this.options.put(entry.getKey(), CompilerOptions.IGNORE); |
| } |
| } |
| this.options.put(CompilerOptions.OPTION_TaskTags, ""); //$NON-NLS-1$ |
| } |
| |
| 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) { |
| return System.getProperty("user.dir"); //$NON-NLS-1$ |
| } |
| return new String(fileName, 0, lastIndex); |
| } |
| 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 ICompilerRequestor() { |
| int lineDelta = 0; |
| public void acceptResult(CompilationResult compilationResult) { |
| if (compilationResult.lineSeparatorPositions != null) { |
| int unitLineCount = compilationResult.lineSeparatorPositions.length; |
| Main.this.lineCount += unitLineCount; |
| this.lineDelta += unitLineCount; |
| if (Main.this.showProgress && this.lineDelta > 2000) { |
| // in -log mode, dump a dot every 2000 lines compiled |
| Main.this.logger.logProgress(); |
| this.lineDelta = 0; |
| } |
| } |
| Main.this.logger.startLoggingSource(compilationResult); |
| if (compilationResult.hasProblems() || compilationResult.hasTasks()) { |
| int localErrorCount = Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this); |
| // exit? |
| if (Main.this.systemExitWhenFinished && !Main.this.proceedOnError && (localErrorCount > 0)) { |
| Main.this.logger.endLoggingSource(); |
| Main.this.logger.endLoggingSources(); |
| Main.this.logger.printStats(Main.this); |
| Main.this.logger.flush(); |
| Main.this.logger.close(); |
| System.exit(-1); |
| } |
| } |
| outputClassFiles(compilationResult); |
| Main.this.logger.endLoggingSource(); |
| } |
| }; |
| } |
| /* |
| * Build the set of compilation source units |
| */ |
| public CompilationUnit[] getCompilationUnits() |
| throws InvalidInputException { |
| int fileCount = this.filenames.length; |
| CompilationUnit[] units = new CompilationUnit[fileCount]; |
| HashtableOfObject knownFileNames = new HashtableOfObject(fileCount); |
| |
| String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding); |
| if ("".equals(defaultEncoding)) //$NON-NLS-1$ |
| defaultEncoding = null; |
| |
| for (int i = 0; i < fileCount; i++) { |
| char[] charName = this.filenames[i].toCharArray(); |
| if (knownFileNames.get(charName) != null) |
| throw new InvalidInputException(Main.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 InvalidInputException(Main.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$ |
| String encoding = this.encodings[i]; |
| if (encoding == null) |
| encoding = defaultEncoding; |
| units[i] = new CompilationUnit(null, this.filenames[i], encoding); |
| } |
| return units; |
| } |
| |
| private File[][] getLibrariesFiles(File[] files) { |
| FilenameFilter filter = new FilenameFilter() { |
| public boolean accept(File dir, String name) { |
| String lowerCaseName = name.toLowerCase(); |
| if (lowerCaseName.endsWith(SUFFIX_STRING_jar) || lowerCaseName.endsWith(SUFFIX_STRING_zip)) { |
| return true; |
| } |
| return false; |
| } |
| }; |
| 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; |
| } |
| |
| /* |
| * 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() { |
| public boolean proceedOnErrors() { |
| return Main.this.proceedOnError; // stop if there are some errors |
| } |
| public boolean stopOnFirstError() { |
| return false; |
| } |
| }; |
| } |
| public FileSystem getLibraryAccess() { |
| |
| String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding); |
| if ("".equals(defaultEncoding)) //$NON-NLS-1$ |
| defaultEncoding = null; |
| return new FileSystem(this.checkedClasspaths, this.filenames); |
| } |
| /* |
| * Low-level API performing the actual compilation |
| */ |
| public IProblemFactory getProblemFactory() { |
| return new DefaultProblemFactory(Locale.getDefault()); |
| } |
| // Dump classfiles onto disk for all compilation units that where successfull. |
| |
| public void outputClassFiles(CompilationResult unitResult) { |
| if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) { |
| ClassFile[] classFiles = unitResult.getClassFiles(); |
| if (!this.generatePackagesStructure) { |
| this.destinationPath = extractDestinationPathFromSourceFile(unitResult); |
| } |
| if (this.destinationPath != 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(SUFFIX_class, 0, relativeName, length, 6); |
| CharOperation.replace(relativeName, '/', File.separatorChar); |
| String relativeStringName = new String(relativeName); |
| try { |
| if (this.compilerOptions.verbose) |
| System.out.println( |
| Messages.bind( |
| Messages.compilation_write, |
| new String[] { |
| String.valueOf(this.exportedClassFilesCounter+1), |
| relativeStringName |
| })); |
| ClassFile.writeToDisk( |
| this.generatePackagesStructure, |
| this.destinationPath, |
| relativeStringName, |
| classFile.getBytes()); |
| this.logger.logClassFile( |
| this.generatePackagesStructure, |
| this.destinationPath, |
| relativeStringName); |
| } catch (IOException e) { |
| String fileName = this.destinationPath + relativeStringName; |
| e.printStackTrace(); |
| this.logger.logNoClassFileCreated(fileName); |
| } |
| this.exportedClassFilesCounter++; |
| } |
| } |
| } |
| } |
| /* |
| * Low-level API performing the actual compilation |
| */ |
| public void performCompilation() throws InvalidInputException { |
| |
| this.startTime = System.currentTimeMillis(); |
| |
| INameEnvironment environment = getLibraryAccess(); |
| Compiler batchCompiler = |
| new Compiler( |
| environment, |
| getHandlingPolicy(), |
| this.options, |
| getBatchRequestor(), |
| getProblemFactory()); |
| this.compilerOptions = batchCompiler.options; |
| |
| // set the non-externally configurable options. |
| this.compilerOptions.verbose = this.verbose; |
| this.compilerOptions.produceReferenceInfo = this.produceRefInfo; |
| try { |
| this.logger.startLoggingSources(); |
| batchCompiler.compile(getCompilationUnits()); |
| } finally { |
| this.logger.endLoggingSources(); |
| } |
| |
| this.logger.printStats(this); |
| |
| // cleanup |
| environment.cleanup(); |
| } |
| |
| public void printUsage() { |
| this.logger.logUsage(Main.bind("misc.usage", //$NON-NLS-1$ |
| new String[] { |
| System.getProperty("path.separator"), //$NON-NLS-1$ |
| Main.bind("compiler.name"), //$NON-NLS-1$ |
| Main.bind("compiler.version"), //$NON-NLS-1$ |
| Main.bind("compiler.copyright") //$NON-NLS-1$ |
| } |
| )); |
| this.logger.flush(); |
| } |
| } |