diff -r da6a2d56e693 -r 17ee27e76ef4 langtools/src/share/classes/com/sun/tools/apt/main/Main.java
--- a/langtools/src/share/classes/com/sun/tools/apt/main/Main.java Wed Feb 22 14:31:13 2012 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1281 +0,0 @@
-/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.apt.main;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.text.MessageFormat;
-import java.util.ResourceBundle;
-import java.util.MissingResourceException;
-import java.util.StringTokenizer;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-
-import java.net.URLClassLoader;
-import java.net.URL;
-import java.net.MalformedURLException;
-
-import javax.tools.JavaFileManager;
-import javax.tools.StandardLocation;
-
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.jvm.Target;
-import com.sun.tools.javac.util.*;
-
-import com.sun.tools.apt.comp.AnnotationProcessingError;
-import com.sun.tools.apt.comp.UsageMessageNeededException;
-import com.sun.tools.apt.util.Bark;
-import com.sun.mirror.apt.AnnotationProcessorFactory;
-
-import static com.sun.tools.javac.file.Locations.pathToURLs;
-
-/** This class provides a commandline interface to the apt build-time
- * tool.
- *
- *
This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.
- */
-@SuppressWarnings("deprecation")
-public class Main {
-
- /** For testing: enter any options you want to be set implicitly
- * here.
- */
- static String[] forcedOpts = {
- // Preserve parameter names from class files if the class was
- // compiled with debug enabled
- "-XDsave-parameter-names"
- };
-
- /** The name of the compiler, for use in diagnostics.
- */
- String ownName;
-
- /** The writer to use for diagnostic output.
- */
- PrintWriter out;
-
-
- /** Instantiated factory to use in lieu of discovery process.
- */
- AnnotationProcessorFactory providedFactory = null;
-
- /** Map representing original command-line arguments.
- */
- Map origOptions = new HashMap();
-
- /** Classloader to use for finding factories.
- */
- ClassLoader aptCL = null;
-
- /** Result codes.
- */
- static final int
- EXIT_OK = 0, // Compilation completed with no errors.
- EXIT_ERROR = 1, // Completed but reported errors.
- EXIT_CMDERR = 2, // Bad command-line arguments
- EXIT_SYSERR = 3, // System error or resource exhaustion.
- EXIT_ABNORMAL = 4; // Compiler terminated abnormally
-
- /** This class represents an option recognized by the main program
- */
- private class Option {
- /** Whether or not the option is used only aptOnly.
- */
- boolean aptOnly = false;
-
- /** Option string.
- */
- String name;
-
- /** Documentation key for arguments.
- */
- String argsNameKey;
-
- /** Documentation key for description.
- */
- String descrKey;
-
- /** Suffix option (-foo=bar or -foo:bar)
- */
- boolean hasSuffix;
-
- Option(String name, String argsNameKey, String descrKey) {
- this.name = name;
- this.argsNameKey = argsNameKey;
- this.descrKey = descrKey;
- char lastChar = name.charAt(name.length()-1);
- hasSuffix = lastChar == ':' || lastChar == '=';
- }
- Option(String name, String descrKey) {
- this(name, null, descrKey);
- }
-
- public String toString() {
- return name;
- }
-
- /** Does this option take a (separate) operand?
- */
- boolean hasArg() {
- return argsNameKey != null && !hasSuffix;
- }
-
- /** Does argument string match option pattern?
- * @param arg The command line argument string.
- */
- boolean matches(String arg) {
- return hasSuffix ? arg.startsWith(name) : arg.equals(name);
- }
-
- /** For javac-only options, print nothing.
- */
- void help() {
- }
-
- String helpSynopsis() {
- return name +
- (argsNameKey == null ? "" :
- ((hasSuffix ? "" : " ") +
- getLocalizedString(argsNameKey)));
- }
-
- /** Print a line of documentation describing this option, if non-standard.
- */
- void xhelp() {}
-
- /** Process the option (with arg). Return true if error detected.
- */
- boolean process(String option, String arg) {
- options.put(option, arg);
- return false;
- }
-
- /** Process the option (without arg). Return true if error detected.
- */
- boolean process(String option) {
- if (hasSuffix)
- return process(name, option.substring(name.length()));
- else
- return process(option, option);
- }
- };
-
- private class SharedOption extends Option {
- SharedOption(String name, String argsNameKey, String descrKey) {
- super(name, argsNameKey, descrKey);
- }
-
- SharedOption(String name, String descrKey) {
- super(name, descrKey);
- }
-
- void help() {
- String s = " " + helpSynopsis();
- out.print(s);
- for (int j = s.length(); j < 29; j++) out.print(" ");
- Bark.printRawLines(out, getLocalizedString(descrKey));
- }
-
- }
-
- private class AptOption extends Option {
- AptOption(String name, String argsNameKey, String descrKey) {
- super(name, argsNameKey, descrKey);
- aptOnly = true;
- }
-
- AptOption(String name, String descrKey) {
- super(name, descrKey);
- aptOnly = true;
- }
-
- /** Print a line of documentation describing this option, if standard.
- */
- void help() {
- String s = " " + helpSynopsis();
- out.print(s);
- for (int j = s.length(); j < 29; j++) out.print(" ");
- Bark.printRawLines(out, getLocalizedString(descrKey));
- }
-
- }
-
- /** A nonstandard or extended (-X) option
- */
- private class XOption extends Option {
- XOption(String name, String argsNameKey, String descrKey) {
- super(name, argsNameKey, descrKey);
- }
- XOption(String name, String descrKey) {
- this(name, null, descrKey);
- }
- void help() {}
- void xhelp() {}
- };
-
- /** A nonstandard or extended (-X) option
- */
- private class AptXOption extends Option {
- AptXOption(String name, String argsNameKey, String descrKey) {
- super(name, argsNameKey, descrKey);
- aptOnly = true;
- }
- AptXOption(String name, String descrKey) {
- this(name, null, descrKey);
- }
- void xhelp() {
- String s = " " + helpSynopsis();
- out.print(s);
- for (int j = s.length(); j < 29; j++) out.print(" ");
- Log.printRawLines(out, getLocalizedString(descrKey));
- }
- };
-
- /** A hidden (implementor) option
- */
- private class HiddenOption extends Option {
- HiddenOption(String name) {
- super(name, null, null);
- }
- HiddenOption(String name, String argsNameKey) {
- super(name, argsNameKey, null);
- }
- void help() {}
- void xhelp() {}
- };
-
- private class AptHiddenOption extends HiddenOption {
- AptHiddenOption(String name) {
- super(name);
- aptOnly = true;
- }
- AptHiddenOption(String name, String argsNameKey) {
- super(name, argsNameKey);
- aptOnly = true;
- }
- }
-
- private Option[] recognizedOptions = {
- new Option("-g", "opt.g"),
- new Option("-g:none", "opt.g.none") {
- boolean process(String option) {
- options.put("-g:", "none");
- return false;
- }
- },
-
- new Option("-g:{lines,vars,source}", "opt.g.lines.vars.source") {
- boolean matches(String s) {
- return s.startsWith("-g:");
- }
- boolean process(String option) {
- String suboptions = option.substring(3);
- options.put("-g:", suboptions);
- // enter all the -g suboptions as "-g:suboption"
- for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
- String tok = t.nextToken();
- String opt = "-g:" + tok;
- options.put(opt, opt);
- }
- return false;
- }
- },
-
- new XOption("-Xlint", "opt.Xlint"),
- new XOption("-Xlint:{"
- + "all,"
- + "cast,deprecation,divzero,empty,unchecked,fallthrough,path,serial,finally,overrides,"
- + "-cast,-deprecation,-divzero,-empty,-unchecked,-fallthrough,-path,-serial,-finally,-overrides,"
- + "none}",
- "opt.Xlint.suboptlist") {
- boolean matches(String s) {
- return s.startsWith("-Xlint:");
- }
- boolean process(String option) {
- String suboptions = option.substring(7);
- options.put("-Xlint:", suboptions);
- // enter all the -Xlint suboptions as "-Xlint:suboption"
- for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
- String tok = t.nextToken();
- String opt = "-Xlint:" + tok;
- options.put(opt, opt);
- }
- return false;
- }
- },
-
- new Option("-nowarn", "opt.nowarn"),
- new Option("-verbose", "opt.verbose"),
-
- // -deprecation is retained for command-line backward compatibility
- new Option("-deprecation", "opt.deprecation") {
- boolean process(String option) {
- options.put("-Xlint:deprecation", option);
- return false;
- }
- },
-
- new SharedOption("-classpath", "opt.arg.path", "opt.classpath"),
- new SharedOption("-cp", "opt.arg.path", "opt.classpath") {
- boolean process(String option, String arg) {
- return super.process("-classpath", arg);
- }
- },
- new Option("-sourcepath", "opt.arg.path", "opt.sourcepath"),
- new Option("-bootclasspath", "opt.arg.path", "opt.bootclasspath") {
- boolean process(String option, String arg) {
- options.remove("-Xbootclasspath/p:");
- options.remove("-Xbootclasspath/a:");
- return super.process(option, arg);
- }
- },
- new XOption("-Xbootclasspath/p:", "opt.arg.path", "opt.Xbootclasspath.p"),
- new XOption("-Xbootclasspath/a:", "opt.arg.path", "opt.Xbootclasspath.a"),
- new XOption("-Xbootclasspath:", "opt.arg.path", "opt.bootclasspath") {
- boolean process(String option, String arg) {
- options.remove("-Xbootclasspath/p:");
- options.remove("-Xbootclasspath/a:");
- return super.process("-bootclasspath", arg);
- }
- },
- new Option("-extdirs", "opt.arg.dirs", "opt.extdirs"),
- new XOption("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs") {
- boolean process(String option, String arg) {
- return super.process("-extdirs", arg);
- }
- },
- new Option("-endorseddirs", "opt.arg.dirs", "opt.endorseddirs"),
- new XOption("-Djava.endorsed.dirs=","opt.arg.dirs", "opt.endorseddirs") {
- boolean process(String option, String arg) {
- return super.process("-endorseddirs", arg);
- }
- },
- new Option("-proc:{none, only}", "opt.proc.none.only") {
- public boolean matches(String s) {
- return s.equals("-proc:none") || s.equals("-proc:only");
- }
- },
- new Option("-processor", "opt.arg.class", "opt.processor"),
- new Option("-processorpath", "opt.arg.path", "opt.processorpath"),
-
- new SharedOption("-d", "opt.arg.path", "opt.d"),
- new SharedOption("-s", "opt.arg.path", "opt.s"),
- new Option("-encoding", "opt.arg.encoding", "opt.encoding"),
- new SharedOption("-source", "opt.arg.release", "opt.source") {
- boolean process(String option, String operand) {
- Source source = Source.lookup(operand);
- if (source == null) {
- error("err.invalid.source", operand);
- return true;
- } else if (source.compareTo(Source.JDK1_5) > 0) {
- error("err.unsupported.source.version", operand);
- return true;
- }
- return super.process(option, operand);
- }
- },
- new Option("-target", "opt.arg.release", "opt.target") {
- boolean process(String option, String operand) {
- Target target = Target.lookup(operand);
- if (target == null) {
- error("err.invalid.target", operand);
- return true;
- } else if (target.compareTo(Target.JDK1_5) > 0) {
- error("err.unsupported.target.version", operand);
- return true;
- }
- return super.process(option, operand);
- }
- },
- new AptOption("-version", "opt.version") {
- boolean process(String option) {
- Bark.printRawLines(out, ownName + " " + AptJavaCompiler.version());
- return super.process(option);
- }
- },
- new HiddenOption("-fullversion"),
- new AptOption("-help", "opt.help") {
- boolean process(String option) {
- Main.this.help();
- return super.process(option);
- }
- },
- new SharedOption("-X", "opt.X") {
- boolean process(String option) {
- Main.this.xhelp();
- return super.process(option);
- }
- },
-
- // This option exists only for the purpose of documenting itself.
- // It's actually implemented by the launcher.
- new AptOption("-J", "opt.arg.flag", "opt.J") {
- String helpSynopsis() {
- hasSuffix = true;
- return super.helpSynopsis();
- }
- boolean process(String option) {
- throw new AssertionError
- ("the -J flag should be caught by the launcher.");
- }
- },
-
-
- new SharedOption("-A", "opt.proc.flag", "opt.A") {
- String helpSynopsis() {
- hasSuffix = true;
- return super.helpSynopsis();
- }
-
- boolean matches(String arg) {
- return arg.startsWith("-A");
- }
-
- boolean hasArg() {
- return false;
- }
-
- boolean process(String option) {
- return process(option, option);
- }
- },
-
- new AptOption("-nocompile", "opt.nocompile"),
-
- new AptOption("-print", "opt.print"),
-
- new AptOption("-factorypath", "opt.arg.path", "opt.factorypath"),
-
- new AptOption("-factory", "opt.arg.class", "opt.factory"),
-
- new AptXOption("-XListAnnotationTypes", "opt.XListAnnotationTypes"),
-
- new AptXOption("-XListDeclarations", "opt.XListDeclarations"),
-
- new AptXOption("-XPrintAptRounds", "opt.XPrintAptRounds"),
-
- new AptXOption("-XPrintFactoryInfo", "opt.XPrintFactoryInfo"),
-
- /*
- * Option to treat both classes and source files as
- * declarations that can be given on the command line and
- * processed as the result of an apt round.
- */
- new AptXOption("-XclassesAsDecls", "opt.XClassesAsDecls"),
-
- // new Option("-moreinfo", "opt.moreinfo") {
- new HiddenOption("-moreinfo") {
- boolean process(String option) {
- Type.moreInfo = true;
- return super.process(option);
- }
- },
-
- // treat warnings as errors
- new HiddenOption("-Werror"),
-
- // use complex inference from context in the position of a method call argument
- new HiddenOption("-complexinference"),
-
- // prompt after each error
- // new Option("-prompt", "opt.prompt"),
- new HiddenOption("-prompt"),
-
- // dump stack on error
- new HiddenOption("-doe"),
-
- // display warnings for generic unchecked and unsafe operations
- new HiddenOption("-warnunchecked") {
- boolean process(String option) {
- options.put("-Xlint:unchecked", option);
- return false;
- }
- },
-
- new HiddenOption("-Xswitchcheck") {
- boolean process(String option) {
- options.put("-Xlint:switchcheck", option);
- return false;
- }
- },
-
- // generate trace output for subtyping operations
- new HiddenOption("-debugsubtyping"),
-
- new XOption("-Xmaxerrs", "opt.arg.number", "opt.maxerrs"),
- new XOption("-Xmaxwarns", "opt.arg.number", "opt.maxwarns"),
- new XOption("-Xstdout", "opt.arg.file", "opt.Xstdout") {
- boolean process(String option, String arg) {
- try {
- out = new PrintWriter(new FileWriter(arg), true);
- } catch (java.io.IOException e) {
- error("err.error.writing.file", arg, e);
- return true;
- }
- return super.process(option, arg);
- }
- },
-
- new XOption("-Xprint", "opt.print"),
-
- new XOption("-XprintRounds", "opt.printRounds"),
-
- new XOption("-XprintProcessorInfo", "opt.printProcessorInfo"),
-
-
- /* -O is a no-op, accepted for backward compatibility. */
- new HiddenOption("-O"),
-
- /* -Xjcov produces tables to support the code coverage tool jcov. */
- new HiddenOption("-Xjcov"),
-
- /* This is a back door to the compiler's option table.
- * -Dx=y sets the option x to the value y.
- * -Dx sets the option x to the value x.
- */
- new HiddenOption("-XD") {
- String s;
- boolean matches(String s) {
- this.s = s;
- return s.startsWith(name);
- }
- boolean process(String option) {
- s = s.substring(name.length());
- int eq = s.indexOf('=');
- String key = (eq < 0) ? s : s.substring(0, eq);
- String value = (eq < 0) ? s : s.substring(eq+1);
- options.put(key, value);
- return false;
- }
- },
-
- new HiddenOption("sourcefile") {
- String s;
- boolean matches(String s) {
- this.s = s;
- return s.endsWith(".java") ||
- (options.get("-XclassesAsDecls") != null);
- }
- boolean process(String option) {
- if (s.endsWith(".java")) {
- if (!sourceFileNames.contains(s))
- sourceFileNames.add(s);
- } else if (options.get("-XclassesAsDecls") != null) {
- classFileNames.add(s);
- }
- return false;
- }
- },
- };
-
- /**
- * Construct a compiler instance.
- */
- public Main(String name) {
- this(name, new PrintWriter(System.err, true));
- }
-
- /**
- * Construct a compiler instance.
- */
- public Main(String name, PrintWriter out) {
- this.ownName = name;
- this.out = out;
- }
-
- /** A table of all options that's passed to the JavaCompiler constructor. */
- private Options options = null;
-
- /** The list of source files to process
- */
- java.util.List sourceFileNames = new java.util.LinkedList();
-
- /** The list of class files to process
- */
- java.util.List classFileNames = new java.util.LinkedList();
-
- /** List of top level names of generated source files from most recent apt round.
- */
- java.util.Set genSourceFileNames = new java.util.LinkedHashSet();
-
- /** List of names of generated class files from most recent apt round.
- */
- java.util.Set genClassFileNames = new java.util.LinkedHashSet();
-
- /**
- * List of all the generated source file names across all apt rounds.
- */
- java.util.Set aggregateGenSourceFileNames = new java.util.LinkedHashSet();
-
- /**
- * List of all the generated class file names across all apt rounds.
- */
- java.util.Set aggregateGenClassFileNames = new java.util.LinkedHashSet();
-
- /**
- * List of all the generated file names across all apt rounds.
- */
- java.util.Set aggregateGenFiles = new java.util.LinkedHashSet();
-
- /**
- * Set of all factories that have provided a processor on some apt round.
- */
- java.util.Set > productiveFactories =
- new java.util.LinkedHashSet >();
-
-
-
- /** Print a string that explains usage.
- */
- void help() {
- Bark.printRawLines(out, getLocalizedString("msg.usage.header", ownName));
- for (int i=0; i < recognizedOptions.length; i++) {
- recognizedOptions[i].help();
- }
- Bark.printRawLines(out, getLocalizedString("msg.usage.footer"));
- out.println();
- }
-
- /** Print a string that explains usage for X options.
- */
- void xhelp() {
- for (int i=0; i processArgs(String[] flags) {
- int ac = 0;
- while (ac < flags.length) {
- String flag = flags[ac];
- ac++;
-
- int j;
- for (j=0; j < recognizedOptions.length; j++)
- if (recognizedOptions[j].matches(flag))
- break;
-
- if (j == recognizedOptions.length) {
- error("err.invalid.flag", flag);
- return null;
- }
-
- Option option = recognizedOptions[j];
- if (option.hasArg()) {
- if (ac == flags.length) {
- error("err.req.arg", flag);
- return null;
- }
- String operand = flags[ac];
- ac++;
- if (option.process(flag, operand))
- return null;
- } else {
- if (option.process(flag))
- return null;
- }
- }
-
- String sourceString = options.get("-source");
- Source source = (sourceString != null)
- ? Source.lookup(sourceString)
- : Source.JDK1_5; // JDK 5 is the latest supported source version
- String targetString = options.get("-target");
- Target target = (targetString != null)
- ? Target.lookup(targetString)
- : Target.JDK1_5; // JDK 5 is the latest supported source version
- // We don't check source/target consistency for CLDC, as J2ME
- // profiles are not aligned with J2SE targets; moreover, a
- // single CLDC target may have many profiles. In addition,
- // this is needed for the continued functioning of the JSR14
- // prototype.
- if (Character.isDigit(target.name.charAt(0)) &&
- target.compareTo(source.requiredTarget()) < 0) {
- if (targetString != null) {
- if (sourceString == null) {
- warning("warn.target.default.source.conflict",
- targetString,
- source.requiredTarget().name);
- } else {
- warning("warn.source.target.conflict",
- sourceString,
- source.requiredTarget().name);
- }
- return null;
- } else {
- options.put("-target", source.requiredTarget().name);
- }
- }
- return sourceFileNames;
- }
-
- /** Programmatic interface for main function.
- * @param args The command line parameters.
- */
- public int compile(String[] args, AnnotationProcessorFactory factory) {
- int returnCode = 0;
- providedFactory = factory;
-
- Context context = new Context();
- JavacFileManager.preRegister(context);
- options = Options.instance(context);
- Bark bark;
-
- /*
- * Process the command line options to create the intial
- * options data. This processing is at least partially reused
- * by any recursive apt calls.
- */
-
- // For testing: assume all arguments in forcedOpts are
- // prefixed to command line arguments.
- processArgs(forcedOpts);
-
- /*
- * A run of apt only gets passed the most recently generated
- * files; the initial run of apt gets passed the files from
- * the command line.
- */
-
- java.util.List origFilenames;
- try {
- // assign args the result of parse to capture results of
- // '@file' expansion
- origFilenames = processArgs((args=CommandLine.parse(args)));
-
- if (options.get("suppress-tool-api-removal-message") == null) {
- Bark.printRawLines(out, getLocalizedString("misc.Deprecation"));
- }
-
- if (origFilenames == null) {
- return EXIT_CMDERR;
- } else if (origFilenames.size() == 0) {
- // it is allowed to compile nothing if just asking for help
- if (options.get("-help") != null ||
- options.get("-X") != null)
- return EXIT_OK;
- }
- } catch (java.io.FileNotFoundException e) {
- Bark.printRawLines(out, ownName + ": " +
- getLocalizedString("err.file.not.found",
- e.getMessage()));
- return EXIT_SYSERR;
- } catch (IOException ex) {
- ioMessage(ex);
- return EXIT_SYSERR;
- } catch (OutOfMemoryError ex) {
- resourceMessage(ex);
- return EXIT_SYSERR;
- } catch (StackOverflowError ex) {
- resourceMessage(ex);
- return EXIT_SYSERR;
- } catch (FatalError ex) {
- feMessage(ex);
- return EXIT_SYSERR;
- } catch (sun.misc.ServiceConfigurationError sce) {
- sceMessage(sce);
- return EXIT_ABNORMAL;
- } catch (Throwable ex) {
- bugMessage(ex);
- return EXIT_ABNORMAL;
- }
-
-
- boolean firstRound = true;
- boolean needSourcePath = false;
- boolean needClassPath = false;
- boolean classesAsDecls = options.get("-XclassesAsDecls") != null;
-
- /*
- * Create augumented classpath and sourcepath values.
- *
- * If any of the prior apt rounds generated any new source
- * files, the n'th apt round (and any javac invocation) has the
- * source destination path ("-s path") as the last element of
- * the "-sourcepath" to the n'th call.
- *
- * If any of the prior apt rounds generated any new class files,
- * the n'th apt round (and any javac invocation) has the class
- * destination path ("-d path") as the last element of the
- * "-classpath" to the n'th call.
- */
- String augmentedSourcePath = "";
- String augmentedClassPath = "";
- String baseClassPath = "";
-
- try {
- /*
- * Record original options for future annotation processor
- * invocations.
- */
- origOptions = new HashMap(options.size());
- for(String s: options.keySet()) {
- String value;
- if (s.equals(value = options.get(s)))
- origOptions.put(s, (String)null);
- else
- origOptions.put(s, value);
- }
- origOptions = Collections.unmodifiableMap(origOptions);
-
- JavacFileManager fm = (JavacFileManager) context.get(JavaFileManager.class);
- {
- // Note: it might be necessary to check for an empty
- // component ("") of the source path or class path
-
- String sourceDest = options.get("-s");
- if (fm.hasLocation(StandardLocation.SOURCE_PATH)) {
- for(File f: fm.getLocation(StandardLocation.SOURCE_PATH))
- augmentedSourcePath += (f + File.pathSeparator);
- augmentedSourcePath += (sourceDest == null)?".":sourceDest;
- } else {
- augmentedSourcePath = ".";
-
- if (sourceDest != null)
- augmentedSourcePath += (File.pathSeparator + sourceDest);
- }
-
- String classDest = options.get("-d");
- if (fm.hasLocation(StandardLocation.CLASS_PATH)) {
- for(File f: fm.getLocation(StandardLocation.CLASS_PATH))
- baseClassPath += (f + File.pathSeparator);
- // put baseClassPath into map to handle any
- // value needed for the classloader
- options.put("-classpath", baseClassPath);
-
- augmentedClassPath = baseClassPath + ((classDest == null)?".":classDest);
- } else {
- baseClassPath = ".";
- if (classDest != null)
- augmentedClassPath = baseClassPath + (File.pathSeparator + classDest);
- }
- assert options.get("-classpath") != null;
- }
-
- /*
- * Create base and augmented class loaders
- */
- ClassLoader augmentedAptCL = null;
- {
- /*
- * Use a url class loader to look for classes on the
- * user-specified class path. Prepend computed bootclass
- * path, which includes extdirs, to the URLClassLoader apt
- * uses.
- */
- String aptclasspath = "";
- String bcp = "";
- Iterable extends File> bootclasspath = fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
-
- if (bootclasspath != null) {
- for(File f: bootclasspath)
- bcp += (f + File.pathSeparator);
- }
-
- // If the factory path is set, use that path
- if (providedFactory == null)
- aptclasspath = options.get("-factorypath");
- if (aptclasspath == null)
- aptclasspath = options.get("-classpath");
-
- assert aptclasspath != null;
- aptclasspath = (bcp + aptclasspath);
- aptCL = new URLClassLoader(pathToURLs(aptclasspath));
-
- if (providedFactory == null &&
- options.get("-factorypath") != null) // same CL even if new class files written
- augmentedAptCL = aptCL;
- else {
- // Create class loader in case new class files are
- // written
- augmentedAptCL = new URLClassLoader(pathToURLs(augmentedClassPath.
- substring(baseClassPath.length())),
- aptCL);
- }
- }
-
- int round = 0; // For -XPrintAptRounds
- do {
- round++;
-
- Context newContext = new Context();
- Options newOptions = Options.instance(newContext); // creates a new context
- newOptions.putAll(options);
-
- // populate with old options... don't bother reparsing command line, etc.
-
- // if genSource files, must add destination to source path
- if (genSourceFileNames.size() > 0 && !firstRound) {
- newOptions.put("-sourcepath", augmentedSourcePath);
- needSourcePath = true;
- }
- aggregateGenSourceFileNames.addAll(genSourceFileNames);
- sourceFileNames.addAll(genSourceFileNames);
- genSourceFileNames.clear();
-
- // Don't really need to track this; just have to add -d
- // "foo" to class path if any class files are generated
- if (genClassFileNames.size() > 0) {
- newOptions.put("-classpath", augmentedClassPath);
- aptCL = augmentedAptCL;
- needClassPath = true;
- }
- aggregateGenClassFileNames.addAll(genClassFileNames);
- classFileNames.addAll(genClassFileNames);
- genClassFileNames.clear();
-
- options = newOptions;
-
- if (options.get("-XPrintAptRounds") != null) {
- out.println("apt Round : " + round);
- out.println("filenames: " + sourceFileNames);
- if (classesAsDecls)
- out.println("classnames: " + classFileNames);
- out.println("options: " + options);
- }
-
- returnCode = compile(args, newContext);
- firstRound = false;
-
- // Check for reported errors before continuing
- bark = Bark.instance(newContext);
- } while(((genSourceFileNames.size() != 0 ) ||
- (classesAsDecls && genClassFileNames.size() != 0)) &&
- bark.nerrors == 0);
- } catch (UsageMessageNeededException umne) {
- help();
- return EXIT_CMDERR; // will cause usage message to be printed
- }
-
- /*
- * Do not compile if a processor has reported an error or if
- * there are no source files to process. A more sophisticated
- * test would also fail for syntax errors caught by javac.
- */
- if (options.get("-nocompile") == null &&
- options.get("-print") == null &&
- bark.nerrors == 0 &&
- (origFilenames.size() > 0 || aggregateGenSourceFileNames.size() > 0 )) {
- /*
- * Need to create new argument string for calling javac:
- * 1. apt specific arguments (e.g. -factory) must be stripped out
- * 2. proper settings for sourcepath and classpath must be used
- * 3. generated class names must be added
- * 4. class file names as declarations must be removed
- */
-
- int newArgsLength = args.length +
- (needSourcePath?1:0) +
- (needClassPath?1:0) +
- aggregateGenSourceFileNames.size();
-
- // Null out apt-specific options and don't copy over into
- // newArgs. This loop should be a lot faster; the options
- // array should be replaced with a better data structure
- // which includes a map from strings to options.
- //
- // If treating classes as declarations, must strip out
- // class names from the javac argument list
- argLoop:
- for(int i = 0; i < args.length; i++) {
- int matchPosition = -1;
-
- // "-A" by itself is recognized by apt but not javac
- if (args[i] != null && args[i].equals("-A")) {
- newArgsLength--;
- args[i] = null;
- continue argLoop;
- } else {
- optionLoop:
- for(int j = 0; j < recognizedOptions.length; j++) {
- if (args[i] != null && recognizedOptions[j].matches(args[i])) {
- matchPosition = j;
- break optionLoop;
- }
- }
-
- if (matchPosition != -1) {
- Option op = recognizedOptions[matchPosition];
- if (op.aptOnly) {
- newArgsLength--;
- args[i] = null;
- if (op.hasArg()) {
- newArgsLength--;
- args[i+1] = null;
- }
- } else {
- if (op.hasArg()) { // skip over next string
- i++;
- continue argLoop;
- }
-
- if ((options.get("-XclassesAsDecls") != null) &&
- (matchPosition == (recognizedOptions.length-1)) ){
- // Remove class file names from
- // consideration by javac.
- if (! args[i].endsWith(".java")) {
- newArgsLength--;
- args[i] = null;
- }
- }
- }
- }
- }
- }
-
- String newArgs[] = new String[newArgsLength];
-
- int j = 0;
- for(int i=0; i < args.length; i++) {
- if (args[i] != null)
- newArgs[j++] = args[i];
- }
-
- if (needClassPath)
- newArgs[j++] = "-XD-classpath=" + augmentedClassPath;
-
- if (needSourcePath) {
- newArgs[j++] = "-XD-sourcepath=" + augmentedSourcePath;
-
- for(String s: aggregateGenSourceFileNames)
- newArgs[j++] = s;
- }
-
- returnCode = com.sun.tools.javac.Main.compile(newArgs);
- }
-
- return returnCode;
- }
-
- /** Programmatic interface for main function.
- * @param args The command line parameters.
- */
- int compile(String[] args, Context context) {
- boolean assertionsEnabled = false;
- assert assertionsEnabled = true;
- if (!assertionsEnabled) {
- // Bark.printLines(out, "fatal error: assertions must be enabled when running javac");
- // return EXIT_ABNORMAL;
- }
- int exitCode = EXIT_OK;
-
- AptJavaCompiler comp = null;
- try {
- context.put(Bark.outKey, out);
-
- comp = AptJavaCompiler.instance(context);
- if (comp == null)
- return EXIT_SYSERR;
-
- java.util.List nameList = new java.util.LinkedList();
- nameList.addAll(sourceFileNames);
- if (options.get("-XclassesAsDecls") != null)
- nameList.addAll(classFileNames);
-
- List cs
- = comp.compile(List.from(nameList.toArray(new String[0])),
- origOptions,
- aptCL,
- providedFactory,
- productiveFactories,
- aggregateGenFiles);
-
- /*
- * If there aren't new source files, we shouldn't bother
- * running javac if there were errors.
- *
- * If there are new files, we should try running javac in
- * case there were typing errors.
- *
- */
-
- if (comp.errorCount() != 0 ||
- options.get("-Werror") != null && comp.warningCount() != 0)
- return EXIT_ERROR;
- } catch (IOException ex) {
- ioMessage(ex);
- return EXIT_SYSERR;
- } catch (OutOfMemoryError ex) {
- resourceMessage(ex);
- return EXIT_SYSERR;
- } catch (StackOverflowError ex) {
- resourceMessage(ex);
- return EXIT_SYSERR;
- } catch (FatalError ex) {
- feMessage(ex);
- return EXIT_SYSERR;
- } catch (UsageMessageNeededException umne) {
- help();
- return EXIT_CMDERR; // will cause usage message to be printed
- } catch (AnnotationProcessingError ex) {
- apMessage(ex);
- return EXIT_ABNORMAL;
- } catch (sun.misc.ServiceConfigurationError sce) {
- sceMessage(sce);
- return EXIT_ABNORMAL;
- } catch (Throwable ex) {
- bugMessage(ex);
- return EXIT_ABNORMAL;
- } finally {
- if (comp != null) {
- comp.close();
- genSourceFileNames.addAll(comp.getSourceFileNames());
- genClassFileNames.addAll(comp.getClassFileNames());
- }
- sourceFileNames = new java.util.LinkedList();
- classFileNames = new java.util.LinkedList();
- }
- return exitCode;
- }
-
- /** Print a message reporting an internal error.
- */
- void bugMessage(Throwable ex) {
- Bark.printRawLines(out, getLocalizedString("msg.bug",
- AptJavaCompiler.version()));
- ex.printStackTrace(out);
- }
-
- /** Print a message reporting an fatal error.
- */
- void apMessage(AnnotationProcessingError ex) {
- Bark.printRawLines(out, getLocalizedString("misc.Problem"));
- ex.getCause().printStackTrace(out);
- }
-
- /** Print a message about sun.misc.Service problem.
- */
- void sceMessage(sun.misc.ServiceConfigurationError ex) {
- Bark.printRawLines(out, getLocalizedString("misc.SunMiscService"));
- ex.printStackTrace(out);
- }
-
- /** Print a message reporting an fatal error.
- */
- void feMessage(Throwable ex) {
- Bark.printRawLines(out, ex.toString());
- }
-
- /** Print a message reporting an input/output error.
- */
- void ioMessage(Throwable ex) {
- Bark.printRawLines(out, getLocalizedString("msg.io"));
- ex.printStackTrace(out);
- }
-
- /** Print a message reporting an out-of-resources error.
- */
- void resourceMessage(Throwable ex) {
- Bark.printRawLines(out, getLocalizedString("msg.resource"));
- ex.printStackTrace(out);
- }
-
- /* ************************************************************************
- * Internationalization
- *************************************************************************/
-
- /** Find a localized string in the resource bundle.
- * @param key The key for the localized string.
- */
- private static String getLocalizedString(String key, Object... args) {
- return getText(key, args);
- }
-
- private static final String javacRB =
- "com.sun.tools.javac.resources.javac";
-
- private static final String aptRB =
- "com.sun.tools.apt.resources.apt";
-
- private static ResourceBundle messageRBjavac;
- private static ResourceBundle messageRBapt;
-
- /** Initialize ResourceBundle.
- */
- private static void initResource() {
- try {
- messageRBapt = ResourceBundle.getBundle(aptRB);
- messageRBjavac = ResourceBundle.getBundle(javacRB);
- } catch (MissingResourceException e) {
- Error x = new FatalError("Fatal Error: Resource for apt or javac is missing");
- x.initCause(e);
- throw x;
- }
- }
-
- /** Get and format message string from resource.
- */
- private static String getText(String key, Object... _args) {
- String[] args = new String[_args.length];
- for (int i=0; i<_args.length; i++) {
- args[i] = "" + _args[i];
- }
- if (messageRBapt == null || messageRBjavac == null )
- initResource();
- try {
- return MessageFormat.format(messageRBapt.getString("apt." + key),
- (Object[]) args);
- } catch (MissingResourceException e) {
- try {
- return MessageFormat.format(messageRBjavac.getString("javac." + key),
- (Object[]) args);
- } catch (MissingResourceException f) {
- String msg = "apt or javac message file broken: key={0} "
- + "arguments={1}, {2}";
- return MessageFormat.format(msg, (Object[]) args);
- }
- }
- }
-}