# HG changeset patch # User jjg # Date 1286303683 25200 # Node ID ef7a9281ad2f91c75c2e04d691735574e323c083 # Parent 7a6305ae07218bb9c324623c3fd386f6fbc7e250 6988836: A new JavacElements is created for each round of annotation processing Reviewed-by: darcy diff -r 7a6305ae0721 -r ef7a9281ad2f langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java --- 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 KEY = - new Context.Key(); - 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); diff -r 7a6305ae0721 -r ef7a9281ad2f langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java --- 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 KEY = - new Context.Key(); - 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); } diff -r 7a6305ae0721 -r ef7a9281ad2f langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- 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 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); diff -r 7a6305ae0721 -r ef7a9281ad2f langtools/test/tools/javac/processing/environment/round/TestContext.java --- /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 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; + } + + 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); + } + } + +} +