/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/** This class provides a commandline interface to the apt build-time
* tool.
*
* <p><b>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.</b>
*/
@SuppressWarnings("deprecation")
public class Main {
/** For testing: enter any options you want to be set implicitly
* here.
*/
// 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.
*/
/** The writer to use for diagnostic output.
*/
/** Instantiated factory to use in lieu of discovery process.
*/
/** Map representing original command-line arguments.
*/
/** Classloader to use for finding factories.
*/
/** Result codes.
*/
static final int
/** 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.
*/
/** Documentation key for arguments.
*/
/** Documentation key for description.
*/
/** Suffix option (-foo=bar or -foo:bar)
*/
boolean hasSuffix;
this.argsNameKey = argsNameKey;
}
}
return name;
}
/** Does this option take a (separate) operand?
*/
boolean hasArg() {
}
/** Does argument string match option pattern?
* @param arg The command line argument string.
*/
}
/** For javac-only options, print nothing.
*/
void help() {
}
return name +
}
/** Print a line of documentation describing this option, if non-standard.
*/
void xhelp() {}
/** Process the option (with arg). Return true if error detected.
*/
return false;
}
/** Process the option (without arg). Return true if error detected.
*/
if (hasSuffix)
else
}
};
}
}
void help() {
}
}
aptOnly = true;
}
aptOnly = true;
}
/** Print a line of documentation describing this option, if standard.
*/
void help() {
}
}
/** A nonstandard or extended (-X) option
*/
}
}
void help() {}
void xhelp() {}
};
/** A nonstandard or extended (-X) option
*/
aptOnly = true;
}
}
void xhelp() {
}
};
/** A hidden (implementor) option
*/
}
}
void help() {}
void xhelp() {}
};
super(name);
aptOnly = true;
}
super(name, argsNameKey);
aptOnly = true;
}
}
return false;
}
},
return s.startsWith("-g:");
}
// enter all the -g suboptions as "-g:suboption"
}
return false;
}
},
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") {
return s.startsWith("-Xlint:");
}
// enter all the -Xlint suboptions as "-Xlint:suboption"
}
return false;
}
},
// -deprecation is retained for command-line backward compatibility
return false;
}
},
}
},
}
},
}
},
}
},
}
},
}
},
return true;
return true;
}
}
},
return true;
return true;
}
}
},
}
},
new HiddenOption("-fullversion"),
}
},
}
},
// This option exists only for the purpose of documenting itself.
// It's actually implemented by the launcher.
String helpSynopsis() {
hasSuffix = true;
return super.helpSynopsis();
}
throw new AssertionError
("the -J flag should be caught by the launcher.");
}
},
String helpSynopsis() {
hasSuffix = true;
return super.helpSynopsis();
}
}
boolean hasArg() {
return false;
}
}
},
/*
* 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 Option("-moreinfo", "opt.moreinfo") {
new HiddenOption("-moreinfo") {
}
},
// 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") {
return false;
}
},
new HiddenOption("-Xswitchcheck") {
return false;
}
},
// generate trace output for subtyping operations
new HiddenOption("-debugsubtyping"),
try {
return true;
}
}
},
/* -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;
this.s = s;
return s.startsWith(name);
}
return false;
}
},
new HiddenOption("sourcefile") {
String s;
this.s = s;
return s.endsWith(".java") ||
}
if (s.endsWith(".java")) {
if (!sourceFileNames.contains(s))
sourceFileNames.add(s);
classFileNames.add(s);
}
return false;
}
},
};
/**
* Construct a compiler instance.
*/
}
/**
* Construct a compiler instance.
*/
}
/** A table of all options that's passed to the JavaCompiler constructor. */
/** The list of source files to process
*/
/** The list of class files to process
*/
/** List of top level names of generated source files from most recent apt round.
*/
/** List of names of generated class files from most recent apt round.
*/
/**
* List of all the generated source file names across all apt rounds.
*/
/**
* List of all the generated class file names across all apt rounds.
*/
/**
* List of all the generated file names across all apt rounds.
*/
/**
* Set of all factories that have provided a processor on some apt round.
*/
/** Print a string that explains usage.
*/
void help() {
recognizedOptions[i].help();
}
}
/** Print a string that explains usage for X options.
*/
void xhelp() {
recognizedOptions[i].xhelp();
}
}
/** Report a usage error.
*/
help();
}
/** Report a warning.
*/
}
/** Process command line arguments: store all command line options
* in `options' table and return all source filenames.
* @param args The array of command line arguments.
*/
int ac = 0;
ac++;
int j;
break;
if (j == recognizedOptions.length) {
return null;
}
return null;
}
ac++;
return null;
} else {
return null;
}
}
// 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 (targetString != null) {
if (sourceString == null) {
} else {
warning("warn.source.target.conflict",
}
return null;
} else {
}
}
return sourceFileNames;
}
/** Programmatic interface for main function.
* @param args The command line parameters.
*/
int returnCode = 0;
/*
* 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.
/*
* 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.
*/
try {
// assign args the result of parse to capture results of
// '@file' expansion
}
if (origFilenames == null) {
return EXIT_CMDERR;
// it is allowed to compile nothing if just asking for help
return EXIT_OK;
}
getLocalizedString("err.file.not.found",
e.getMessage()));
return EXIT_SYSERR;
} catch (IOException ex) {
return EXIT_SYSERR;
} catch (OutOfMemoryError ex) {
return EXIT_SYSERR;
} catch (StackOverflowError ex) {
return EXIT_SYSERR;
} catch (FatalError ex) {
return EXIT_SYSERR;
return EXIT_ABNORMAL;
bugMessage(ex);
return EXIT_ABNORMAL;
}
boolean firstRound = true;
boolean needSourcePath = false;
boolean needClassPath = false;
/*
* 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.
*/
try {
/*
* Record original options for future annotation processor
* invocations.
*/
else
}
{
// Note: it might be necessary to check for an empty
// component ("") of the source path or class path
} else {
augmentedSourcePath = ".";
if (sourceDest != null)
}
// put baseClassPath into map to handle any
// value needed for the classloader
} else {
baseClassPath = ".";
}
}
/*
* Create base and augmented class loaders
*/
{
/*
* 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.
*/
if (bootclasspath != null) {
for(File f: bootclasspath)
}
// If the factory path is set, use that path
if (providedFactory == null)
if (aptclasspath == null)
assert aptclasspath != null;
if (providedFactory == null &&
else {
// Create class loader in case new class files are
// written
aptCL);
}
}
do {
round++;
// populate with old options... don't bother reparsing command line, etc.
// if genSource files, must add destination to source path
needSourcePath = true;
}
// Don't really need to track this; just have to add -d
// "foo" to class path if any class files are generated
needClassPath = true;
}
if (classesAsDecls)
}
firstRound = false;
// Check for reported errors before continuing
} 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.
*/
/*
* 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
*/
// 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
int matchPosition = -1;
// "-A" by itself is recognized by apt but not javac
continue argLoop;
} else {
matchPosition = j;
break optionLoop;
}
}
if (matchPosition != -1) {
}
} else {
i++;
continue argLoop;
}
// Remove class file names from
// consideration by javac.
}
}
}
}
}
}
int j = 0;
}
if (needClassPath)
if (needSourcePath) {
for(String s: aggregateGenSourceFileNames)
newArgs[j++] = s;
}
}
return returnCode;
}
/** Programmatic interface for main function.
* @param args The command line parameters.
*/
boolean assertionsEnabled = false;
assert assertionsEnabled = true;
if (!assertionsEnabled) {
// Bark.printLines(out, "fatal error: assertions must be enabled when running javac");
// return EXIT_ABNORMAL;
}
try {
return EXIT_SYSERR;
/*
* 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.
*
*/
return EXIT_ERROR;
} catch (IOException ex) {
return EXIT_SYSERR;
} catch (OutOfMemoryError ex) {
return EXIT_SYSERR;
} catch (StackOverflowError ex) {
return EXIT_SYSERR;
} catch (FatalError ex) {
return EXIT_SYSERR;
} catch (UsageMessageNeededException umne) {
help();
return EXIT_CMDERR; // will cause usage message to be printed
} catch (AnnotationProcessingError ex) {
return EXIT_ABNORMAL;
return EXIT_ABNORMAL;
bugMessage(ex);
return EXIT_ABNORMAL;
} finally {
}
}
return exitCode;
}
/** Print a message reporting an internal error.
*/
AptJavaCompiler.version()));
}
/** Print a message reporting an fatal error.
*/
}
/** Print a message about sun.misc.Service problem.
*/
}
/** Print a message reporting an fatal error.
*/
}
*/
}
/** Print a message reporting an out-of-resources error.
*/
}
/* ************************************************************************
* Internationalization
*************************************************************************/
/** Find a localized string in the resource bundle.
* @param key The key for the localized string.
*/
}
"com.sun.tools.apt.resources.apt";
/** Initialize ResourceBundle.
*/
private static void initResource() {
try {
} catch (MissingResourceException e) {
x.initCause(e);
throw x;
}
}
/** Get and format message string from resource.
*/
}
initResource();
try {
} catch (MissingResourceException e) {
try {
} catch (MissingResourceException f) {
+ "arguments={1}, {2}";
}
}
}
}