--- a/langtools/src/share/classes/com/sun/source/util/JavacTask.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/JavacTask.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -25,9 +25,9 @@
package com.sun.source.util;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.Tree;
import java.io.IOException;
+
+import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
@@ -35,6 +35,12 @@
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.tools.javac.api.BasicJavacTask;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.Context;
+
/**
* Provides access to functionality specific to the JDK Java Compiler, javac.
*
@@ -45,10 +51,29 @@
public abstract class JavacTask implements CompilationTask {
/**
+ * Get the {@code JavacTask} for a {@code ProcessingEnvironment}.
+ * If the compiler is being invoked using a
+ * {@link javax.tools.JavaCompiler.CompilationTask CompilationTask},
+ * then that task will be returned.
+ * @param processingEnvironment
+ * @return the {@code JavacTask} for a {@code ProcessingEnvironment}
+ * @since 1.8
+ */
+ public static JavacTask instance(ProcessingEnvironment processingEnvironment) {
+ if (!processingEnvironment.getClass().getName().equals(
+ "com.sun.tools.javac.processing.JavacProcessingEnvironment"))
+ throw new IllegalArgumentException();
+ Context c = ((JavacProcessingEnvironment) processingEnvironment).getContext();
+ JavacTask t = c.get(JavacTask.class);
+ return (t != null) ? t : new BasicJavacTask(c, true);
+ }
+
+ /**
* Parse the specified files returning a list of abstract syntax trees.
*
* @return a list of abstract syntax trees
* @throws IOException if an unhandled I/O error occurred in the compiler.
+ * @throws IllegalStateException if the operation cannot be performed at this time.
*/
public abstract Iterable<? extends CompilationUnitTree> parse()
throws IOException;
@@ -58,6 +83,7 @@
*
* @return a list of elements that were analyzed
* @throws IOException if an unhandled I/O error occurred in the compiler.
+ * @throws IllegalStateException if the operation cannot be performed at this time.
*/
public abstract Iterable<? extends Element> analyze() throws IOException;
@@ -66,17 +92,51 @@
*
* @return a list of files that were generated
* @throws IOException if an unhandled I/O error occurred in the compiler.
+ * @throws IllegalStateException if the operation cannot be performed at this time.
*/
public abstract Iterable<? extends JavaFileObject> generate() throws IOException;
/**
- * The specified listener will receive events describing the progress of
- * this compilation task.
+ * The specified listener will receive notification of events
+ * describing the progress of this compilation task.
+ *
+ * If another listener is receiving notifications as a result of a prior
+ * call of this method, then that listener will no longer receive notifications.
+ *
+ * Informally, this method is equivalent to calling {@code removeTaskListener} for
+ * any listener that has been previously set, followed by {@code addTaskListener}
+ * for the new listener.
+ *
+ * @throws IllegalStateException if the specified listener has already been added.
*/
public abstract void setTaskListener(TaskListener taskListener);
/**
+ * The specified listener will receive notification of events
+ * describing the progress of this compilation task.
+ *
+ * This method may be called at any time before or during the compilation.
+ *
+ * @throws IllegalStateException if the specified listener has already been added.
+ * @since 1.8
+ */
+ public abstract void addTaskListener(TaskListener taskListener);
+
+ /**
+ * The specified listener will no longer receive notification of events
+ * describing the progress of this compilation task.
+ *
+ * This method may be called at any time before or during the compilation.
+ *
+ * @since 1.8
+ */
+ public abstract void removeTaskListener(TaskListener taskListener);
+
+ /**
* Get 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}.
+ * @see com.sun.source.util.Trees#getTypeMirror
*/
public abstract TypeMirror getTypeMirror(Iterable<? extends Tree> path);
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Tue Feb 28 10:33:49 2012 -0800
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2005, 2012, 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.api;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.annotation.processing.Processor;
+import javax.lang.model.element.Element;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.JavaFileObject;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.model.JavacElements;
+import com.sun.tools.javac.model.JavacTypes;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.Context;
+import java.util.Collection;
+
+/**
+ * Provides basic functionality for implementations of JavacTask.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class BasicJavacTask extends JavacTask {
+ protected Context context;
+ private TaskListener taskListener;
+
+ public BasicJavacTask(Context c, boolean register) {
+ context = c;
+ if (register)
+ context.put(JavacTask.class, this);
+ }
+
+ @Override
+ public Iterable<? extends CompilationUnitTree> parse() throws IOException {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Iterable<? extends Element> analyze() throws IOException {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Iterable<? extends JavaFileObject> generate() throws IOException {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void setTaskListener(TaskListener tl) {
+ MultiTaskListener mtl = MultiTaskListener.instance(context);
+ if (taskListener != null)
+ mtl.remove(taskListener);
+ if (tl != null)
+ mtl.add(tl);
+ taskListener = tl;
+ }
+
+ @Override
+ public void addTaskListener(TaskListener taskListener) {
+ MultiTaskListener mtl = MultiTaskListener.instance(context);
+ mtl.add(taskListener);
+ }
+
+ @Override
+ public void removeTaskListener(TaskListener taskListener) {
+ MultiTaskListener mtl = MultiTaskListener.instance(context);
+ mtl.remove(taskListener);
+ }
+
+ public Collection<TaskListener> getTaskListeners() {
+ MultiTaskListener mtl = MultiTaskListener.instance(context);
+ return mtl.getTaskListeners();
+ }
+
+ @Override
+ 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;
+ }
+
+ @Override
+ public Elements getElements() {
+ return JavacElements.instance(context);
+ }
+
+ @Override
+ public Types getTypes() {
+ return JavacTypes.instance(context);
+ }
+
+ public void setProcessors(Iterable<? extends Processor> processors) {
+ throw new IllegalStateException();
+ }
+
+ public void setLocale(Locale locale) {
+ throw new IllegalStateException();
+ }
+
+ public Boolean call() {
+ throw new IllegalStateException();
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -31,8 +31,13 @@
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -41,25 +46,21 @@
import java.util.Map;
import java.util.Set;
+import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import javax.lang.model.element.Modifier;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject.Kind;
/**
* Wrap objects to enable unchecked exceptions to be caught and handled.
@@ -160,6 +161,20 @@
return new WrappedTaskListener(tl);
}
+ TaskListener unwrap(TaskListener l) {
+ if (l instanceof WrappedTaskListener)
+ return ((WrappedTaskListener) l).clientTaskListener;
+ else
+ return l;
+ }
+
+ Collection<TaskListener> unwrap(Collection<? extends TaskListener> listeners) {
+ Collection<TaskListener> c = new ArrayList<TaskListener>(listeners.size());
+ for (TaskListener l: listeners)
+ c.add(unwrap(l));
+ return c;
+ }
+
@SuppressWarnings("unchecked")
private <T> Diagnostic<T> unwrap(final Diagnostic<T> diagnostic) {
if (diagnostic instanceof JCDiagnostic) {
@@ -181,6 +196,10 @@
return trusted;
}
+ private String wrappedToString(Class<?> wrapperClass, Object wrapped) {
+ return wrapperClass.getSimpleName() + "[" + wrapped + "]";
+ }
+
// <editor-fold defaultstate="collapsed" desc="Wrapper classes">
// FIXME: all these classes should be converted to use multi-catch when
@@ -361,6 +380,11 @@
throw new ClientCodeException(e);
}
}
+
+ @Override
+ public String toString() {
+ return wrappedToString(getClass(), clientJavaFileManager);
+ }
}
protected class WrappedFileObject implements FileObject {
@@ -486,6 +510,11 @@
throw new ClientCodeException(e);
}
}
+
+ @Override
+ public String toString() {
+ return wrappedToString(getClass(), clientFileObject);
+ }
}
protected class WrappedJavaFileObject extends WrappedFileObject implements JavaFileObject {
@@ -544,6 +573,11 @@
throw new ClientCodeException(e);
}
}
+
+ @Override
+ public String toString() {
+ return wrappedToString(getClass(), clientFileObject);
+ }
}
protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
@@ -565,6 +599,11 @@
throw new ClientCodeException(e);
}
}
+
+ @Override
+ public String toString() {
+ return wrappedToString(getClass(), clientDiagnosticListener);
+ }
}
public class DiagnosticSourceUnwrapper implements Diagnostic<JavaFileObject> {
@@ -610,6 +649,7 @@
return d.getMessage(locale);
}
+ @Override
public String toString() {
return d.toString();
}
@@ -647,6 +687,11 @@
throw new ClientCodeException(e);
}
}
+
+ @Override
+ public String toString() {
+ return wrappedToString(getClass(), clientTaskListener);
+ }
}
// </editor-fold>
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -44,6 +44,7 @@
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;
@@ -51,7 +52,6 @@
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.main.JavaCompiler;
/**
* Provides access to functionality specific to the JDK Java Compiler, javac.
@@ -64,18 +64,16 @@
* @author Peter von der Ahé
* @author Jonathan Gibbons
*/
-public class JavacTaskImpl extends JavacTask {
+public class JavacTaskImpl extends BasicJavacTask {
private ClientCodeWrapper ccw;
private Main compilerMain;
private JavaCompiler compiler;
private Locale locale;
private String[] args;
private String[] classNames;
- private Context context;
private List<JavaFileObject> fileObjects;
private Map<JavaFileObject, JCCompilationUnit> notYetEntered;
private ListBuffer<Env<AttrContext>> genList;
- private TaskListener taskListener;
private AtomicBoolean used = new AtomicBoolean();
private Iterable<? extends Processor> processors;
@@ -86,6 +84,7 @@
String[] classNames,
Context context,
List<JavaFileObject> fileObjects) {
+ super(null, false);
this.ccw = ClientCodeWrapper.instance(context);
this.compilerMain = compilerMain;
this.args = args;
@@ -190,11 +189,7 @@
}
private void initContext() {
- context.put(JavacTaskImpl.class, this);
- if (context.get(TaskListener.class) != null)
- context.put(TaskListener.class, (TaskListener)null);
- if (taskListener != null)
- context.put(TaskListener.class, ccw.wrap(taskListener));
+ context.put(JavacTask.class, this);
//initialize compiler's default locale
context.put(Locale.class, locale);
}
@@ -224,10 +219,6 @@
return fm.getRegularFile(file);
}
- public void setTaskListener(TaskListener taskListener) {
- this.taskListener = taskListener;
- }
-
/**
* Parse the specified files returning a list of abstract syntax trees.
*
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -26,7 +26,7 @@
package com.sun.tools.javac.api;
import java.io.IOException;
-import java.util.Map;
+
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
@@ -44,13 +44,14 @@
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type.UnionClassType;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
@@ -61,8 +62,8 @@
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
-import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.TreeMaker;
@@ -95,12 +96,14 @@
private JavacElements elements;
private JavacTaskImpl javacTaskImpl;
+ // called reflectively from Trees.instance(CompilationTask task)
public static JavacTrees instance(JavaCompiler.CompilationTask task) {
if (!(task instanceof JavacTaskImpl))
throw new IllegalArgumentException();
return instance(((JavacTaskImpl)task).getContext());
}
+ // called reflectively from Trees.instance(ProcessingEnvironment env)
public static JavacTrees instance(ProcessingEnvironment env) {
if (!(env instanceof JavacProcessingEnvironment))
throw new IllegalArgumentException();
@@ -131,7 +134,10 @@
resolve = Resolve.instance(context);
treeMaker = TreeMaker.instance(context);
memberEnter = MemberEnter.instance(context);
- javacTaskImpl = context.get(JavacTaskImpl.class);
+
+ JavacTask t = context.get(JavacTask.class);
+ if (t instanceof JavacTaskImpl)
+ javacTaskImpl = (JavacTaskImpl) t;
}
public SourcePositions getSourcePositions() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/MultiTaskListener.java Tue Feb 28 10:33:49 2012 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2011, 2012, 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.api;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.util.Context;
+
+/**
+ * TODO.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class MultiTaskListener implements TaskListener {
+ /** The context key for the MultiTaskListener. */
+ public static final Context.Key<MultiTaskListener> taskListenerKey =
+ new Context.Key<MultiTaskListener>();
+
+ /** Get the MultiTaskListener instance for this context. */
+ public static MultiTaskListener instance(Context context) {
+ MultiTaskListener instance = context.get(taskListenerKey);
+ if (instance == null)
+ instance = new MultiTaskListener(context);
+ return instance;
+ }
+
+ protected MultiTaskListener(Context context) {
+ context.put(taskListenerKey, this);
+ ccw = ClientCodeWrapper.instance(context);
+ }
+
+ /**
+ * The current set of registered listeners.
+ * This is a mutable reference to an immutable array.
+ */
+ TaskListener[] listeners = { };
+
+ ClientCodeWrapper ccw;
+
+ public Collection<TaskListener> getTaskListeners() {
+ return Arrays.asList(listeners);
+ }
+
+ public boolean isEmpty() {
+ return (listeners.length == 0);
+ }
+
+ public void add(TaskListener listener) {
+ for (TaskListener l: listeners) {
+ if (ccw.unwrap(l) == listener)
+ throw new IllegalStateException();
+ }
+ TaskListener[] newListeners = new TaskListener[listeners.length + 1];
+ System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
+ newListeners[newListeners.length - 1] = ccw.wrap(listener);
+ listeners = newListeners;
+ }
+
+ public void remove(TaskListener listener) {
+ for (int i = 0; i < listeners.length; i++) {
+ if (ccw.unwrap(listeners[i]) == listener) {
+ TaskListener[] newListeners = new TaskListener[listeners.length - 1];
+ System.arraycopy(listeners, 0, newListeners, 0, i);
+ System.arraycopy(listeners, i + 1, newListeners, i, newListeners.length - i);
+ listeners = newListeners;
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void started(TaskEvent e) {
+ // guard against listeners being updated by a listener
+ TaskListener[] ll = this.listeners;
+ for (TaskListener l: ll)
+ l.started(e);
+ }
+
+ @Override
+ public void finished(TaskEvent e) {
+ // guard against listeners being updated by a listener
+ TaskListener[] ll = this.listeners;
+ for (TaskListener l: ll)
+ l.finished(e);
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.toString(listeners);
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -28,8 +28,8 @@
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
-import java.util.LinkedHashMap;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Queue;
@@ -41,13 +41,13 @@
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
+import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
-import javax.tools.DiagnosticListener;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskListener;
-
+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.*;
@@ -60,8 +60,6 @@
import com.sun.tools.javac.tree.JCTree.*;
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.main.Option.*;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
import static com.sun.tools.javac.util.ListBuffer.lb;
@@ -289,9 +287,9 @@
*/
protected ParserFactory parserFactory;
- /** Optional listener for progress events
+ /** Broadcasting listener for progress events
*/
- protected TaskListener taskListener;
+ protected MultiTaskListener taskListener;
/**
* Annotation processing may require and provide a new instance
@@ -356,7 +354,7 @@
lower = Lower.instance(context);
annotate = Annotate.instance(context);
types = Types.instance(context);
- taskListener = context.get(TaskListener.class);
+ taskListener = MultiTaskListener.instance(context);
reader.sourceCompleter = this;
@@ -592,7 +590,7 @@
if (verbose) {
log.printVerbose("parsing.started", filename);
}
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);
taskListener.started(e);
}
@@ -605,7 +603,7 @@
tree.sourcefile = filename;
- if (content != null && taskListener != null) {
+ if (content != null && !taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
taskListener.finished(e);
}
@@ -751,14 +749,14 @@
log.useSource(prev);
}
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
taskListener.started(e);
}
enter.complete(List.of(tree), c);
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
taskListener.finished(e);
}
@@ -924,7 +922,7 @@
*/
public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
//enter symbols for all files
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
taskListener.started(e);
@@ -933,7 +931,7 @@
enter.main(roots);
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
taskListener.finished(e);
@@ -1002,7 +1000,7 @@
reader.saveParameterNames = true;
keepComments = true;
genEndPos = true;
- if (taskListener != null)
+ if (!taskListener.isEmpty())
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
log.deferDiagnostics = true;
} else { // free resources
@@ -1017,7 +1015,7 @@
}
/**
- * Process any anotations found in the specifed compilation units.
+ * Process any annotations found in the specified compilation units.
* @param roots a list of compilation units
* @return an instance of the compiler in which to complete the compilation
*/
@@ -1176,7 +1174,7 @@
if (verbose)
log.printVerbose("checking.attribution", env.enclClass.sym);
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
taskListener.started(e);
}
@@ -1259,7 +1257,7 @@
}
}
finally {
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
taskListener.finished(e);
}
@@ -1440,7 +1438,7 @@
+ " " + cdef.sym + "]");
}
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE, env.toplevel, cdef.sym);
taskListener.started(e);
}
@@ -1464,7 +1462,7 @@
log.useSource(prev);
}
- if (taskListener != null) {
+ if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE, env.toplevel, cdef.sym);
taskListener.finished(e);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -25,34 +25,33 @@
package com.sun.tools.javac.processing;
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.regex.*;
-
-import java.net.URL;
import java.io.Closeable;
import java.io.File;
import java.io.PrintWriter;
-import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import java.util.regex.*;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.PackageElement;
import javax.lang.model.util.*;
+import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.DiagnosticListener;
+import static javax.tools.StandardLocation.*;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.api.MultiTaskListener;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.FSInfo;
@@ -71,19 +70,16 @@
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert;
-import com.sun.tools.javac.util.FatalError;
import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Options;
-
-import static javax.tools.StandardLocation.*;
+import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
+import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
-import static com.sun.tools.javac.main.Option.*;
-import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
/**
* Objects of this class hold and manage the state needed to support
@@ -157,6 +153,8 @@
*/
private JavacMessages messages;
+ private MultiTaskListener taskListener;
+
private Context context;
public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) {
@@ -185,6 +183,7 @@
processorOptions = initProcessorOptions(context);
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context);
+ taskListener = MultiTaskListener.instance(context);
initProcessorIterator(context, processors);
}
@@ -976,8 +975,7 @@
void run(boolean lastRound, boolean errorStatus) {
printRoundInfo(lastRound);
- TaskListener taskListener = context.get(TaskListener.class);
- if (taskListener != null)
+ if (!taskListener.isEmpty())
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
try {
@@ -993,7 +991,7 @@
discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles);
}
} finally {
- if (taskListener != null)
+ if (!taskListener.isEmpty())
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
}
@@ -1051,9 +1049,9 @@
if (dl != null)
next.put(DiagnosticListener.class, dl);
- TaskListener tl = context.get(TaskListener.class);
- if (tl != null)
- next.put(TaskListener.class, tl);
+ MultiTaskListener mtl = context.get(MultiTaskListener.taskListenerKey);
+ if (mtl != null)
+ next.put(MultiTaskListener.taskListenerKey, mtl);
FSInfo fsInfo = context.get(FSInfo.class);
if (fsInfo != null)
@@ -1086,9 +1084,9 @@
elementUtils.setContext(next);
typeUtils.setContext(next);
- JavacTaskImpl task = context.get(JavacTaskImpl.class);
+ JavacTaskImpl task = (JavacTaskImpl) context.get(JavacTask.class);
if (task != null) {
- next.put(JavacTaskImpl.class, task);
+ next.put(JavacTask.class, task);
task.updateContext(next);
}
@@ -1110,8 +1108,6 @@
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
Iterable<? extends PackageSymbol> pckSymbols) {
-
- TaskListener taskListener = context.get(TaskListener.class);
log = Log.instance(context);
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
@@ -1182,7 +1178,7 @@
// Free resources
this.close();
- if (taskListener != null)
+ if (!taskListener.isEmpty())
taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
if (errorStatus) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/taskListeners/TestSimpleAddRemove.java Tue Feb 28 10:33:49 2012 -0800
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2011, 2012, 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 7093891
+ * @summary support multiple task listeners
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.api.JavacTool;
+
+public class TestSimpleAddRemove {
+ enum AddKind {
+ SET_IN_TASK,
+ ADD_IN_TASK,
+ ADD_IN_PROCESSOR,
+ ADD_IN_LISTENER;
+ }
+
+ enum RemoveKind {
+ REMOVE_IN_TASK,
+ REMOVE_IN_PROCESSOR,
+ REMOVE_IN_LISTENER,
+ }
+
+ enum CompileKind {
+ CALL {
+ void run(JavacTask t) {
+ if (!t.call()) throw new Error("compilation failed");
+ }
+ },
+ GENERATE {
+ void run(JavacTask t) throws IOException {
+ t.generate();
+ }
+ };
+ abstract void run(JavacTask t) throws IOException;
+ }
+
+ static class EventKindCounter extends EnumMap<TaskEvent.Kind, EventKindCounter.Count> {
+ static class Count {
+ int started;
+ int finished;
+
+ @Override
+ public String toString() {
+ return started + ":" + finished;
+ }
+ }
+
+ EventKindCounter() {
+ super(TaskEvent.Kind.class);
+ }
+
+ void inc(TaskEvent.Kind k, boolean started) {
+ Count c = get(k);
+ if (c == null)
+ put(k, c = new Count());
+
+ if (started)
+ c.started++;
+ else
+ c.finished++;
+ }
+ }
+
+ static class TestListener implements TaskListener {
+ EventKindCounter counter;
+
+ TestListener(EventKindCounter c) {
+ counter = c;
+ }
+
+ public void started(TaskEvent e) {
+ counter.inc(e.getKind(), true);
+ }
+
+ public void finished(TaskEvent e) {
+ counter.inc(e.getKind(), false);
+ }
+ }
+
+ static void addInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
+ task.addTaskListener(new TaskListener() {
+ public void started(TaskEvent e) {
+ if (e.getKind() == kind) {
+ task.addTaskListener(listener);
+ task.removeTaskListener(this);
+ }
+ }
+
+ public void finished(TaskEvent e) { }
+ });
+ }
+
+ static void removeInListener(final JavacTask task, final TaskEvent.Kind kind, final TaskListener listener) {
+ task.addTaskListener(new TaskListener() {
+ public void started(TaskEvent e) {
+ if (e.getKind() == kind) {
+ task.removeTaskListener(listener);
+ task.removeTaskListener(this);
+ }
+ }
+
+ public void finished(TaskEvent e) { }
+ });
+ }
+
+ @SupportedAnnotationTypes("*")
+ class TestProcessor extends AbstractProcessor {
+ AddKind ak;
+ RemoveKind rk;
+ TaskListener listener;
+
+ TestProcessor(AddKind ak, RemoveKind rk, TaskListener listener) {
+ this.ak = ak;
+ this.rk = rk;
+ this.listener = listener;
+ }
+
+ int round = 0;
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+// System.err.println("TestProcessor.process " + roundEnv);
+ JavacTask task = JavacTask.instance(processingEnv);
+ if (++round == 1) {
+ switch (ak) {
+ case ADD_IN_PROCESSOR:
+ task.addTaskListener(listener);
+ break;
+ case ADD_IN_LISTENER:
+ addInListener(task, TaskEvent.Kind.ANALYZE, listener);
+ break;
+ }
+ } else if (roundEnv.processingOver()) {
+ switch (rk) {
+ case REMOVE_IN_PROCESSOR:
+ task.removeTaskListener(listener);
+ break;
+ case REMOVE_IN_LISTENER:
+ removeInListener(task, TaskEvent.Kind.GENERATE, listener);
+ break;
+ }
+ }
+ return true;
+ }
+ }
+
+ static class TestSource extends SimpleJavaFileObject {
+ public TestSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return "class Test { }";
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ new TestSimpleAddRemove().run();
+ }
+
+ JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+
+ void run() throws Exception {
+ for (CompileKind ck: CompileKind.values()) {
+ for (AddKind ak: AddKind.values()) {
+ for (RemoveKind rk: RemoveKind.values()) {
+ test(ck, ak, rk);
+ }
+ }
+ }
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ void test(CompileKind ck, AddKind ak, RemoveKind rk) throws IOException {
+ System.err.println("Test: " + ck + " " + ak + " " + rk);
+
+ File tmpDir = new File(ck + "-" + ak + "-" + rk);
+ tmpDir.mkdirs();
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir));
+
+ List<String> options = new ArrayList<String>();
+ Iterable<? extends JavaFileObject> files = Arrays.asList(new TestSource());
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ JavacTask task = tool.getTask(pw, fm, null, options, null, files);
+
+ EventKindCounter ec = new EventKindCounter();
+ TaskListener listener = new TestListener(ec);
+ boolean needProcessor = false;
+
+ switch (ak) {
+ case SET_IN_TASK:
+ task.setTaskListener(listener);
+ break;
+ case ADD_IN_TASK:
+ task.addTaskListener(listener);
+ break;
+ case ADD_IN_PROCESSOR:
+ case ADD_IN_LISTENER:
+ needProcessor = true;
+ }
+
+ switch (rk) {
+ case REMOVE_IN_TASK:
+ task.removeTaskListener(listener);
+ break;
+ case REMOVE_IN_PROCESSOR:
+ case REMOVE_IN_LISTENER:
+ needProcessor = true;
+ }
+
+ if (needProcessor)
+ task.setProcessors(Arrays.asList(new TestProcessor(ak, rk, listener)));
+
+ ck.run(task);
+ System.err.println(ec);
+
+ check(ck, ak, rk, ec);
+
+ System.err.println();
+ }
+
+ void check(CompileKind ck, AddKind ak, RemoveKind rk, EventKindCounter ec) {
+ // All results should be independent of ck, so we can ignore that
+
+ // Quick way to compare expected values of ec, by comparing ec.toString()
+ String expect = ec.toString();
+ String found;
+
+ switch (ak) {
+ // Add/set in task should record all events until the listener is removed
+ case SET_IN_TASK:
+ case ADD_IN_TASK:
+ switch (rk) {
+ case REMOVE_IN_TASK:
+ // Remove will succeed, meaning no events will be recorded
+ found = "{}";
+ break;
+ case REMOVE_IN_PROCESSOR:
+ found = "{PARSE=1:1, ENTER=2:2, ANNOTATION_PROCESSING=1:0, ANNOTATION_PROCESSING_ROUND=2:1}";
+ break;
+ case REMOVE_IN_LISTENER:
+ found = "{PARSE=1:1, ENTER=3:3, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=1:1, ANNOTATION_PROCESSING_ROUND=2:2}";
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ break;
+
+ // "Add in processor" should skip initial PARSE/ENTER events
+ case ADD_IN_PROCESSOR:
+ switch (rk) {
+ // Remove will fail (too early), so events to end will be recorded
+ case REMOVE_IN_TASK:
+ found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:1, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
+ break;
+ case REMOVE_IN_PROCESSOR:
+ found = "{ENTER=1:1, ANNOTATION_PROCESSING_ROUND=1:1}";
+ break;
+ case REMOVE_IN_LISTENER:
+ found = "{ENTER=2:2, ANALYZE=1:1, GENERATE=1:0, ANNOTATION_PROCESSING=0:1, ANNOTATION_PROCESSING_ROUND=1:2}";
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ break;
+
+ // "Add in listener" will occur during "ANALYSE.started" event
+ case ADD_IN_LISTENER:
+ switch (rk) {
+ // Remove will fail (too early, so events to end will be recorded
+ case REMOVE_IN_TASK:
+ case REMOVE_IN_PROCESSOR:
+ found = "{ANALYZE=0:1, GENERATE=1:1}";
+ break;
+ // Remove will succeed during "GENERATE.finished" event
+ case REMOVE_IN_LISTENER:
+ found = "{ANALYZE=0:1, GENERATE=1:0}";
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+
+ if (!found.equals(expect)) {
+ System.err.println("Expected: " + expect);
+ System.err.println(" Found: " + found);
+ error("unexpected value found");
+ }
+ }
+
+ int errors;
+
+ void error(String message) {
+ System.err.println("Error: " + message);
+ errors++;
+ }
+}
--- a/langtools/test/tools/javac/processing/loader/testClose/TestClose.java Tue Feb 28 10:25:53 2012 -0800
+++ b/langtools/test/tools/javac/processing/loader/testClose/TestClose.java Tue Feb 28 10:33:49 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -31,6 +31,7 @@
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
+import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
@@ -89,10 +90,10 @@
" public void run() {\n" +
" System.out.println(getClass().getName() + \": run()\");\n" +
" try {\n" +
- " cl.loadClass(\"Callback\")\n" +
- " .asSubclass(Runnable.class)\n" +
- " .newInstance()\n" +
- " .run();\n" +
+ " cl.loadClass(\"Callback\")\n" +
+ " .asSubclass(Runnable.class)\n" +
+ " .newInstance()\n" +
+ " .run();\n" +
" } catch (ReflectiveOperationException e) {\n" +
" throw new Error(e);\n" +
" }\n" +
@@ -184,25 +185,24 @@
throw new AssertionError();
}
-
public static void add(ProcessingEnvironment env, Runnable r) {
try {
- Context c = ((JavacProcessingEnvironment) env).getContext();
- Object o = c.get(TaskListener.class);
+ JavacTask task = JavacTask.instance(env);
+ TaskListener l = ((BasicJavacTask) task).getTaskListeners().iterator().next();
// The TaskListener is an instanceof TestClose, but when using the
// default class loaders. the taskListener uses a different
// instance of Class<TestClose> than the anno processor.
// If you try to evaluate
- // TestClose tc = (TestClose) (o).
+ // TestClose tc = (TestClose) (l).
// you get the following somewhat confusing error:
// java.lang.ClassCastException: TestClose cannot be cast to TestClose
// The workaround is to access the fields of TestClose with reflection.
- Field f = o.getClass().getField("runnables");
+ Field f = l.getClass().getField("runnables");
@SuppressWarnings("unchecked")
- List<Runnable> runnables = (List<Runnable>) f.get(o);
+ List<Runnable> runnables = (List<Runnable>) f.get(l);
runnables.add(r);
} catch (Throwable t) {
- System.err.println(t);
+ t.printStackTrace();
}
}