8044859: javac duplicates option processing when using Compiler API
Reviewed-by: mcimadamore, vromero, jlahoda
--- a/langtools/make/build.properties Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/make/build.properties Fri Aug 22 16:28:16 2014 -0700
@@ -44,7 +44,7 @@
target.java = ${target.java.home}/bin/java
# Version info -- override as needed
-jdk.version = 1.8.0
+jdk.version = 1.9.0
build.number = b00
milestone = internal
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/JavacTask.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/JavacTask.java Fri Aug 22 16:28:16 2014 -0700
@@ -141,6 +141,7 @@
* Returns a type mirror of the tree node determined by the specified path.
* This method has been superceded by methods on
* {@link com.sun.source.util.Trees Trees}.
+ *
* @param path the path
* @return the type mirror
* @see com.sun.source.util.Trees#getTypeMirror
@@ -149,12 +150,14 @@
/**
* Returns a utility object for dealing with program elements.
- * @return the utility object for dealing with program elements
+ *
+ * @return a utility object for dealing with program elements
*/
public abstract Elements getElements();
/**
* Returns a utility object for dealing with type mirrors.
+ *
* @return the utility object for dealing with type mirrors
*/
public abstract Types getTypes();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -29,14 +29,11 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
-import java.util.Set;
import javax.lang.model.element.Name;
-import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import com.sun.source.doctree.DocCommentTree;
@@ -114,6 +111,9 @@
/**
* Simple API entry point.
+ * @param args Options and operands for doclint
+ * @throws BadArgs if an error is detected in any args
+ * @throws IOException if there are problems with any of the file arguments
*/
public void run(String... args) throws BadArgs, IOException {
PrintWriter out = new PrintWriter(System.out);
@@ -128,12 +128,14 @@
env = new Env();
processArgs(args);
- if (needHelp)
+ boolean noFiles = javacFiles.isEmpty();
+ if (needHelp) {
showHelp(out);
-
- if (javacFiles.isEmpty()) {
- if (!needHelp)
- out.println(localize("dc.main.no.files.given"));
+ if (noFiles)
+ return;
+ } else if (noFiles) {
+ out.println(localize("dc.main.no.files.given"));
+ return;
}
JavacTool tool = JavacTool.create();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Fri Aug 22 16:28:16 2014 -0700
@@ -25,9 +25,10 @@
package com.sun.tools.javac.api;
-import java.io.IOException;
import java.util.Collection;
+import java.util.LinkedHashSet;
import java.util.Locale;
+import java.util.Set;
import javax.annotation.processing.Processor;
import javax.lang.model.element.Element;
@@ -39,11 +40,19 @@
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
import com.sun.source.util.TaskListener;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.PropagatedException;
+import com.sun.tools.javac.util.ServiceLoader;
/**
* Provides basic functionality for implementations of JavacTask.
@@ -71,17 +80,17 @@
}
@Override
- public Iterable<? extends CompilationUnitTree> parse() throws IOException {
+ public Iterable<? extends CompilationUnitTree> parse() {
throw new IllegalStateException();
}
@Override
- public Iterable<? extends Element> analyze() throws IOException {
+ public Iterable<? extends Element> analyze() {
throw new IllegalStateException();
}
@Override
- public Iterable<? extends JavaFileObject> generate() throws IOException {
+ public Iterable<? extends JavaFileObject> generate() {
throw new IllegalStateException();
}
@@ -123,32 +132,72 @@
@Override
public Elements getElements() {
+ if (context == null)
+ throw new IllegalStateException();
return JavacElements.instance(context);
}
@Override
public Types getTypes() {
+ if (context == null)
+ throw new IllegalStateException();
return JavacTypes.instance(context);
}
+ @Override
public void setProcessors(Iterable<? extends Processor> processors) {
throw new IllegalStateException();
}
+ @Override
public void setLocale(Locale locale) {
throw new IllegalStateException();
}
+ @Override
public Boolean call() {
throw new IllegalStateException();
}
/**
- * For internal use only. This method will be
- * removed without warning.
+ * For internal use only.
+ * This method will be removed without warning.
+ * @return the context
*/
public Context getContext() {
return context;
}
+ public void initPlugins(Set<List<String>> pluginOpts) {
+ if (pluginOpts.isEmpty())
+ return;
+
+ Set<List<String>> pluginsToCall = new LinkedHashSet<>(pluginOpts);
+ JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
+ ClassLoader cl = pEnv.getProcessorClassLoader();
+ ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
+ for (Plugin plugin : sl) {
+ for (List<String> p : pluginsToCall) {
+ if (plugin.getName().equals(p.head)) {
+ pluginsToCall.remove(p);
+ try {
+ plugin.init(this, p.tail.toArray(new String[p.tail.size()]));
+ } catch (RuntimeException ex) {
+ throw new PropagatedException(ex);
+ }
+ }
+ }
+ }
+ for (List<String> p: pluginsToCall) {
+ Log.instance(context).error("msg.plugin.not.found", p.head);
+ }
+ }
+
+ public void initDocLint(List<String> docLintOpts) {
+ if (docLintOpts.isEmpty())
+ return;
+
+ new DocLint().init(this, docLintOpts.toArray(new String[docLintOpts.size()]));
+ JavaCompiler.instance(context).keepComments = true;
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Aug 22 16:28:16 2014 -0700
@@ -25,33 +25,32 @@
package com.sun.tools.javac.api;
-import java.io.File;
-import java.io.IOException;
import java.nio.CharBuffer;
import java.util.*;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.processing.Processor;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
import javax.tools.*;
import com.sun.source.tree.*;
-import com.sun.source.util.*;
import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.comp.*;
-import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.*;
import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.model.*;
import com.sun.tools.javac.parser.Parser;
import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.processing.AnnotationProcessingError;
import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log.PrefixKind;
+import com.sun.tools.javac.util.Log.WriterKind;
/**
* Provides access to functionality specific to the JDK Java Compiler, javac.
@@ -65,82 +64,45 @@
* @author Jonathan Gibbons
*/
public class JavacTaskImpl extends BasicJavacTask {
- private Main compilerMain;
+ private final Arguments args;
private JavaCompiler compiler;
private Locale locale;
- private String[] args;
- private String[] classNames;
- private List<JavaFileObject> fileObjects;
private Map<JavaFileObject, JCCompilationUnit> notYetEntered;
private ListBuffer<Env<AttrContext>> genList;
private final AtomicBoolean used = new AtomicBoolean();
private Iterable<? extends Processor> processors;
- private Main.Result result = null;
-
- JavacTaskImpl(Main compilerMain,
- String[] args,
- String[] classNames,
- Context context,
- List<JavaFileObject> fileObjects) {
- super(null, false);
- this.compilerMain = compilerMain;
- this.args = args;
- this.classNames = classNames;
- this.context = context;
- this.fileObjects = fileObjects;
- setLocale(Locale.getDefault());
- // null checks
- compilerMain.getClass();
- args.getClass();
- fileObjects.getClass();
- }
-
- JavacTaskImpl(Main compilerMain,
- Iterable<String> args,
- Context context,
- Iterable<String> classes,
- Iterable<? extends JavaFileObject> fileObjects) {
- this(compilerMain, toArray(args), toArray(classes), context, toList(fileObjects));
+ JavacTaskImpl(Context context) {
+ super(context, true);
+ args = Arguments.instance(context);
}
- static private String[] toArray(Iterable<String> iter) {
- ListBuffer<String> result = new ListBuffer<>();
- if (iter != null)
- for (String s : iter)
- result.append(s);
- return result.toArray(new String[result.length()]);
- }
-
- static private List<JavaFileObject> toList(Iterable<? extends JavaFileObject> fileObjects) {
- if (fileObjects == null)
- return List.nil();
- ListBuffer<JavaFileObject> result = new ListBuffer<>();
- for (JavaFileObject fo : fileObjects)
- result.append(fo);
- return result.toList();
- }
-
- public Main.Result doCall() {
- if (!used.getAndSet(true)) {
- initContext();
- notYetEntered = new HashMap<>();
- compilerMain.setAPIMode(true);
- compiler = JavaCompiler.instance(context);
- compiler.keepComments = true;
- compiler.genEndPos = true;
- result = compilerMain.compile(args, classNames, context, fileObjects, processors);
- cleanup();
- return result;
- } else {
- throw new IllegalStateException("multiple calls to method 'call'");
- }
- }
-
+ @Override // @DefinedBy(COMPILER_API)
public Boolean call() {
return doCall().isOK();
}
+ /* Internal version of call exposing Main.Result. */
+ public Main.Result doCall() {
+ try {
+ return handleExceptions(new Callable<Main.Result>() {
+ @Override
+ public Main.Result call() throws Exception {
+ prepareCompiler(false);
+ compiler.compile(args.getFileObjects(), args.getClassNames(), processors);
+ return (compiler.errorCount() > 0) ? Main.Result.ERROR : Main.Result.OK; // FIXME?
+ }
+ }, Main.Result.SYSERR, Main.Result.ABNORMAL);
+ } finally {
+ try {
+ cleanup();
+ } catch (ClientCodeException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ }
+ }
+
+ @Override // @DefinedBy(COMPILER_API)
public void setProcessors(Iterable<? extends Processor> processors) {
processors.getClass(); // null check
// not mt-safe
@@ -149,46 +111,79 @@
this.processors = processors;
}
+ @Override // @DefinedBy(COMPILER_API)
public void setLocale(Locale locale) {
if (used.get())
throw new IllegalStateException();
this.locale = locale;
}
- private void prepareCompiler() throws IOException {
+ private <T> T handleExceptions(Callable<T> c, T sysErrorResult, T abnormalErrorResult) {
+ try {
+ return c.call();
+ } catch (FatalError ex) {
+ Log log = Log.instance(context);
+ Options options = Options.instance(context);
+ log.printRawLines(ex.getMessage());
+ if (ex.getCause() != null && options.isSet("dev")) {
+ ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
+ }
+ return sysErrorResult;
+ } catch (AnnotationProcessingError | ClientCodeException e) {
+ // AnnotationProcessingError is thrown from JavacProcessingEnvironment,
+ // to forward errors thrown from an annotation processor
+ // ClientCodeException is thrown from ClientCodeWrapper,
+ // to forward errors thrown from user-supplied code for Compiler API
+ // as specified by javax.tools.JavaCompiler#getTask
+ // and javax.tools.JavaCompiler.CompilationTask#call
+ throw new RuntimeException(e.getCause());
+ } catch (PropagatedException e) {
+ throw e.getCause();
+ } catch (IllegalStateException e) {
+ throw e;
+ } catch (Exception | Error ex) {
+ // Nasty. If we've already reported an error, compensate
+ // for buggy compiler error recovery by swallowing thrown
+ // exceptions.
+ if (compiler == null || compiler.errorCount() == 0
+ || Options.instance(context).isSet("dev")) {
+ Log log = Log.instance(context);
+ log.printLines(PrefixKind.JAVAC, "msg.bug", JavaCompiler.version());
+ ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
+ }
+ return abnormalErrorResult;
+ }
+ }
+
+ private void prepareCompiler(boolean forParse) {
if (used.getAndSet(true)) {
if (compiler == null)
- throw new IllegalStateException();
+ throw new PropagatedException(new IllegalStateException());
} else {
- initContext();
- compilerMain.log = Log.instance(context);
- compilerMain.setOptions(Options.instance(context));
- compilerMain.filenames = new LinkedHashSet<>();
- compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
- // The following line is conceptually wrong. It should not refer to args
- // which may include inappropriate file manager options.
- // (Ideally, args should not even be passed into JavacTaskImpl at all.)
- // The "no filenames in args" check should have been handled by the use of
- // the GrumpyHelper in JavacTool.getTask, but processArgs also has some
- // additional checking, which should be factored out and called separately.
- // If we fix this, then filenames and deferredFileManagerOptions in Main
- // can revert to being protected or private, not public.
- Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames);
- if (filenames != null && !filenames.isEmpty())
- throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " "));
+ args.validate();
+
+ //initialize compiler's default locale
+ context.put(Locale.class, locale);
+
+ // hack
+ JavacMessages messages = context.get(JavacMessages.messagesKey);
+ if (messages != null && !messages.getCurrentLocale().equals(locale))
+ messages.setCurrentLocale(locale);
+
+ initPlugins(args.getPluginOpts());
+ initDocLint(args.getDocLintOpts());
+
+ // init JavaCompiler and queues
compiler = JavaCompiler.instance(context);
compiler.keepComments = true;
compiler.genEndPos = true;
- // NOTE: this value will be updated after annotation processing
- compiler.initProcessAnnotations(processors);
notYetEntered = new HashMap<>();
- for (JavaFileObject file: fileObjects)
- notYetEntered.put(file, null);
- genList = new ListBuffer<>();
- // endContext will be called when all classes have been generated
- // TODO: should handle the case after each phase if errors have occurred
- args = null;
- classNames = null;
+ if (forParse) {
+ compiler.initProcessAnnotations(processors);
+ for (JavaFileObject file: args.getFileObjects())
+ notYetEntered.put(file, null);
+ genList = new ListBuffer<>();
+ }
}
}
@@ -203,47 +198,28 @@
return sb.toString();
}
- private void initContext() {
- context.put(JavacTask.class, this);
- //initialize compiler's default locale
- context.put(Locale.class, locale);
- }
-
void cleanup() {
if (compiler != null)
compiler.close();
compiler = null;
- compilerMain = null;
- args = null;
- classNames = null;
context = null;
- fileObjects = null;
notYetEntered = null;
}
- /**
- * Construct a JavaFileObject from the given file.
- *
- * <p><b>TODO: this method is useless here</b></p>
- *
- * @param file a file
- * @return a JavaFileObject from the standard file manager.
- */
- public JavaFileObject asJavaFileObject(File file) {
- JavacFileManager fm = (JavacFileManager)context.get(JavaFileManager.class);
- return fm.getRegularFile(file);
+ @Override // @DefinedBy(TREE_API)
+ public Iterable<? extends CompilationUnitTree> parse() {
+ return handleExceptions(new Callable<Iterable<? extends CompilationUnitTree>>() {
+ @Override
+ public Iterable<? extends CompilationUnitTree> call() {
+ return parseInternal();
+ }
+ }, List.<CompilationUnitTree>nil(), List.<CompilationUnitTree>nil());
}
- /**
- * Parse the specified files returning a list of abstract syntax trees.
- *
- * @throws java.io.IOException TODO
- * @return a list of abstract syntax trees
- */
- public Iterable<? extends CompilationUnitTree> parse() throws IOException {
+ private Iterable<? extends CompilationUnitTree> parseInternal() {
try {
- prepareCompiler();
- List<JCCompilationUnit> units = compiler.parseFiles(fileObjects);
+ prepareCompiler(true);
+ List<JCCompilationUnit> units = compiler.parseFiles(args.getFileObjects());
for (JCCompilationUnit unit: units) {
JavaFileObject file = unit.getSourceFile();
if (notYetEntered.containsKey(file))
@@ -263,11 +239,10 @@
/**
* Translate all the abstract syntax trees to elements.
*
- * @throws IOException TODO
* @return a list of elements corresponding to the top level
* classes in the abstract syntax trees
*/
- public Iterable<? extends TypeElement> enter() throws IOException {
+ public Iterable<? extends TypeElement> enter() {
return enter(null);
}
@@ -275,17 +250,15 @@
* Translate the given abstract syntax trees to elements.
*
* @param trees a list of abstract syntax trees.
- * @throws java.io.IOException TODO
* @return a list of elements corresponding to the top level
* classes in the abstract syntax trees
*/
public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees)
- throws IOException
{
if (trees == null && notYetEntered != null && notYetEntered.isEmpty())
return List.nil();
- prepareCompiler();
+ prepareCompiler(true);
ListBuffer<JCCompilationUnit> roots = null;
@@ -296,8 +269,8 @@
// list to be entered.
if (notYetEntered.size() > 0) {
if (!parsed)
- parse(); // TODO would be nice to specify files needed to be parsed
- for (JavaFileObject file: fileObjects) {
+ parseInternal(); // TODO would be nice to specify files needed to be parsed
+ for (JavaFileObject file: args.getFileObjects()) {
JCCompilationUnit unit = notYetEntered.remove(file);
if (unit != null) {
if (roots == null)
@@ -347,13 +320,14 @@
}
}
- /**
- * Complete all analysis.
- * @throws IOException TODO
- */
- @Override
- public Iterable<? extends Element> analyze() throws IOException {
- return analyze(null);
+ @Override // @DefinedBy(TREE_API)
+ public Iterable<? extends Element> analyze() {
+ return handleExceptions(new Callable<Iterable<? extends Element>>() {
+ @Override
+ public Iterable<? extends Element> call() {
+ return analyze(null);
+ }
+ }, List.<Element>nil(), List.<Element>nil());
}
/**
@@ -363,11 +337,12 @@
* If null is specified, all outstanding classes will be analyzed.
*
* @param classes a list of class elements
+ * @return the elements that were analyzed
*/
// This implementation requires that we open up privileges on JavaCompiler.
// An alternative implementation would be to move this code to JavaCompiler and
// wrap it here
- public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) throws IOException {
+ public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) {
enter(null); // ensure all classes have been entered
final ListBuffer<Element> results = new ListBuffer<>();
@@ -376,6 +351,7 @@
handleFlowResults(compiler.flow(compiler.attribute(compiler.todo)), results);
} else {
Filter f = new Filter() {
+ @Override
public void process(Env<AttrContext> env) {
handleFlowResults(compiler.flow(compiler.attribute(env)), results);
}
@@ -406,14 +382,14 @@
genList.addAll(queue);
}
-
- /**
- * Generate code.
- * @throws IOException TODO
- */
- @Override
- public Iterable<? extends JavaFileObject> generate() throws IOException {
- return generate(null);
+ @Override // @DefinedBy(TREE_API)
+ public Iterable<? extends JavaFileObject> generate() {
+ return handleExceptions(new Callable<Iterable<? extends JavaFileObject>>() {
+ @Override
+ public Iterable<? extends JavaFileObject> call() {
+ return generate(null);
+ }
+ }, List.<JavaFileObject>nil(), List.<JavaFileObject>nil());
}
/**
@@ -424,8 +400,9 @@
* If null is specified, code will be generated for all outstanding classes.
*
* @param classes a list of class elements
+ * @return the files that were generated
*/
- public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) throws IOException {
+ public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) {
final ListBuffer<JavaFileObject> results = new ListBuffer<>();
try {
analyze(null); // ensure all classes have been parsed, entered, and analyzed
@@ -436,6 +413,7 @@
}
else {
Filter f = new Filter() {
+ @Override
public void process(Env<AttrContext> env) {
compiler.generate(compiler.desugar(ListBuffer.of(env)), results);
}
@@ -454,26 +432,6 @@
return results;
}
- public TypeMirror getTypeMirror(Iterable<? extends Tree> path) {
- // TODO: Should complete attribution if necessary
- Tree last = null;
- for (Tree node : path)
- last = node;
- return ((JCTree)last).type;
- }
-
- public JavacElements getElements() {
- if (context == null)
- throw new IllegalStateException();
- return JavacElements.instance(context);
- }
-
- public JavacTypes getTypes() {
- if (context == null)
- throw new IllegalStateException();
- return JavacTypes.instance(context);
- }
-
public Iterable<? extends Tree> pathFor(CompilationUnitTree unit, Tree node) {
return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse();
}
@@ -503,6 +461,10 @@
/**
* For internal use only. This method will be
* removed without warning.
+ * @param expr the type expression to be analyzed
+ * @param scope the scope in which to analyze the type expression
+ * @return the type
+ * @throws IllegalArgumentException if the type expression of null or empty
*/
public Type parseType(String expr, TypeElement scope) {
if (expr == null || expr.equals(""))
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java Fri Aug 22 16:28:16 2014 -0700
@@ -33,23 +33,20 @@
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.EnumSet;
-import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
+
import javax.lang.model.SourceVersion;
import javax.tools.*;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.Option;
-import com.sun.tools.javac.main.OptionHelper;
-import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Log.PrefixKind;
-import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.PropagatedException;
/**
* TODO: describe com.sun.tools.javac.api.Tool
@@ -81,6 +78,7 @@
return new JavacTool();
}
+ @Override // @DefinedBy(COMPILER_API)
public JavacFileManager getStandardFileManager(
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Locale locale,
@@ -96,7 +94,7 @@
return new JavacFileManager(context, true, charset);
}
- @Override
+ @Override // @DefinedBy(COMPILER_API)
public JavacTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
@@ -109,6 +107,7 @@
context);
}
+ /* Internal version of getTask, allowing context to be provided. */
public JavacTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
@@ -120,14 +119,17 @@
try {
ClientCodeWrapper ccw = ClientCodeWrapper.instance(context);
- if (options != null)
+ if (options != null) {
for (String option : options)
option.getClass(); // null check
+ }
+
if (classes != null) {
for (String cls : classes)
if (!SourceVersion.isName(cls)) // implicit null check
throw new IllegalArgumentException("Not a valid class name: " + cls);
}
+
if (compilationUnits != null) {
compilationUnits = ccw.wrapJavaFileObjects(compilationUnits); // implicit null check
for (JavaFileObject cu : compilationUnits) {
@@ -153,82 +155,17 @@
context.put(JavaFileManager.class, fileManager);
- processOptions(context, fileManager, options);
- Main compiler = new Main("javacTask", context.get(Log.outKey));
- return new JavacTaskImpl(compiler, options, context, classes, compilationUnits);
+ Arguments args = Arguments.instance(context);
+ args.init("javac", options, classes, compilationUnits);
+ return new JavacTaskImpl(context);
+ } catch (PropagatedException ex) {
+ throw ex.getCause();
} catch (ClientCodeException ex) {
throw new RuntimeException(ex.getCause());
}
}
- private void processOptions(Context context,
- JavaFileManager fileManager,
- Iterable<String> options)
- {
- if (options == null)
- return;
-
- final Options optionTable = Options.instance(context);
- Log log = Log.instance(context);
-
- Option[] recognizedOptions =
- Option.getJavacToolOptions().toArray(new Option[0]);
- OptionHelper optionHelper = new GrumpyHelper(log) {
- @Override
- public String get(Option option) {
- return optionTable.get(option.getText());
- }
-
- @Override
- public void put(String name, String value) {
- optionTable.put(name, value);
- }
-
- @Override
- public void remove(String name) {
- optionTable.remove(name);
- }
- };
-
- Iterator<String> flags = options.iterator();
- while (flags.hasNext()) {
- String flag = flags.next();
- int j;
- for (j=0; j<recognizedOptions.length; j++)
- if (recognizedOptions[j].matches(flag))
- break;
-
- if (j == recognizedOptions.length) {
- if (fileManager.handleOption(flag, flags)) {
- continue;
- } else {
- String msg = log.localize(PrefixKind.JAVAC, "err.invalid.flag", flag);
- throw new IllegalArgumentException(msg);
- }
- }
-
- Option option = recognizedOptions[j];
- if (option.hasArg()) {
- if (!flags.hasNext()) {
- String msg = log.localize(PrefixKind.JAVAC, "err.req.arg", flag);
- throw new IllegalArgumentException(msg);
- }
- String operand = flags.next();
- if (option.process(optionHelper, flag, operand))
- // should not happen as the GrumpyHelper will throw exceptions
- // in case of errors
- throw new IllegalArgumentException(flag + " " + operand);
- } else {
- if (option.process(optionHelper, flag))
- // should not happen as the GrumpyHelper will throw exceptions
- // in case of errors
- throw new IllegalArgumentException(flag);
- }
- }
-
- optionTable.notifyListeners();
- }
-
+ @Override // @DefinedBy(COMPILER_API)
public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
if (err == null)
err = System.err;
@@ -237,11 +174,13 @@
return com.sun.tools.javac.Main.compile(arguments, new PrintWriter(err, true));
}
+ @Override // @DefinedBy(COMPILER_API)
public Set<SourceVersion> getSourceVersions() {
return Collections.unmodifiableSet(EnumSet.range(SourceVersion.RELEASE_3,
SourceVersion.latest()));
}
+ @Override // @DefinedBy(COMPILER_API)
public int isSupportedOption(String option) {
Set<Option> recognizedOptions = Option.getJavacToolOptions();
for (Option o : recognizedOptions) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Aug 22 16:28:16 2014 -0700
@@ -735,11 +735,7 @@
// if we're being invoked from JSR 199 or JSR 269, then the classes
// will already have been entered.
if (javacTaskImpl != null) {
- try {
- javacTaskImpl.enter(null);
- } catch (IOException e) {
- throw new Error("unexpected error while entering symbols: " + e);
- }
+ javacTaskImpl.enter(null);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 1999, 2014, 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.javac.main;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
+import com.sun.tools.javac.util.BaseFileManager;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.PrefixKind;
+import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.PropagatedException;
+
+/**
+ * Shared option and argument handling for command line and API usage of javac.
+ */
+public class Arguments {
+
+ /**
+ * The context key for the arguments.
+ */
+ protected static final Context.Key<Arguments> argsKey = new Context.Key<>();
+
+ private String ownName;
+ private Set<String> classNames;
+ private Set<File> files;
+ private Map<Option, String> deferredFileManagerOptions;
+ private Set<JavaFileObject> fileObjects;
+ private final Options options;
+
+ private JavaFileManager fileManager;
+ private final Log log;
+ private final Context context;
+
+ private enum ErrorMode { ILLEGAL_ARGUMENT, ILLEGAL_STATE, LOG };
+ private ErrorMode errorMode;
+ private boolean errors;
+
+ /**
+ * Gets the Arguments instance for this context.
+ *
+ * @param context the content
+ * @return the Arguments instance for this context.
+ */
+ public static Arguments instance(Context context) {
+ Arguments instance = context.get(argsKey);
+ if (instance == null) {
+ instance = new Arguments(context);
+ }
+ return instance;
+ }
+
+ protected Arguments(Context context) {
+ context.put(argsKey, this);
+ options = Options.instance(context);
+ log = Log.instance(context);
+ this.context = context;
+
+ // Ideally, we could init this here and update/configure it as
+ // needed, but right now, initializing a file manager triggers
+ // initialization of other items in the context, such as Lint
+ // and FSInfo, which should not be initialized until after
+ // processArgs
+ // fileManager = context.get(JavaFileManager.class);
+ }
+
+ private final OptionHelper cmdLineHelper = new OptionHelper() {
+ @Override
+ public String get(Option option) {
+ return options.get(option);
+ }
+
+ @Override
+ public void put(String name, String value) {
+ options.put(name, value);
+ }
+
+ @Override
+ public void remove(String name) {
+ options.remove(name);
+ }
+
+ @Override
+ public boolean handleFileManagerOption(Option option, String value) {
+ options.put(option.getText(), value);
+ deferredFileManagerOptions.put(option, value);
+ return true;
+ }
+
+ @Override
+ public Log getLog() {
+ return log;
+ }
+
+ @Override
+ public String getOwnName() {
+ return ownName;
+ }
+
+ @Override
+ public void error(String key, Object... args) {
+ Arguments.this.error(key, args);
+ }
+
+ @Override
+ public void addFile(File f) {
+ files.add(f);
+ }
+
+ @Override
+ public void addClassName(String s) {
+ classNames.add(s);
+ }
+
+ };
+
+ /**
+ * Initializes this Args instance with a set of command line args.
+ * The args will be processed in conjunction with the full set of
+ * command line options, including -help, -version etc.
+ * The args may also contain class names and filenames.
+ * Any errors during this call, and later during validate, will be reported
+ * to the log.
+ * @param ownName the name of this tool; used to prefix messages
+ * @param args the args to be processed
+ */
+ public void init(String ownName, String... args) {
+ this.ownName = ownName;
+ errorMode = ErrorMode.LOG;
+ files = new LinkedHashSet<>();
+ deferredFileManagerOptions = new LinkedHashMap<>();
+ fileObjects = null;
+ classNames = new LinkedHashSet<>();
+ processArgs(List.from(args), Option.getJavaCompilerOptions(), cmdLineHelper, true, false);
+ }
+
+ private final OptionHelper apiHelper = new GrumpyHelper(null) {
+ @Override
+ public String get(Option option) {
+ return options.get(option.getText());
+ }
+
+ @Override
+ public void put(String name, String value) {
+ options.put(name, value);
+ }
+
+ @Override
+ public void remove(String name) {
+ options.remove(name);
+ }
+
+ @Override
+ public void error(String key, Object... args) {
+ Arguments.this.error(key, args);
+ }
+
+ @Override
+ public Log getLog() {
+ return Arguments.this.log;
+ }
+ };
+
+ /**
+ * Initializes this Args instance with the parameters for a JavacTask.
+ * The options will be processed in conjunction with the restricted set
+ * of tool options, which does not include -help, -version, etc,
+ * nor does it include classes and filenames, which should be specified
+ * separately.
+ * File manager options are handled directly by the file manager.
+ * Any errors found while processing individual args will be reported
+ * via IllegalArgumentException.
+ * Any subsequent errors during validate will be reported via IllegalStateException.
+ * @param ownName the name of this tool; used to prefix messages
+ * @param options the options to be processed
+ * @param classNames the classes to be subject to annotation processing
+ * @param files the files to be compiled
+ */
+ public void init(String ownName,
+ Iterable<String> options,
+ Iterable<String> classNames,
+ Iterable<? extends JavaFileObject> files) {
+ this.ownName = ownName;
+ this.classNames = toSet(classNames);
+ this.fileObjects = toSet(files);
+ this.files = null;
+ errorMode = ErrorMode.ILLEGAL_ARGUMENT;
+ if (options != null) {
+ processArgs(toList(options), Option.getJavacToolOptions(), apiHelper, false, true);
+ }
+ errorMode = ErrorMode.ILLEGAL_STATE;
+ }
+
+ /**
+ * Gets the files to be compiled.
+ * @return the files to be compiled
+ */
+ public Set<JavaFileObject> getFileObjects() {
+ if (fileObjects == null) {
+ if (files == null) {
+ fileObjects = Collections.emptySet();
+ } else {
+ fileObjects = new LinkedHashSet<>();
+ JavacFileManager jfm = (JavacFileManager) getFileManager();
+ for (JavaFileObject fo: jfm.getJavaFileObjectsFromFiles(files))
+ fileObjects.add(fo);
+ }
+ }
+ return fileObjects;
+ }
+
+ /**
+ * Gets the classes to be subject to annotation processing.
+ * @return the classes to be subject to annotation processing
+ */
+ public Set<String> getClassNames() {
+ return classNames;
+ }
+
+ /**
+ * Processes strings containing options and operands.
+ * @param args the strings to be processed
+ * @param allowableOpts the set of option declarations that are applicable
+ * @param helper a help for use by Option.process
+ * @param allowOperands whether or not to check for files and classes
+ * @param checkFileManager whether or not to check if the file manager can handle
+ * options which are not recognized by any of allowableOpts
+ * @return true if all the strings were successfully processed; false otherwise
+ * @throws IllegalArgumentException if a problem occurs and errorMode is set to
+ * ILLEGAL_ARGUMENT
+ */
+ private boolean processArgs(Iterable<String> args,
+ Set<Option> allowableOpts, OptionHelper helper,
+ boolean allowOperands, boolean checkFileManager) {
+ JavaFileManager fm = checkFileManager ? getFileManager() : null;
+ Iterator<String> argIter = args.iterator();
+ while (argIter.hasNext()) {
+ String arg = argIter.next();
+ if (arg.isEmpty()) {
+ error("err.invalid.flag", arg);
+ return false;
+ }
+
+ Option option = null;
+ if (arg.startsWith("-")) {
+ for (Option o : allowableOpts) {
+ if (o.matches(arg)) {
+ option = o;
+ break;
+ }
+ }
+ } else if (allowOperands && Option.SOURCEFILE.matches(arg)) {
+ option = Option.SOURCEFILE;
+ }
+
+ if (option == null) {
+ if (fm != null && fm.handleOption(arg, argIter)) {
+ continue;
+ }
+ error("err.invalid.flag", arg);
+ return false;
+ }
+
+ if (option.hasArg()) {
+ if (!argIter.hasNext()) {
+ error("err.req.arg", arg);
+ return false;
+ }
+ String operand = argIter.next();
+ if (option.process(helper, arg, operand)) {
+ return false;
+ }
+ } else {
+ if (option.process(helper, arg)) {
+ return false;
+ }
+ }
+
+ }
+
+ options.notifyListeners();
+
+ return true;
+ }
+
+ /**
+ * Validates the overall consistency of the options and operands
+ * processed by processOptions.
+ * @return true if all args are successfully validating; false otherwise.
+ * @throws IllegalStateException if a problem is found and errorMode is set to
+ * ILLEGAL_STATE
+ */
+ public boolean validate() {
+ if (isEmpty()) {
+ // It is allowed to compile nothing if just asking for help or version info.
+ // But also note that none of these options are supported in API mode.
+ if (options.isSet(Option.HELP)
+ || options.isSet(Option.X)
+ || options.isSet(Option.VERSION)
+ || options.isSet(Option.FULLVERSION))
+ return true;
+
+ if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
+ error("err.no.source.files.classes");
+ } else {
+ error("err.no.source.files");
+ }
+ return false;
+ }
+
+ if (!checkDirectory(Option.D)) {
+ return false;
+ }
+ if (!checkDirectory(Option.S)) {
+ return false;
+ }
+
+ String sourceString = options.get(Option.SOURCE);
+ Source source = (sourceString != null)
+ ? Source.lookup(sourceString)
+ : Source.DEFAULT;
+ String targetString = options.get(Option.TARGET);
+ Target target = (targetString != null)
+ ? Target.lookup(targetString)
+ : Target.DEFAULT;
+
+ // 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))) {
+ if (target.compareTo(source.requiredTarget()) < 0) {
+ if (targetString != null) {
+ if (sourceString == null) {
+ error("warn.target.default.source.conflict",
+ targetString,
+ source.requiredTarget().name);
+ } else {
+ error("warn.source.target.conflict",
+ sourceString,
+ source.requiredTarget().name);
+ }
+ return false;
+ } else {
+ target = source.requiredTarget();
+ options.put("-target", target.name);
+ }
+ }
+ }
+
+ String profileString = options.get(Option.PROFILE);
+ if (profileString != null) {
+ Profile profile = Profile.lookup(profileString);
+ if (!profile.isValid(target)) {
+ error("warn.profile.target.conflict", profileString, target.name);
+ }
+
+ // This check is only effective in command line mode,
+ // where the file manager options are added to options
+ if (options.get(Option.BOOTCLASSPATH) != null) {
+ error("err.profile.bootclasspath.conflict");
+ }
+ }
+
+ boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
+
+ if (lintOptions && source.compareTo(Source.DEFAULT) < 0) {
+ JavaFileManager fm = getFileManager();
+ if (fm instanceof BaseFileManager) {
+ if (((BaseFileManager) fm).isDefaultBootClassPath())
+ log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name);
+ }
+ }
+
+ boolean obsoleteOptionFound = false;
+
+ if (source.compareTo(Source.MIN) < 0) {
+ log.error("option.removed.source", source.name, Source.MIN.name);
+ } else if (source == Source.MIN && lintOptions) {
+ log.warning(LintCategory.OPTIONS, "option.obsolete.source", source.name);
+ obsoleteOptionFound = true;
+ }
+
+ if (target.compareTo(Target.MIN) < 0) {
+ log.error("option.removed.target", target.name, Target.MIN.name);
+ } else if (target == Target.MIN && lintOptions) {
+ log.warning(LintCategory.OPTIONS, "option.obsolete.target", target.name);
+ obsoleteOptionFound = true;
+ }
+
+ if (obsoleteOptionFound)
+ log.warning(LintCategory.OPTIONS, "option.obsolete.suppression");
+
+ return !errors;
+ }
+
+ /**
+ * Returns true if there are no files or classes specified for use.
+ * @return true if there are no files or classes specified for use
+ */
+ public boolean isEmpty() {
+ return ((files == null) || files.isEmpty())
+ && ((fileObjects == null) || fileObjects.isEmpty())
+ && classNames.isEmpty();
+ }
+
+ /**
+ * Gets the file manager options which may have been deferred
+ * during processArgs.
+ * @return the deferred file manager options
+ */
+ public Map<Option, String> getDeferredFileManagerOptions() {
+ return deferredFileManagerOptions;
+ }
+
+ /**
+ * Gets any options specifying plugins to be run.
+ * @return options for plugins
+ */
+ public Set<List<String>> getPluginOpts() {
+ String plugins = options.get(Option.PLUGIN);
+ if (plugins == null)
+ return Collections.emptySet();
+
+ Set<List<String>> pluginOpts = new LinkedHashSet<>();
+ for (String plugin: plugins.split("\\x00")) {
+ pluginOpts.add(List.from(plugin.split("\\s+")));
+ }
+ return Collections.unmodifiableSet(pluginOpts);
+ }
+
+ /**
+ * Gets any options specifying how doclint should be run.
+ * An empty list is returned if no doclint options are specified
+ * or if the only doclint option is -Xdoclint:none.
+ * @return options for doclint
+ */
+ public List<String> getDocLintOpts() {
+ String xdoclint = options.get(Option.XDOCLINT);
+ String xdoclintCustom = options.get(Option.XDOCLINT_CUSTOM);
+ if (xdoclint == null && xdoclintCustom == null)
+ return List.nil();
+
+ Set<String> doclintOpts = new LinkedHashSet<>();
+ if (xdoclint != null)
+ doclintOpts.add(DocLint.XMSGS_OPTION);
+ if (xdoclintCustom != null) {
+ for (String s: xdoclintCustom.split("\\s+")) {
+ if (s.isEmpty())
+ continue;
+ doclintOpts.add(s.replace(Option.XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
+ }
+ }
+
+ if (doclintOpts.equals(Collections.singleton(DocLint.XMSGS_CUSTOM_PREFIX + "none")))
+ return List.nil();
+
+ // standard doclet normally generates H1, H2,
+ // so for now, allow user comments to assume that
+ doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
+
+ return List.from(doclintOpts.toArray(new String[doclintOpts.size()]));
+ }
+
+ private boolean checkDirectory(Option option) {
+ String value = options.get(option);
+ if (value == null) {
+ return true;
+ }
+ File file = new File(value);
+ if (!file.exists()) {
+ error("err.dir.not.found", value);
+ return false;
+ }
+ if (!file.isDirectory()) {
+ error("err.file.not.directory", value);
+ return false;
+ }
+ return true;
+ }
+
+ void error(String key, Object... args) {
+ errors = true;
+ switch (errorMode) {
+ case ILLEGAL_ARGUMENT: {
+ String msg = log.localize(PrefixKind.JAVAC, key, args);
+ throw new PropagatedException(new IllegalArgumentException(msg));
+ }
+ case ILLEGAL_STATE: {
+ String msg = log.localize(PrefixKind.JAVAC, key, args);
+ throw new PropagatedException(new IllegalStateException(msg));
+ }
+ case LOG:
+ report(key, args);
+ log.printLines(PrefixKind.JAVAC, "msg.usage", ownName);
+ }
+ }
+
+ void warning(String key, Object... args) {
+ report(key, args);
+ }
+
+ private void report(String key, Object... args) {
+ log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
+ }
+
+ private JavaFileManager getFileManager() {
+ if (fileManager == null)
+ fileManager = context.get(JavaFileManager.class);
+ return fileManager;
+ }
+
+ <T> ListBuffer<T> toList(Iterable<? extends T> items) {
+ ListBuffer<T> list = new ListBuffer<>();
+ if (items != null) {
+ for (T item : items) {
+ list.add(item);
+ }
+ }
+ return list;
+ }
+
+ <T> Set<T> toSet(Iterable<? extends T> items) {
+ Set<T> set = new LinkedHashSet<>();
+ if (items != null) {
+ for (T item : items) {
+ set.add(item);
+ }
+ }
+ return set;
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Aug 22 16:28:16 2014 -0700
@@ -26,6 +26,7 @@
package com.sun.tools.javac.main;
import java.io.*;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -43,13 +44,13 @@
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
-import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
import com.sun.source.util.TaskEvent;
import com.sun.tools.javac.api.MultiTaskListener;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
-import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.file.JavacFileManager;
@@ -57,10 +58,18 @@
import com.sun.tools.javac.parser.*;
import com.sun.tools.javac.processing.*;
import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
+import com.sun.tools.javac.tree.JCTree.JCMemberReference;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Log.WriterKind;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
@@ -394,19 +403,6 @@
processPcks = options.isSet("process.packages");
werror = options.isSet(WERROR);
- // Should this be with other option checking, in Main
- if (source.compareTo(Source.DEFAULT) < 0) {
- if (options.isUnset(XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option)) {
- if (fileManager instanceof BaseFileManager) {
- if (((BaseFileManager) fileManager).isDefaultBootClassPath())
- log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name);
- }
- }
- }
-
- // Should this be with other option checking, in Main
- checkForObsoleteOptions(target);
-
verboseCompilePolicy = options.isSet("verboseCompilePolicy");
if (attrParseOnly)
@@ -436,33 +432,6 @@
log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
}
- // Should this be with other option checking, in Main
- private void checkForObsoleteOptions(Target target) {
- // Unless lint checking on options is disabled, check for
- // obsolete source and target options.
- boolean obsoleteOptionFound = false;
-
- boolean lintOptions =
- options.isUnset(XLINT_CUSTOM, "-"+LintCategory.OPTIONS.option);
-
- if (source.compareTo(Source.MIN) < 0) {
- log.error("option.removed.source", source.name, Source.MIN.name);
- } else if (source == Source.MIN && lintOptions) {
- log.warning(LintCategory.OPTIONS, "option.obsolete.source", source.name);
- obsoleteOptionFound = true;
- }
-
- if (target.compareTo(Target.MIN) < 0) {
- log.error("option.removed.target", target.name, Target.MIN.name);
- } else if (target == Target.MIN && lintOptions) {
- log.warning(LintCategory.OPTIONS, "option.obsolete.target", target.name);
- obsoleteOptionFound = true;
- }
-
- if (obsoleteOptionFound)
- log.warning(LintCategory.OPTIONS, "option.obsolete.suppression");
- }
-
/* Switches:
*/
@@ -834,8 +803,8 @@
* @param processors user provided annotation processors to bypass
* discovery, {@code null} means that no processors were provided
*/
- public void compile(List<JavaFileObject> sourceFileObjects,
- List<String> classnames,
+ public void compile(Collection<JavaFileObject> sourceFileObjects,
+ Collection<String> classnames,
Iterable<? extends Processor> processors)
{
if (!taskListener.isEmpty()) {
@@ -1082,7 +1051,7 @@
// and all deferredDiagnostics must have been handled: i.e. either reported
// or determined to be transient, and therefore suppressed.
public void processAnnotations(List<JCCompilationUnit> roots,
- List<String> classnames) {
+ Collection<String> classnames) {
if (shouldStop(CompileState.PROCESS)) {
// Errors were encountered.
// Unless all the errors are resolve errors, the errors were parse errors
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Fri Aug 22 16:28:16 2014 -0700
@@ -25,40 +25,25 @@
package com.sun.tools.javac.main;
-import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
+import java.security.NoSuchAlgorithmException;
+
import java.util.Set;
-import javax.annotation.processing.Processor;
import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.Plugin;
-import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.api.BasicJavacTask;
-import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.file.CacheFSInfo;
import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.jvm.Profile;
-import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.processing.AnnotationProcessingError;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Log.PrefixKind;
import com.sun.tools.javac.util.Log.WriterKind;
-import com.sun.tools.javac.util.ServiceLoader;
-
-import static com.sun.tools.javac.main.Option.*;
/** This class provides a command line interface to the javac compiler.
*
@@ -108,61 +93,9 @@
public final int exitCode;
}
- private Option[] recognizedOptions =
- Option.getJavaCompilerOptions().toArray(new Option[0]);
-
- private OptionHelper optionHelper = new OptionHelper() {
- @Override
- public String get(Option option) {
- return options.get(option);
- }
-
- @Override
- public void put(String name, String value) {
- options.put(name, value);
- }
-
- @Override
- public boolean handleFileManagerOption(Option option, String value) {
- options.put(option.getText(), value);
- deferredFileManagerOptions.put(option, value);
- return true;
- }
-
- @Override
- public void remove(String name) {
- options.remove(name);
- }
-
- @Override
- public Log getLog() {
- return log;
- }
-
- @Override
- public String getOwnName() {
- return ownName;
- }
-
- @Override
- public void error(String key, Object... args) {
- Main.this.error(key, args);
- }
-
- @Override
- public void addFile(File f) {
- filenames.add(f);
- }
-
- @Override
- public void addClassName(String s) {
- classnames.append(s);
- }
-
- };
-
/**
* Construct a compiler instance.
+ * @param name the name of this tool
*/
public Main(String name) {
this(name, new PrintWriter(System.err, true));
@@ -170,25 +103,14 @@
/**
* Construct a compiler instance.
+ * @param name the name of this tool
+ * @param out a stream to which to write messages
*/
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
- */
- public Set<File> filenames = null; // XXX should be protected or private
-
- /** List of class files names passed on the command line
- */
- protected ListBuffer<String> classnames = null;
-
- public Map<Option, String> deferredFileManagerOptions; // XXX should be protected or private
-
/** Report a usage error.
*/
void error(String key, Object... args) {
@@ -206,156 +128,11 @@
log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
}
- public Option getOption(String flag) {
- for (Option option : recognizedOptions) {
- if (option.matches(flag))
- return option;
- }
- return null;
- }
- public void setOptions(Options options) {
- if (options == null)
- throw new NullPointerException();
- this.options = options;
- }
-
- public void setAPIMode(boolean apiMode) {
- this.apiMode = apiMode;
- }
-
- /** Process command line arguments: store all command line options
- * in `options' table and return all source filenames.
- * @param flags The array of command line arguments.
- */
- public Collection<File> processArgs(String[] flags) { // XXX sb protected
- return processArgs(flags, null);
- }
-
- public Collection<File> processArgs(String[] flags, String[] classNames) { // XXX sb protected
- int ac = 0;
- while (ac < flags.length) {
- String flag = flags[ac];
- ac++;
-
- Option option = null;
-
- if (flag.length() > 0) {
- // quick hack to speed up file processing:
- // if the option does not begin with '-', there is no need to check
- // most of the compiler options.
- int firstOptionToCheck = flag.charAt(0) == '-' ? 0 : recognizedOptions.length-1;
- for (int j=firstOptionToCheck; j<recognizedOptions.length; j++) {
- if (recognizedOptions[j].matches(flag)) {
- option = recognizedOptions[j];
- break;
- }
- }
- }
-
- if (option == null) {
- error("err.invalid.flag", flag);
- return null;
- }
-
- if (option.hasArg()) {
- if (ac == flags.length) {
- error("err.req.arg", flag);
- return null;
- }
- String operand = flags[ac];
- ac++;
- if (option.process(optionHelper, flag, operand))
- return null;
- } else {
- if (option.process(optionHelper, flag))
- return null;
- }
- }
-
- if (options.get(PROFILE) != null && options.get(BOOTCLASSPATH) != null) {
- error("err.profile.bootclasspath.conflict");
- return null;
- }
-
- if (this.classnames != null && classNames != null) {
- this.classnames.addAll(Arrays.asList(classNames));
- }
-
- if (!checkDirectory(D))
- return null;
- if (!checkDirectory(S))
- return null;
-
- String sourceString = options.get(SOURCE);
- Source source = (sourceString != null)
- ? Source.lookup(sourceString)
- : Source.DEFAULT;
- String targetString = options.get(TARGET);
- Target target = (targetString != null)
- ? Target.lookup(targetString)
- : Target.DEFAULT;
-
- if (Character.isDigit(target.name.charAt(0))) {
- if (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 {
- target = source.requiredTarget();
- options.put("-target", target.name);
- }
- }
- }
-
- String profileString = options.get(PROFILE);
- if (profileString != null) {
- Profile profile = Profile.lookup(profileString);
- if (!profile.isValid(target)) {
- warning("warn.profile.target.conflict", profileString, target.name);
- return null;
- }
- }
-
- // handle this here so it works even if no other options given
- String showClass = options.get("showClass");
- if (showClass != null) {
- if (showClass.equals("showClass")) // no value given for option
- showClass = "com.sun.tools.javac.Main";
- showClass(showClass);
- }
-
- options.notifyListeners();
-
- return filenames;
- }
- // where
- private boolean checkDirectory(Option option) {
- String value = options.get(option);
- if (value == null)
- return true;
- File file = new File(value);
- if (!file.exists()) {
- error("err.dir.not.found", value);
- return false;
- }
- if (!file.isDirectory()) {
- error("err.file.not.directory", value);
- return false;
- }
- return true;
- }
-
- /** Programmatic interface for main function.
- * @param args The command line parameters.
+ /**
+ * Programmatic interface for main function.
+ * @param args the command line parameters
+ * @return the result of the compilation
*/
public Result compile(String[] args) {
Context context = new Context();
@@ -368,174 +145,108 @@
return result;
}
- public Result compile(String[] args, Context context) {
- return compile(args, context, List.<JavaFileObject>nil(), null);
- }
-
- /** Programmatic interface for main function.
- * @param args The command line parameters.
+ /**
+ * Internal version of compile, allowing context to be provided.
+ * Note that the context needs to have a file manager set up.
+ * @param argv the command line parameters
+ * @param context the context
+ * @return the result of the compilation
*/
- protected Result compile(String[] args,
- Context context,
- List<JavaFileObject> fileObjects,
- Iterable<? extends Processor> processors)
- {
- return compile(args, null, context, fileObjects, processors);
- }
-
- public Result compile(String[] args,
- String[] classNames,
- Context context,
- List<JavaFileObject> fileObjects,
- Iterable<? extends Processor> processors)
- {
+ public Result compile(String[] argv, Context context) {
context.put(Log.outKey, out);
log = Log.instance(context);
- if (options == null)
- options = Options.instance(context); // creates a new one
+ if (argv.length == 0) {
+ Option.HELP.process(new OptionHelper.GrumpyHelper(log) {
+ @Override
+ public String getOwnName() { return ownName; }
+ }, "-help");
+ return Result.CMDERR;
+ }
- filenames = new LinkedHashSet<>();
- classnames = new ListBuffer<>();
- deferredFileManagerOptions = new LinkedHashMap<>();
- JavaCompiler comp = null;
- /*
- * TODO: Logic below about what is an acceptable command line
- * should be updated to take annotation processing semantics
- * into account.
- */
try {
- if (args.length == 0
- && (classNames == null || classNames.length == 0)
- && fileObjects.isEmpty()) {
- Option.HELP.process(optionHelper, "-help");
- return Result.CMDERR;
- }
+ argv = CommandLine.parse(argv);
+ } catch (FileNotFoundException e) {
+ warning("err.file.not.found", e.getMessage());
+ return Result.SYSERR;
+ } catch (IOException ex) {
+ log.printLines(PrefixKind.JAVAC, "msg.io");
+ ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
+ return Result.SYSERR;
+ }
- Collection<File> files;
- try {
- files = processArgs(CommandLine.parse(args), classNames);
- if (files == null) {
- // null signals an error in options, abort
- return Result.CMDERR;
- } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) {
- // it is allowed to compile nothing if just asking for help or version info
- if (options.isSet(HELP)
- || options.isSet(X)
- || options.isSet(VERSION)
- || options.isSet(FULLVERSION))
- return Result.OK;
- if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
- error("err.no.source.files.classes");
- } else {
- error("err.no.source.files");
- }
- return Result.CMDERR;
- }
- } catch (java.io.FileNotFoundException e) {
- warning("err.file.not.found", e.getMessage());
- return Result.SYSERR;
- }
+ Arguments args = Arguments.instance(context);
+ args.init(ownName, argv);
+
+ if (log.nerrors > 0)
+ return Result.CMDERR;
+
+ Options options = Options.instance(context);
- boolean forceStdOut = options.isSet("stdout");
- if (forceStdOut) {
- log.flush();
- log.setWriters(new PrintWriter(System.out, true));
- }
+ // init Log
+ boolean forceStdOut = options.isSet("stdout");
+ if (forceStdOut) {
+ log.flush();
+ log.setWriters(new PrintWriter(System.out, true));
+ }
- // allow System property in following line as a Mustang legacy
- boolean batchMode = (options.isUnset("nonBatchMode")
- && System.getProperty("nonBatchMode") == null);
- if (batchMode)
- CacheFSInfo.preRegister(context);
-
- fileManager = context.get(JavaFileManager.class);
- if (fileManager instanceof BaseFileManager) {
- ((BaseFileManager) fileManager).handleOptions(deferredFileManagerOptions);
- }
+ // init CacheFSInfo
+ // allow System property in following line as a Mustang legacy
+ boolean batchMode = (options.isUnset("nonBatchMode")
+ && System.getProperty("nonBatchMode") == null);
+ if (batchMode)
+ CacheFSInfo.preRegister(context);
- // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
- // invoke any available plugins
- String plugins = options.get(PLUGIN);
- if (plugins != null) {
- JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
- ClassLoader cl = pEnv.getProcessorClassLoader();
- ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
- Set<List<String>> pluginsToCall = new LinkedHashSet<>();
- for (String plugin: plugins.split("\\x00")) {
- pluginsToCall.add(List.from(plugin.split("\\s+")));
- }
- JavacTask task = null;
- for (Plugin plugin : sl) {
- for (List<String> p : pluginsToCall) {
- if (plugin.getName().equals(p.head)) {
- pluginsToCall.remove(p);
- try {
- if (task == null)
- task = JavacTask.instance(pEnv);
- plugin.init(task, p.tail.toArray(new String[p.tail.size()]));
- } catch (Throwable ex) {
- if (apiMode)
- throw new RuntimeException(ex);
- pluginMessage(ex);
- return Result.SYSERR;
- }
- }
- }
- }
- for (List<String> p: pluginsToCall) {
- log.printLines(PrefixKind.JAVAC, "msg.plugin.not.found", p.head);
- }
- }
+ // init file manager
+ fileManager = context.get(JavaFileManager.class);
+ if (fileManager instanceof BaseFileManager) {
+ ((BaseFileManager) fileManager).setContext(context); // reinit with options
+ ((BaseFileManager) fileManager).handleOptions(args.getDeferredFileManagerOptions());
+ }
- if (options.isSet("completionDeps")) {
- Dependencies.GraphDependencies.preRegister(context);
- }
+ // handle this here so it works even if no other options given
+ String showClass = options.get("showClass");
+ if (showClass != null) {
+ if (showClass.equals("showClass")) // no value given for option
+ showClass = "com.sun.tools.javac.Main";
+ showClass(showClass);
+ }
- comp = JavaCompiler.instance(context);
+ boolean ok = args.validate();
+ if (!ok || log.nerrors > 0)
+ return Result.CMDERR;
+
+ if (args.isEmpty())
+ return Result.OK;
- // FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
- String xdoclint = options.get(XDOCLINT);
- String xdoclintCustom = options.get(XDOCLINT_CUSTOM);
- if (xdoclint != null || xdoclintCustom != null) {
- Set<String> doclintOpts = new LinkedHashSet<>();
- if (xdoclint != null)
- doclintOpts.add(DocLint.XMSGS_OPTION);
- if (xdoclintCustom != null) {
- for (String s: xdoclintCustom.split("\\s+")) {
- if (s.isEmpty())
- continue;
- doclintOpts.add(s.replace(XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
- }
- }
- if (!(doclintOpts.size() == 1
- && doclintOpts.iterator().next().equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) {
- JavacTask t = BasicJavacTask.instance(context);
- // standard doclet normally generates H1, H2
- doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
- new DocLint().init(t, doclintOpts.toArray(new String[doclintOpts.size()]));
- comp.keepComments = true;
- }
- }
+ // init plugins
+ Set<List<String>> pluginOpts = args.getPluginOpts();
+ if (!pluginOpts.isEmpty()) {
+ BasicJavacTask t = (BasicJavacTask) BasicJavacTask.instance(context);
+ t.initPlugins(pluginOpts);
+ }
+
+ // init doclint
+ List<String> docLintOpts = args.getDocLintOpts();
+ if (!docLintOpts.isEmpty()) {
+ BasicJavacTask t = (BasicJavacTask) BasicJavacTask.instance(context);
+ t.initDocLint(docLintOpts);
+ }
- if (options.get(XSTDOUT) != null) {
- // Stdout reassigned - ask compiler to close it when it is done
- comp.closeables = comp.closeables.prepend(log.getWriter(WriterKind.NOTICE));
- }
+ // init Depeendencies
+ if (options.isSet("completionDeps")) {
+ Dependencies.GraphDependencies.preRegister(context);
+ }
- if (!files.isEmpty()) {
- // add filenames to fileObjects
- comp = JavaCompiler.instance(context);
- List<JavaFileObject> otherFiles = List.nil();
- JavacFileManager dfm = (JavacFileManager)fileManager;
- for (JavaFileObject fo : dfm.getJavaFileObjectsFromFiles(files))
- otherFiles = otherFiles.prepend(fo);
- for (JavaFileObject fo : otherFiles)
- fileObjects = fileObjects.prepend(fo);
- }
- comp.compile(fileObjects,
- classnames.toList(),
- processors);
+ // init JavaCompiler
+ JavaCompiler comp = JavaCompiler.instance(context);
+ if (options.get(Option.XSTDOUT) != null) {
+ // Stdout reassigned - ask compiler to close it when it is done
+ comp.closeables = comp.closeables.prepend(log.getWriter(WriterKind.NOTICE));
+ }
+
+ try {
+ comp.compile(args.getFileObjects(), args.getClassNames(), null);
if (log.expectDiagKeys != null) {
if (log.expectDiagKeys.isEmpty()) {
@@ -547,37 +258,25 @@
}
}
- if (comp.errorCount() != 0)
- return Result.ERROR;
- } catch (IOException ex) {
- ioMessage(ex);
- return Result.SYSERR;
- } catch (OutOfMemoryError ex) {
- resourceMessage(ex);
- return Result.SYSERR;
- } catch (StackOverflowError ex) {
+ return (comp.errorCount() == 0) ? Result.OK : Result.ERROR;
+
+ } catch (OutOfMemoryError | StackOverflowError ex) {
resourceMessage(ex);
return Result.SYSERR;
} catch (FatalError ex) {
- feMessage(ex);
+ feMessage(ex, options);
return Result.SYSERR;
} catch (AnnotationProcessingError ex) {
- if (apiMode)
- throw new RuntimeException(ex.getCause());
apMessage(ex);
return Result.SYSERR;
- } catch (ClientCodeException ex) {
- // as specified by javax.tools.JavaCompiler#getTask
- // and javax.tools.JavaCompiler.CompilationTask#call
- throw new RuntimeException(ex.getCause());
} catch (PropagatedException ex) {
+ // TODO: what about errors from plugins? should not simply rethrow the error here
throw ex.getCause();
} catch (Throwable ex) {
// Nasty. If we've already reported an error, compensate
// for buggy compiler error recovery by swallowing thrown
// exceptions.
- if (comp == null || comp.errorCount() == 0 ||
- options == null || options.isSet("dev"))
+ if (comp == null || comp.errorCount() == 0 || options.isSet("dev"))
bugMessage(ex);
return Result.ABNORMAL;
} finally {
@@ -588,10 +287,7 @@
throw new RuntimeException(ex.getCause());
}
}
- filenames = null;
- options = null;
}
- return Result.OK;
}
/** Print a message reporting an internal error.
@@ -603,7 +299,7 @@
/** Print a message reporting a fatal error.
*/
- void feMessage(Throwable ex) {
+ void feMessage(Throwable ex, Options options) {
log.printRawLines(ex.getMessage());
if (ex.getCause() != null && options.isSet("dev")) {
ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
@@ -663,47 +359,19 @@
for (byte b: digest)
sb.append(String.format("%02x", b));
pw.println(" " + algorithm + " checksum: " + sb);
- } catch (Exception e) {
+ } catch (NoSuchAlgorithmException | IOException e) {
pw.println(" cannot compute digest: " + e);
}
}
}
+ // TODO: update this to JavacFileManager
private JavaFileManager fileManager;
/* ************************************************************************
* Internationalization
*************************************************************************/
-// /** Find a localized string in the resource bundle.
-// * @param key The key for the localized string.
-// */
-// public static String getLocalizedString(String key, Object... args) { // FIXME sb private
-// try {
-// if (messages == null)
-// messages = new JavacMessages(javacBundleName);
-// return messages.getLocalizedString("javac." + key, args);
-// }
-// catch (MissingResourceException e) {
-// throw new Error("Fatal Error: Resource for javac is missing", e);
-// }
-// }
-//
-// public static void useRawMessages(boolean enable) {
-// if (enable) {
-// messages = new JavacMessages(javacBundleName) {
-// @Override
-// public String getLocalizedString(String key, Object... args) {
-// return key;
-// }
-// };
-// } else {
-// messages = new JavacMessages(javacBundleName);
-// }
-// }
-
public static final String javacBundleName =
"com.sun.tools.javac.resources.javac";
-//
-// private static JavacMessages messages;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Fri Aug 22 16:28:16 2014 -0700
@@ -55,7 +55,7 @@
/**
* Options for javac. The specific Option to handle a command-line option
- * is identified by searching the members of this enum in order, looking
+ * is identified by searching the members of this enum in order, looking for
* the first {@link #matches match}. The action for an Option is performed
* by calling {@link #process process}, and by providing a suitable
* {@link OptionHelper} to provide access the compiler state.
--- a/langtools/test/tools/javac/6410653/T6410653.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/6410653/T6410653.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -45,6 +45,7 @@
useRawMessages.setBoolean(null, true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
compiler.run(null, null, out, "-d", source, source);
+ System.err.println(">>>" + out + "<<<");
useRawMessages.setBoolean(null, false);
if (!out.toString().equals(String.format("%s%n%s%n",
"javac: javac.err.file.not.directory",
--- a/langtools/test/tools/javac/6457284/T6457284.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/6457284/T6457284.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -32,7 +32,8 @@
import java.net.URI;
import javax.lang.model.element.Element;
-import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.JavacMessages;
@@ -49,10 +50,12 @@
}
}
public static void main(String[] args) throws IOException {
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- JavacTaskImpl task = (JavacTaskImpl)compiler.getTask(null, null, null, null, null,
- List.of(new MyFileObject()));
- MyMessages.preRegister(task.getContext());
+ Context context = new Context();
+ MyMessages.preRegister(context);
+ JavacTool tool = JavacTool.create();
+ JavacTask task = tool.getTask(null, null, null, null, null,
+ List.of(new MyFileObject()),
+ context);
task.parse();
for (Element e : task.analyze()) {
if (!e.getEnclosingElement().toString().equals("compiler.misc.unnamed.package"))
--- a/langtools/test/tools/javac/T6358166.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/T6358166.java Fri Aug 22 16:28:16 2014 -0700
@@ -29,13 +29,15 @@
import java.io.*;
import java.util.*;
+
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.tools.*;
-import com.sun.tools.javac.file.*;
-import com.sun.tools.javac.file.JavacFileManager; // disambiguate
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List; // disambiguate
@@ -58,12 +60,11 @@
static void test(JavacFileManager fm, JavaFileObject f, String... args) throws Throwable {
Context context = new Context();
- Main compilerMain = initCompilerMain(context, fm, args);
+ JavacTool tool = JavacTool.create();
+ JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, Arrays.asList(args), null, List.of(f), context);
+ task.call();
JavaCompiler c = JavaCompiler.instance(context);
-
- c.compile(List.of(f));
-
if (c.errorCount() != 0)
throw new AssertionError("compilation failed");
@@ -72,19 +73,6 @@
throw new AssertionError("elapsed time is suspect: " + msec);
}
- static Main initCompilerMain(Context context, JavacFileManager fm, String... args) {
- fm.setContext(context);
- context.put(JavaFileManager.class, fm);
-
- Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
- compilerMain.setOptions(Options.instance(context));
- compilerMain.filenames = new LinkedHashSet<File>();
- compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
- compilerMain.processArgs(args);
- fm.handleOptions(compilerMain.deferredFileManagerOptions);
- return compilerMain;
- }
-
public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
return true;
}
--- a/langtools/test/tools/javac/T6358168.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/T6358168.java Fri Aug 22 16:28:16 2014 -0700
@@ -28,61 +28,63 @@
*/
import java.io.*;
-import java.net.*;
import java.util.*;
+
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.tools.*;
-import com.sun.tools.javac.file.*;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.main.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List; // disambiguate
@SupportedAnnotationTypes("*")
public class T6358168 extends AbstractProcessor {
- private static String testClasses = System.getProperty("test.classes");
- private static String testSrc = System.getProperty("test.src");
- private static String self = T6358168.class.getName();
+ private static final String testClasses = System.getProperty("test.classes");
+ private static final String testSrc = System.getProperty("test.src");
+ private static final String self = T6358168.class.getName();
public static void main(String... args) throws Throwable {
JavacFileManager fm = new JavacFileManager(new Context(), false, null);
- JavaFileObject f = fm.getFileForInput(testSrc + File.separatorChar + T6358168.class.getName() + ".java");
+ List<JavaFileObject> files = toList(fm.getJavaFileObjects(new File(testSrc, self + ".java")));
try {
// first, test case with no annotation processing
- testNoAnnotationProcessing(fm, f);
+ testNoAnnotationProcessing(fm, files);
// now, test case with annotation processing
- testAnnotationProcessing(fm, f);
+ testAnnotationProcessing(fm, files);
}
catch (Throwable t) {
- AssertionError e = new AssertionError();
- e.initCause(t);
- throw e;
+ throw new AssertionError(t);
}
}
- static void testNoAnnotationProcessing(JavacFileManager fm, JavaFileObject f) throws Throwable {
+ static void testNoAnnotationProcessing(JavacFileManager fm, List<JavaFileObject> files) throws Throwable {
Context context = new Context();
String[] args = { "-d", "." };
- Main compilerMain = initCompilerMain(context, fm, args);
+
+ JavacTool tool = JavacTool.create();
+ JavacTask task = tool.getTask(null, fm, null, List.from(args), null, files, context);
+ // no need in this simple case to call task.prepareCompiler(false)
JavaCompiler compiler = JavaCompiler.instance(context);
- compiler.compile(List.of(f));
+ compiler.compile(files);
try {
- compiler.compile(List.of(f));
+ compiler.compile(files);
throw new Error("Error: AssertionError not thrown after second call of compile");
} catch (AssertionError e) {
System.err.println("Exception from compiler (expected): " + e);
}
}
- static void testAnnotationProcessing(JavacFileManager fm, JavaFileObject f) throws Throwable {
+ static void testAnnotationProcessing(JavacFileManager fm, List<JavaFileObject> files) throws Throwable {
Context context = new Context();
String[] args = {
@@ -91,31 +93,29 @@
"-processor", self,
"-d", "."
};
- Main compilerMain = initCompilerMain(context, fm, args);
+
+ JavacTool tool = JavacTool.create();
+ JavacTask task = tool.getTask(null, fm, null, List.from(args), null, files, context);
+ // no need in this simple case to call task.prepareCompiler(false)
JavaCompiler compiler = JavaCompiler.instance(context);
- compiler.compile(List.of(f));
+ compiler.compile(files);
try {
- compiler.compile(List.of(f));
+ compiler.compile(files);
throw new Error("Error: AssertionError not thrown after second call of compile");
} catch (AssertionError e) {
System.err.println("Exception from compiler (expected): " + e);
}
}
- static Main initCompilerMain(Context context, JavacFileManager fm, String... args) {
- fm.setContext(context);
- context.put(JavaFileManager.class, fm);
-
- Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
- compilerMain.setOptions(Options.instance(context));
- compilerMain.filenames = new LinkedHashSet<File>();
- compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
- compilerMain.processArgs(args);
- fm.handleOptions(compilerMain.deferredFileManagerOptions);
- return compilerMain;
+ private static List<JavaFileObject> toList(Iterable<? extends JavaFileObject> iter) {
+ ListBuffer<JavaFileObject> files = new ListBuffer<>();
+ for (JavaFileObject file: iter)
+ files.add(file);
+ return files.toList();
}
+ @Override
public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
return true;
}
--- a/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -44,12 +44,14 @@
public static void main(String args[]) throws Exception {
ToolBox tb = new ToolBox();
+ tb.writeFile("Test.java", TestSrc);
ToolBox.Result result = tb.new JavacTask(ToolBox.Mode.CMDLINE)
.options("-profile", "compact1",
"-bootclasspath", Paths.get(ToolBox.testJDK, "jre/lib/rt.jar").toString())
- .sources(TestSrc)
- .run(ToolBox.Expect.FAIL);
+ .files("Test.java")
+ .run(ToolBox.Expect.FAIL)
+ .writeAll();
String out = result.getOutput(ToolBox.OutputKind.DIRECT);
Assert.check(out.startsWith(
--- a/langtools/test/tools/javac/api/6410643/T6410643.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/6410643/T6410643.java Fri Aug 22 16:28:16 2014 -0700
@@ -49,9 +49,13 @@
void test(String... args) {
task = tool.getTask(null, null, null, null, null, null);
- if (task.call())
+ try {
+ task.call();
throw new AssertionError("Error expected");
- System.err.println("Compilation failed as expected!");
+ } catch (IllegalStateException e) {
+ System.err.println("Expected error occurred: " + e);
+ }
+
Iterable<String> s = singleton(null);
Iterable<JavaFileObject> f = singleton(null);
// case (null, null, null) is tested above
--- a/langtools/test/tools/javac/api/T6357331.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/T6357331.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -27,7 +27,7 @@
* @summary NPE from JavacTask.getElements() after calling CompilationTask.run
*/
import java.io.*;
-import java.util.Arrays;
+import java.util.*;
import javax.tools.*;
import com.sun.source.util.*;
@@ -36,7 +36,11 @@
public static void main(String... args) {
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
PrintWriter out = new PrintWriter(new StringWriter());
- final JavacTask task = (JavacTask) (tool.getTask(out, null, null, null, null, null));
+ List<String> opts = Arrays.asList("-d", ".");
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File thisFile = new File(System.getProperty("test.src"), "T6357331.java");
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(thisFile);
+ final JavacTask task = (JavacTask) (tool.getTask(out, fm, null, opts, null, files));
// set a listener to verify that IllegalStateException is not thrown
// during the compilation
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java Fri Aug 22 16:28:16 2014 -0700
@@ -75,11 +75,7 @@
public void run() {
Iterable<? extends TypeElement> toplevels;
- try {
- toplevels = task.enter(task.parse());
- } catch (IOException ex) {
- throw new AssertionError(ex);
- }
+ toplevels = task.enter(task.parse());
for (TypeElement clazz : toplevels) {
System.out.format("Testing %s:%n%n", clazz.getSimpleName());
testParseType(clazz);
--- a/langtools/test/tools/javac/api/TestJavacTask_Lock.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/TestJavacTask_Lock.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -51,7 +51,7 @@
int test(CompilationTask t) {
try {
((JavacTask) t).parse();
- return 1;
+ return 1;
} catch (IOException ex) {
throw new Error(ex);
}
@@ -94,6 +94,7 @@
second.test(t);
error("No exception thrown");
} catch (IllegalStateException e) {
+ e.printStackTrace();
System.err.println("Expected exception caught: " + e);
} catch (Exception e) {
error("Unexpected exception caught: " + e);
--- a/langtools/test/tools/javac/api/TestResolveError.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/TestResolveError.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -65,11 +65,7 @@
types = task.getTypes();
Iterable<? extends TypeElement> toplevels;
- try {
- toplevels = task.enter(task.parse());
- } catch (IOException ex) {
- throw new AssertionError(ex);
- }
+ toplevels = task.enter(task.parse());
for (TypeElement clazz : toplevels) {
System.out.format("Testing %s:%n%n", clazz.getSimpleName());
--- a/langtools/test/tools/javac/api/taskListeners/CompileEvent.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/taskListeners/CompileEvent.java Fri Aug 22 16:28:16 2014 -0700
@@ -70,27 +70,29 @@
}, new PrintWriter(out, true));
if (mainResult != 0)
throw new AssertionError("Compilation failed unexpectedly, exit code: " + mainResult);
- assertOutput(out);
+ assertOutput(out.toString());
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> testFileObjects = fm.getJavaFileObjects(test);
//test events fired to listeners registered from plugins
- //when starting compiler using JavaCompiler.getTak(...).call
+ //when starting compiler using JavaCompiler.getTask(...).call
List<String> options =
Arrays.asList("-Xplugin:compile-event", "-processorpath", testClasses);
out = new StringWriter();
boolean compResult = comp.getTask(out, null, null, options, null, testFileObjects).call();
if (!compResult)
throw new AssertionError("Compilation failed unexpectedly.");
- assertOutput(out);
+ assertOutput(out.toString());
}
- void assertOutput(StringWriter out) {
+ void assertOutput(String found) {
String lineSeparator = System.getProperty("line.separator");
- if (!out.toString().trim().replace(lineSeparator, "\n").equals(EXPECTED)) {
- throw new AssertionError("Unexpected events: " + out.toString());
+ if (!found.trim().replace(lineSeparator, "\n").equals(EXPECTED)) {
+ System.err.println("Expected: " + EXPECTED);
+ System.err.println("Found: " + found);
+ throw new AssertionError("Unexpected events: " + found);
}
}
--- a/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/api/taskListeners/EventsBalancedTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -66,11 +66,10 @@
}
}
- void test(Iterable<String> options, Iterable<JavaFileObject> files) throws IOException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
+ void test(List<String> options, List<JavaFileObject> files) throws IOException {
+ System.err.println("testing: " + options + ", " + files);
TestListener listener = new TestListener();
- JavacTask task = tool.getTask(pw, fm, null, options, null, files);
+ JavacTask task = tool.getTask(null, fm, null, options, null, files);
task.setTaskListener(listener);
--- a/langtools/test/tools/javac/failover/CheckAttributedTree.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -54,10 +54,10 @@
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.lang.model.element.Element;
import javax.swing.DefaultComboBoxModel;
@@ -80,11 +80,13 @@
import javax.tools.JavaFileObject;
import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
-import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -256,6 +258,7 @@
}
}
});
+ return;
}
if (!quiet)
@@ -272,7 +275,7 @@
* @param file the file to be read
* @return the tree for the content of the file
* @throws IOException if any IO errors occur
- * @throws TreePosTest.ParseException if any errors occur while parsing the file
+ * @throws AttributionException if any errors occur while analyzing the file
*/
List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
r.errors = 0;
@@ -283,22 +286,28 @@
task.setTaskListener(new TaskListener() {
public void started(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ANALYZE)
- analyzedElems.add(e.getTypeElement());
+ analyzedElems.add(e.getTypeElement());
}
public void finished(TaskEvent e) { }
});
try {
Iterable<? extends CompilationUnitTree> trees = task.parse();
- task.analyze();
+// JavaCompiler c = JavaCompiler.instance(((JavacTaskImpl) task).getContext());
+// System.err.println("verboseCompilePolicy: " + c.verboseCompilePolicy);
+// System.err.println("shouldStopIfError: " + c.shouldStopPolicyIfError);
+// System.err.println("shouldStopIfNoError: " + c.shouldStopPolicyIfNoError);
+ Iterable<? extends Element> elems = task.analyze();
+ if (!elems.iterator().hasNext())
+ throw new AttributionException("No results from analyze");
List<Pair<JCCompilationUnit, JCTree>> res = new ArrayList<>();
- //System.out.println("Try to add pairs. Elems are " + analyzedElems);
+ //System.err.println("Try to add pairs. Elems are " + analyzedElems);
for (CompilationUnitTree t : trees) {
JCCompilationUnit cu = (JCCompilationUnit)t;
for (JCTree def : cu.defs) {
if (def.hasTag(CLASSDEF) &&
analyzedElems.contains(((JCTree.JCClassDecl)def).sym)) {
- //System.out.println("Adding pair...");
+ //System.err.println("Adding pair..." + cu.sourcefile + " " + ((JCTree.JCClassDecl) def).name);
res.add(new Pair<>(cu, def));
}
}
@@ -316,7 +325,9 @@
* @param msg the error message
*/
void error(String msg) {
+ System.err.println();
System.err.println(msg);
+ System.err.println();
errCount.incrementAndGet();
}
@@ -347,6 +358,7 @@
private class NPETester extends TreeScanner {
void test(List<Pair<JCCompilationUnit, JCTree>> trees) {
for (Pair<JCCompilationUnit, JCTree> p : trees) {
+// System.err.println("checking " + p.fst.sourcefile);
sourcefile = p.fst.sourcefile;
endPosTable = p.fst.endPositions;
encl = new Info(p.snd, endPosTable);
@@ -366,7 +378,7 @@
check(tree.type != null,
"'null' field 'type' found in tree ", self);
if (tree.type==null)
- new Throwable().printStackTrace();
+ Thread.dumpStack();
}
Field errField = checkFields(tree);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/AtFilesTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for at-files
+ * @build Tester
+ * @run main AtFilesTest
+ */
+
+import java.io.IOException;
+
+public class AtFilesTest extends Tester {
+ public static void main(String... args) throws Exception {
+ AtFilesTest t = new AtFilesTest();
+ t.runTests();
+ }
+
+ @Test
+ void testAtFiles() throws IOException {
+ writeFile("src/A.java", "class A { }");
+ writeFile("files.txt", "src/A.java");
+ mkdirs("classes");
+
+ String[] opts = { "-d", "classes", "@files.txt" };
+ String[] files = { };
+
+ runMain(opts, files)
+ .checkOK()
+ .checkClass("A");
+
+ runCall(opts, files)
+ .checkIllegalArgumentException();
+
+ runParse(opts, files)
+ .checkIllegalArgumentException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/DocLintTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for -Xdoclint
+ * @build Tester
+ * @run main DocLintTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+
+public class DocLintTest extends Tester {
+ public static void main(String... args) throws Exception {
+ DocLintTest t = new DocLintTest();
+ t.runTests();
+ }
+
+ @Test
+ void testDocLint() throws IOException {
+ writeFile("src/C.java", "/** & */ class C { }");
+ mkdirs("classes");
+
+ String[] opts = { "-d", "classes", "-Xdoclint" };
+ String[] files = { "src/C.java" };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.ERROR.exitCode);
+
+ runCall(opts, files)
+ .checkResult(false);
+
+ // 1. doclint runs at the beginning of analyze
+ // 2. the analyze call itself succeeds, so we check for errors being reported
+ runAnalyze(opts, files)
+ .checkResult(true)
+ .checkLog(Log.DIRECT, "^");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/FSInfoTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for the internal file system cache
+ * @build Tester
+ * @run main FSInfoTest
+ */
+
+import com.sun.tools.javac.file.CacheFSInfo;
+import com.sun.tools.javac.file.FSInfo;
+import java.io.IOException;
+
+public class FSInfoTest extends Tester {
+ public static void main(String... args) throws Exception {
+ FSInfoTest t = new FSInfoTest();
+ t.writeFile("C.java", "class C { }");
+ t.runTests();
+ }
+
+ @Test
+ void testCacheEnabled() throws IOException {
+
+ String[] args = { };
+ String[] files = { "C.java"};
+
+ TestResult tr = runMain(args, files);
+ FSInfo info = tr.context.get(FSInfo.class);
+ if (!(info instanceof CacheFSInfo))
+ error("unexpected FSInfo; found " + info.getClass() + ", expected CacheFSInfo");
+ }
+
+ @Test
+ void testCacheDisabled() throws IOException {
+ writeFile("C.java", "class C { }");
+
+ String[] args = { "-XDnonBatchMode" };
+ String[] files = { "C.java"};
+
+ TestResult tr = runMain(args, files);
+ FSInfo info = tr.context.get(FSInfo.class);
+ if (info instanceof CacheFSInfo)
+ error("unexpected CacheFSInfo found");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/InfoOptsTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for info options -help -X -version -fullversion
+ * @build Tester
+ * @run main InfoOptsTest
+ */
+
+import java.io.IOException;
+
+public class InfoOptsTest extends Tester {
+ public static void main(String... args) throws Exception {
+ InfoOptsTest t = new InfoOptsTest();
+ t.runTests();
+ }
+
+ @Test
+ void testInfoOpts() throws IOException {
+ testInfoOpt("-help", "-deprecation");
+ testInfoOpt("-X", "-Xlint");
+
+ String specVersion = System.getProperty("java.specification.version");
+ testInfoOpt("-version", "javac", specVersion);
+ testInfoOpt("-fullversion", "javac", specVersion, "-b");
+ }
+
+ void testInfoOpt(String opt, String... expect) {
+ String[] opts = { opt };
+ String[] files = { };
+
+ runMain(opts, files)
+ .checkOK()
+ .checkLog(expect);
+
+ runCall(opts, files)
+ .checkIllegalArgumentException();
+
+ runParse(opts, files)
+ .checkIllegalArgumentException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/NoOperandsTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support no operands being specified
+ * @build Tester
+ * @run main NoOperandsTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+
+public class NoOperandsTest extends Tester {
+ public static void main(String... args) throws Exception {
+ NoOperandsTest t = new NoOperandsTest();
+ t.runTests();
+ }
+
+ @Test
+ void testNoOperands() throws IOException {
+ String[] opts = { "-d", "." };
+ String[] files = { };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.CMDERR.exitCode);
+
+ runCall(opts, files)
+ .checkIllegalStateException();
+
+ runParse(opts, files)
+ .checkIllegalStateException();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/OutputDirTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for output directory options -d and -s
+ * @build Tester
+ * @run main OutputDirTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+
+public class OutputDirTest extends Tester {
+ public static void main(String... args) throws Exception {
+ OutputDirTest t = new OutputDirTest();
+ t.writeFile("src/C.java", "class C { }");
+ t.runTests();
+ }
+
+ @Test
+ void testClassOutputDir() throws IOException {
+ testOutputDir("-d");
+ }
+
+ @Test
+ void testSourceOutputDir() throws IOException {
+ testOutputDir("-s");
+ }
+
+ void testOutputDir(String opt) {
+ String[] opts = { opt, "does-not-exist"};
+ String[] files = { "src/C.java" };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.CMDERR.exitCode);
+
+// The API tests are disabled (for now) because Args.validate does
+// not have an easy way to access/validate file manager options,
+// which are handled directly by the file manager
+
+// runCall(opts, files)
+// .checkIllegalStateException();
+
+// runParse(opts, files)
+// .checkIllegalStateException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/ProfileBootClassPathTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for checking -profile and -bootclasspath
+ * @build Tester
+ * @run main ProfileBootClassPathTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.File;
+import java.io.IOException;
+
+public class ProfileBootClassPathTest extends Tester {
+ public static void main(String... args) throws Exception {
+ ProfileBootClassPathTest t = new ProfileBootClassPathTest();
+ t.runTests();
+ }
+
+ @Tester.Test
+ void testProfileBootClassPath() throws IOException {
+ writeFile("C.java", "class C { }");
+
+ String javaHome = System.getProperty("java.home");
+ String rt_jar = new File(javaHome, "jre/lib/rt.jar").getPath();
+ String[] opts = { "-profile", "compact1", "-bootclasspath", rt_jar };
+ String[] files = { "C.java" };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.CMDERR.exitCode);
+
+// The API tests are disabled (for now) because Args.validate does
+// not have an easy way to access/validate file manager options,
+// which are handled directly by the file manager
+
+// runCall(opts, files)
+// .checkIllegalStateException();
+
+// runParse(opts, files)
+// .checkIllegalStateException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/ProfileTargetTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for checking -profile and -target
+ * @build Tester
+ * @run main ProfileTargetTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+
+public class ProfileTargetTest extends Tester {
+ public static void main(String... args) throws Exception {
+ ProfileTargetTest t = new ProfileTargetTest();
+ t.runTests();
+ }
+
+ @Test
+ void testProfileTarget() throws IOException {
+ writeFile("C.java", "class C { }");
+
+ String[] opts = { "-profile", "compact1", "-source", "7", "-target", "7" };
+ String[] files = { "C.java" };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.CMDERR.exitCode);
+
+ runCall(opts, files)
+ .checkIllegalStateException();
+
+ runParse(opts, files)
+ .checkIllegalStateException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/SourceTargetTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for -source and -target checks
+ * @build Tester
+ * @run main SourceTargetTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+
+public class SourceTargetTest extends Tester {
+ public static void main(String... args) throws Exception {
+ SourceTargetTest t = new SourceTargetTest();
+ t.runTests();
+ }
+
+ @Test
+ void testSourceTarget() throws IOException {
+ String v = System.getProperty("java.specification.version");
+ String latest = v.substring(v.lastIndexOf(".") + 1);
+ String prev = String.valueOf(Integer.valueOf(latest) - 1);
+
+ writeFile("C.java", "class C { }");
+
+ String[] opts = { "-source", latest, "-target", prev };
+ String[] files = { "C.java" };
+
+ runMain(opts, files)
+ .checkResult(Main.Result.CMDERR.exitCode);
+
+ runCall(opts, files)
+ .checkIllegalStateException();
+
+ runParse(opts, files)
+ .checkIllegalStateException();
+ }
+
+ @Test
+ void testObsoleteSourceTarget() throws IOException {
+
+ writeFile("C.java", "class C { }");
+
+ String[] opts = { "-source", "1.6", "-target", "1.6" };
+ String[] files = { "C.java" };
+
+ runMain(opts, files)
+ .checkOK()
+ .checkLog("obsolete");
+
+ runCall(opts, files)
+ .checkOK()
+ .checkLog("obsolete");
+
+ runParse(opts, files)
+ .checkOK()
+ .checkLog("obsolete");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/StdOutTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044859
+ * @summary test support for -Xstdout file and -XDstdout
+ * @build Tester
+ * @run main StdOutTest
+ */
+
+import com.sun.tools.javac.main.Main;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class StdOutTest extends Tester {
+ public static void main(String... args) throws Exception {
+ StdOutTest t = new StdOutTest();
+ t.writeFile("src/Bad.java", "class Bad");
+ t.runTests();
+ }
+
+ @Test
+ void testXstdout() throws IOException {
+ String[] args = { "-Xstdout", "out.txt" };
+ String[] files = { "src/Bad.java" };
+
+ // verify messages get written to the specified file
+ runMain(args, files)
+ .checkResult(Main.Result.ERROR.exitCode);
+ if (!Files.exists(Paths.get("out.txt"))) {
+ error("expected file not found");
+ }
+
+ runCall(args, files)
+ .checkIllegalArgumentException();
+
+ runParse(args, files)
+ .checkIllegalArgumentException();
+ }
+
+ @Test
+ void testXDstdout() throws IOException {
+ String[] args = { "-XDstdout" };
+ String[] files = { "src/Bad.java" };
+
+ runMain(args, files)
+ .checkLog(Log.STDOUT, "Bad");
+
+ runCall(args, files)
+ .checkLog(Log.DIRECT, "Bad");
+
+ runParse(args, files)
+ .checkLog(Log.DIRECT, "Bad");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/modes/Tester.java Fri Aug 22 16:28:16 2014 -0700
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.Context;
+import java.io.ByteArrayOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class Tester {
+
+ /** Marker annotation for test methods to be invoked by runTests. */
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface Test { }
+
+ /**
+ * Run all methods annotated with @Test, and throw an exception if any
+ * errors are reported..
+ * Typically called on a tester object in main()
+ * @throws Exception if any errors occurred
+ */
+ void runTests() throws Exception {
+ for (Method m: getClass().getDeclaredMethods()) {
+ Annotation a = m.getAnnotation(Test.class);
+ if (a != null) {
+ try {
+ out.println("Running test " + m.getName());
+ m.invoke(this);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ throw (cause instanceof Exception) ? ((Exception) cause) : e;
+ }
+ out.println();
+ }
+ }
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ TestResult runMain(String[] opts, String[] files) {
+ out.println("Main " + Arrays.toString(opts) + " " + Arrays.toString(files));
+ return run(new TestResult(opts), (tr, c, pw) -> {
+ com.sun.tools.javac.main.Main compiler =
+ new com.sun.tools.javac.main.Main("javac", pw);
+ int rc = compiler.compile(join(opts, files), c).exitCode;
+ tr.setResult(rc);
+ });
+ }
+
+ TestResult runCall(String[] opts, String[] files) {
+ out.println("Call " + Arrays.toString(opts) + " " + Arrays.toString(files));
+ return run(new TestResult(opts), (tr, c, pw) -> {
+ boolean ok = JavacTool.create()
+ .getTask(pw, null, null, Arrays.asList(opts), null, getFiles(files), c)
+ .call();
+ tr.setResult(ok);
+ });
+ }
+
+ TestResult runParse(String[] opts, String[] files) {
+ out.println("Parse " + Arrays.toString(opts) + " " + Arrays.toString(files));
+ return run(new TestResult(opts), (tr, c, pw) -> {
+ JavacTool.create()
+ .getTask(pw, null, null, Arrays.asList(opts), null, getFiles(files), c)
+ .parse();
+ tr.setResult(true);
+ });
+ }
+
+ TestResult runAnalyze(String[] opts, String[] files) {
+ out.println("Analyze " + Arrays.toString(opts) + " " + Arrays.toString(files));
+ return run(new TestResult(opts), (tr, c, pw) -> {
+ JavacTool.create()
+ .getTask(pw, null, null, Arrays.asList(opts), null, getFiles(files), c)
+ .analyze();
+ tr.setResult(true);
+ });
+ }
+
+ interface Runnable {
+ void run(TestResult tr, Context c, PrintWriter pw) throws IOException;
+ }
+
+ TestResult run(TestResult tr, Runnable r) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+ StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+ Context context = new Context();
+ JavacFileManager.preRegister(context);
+ try {
+ r.run(tr, context, pw);
+ } catch (IllegalArgumentException | IllegalStateException | IOException e) {
+ tr.setThrown(e);
+ } finally {
+ ((JavacFileManager) context.get(JavaFileManager.class)).close();
+ tr.setLogs(sw.toString(), sysOut.close(), sysErr.close());
+ }
+ tr.setContext(context);
+ tr.show();
+ return tr;
+ }
+
+ enum Log { DIRECT, STDOUT, STDERR };
+
+ class TestResult {
+ final List<String> args;
+ Throwable thrown;
+ Object rc; // Number or Boolean
+ Map<Log, String> logs;
+ Context context;
+
+ TestResult(String... args) {
+ this.args = Arrays.asList(args);
+ }
+
+ TestResult(List<String> args, Iterable<? extends JavaFileObject> files) {
+ this.args = new ArrayList<>();
+ this.args.addAll(args);
+ for (JavaFileObject f: files)
+ this.args.add(f.getName());
+ }
+
+ void setResult(int rc) {
+ this.rc = rc;
+ }
+
+ void setResult(boolean ok) {
+ this.rc = ok ? 0 : 1;
+ }
+
+ void setThrown(Throwable thrown) {
+ this.thrown = thrown;
+ }
+
+ void setLogs(String direct, String stdOut, String stdErr) {
+ logs = new EnumMap<>(Log.class);
+ logs.put(Log.DIRECT, direct);
+ logs.put(Log.STDOUT, stdOut);
+ logs.put(Log.STDERR, stdErr);
+ }
+
+ void setContext(Context context) {
+ this.context = context;
+ }
+
+ final void show() {
+ String NL = System.getProperty("line.separator");
+ boolean needSep = false;
+ if (rc != null) {
+ out.print("rc:" + rc);
+ needSep = true;
+ }
+ if (thrown != null) {
+ if (needSep) out.print("; ");
+ out.print("thrown:" + thrown);
+ needSep = true;
+ }
+ if (needSep)
+ out.println();
+ logs.forEach((k, v) -> {
+ if (!v.isEmpty()) {
+ out.println("javac/" + k + ":");
+ if (v.endsWith(NL))
+ out.print(v);
+ else
+ out.println(v);
+ }
+
+ });
+ }
+
+ TestResult checkOK() {
+ if (thrown != null) {
+ error("unexpected exception thrown: " + thrown);
+ } else if (rc == null) {
+ error("no result set");
+ } else if (rc != (Integer) 0 && rc != (Boolean) true) {
+ error("compilation failed unexpectedly; rc=" + rc);
+ }
+ return this;
+ }
+
+ TestResult checkResult(int expect) {
+ if (thrown != null) {
+ error("unexpected exception thrown: " + thrown);
+ } else if (rc != (Integer) expect) {
+ error("unexpected result: " + rc +", expected:" + expect);
+ }
+ return this;
+ }
+
+ TestResult checkResult(boolean expect) {
+ if (thrown != null) {
+ error("unexpected exception thrown: " + thrown);
+ } else if (rc != (Integer) (expect ? 0 : 1)) {
+ error("unexpected result: " + rc +", expected:" + expect);
+ }
+ return this;
+ }
+
+ TestResult checkLog(String... expects) {
+ return checkLog(Log.DIRECT, expects);
+ }
+
+ TestResult checkLog(Log l, String... expects) {
+ for (String e: expects) {
+ if (!logs.get(l).contains(e))
+ error("expected string not found: " + e);
+ }
+ return this;
+ }
+
+ TestResult checkIllegalArgumentException() {
+ return checkThrown(IllegalArgumentException.class);
+ }
+
+ TestResult checkIllegalStateException() {
+ return checkThrown(IllegalStateException.class);
+ }
+
+ TestResult checkThrown(Class<? extends Throwable> t) {
+ if (thrown == null)
+ error("expected exception not thrown: " + t);
+ else if (!t.isAssignableFrom(thrown.getClass()))
+ error("unexpected exception thrown: " + thrown + "; expected: " + t);
+ return this;
+ }
+
+ TestResult checkClass(String name) {
+ Path p = getOutDir().resolve(name.replace(".", "/") + ".class");
+ if (!Files.exists(p))
+ error("expected class not found: " + name + " (" + p + ")");
+ return this;
+ }
+
+ Path getOutDir() {
+ Iterator<String> iter = args.iterator();
+ while (iter.hasNext()) {
+ if (iter.next().equals("-d")) {
+ return Paths.get(iter.next());
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Utility class to simplify the handling of temporarily setting a
+ * new stream for System.out or System.err.
+ */
+ private static class StreamOutput {
+ // functional interface to set a stream.
+ private interface Initializer {
+ void set(PrintStream s);
+ }
+
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private final PrintStream ps = new PrintStream(baos);
+ private final PrintStream prev;
+ private final Initializer init;
+
+ StreamOutput(PrintStream s, Initializer init) {
+ prev = s;
+ init.set(ps);
+ this.init = init;
+ }
+
+ String close() {
+ init.set(prev);
+ ps.close();
+ return baos.toString();
+ }
+ }
+
+ List<JavaFileObject> getFiles(String... paths) {
+ List<JavaFileObject> files = new ArrayList<>();
+ for (JavaFileObject f : fm.getJavaFileObjects(paths))
+ files.add(f);
+ return files;
+ }
+
+ String toString(List<JavaFileObject> files) {
+ return files.stream().map(f -> f.getName()).collect(Collectors.toList()).toString();
+ }
+
+ void mkdirs(String path) throws IOException {
+ Files.createDirectories(Paths.get(path));
+ }
+
+ void writeFile(String path, String body) throws IOException {
+ Path p = Paths.get(path);
+ if (p.getParent() != null)
+ Files.createDirectories(p.getParent());
+ try (FileWriter w = new FileWriter(path)) {
+ w.write(body);
+ }
+ }
+
+ String[] join(String[] a, String[] b) {
+ String[] result = new String[a.length + b.length];
+ System.arraycopy(a, 0, result, 0, a.length);
+ System.arraycopy(b, 0, result, a.length, b.length);
+ return result;
+ }
+
+ void error(String message) {
+ out.print(">>>>> ");
+ out.println(message);
+ errors++;
+ }
+
+ StandardJavaFileManager fm =
+ ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null);
+ PrintStream out = System.err;
+ int errors;
+
+}
--- a/langtools/test/tools/javac/profiles/ProfileOptionTest.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java Fri Aug 22 16:28:16 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -67,7 +67,7 @@
// ---------- Test cases, invoked reflectively via run. ----------
@Test
- void testInvalidProfile_CommandLine() throws Exception {
+ void testInvalidProfile_API() throws Exception {
JavaFileObject fo = new StringJavaFileObject("Test.java", "class Test { }");
String badName = "foo";
List<String> opts = Arrays.asList("-profile", badName);
@@ -82,7 +82,7 @@
}
@Test
- void testInvalidProfile_API() throws Exception {
+ void testInvalidProfile_CommandLine() throws Exception {
String badName = "foo";
String[] opts = { "-profile", badName };
StringWriter sw = new StringWriter();
@@ -115,10 +115,17 @@
opts.add("-Xlint:-options"); // dont warn about no -bootclasspath
if (p != Profile.DEFAULT)
opts.addAll(Arrays.asList("-profile", p.name));
+
+ IllegalStateException ise;
StringWriter sw = new StringWriter();
- JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
- Arrays.asList(fo));
- task.analyze();
+ try {
+ JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
+ Arrays.asList(fo));
+ task.analyze();
+ ise = null;
+ } catch (IllegalStateException e) {
+ ise = e;
+ }
// sadly, command line errors are not (yet?) reported to
// the diag listener
@@ -129,14 +136,17 @@
switch (t) {
case JDK1_8:
case JDK1_9:
- if (!out.isEmpty())
- error("unexpected output from compiler");
+ if (ise != null)
+ error("unexpected exception from compiler: " + ise);
break;
default:
- if (p != Profile.DEFAULT
- && !out.contains("profile " + p.name
+ if (p == Profile.DEFAULT)
+ break;
+ if (ise == null)
+ error("IllegalStateException not thrown as expected");
+ else if (!ise.getMessage().contains("profile " + p.name
+ " is not valid for target release " + t.name)) {
- error("expected message not found");
+ error("exception not thrown as expected: " + ise);
}
}
}
--- a/langtools/test/tools/javac/versions/Versions.java Fri Aug 22 12:25:01 2014 +0200
+++ b/langtools/test/tools/javac/versions/Versions.java Fri Aug 22 16:28:16 2014 -0700
@@ -279,7 +279,13 @@
options, // Iterable<String>
null, // Iterable<String> classes
files); // Iterable<? extends JavaFileObject>
- return jctask.call();
+
+ try {
+ return jctask.call();
+ } catch (IllegalStateException e) {
+ System.err.println(e);
+ return false;
+ }
}