6988836: A new JavacElements is created for each round of annotation processing
Reviewed-by: darcy
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Sun Oct 03 19:40:15 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Oct 05 11:34:43 2010 -0700
@@ -66,32 +66,26 @@
private Types types;
private Enter enter;
- private static final Context.Key<JavacElements> KEY =
- new Context.Key<JavacElements>();
-
public static JavacElements instance(Context context) {
- JavacElements instance = context.get(KEY);
- if (instance == null) {
+ JavacElements instance = context.get(JavacElements.class);
+ if (instance == null)
instance = new JavacElements(context);
- context.put(KEY, instance);
- }
return instance;
}
/**
* Public for use only by JavacProcessingEnvironment
*/
- // TODO JavacElements constructor should be protected
- public JavacElements(Context context) {
+ protected JavacElements(Context context) {
setContext(context);
}
/**
* Use a new context. May be called from outside to update
* internal state for a new annotation-processing round.
- * This instance is *not* then registered with the new context.
*/
public void setContext(Context context) {
+ context.put(JavacElements.class, this);
javaCompiler = JavaCompiler.instance(context);
syms = Symtab.instance(context);
names = Names.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Sun Oct 03 19:40:15 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Tue Oct 05 11:34:43 2010 -0700
@@ -47,32 +47,26 @@
private Symtab syms;
private Types types;
- private static final Context.Key<JavacTypes> KEY =
- new Context.Key<JavacTypes>();
-
public static JavacTypes instance(Context context) {
- JavacTypes instance = context.get(KEY);
- if (instance == null) {
+ JavacTypes instance = context.get(JavacTypes.class);
+ if (instance == null)
instance = new JavacTypes(context);
- context.put(KEY, instance);
- }
return instance;
}
/**
* Public for use only by JavacProcessingEnvironment
*/
- // TODO JavacTypes constructor should be protected
- public JavacTypes(Context context) {
+ protected JavacTypes(Context context) {
setContext(context);
}
/**
* Use a new context. May be called from outside to update
* internal state for a new annotation-processing round.
- * This instance is *not* then registered with the new context.
*/
public void setContext(Context context) {
+ context.put(JavacTypes.class, this);
syms = Symtab.instance(context);
types = Types.instance(context);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Sun Oct 03 19:40:15 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Oct 05 11:34:43 2010 -0700
@@ -173,12 +173,12 @@
platformAnnotations = initPlatformAnnotations();
foundTypeProcessors = false;
- // Initialize services before any processors are initialzied
+ // Initialize services before any processors are initialized
// in case processors use them.
filer = new JavacFiler(context);
messager = new JavacMessager(context, this);
- elementUtils = new JavacElements(context);
- typeUtils = new JavacTypes(context);
+ elementUtils = JavacElements.instance(context);
+ typeUtils = JavacTypes.instance(context);
processorOptions = initProcessorOptions(context);
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context);
@@ -865,8 +865,6 @@
this(prev.nextContext(), prev.number+1, prev.compiler.log.nwarnings);
this.genClassFiles = prev.genClassFiles;
- updateProcessingState();
-
List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles);
roots = cleanTrees(prev.roots).appendList(parsedFiles);
@@ -1029,15 +1027,6 @@
log.reportDeferredDiagnostics(kinds);
}
- /** Update the processing state for the current context. */
- private void updateProcessingState() {
- filer.newRound(context);
- messager.newRound(context);
-
- elementUtils.setContext(context);
- typeUtils.setContext(context);
- }
-
/** Print info about this round. */
private void printRoundInfo(boolean lastRound) {
if (printRounds || verbose) {
@@ -1100,6 +1089,11 @@
JavaCompiler nextCompiler = JavaCompiler.instance(next);
nextCompiler.initRound(oldCompiler);
+ filer.newRound(next);
+ messager.newRound(next);
+ elementUtils.setContext(next);
+ typeUtils.setContext(next);
+
JavacTaskImpl task = context.get(JavacTaskImpl.class);
if (task != null) {
next.put(JavacTaskImpl.class, task);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/environment/round/TestContext.java Tue Oct 05 11:34:43 2010 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2010, 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 6988836
+ * @summary A new JavacElements is created for each round of annotation processing
+ * @library ../../../lib
+ * @build JavacTestingAbstractProcessor TestContext
+ * @compile/process -processor TestContext -XprintRounds TestContext
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.*;
+import static javax.tools.Diagnostic.Kind.*;
+
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTrees;
+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.util.Context;
+
+public class TestContext extends JavacTestingAbstractProcessor {
+
+ Trees treeUtils;
+ int round = 0;
+
+ @Override
+ public void init(ProcessingEnvironment pEnv) {
+ super.init(pEnv);
+ treeUtils = Trees.instance(processingEnv);
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ round++;
+
+ JavacProcessingEnvironment jpe = (JavacProcessingEnvironment) processingEnv;
+ Context c = jpe.getContext();
+ check(c.get(JavacElements.class), eltUtils);
+ check(c.get(JavacTypes.class), typeUtils);
+ check(c.get(JavacTrees.class), treeUtils);
+
+ final int MAXROUNDS = 3;
+ if (round < MAXROUNDS)
+ generateSource("Gen" + round);
+
+ return true;
+ }
+
+ <T> void check(T actual, T expected) {
+// messager.printMessage(NOTE, "expect: " + expected);
+// messager.printMessage(NOTE, "actual: " + actual);
+
+ if (actual != expected) {
+ messager.printMessage(ERROR,
+ "round " + round + " unexpected value for " + expected.getClass().getName() + ": " + actual);
+ }
+ }
+
+ void generateSource(String name) {
+ String text = "class " + name + " { }\n";
+
+ try (Writer out = filer.createSourceFile(name).openWriter()) {
+ out.write(text);
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ }
+
+}
+