--- a/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -151,11 +151,4 @@
return context;
}
- /**
- * For internal use only. This method will be
- * removed without warning.
- */
- public void updateContext(Context newContext) {
- context = newContext;
- }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -316,7 +316,7 @@
List<JCCompilationUnit> units = compiler.enterTrees(roots.toList());
if (notYetEntered.isEmpty())
- compiler = compiler.processAnnotations(units);
+ compiler.processAnnotations(units);
ListBuffer<TypeElement> elements = new ListBuffer<>();
for (JCCompilationUnit unit : units) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Apr 09 17:18:22 2014 -0700
@@ -905,6 +905,12 @@
public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
return v.visitPackageSymbol(this, p);
}
+
+ /**Resets the Symbol into the state good for next round of annotation processing.*/
+ public void reset() {
+ metadata = null;
+ }
+
}
/** A class for class symbols
@@ -1154,6 +1160,26 @@
public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
return v.visitClassSymbol(this, p);
}
+
+ /**Resets the Symbol into the state good for next round of annotation processing.*/
+ public void reset() {
+ kind = TYP;
+ erasure_field = null;
+ members_field = null;
+ flags_field = 0;
+ if (type instanceof ClassType) {
+ ClassType t = (ClassType)type;
+ t.setEnclosingType(Type.noType);
+ t.rank_field = -1;
+ t.typarams_field = null;
+ t.allparams_field = null;
+ t.supertype_field = null;
+ t.interfaces_field = null;
+ t.all_interfaces_field = null;
+ }
+ metadata = null;
+ }
+
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Apr 09 17:18:22 2014 -0700
@@ -4684,4 +4684,12 @@
}
}
// </editor-fold>
+
+ public void newRound() {
+ descCache._map.clear();
+ isDerivedRawCache.clear();
+ implCache._map.clear();
+ membersCache._map.clear();
+ closureCache.clear();
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Apr 09 17:18:22 2014 -0700
@@ -804,6 +804,10 @@
boolean classExpected,
boolean interfaceExpected,
boolean checkExtensible) {
+ if (t.tsym.isAnonymous()) {
+ log.error(tree.pos(), "cant.inherit.from.anon");
+ return types.createErrorType(t);
+ }
if (t.isErroneous())
return t;
if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Apr 09 17:18:22 2014 -0700
@@ -425,6 +425,10 @@
}
}
+ public void newRound() {
+ compiled.clear();
+ }
+
/* *************************************************************************
* Type Checking
**************************************************************************/
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Apr 09 17:18:22 2014 -0700
@@ -154,6 +154,10 @@
return typeEnvs.get(sym);
}
+ public Iterable<Env<AttrContext>> getEnvs() {
+ return typeEnvs.values();
+ }
+
public Env<AttrContext> getClassEnv(TypeSymbol sym) {
Env<AttrContext> localEnv = getEnv(sym);
Env<AttrContext> lintEnv = localEnv;
@@ -514,4 +518,8 @@
annotate.enterDone();
}
}
+
+ public void newRound() {
+ typeEnvs.clear();
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Apr 09 17:18:22 2014 -0700
@@ -748,7 +748,7 @@
tree.clazz = translate(tree.clazz, null);
Type originalTarget = tree.type;
tree.type = erasure(tree.type);
- tree.expr = translate(tree.expr, tree.type);
+ tree.expr = translate(tree.expr, erasure(tree.expr.type));
if (originalTarget.isCompound()) {
Type.IntersectionClassType ict = (Type.IntersectionClassType)originalTarget;
for (Type c : ict.getExplicitComponents()) {
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -107,10 +107,6 @@
*/
ZipFileIndex.Entry entry;
- /** The InputStream for this zip entry (file.)
- */
- InputStream inputStream = null;
-
/** The name of the zip file where this entry resides.
*/
File zipName;
@@ -146,11 +142,8 @@
@Override
public InputStream openInputStream() throws IOException {
- if (inputStream == null) {
- Assert.checkNonNull(entry); // see constructor
- inputStream = new ByteArrayInputStream(zfIndex.read(entry));
- }
- return inputStream;
+ Assert.checkNonNull(entry); // see constructor
+ return new ByteArrayInputStream(zfIndex.read(entry));
}
@Override
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Apr 09 17:18:22 2014 -0700
@@ -299,12 +299,6 @@
protected MultiTaskListener taskListener;
/**
- * Annotation processing may require and provide a new instance
- * of the compiler to be used for the analyze and generate phases.
- */
- protected JavaCompiler delegateCompiler;
-
- /**
* SourceCompleter that delegates to the complete-method of this class.
*/
protected final ClassReader.SourceCompleter thisCompleter =
@@ -567,12 +561,8 @@
/** The number of errors reported so far.
*/
public int errorCount() {
- if (delegateCompiler != null && delegateCompiler != this)
- return delegateCompiler.errorCount();
- else {
- if (werror && log.nerrors == 0 && log.nwarnings > 0) {
- log.error("warnings.and.werror");
- }
+ if (werror && log.nerrors == 0 && log.nwarnings > 0) {
+ log.error("warnings.and.werror");
}
return log.nerrors;
}
@@ -588,10 +578,7 @@
/** The number of warnings reported so far.
*/
public int warningCount() {
- if (delegateCompiler != null && delegateCompiler != this)
- return delegateCompiler.warningCount();
- else
- return log.nwarnings;
+ return log.nwarnings;
}
/** Try to open input stream with given name.
@@ -759,21 +746,32 @@
* @param c The class the source file of which needs to be compiled.
*/
public void complete(ClassSymbol c) throws CompletionFailure {
+ complete(null, c);
+ }
+
+ /** Complete a ClassSymbol from source, optionally using the given compilation unit as
+ * the source tree.
+ * @param tree the compilation unit int which the given ClassSymbol resides,
+ * or null if should be parsed from source
+ * @param c the ClassSymbol to complete
+ */
+ public void complete(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
// System.err.println("completing " + c);//DEBUG
if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name");
}
- JCCompilationUnit tree;
JavaFileObject filename = c.classfile;
JavaFileObject prev = log.useSource(filename);
- try {
- tree = parse(filename, filename.getCharContent(false));
- } catch (IOException e) {
- log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
- tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
- } finally {
- log.useSource(prev);
+ if (tree == null) {
+ try {
+ tree = parse(filename, filename.getCharContent(false));
+ } catch (IOException e) {
+ log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
+ tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
+ } finally {
+ log.useSource(prev);
+ }
}
if (!taskListener.isEmpty()) {
@@ -851,35 +849,16 @@
initProcessAnnotations(processors);
// These method calls must be chained to avoid memory leaks
- delegateCompiler =
- processAnnotations(
- enterTrees(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))),
- classnames);
+ processAnnotations(
+ enterTrees(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))),
+ classnames);
// If it's safe to do so, skip attr / flow / gen for implicit classes
if (taskListener.isEmpty() &&
implicitSourcePolicy == ImplicitSourcePolicy.NONE) {
- delegateCompiler.todo.retainFiles(delegateCompiler.inputFiles);
+ todo.retainFiles(inputFiles);
}
- delegateCompiler.compile2();
- delegateCompiler.close();
- elapsed_msec = delegateCompiler.elapsed_msec;
- } catch (Abort ex) {
- if (devVerbose)
- ex.printStackTrace(System.err);
- } finally {
- if (procEnvImpl != null)
- procEnvImpl.close();
- }
- }
-
- /**
- * The phases following annotation processing: attribution,
- * desugar, and finally code generation.
- */
- private void compile2() {
- try {
switch (compilePolicy) {
case ATTR_ONLY:
attribute(todo);
@@ -912,18 +891,21 @@
} catch (Abort ex) {
if (devVerbose)
ex.printStackTrace(System.err);
- }
+ } finally {
+ if (verbose) {
+ elapsed_msec = elapsed(start_msec);
+ log.printVerbose("total", Long.toString(elapsed_msec));
+ }
+
+ reportDeferredDiagnostics();
- if (verbose) {
- elapsed_msec = elapsed(start_msec);
- log.printVerbose("total", Long.toString(elapsed_msec));
- }
-
- reportDeferredDiagnostics();
-
- if (!log.hasDiagnosticListener()) {
- printCount("error", errorCount());
- printCount("warn", warningCount());
+ if (!log.hasDiagnosticListener()) {
+ printCount("error", errorCount());
+ printCount("warn", warningCount());
+ }
+ close();
+ if (procEnvImpl != null)
+ procEnvImpl.close();
}
}
@@ -1069,8 +1051,8 @@
}
// TODO: called by JavacTaskImpl
- public JavaCompiler processAnnotations(List<JCCompilationUnit> roots) {
- return processAnnotations(roots, List.<String>nil());
+ public void processAnnotations(List<JCCompilationUnit> roots) {
+ processAnnotations(roots, List.<String>nil());
}
/**
@@ -1084,8 +1066,8 @@
// By the time this method exits, log.deferDiagnostics must be set back to false,
// and all deferredDiagnostics must have been handled: i.e. either reported
// or determined to be transient, and therefore suppressed.
- public JavaCompiler processAnnotations(List<JCCompilationUnit> roots,
- List<String> classnames) {
+ public void processAnnotations(List<JCCompilationUnit> roots,
+ List<String> classnames) {
if (shouldStop(CompileState.PROCESS)) {
// Errors were encountered.
// Unless all the errors are resolve errors, the errors were parse errors
@@ -1094,7 +1076,7 @@
if (unrecoverableError()) {
deferredDiagnosticHandler.reportDeferredDiagnostics();
log.popDiagnosticHandler(deferredDiagnosticHandler);
- return this;
+ return ;
}
}
@@ -1117,7 +1099,7 @@
classnames);
}
Assert.checkNull(deferredDiagnosticHandler);
- return this; // continue regular compilation
+ return ; // continue regular compilation
}
Assert.checkNonNull(deferredDiagnosticHandler);
@@ -1133,7 +1115,7 @@
classnames);
deferredDiagnosticHandler.reportDeferredDiagnostics();
log.popDiagnosticHandler(deferredDiagnosticHandler);
- return this; // TODO: Will this halt compilation?
+ return ; // TODO: Will this halt compilation?
} else {
boolean errors = false;
for (String nameStr : classnames) {
@@ -1167,25 +1149,26 @@
if (errors) {
deferredDiagnosticHandler.reportDeferredDiagnostics();
log.popDiagnosticHandler(deferredDiagnosticHandler);
- return this;
+ return ;
}
}
}
try {
- JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols,
- deferredDiagnosticHandler);
- if (c != this)
- annotationProcessingOccurred = c.annotationProcessingOccurred = true;
+ annotationProcessingOccurred =
+ procEnvImpl.doProcessing(roots,
+ classSymbols,
+ pckSymbols,
+ deferredDiagnosticHandler);
// doProcessing will have handled deferred diagnostics
- return c;
} finally {
procEnvImpl.close();
}
} catch (CompletionFailure ex) {
log.error("cant.access", ex.sym, ex.getDetailValue());
- deferredDiagnosticHandler.reportDeferredDiagnostics();
- log.popDiagnosticHandler(deferredDiagnosticHandler);
- return this;
+ if (deferredDiagnosticHandler != null) {
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
+ }
}
}
@@ -1213,6 +1196,10 @@
options.isSet(XPRINT);
}
+ public void setDeferredDiagnosticHandler(Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
+ this.deferredDiagnosticHandler = deferredDiagnosticHandler;
+ }
+
/**
* Attribute a list of parse trees, such as found on the "todo" list.
* Note that attributing classes may cause additional files to be
@@ -1674,10 +1661,6 @@
/** Close the compiler, flushing the logs
*/
public void close() {
- close(true);
- }
-
- public void close(boolean disposeNames) {
rootClasses = null;
reader = null;
make = null;
@@ -1704,7 +1687,7 @@
} catch (IOException e) {
throw new Abort(e);
} finally {
- if (names != null && disposeNames)
+ if (names != null)
names.dispose();
names = null;
@@ -1750,14 +1733,8 @@
return now() - then;
}
- public void initRound(JavaCompiler prev) {
- genEndPos = prev.genEndPos;
- keepComments = prev.keepComments;
- start_msec = prev.start_msec;
- hasBeenUsed = true;
- closeables = prev.closeables;
- prev.closeables = List.nil();
- shouldStopPolicyIfError = prev.shouldStopPolicyIfError;
- shouldStopPolicyIfNoError = prev.shouldStopPolicyIfNoError;
+ public void newRound() {
+ inputFiles.clear();
+ todo.clear();
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -60,11 +60,11 @@
*/
public class JavacElements implements Elements {
- private JavaCompiler javaCompiler;
- private Symtab syms;
- private Names names;
- private Types types;
- private Enter enter;
+ private final JavaCompiler javaCompiler;
+ private final Symtab syms;
+ private final Names names;
+ private final Types types;
+ private final Enter enter;
public static JavacElements instance(Context context) {
JavacElements instance = context.get(JavacElements.class);
@@ -73,18 +73,7 @@
return instance;
}
- /**
- * Public for use only by JavacProcessingEnvironment
- */
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.
- */
- public void setContext(Context context) {
context.put(JavacElements.class, this);
javaCompiler = JavaCompiler.instance(context);
syms = Symtab.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -48,8 +48,8 @@
*/
public class JavacTypes implements javax.lang.model.util.Types {
- private Symtab syms;
- private Types types;
+ private final Symtab syms;
+ private final Types types;
public static JavacTypes instance(Context context) {
JavacTypes instance = context.get(JavacTypes.class);
@@ -58,18 +58,7 @@
return instance;
}
- /**
- * Public for use only by JavacProcessingEnvironment
- */
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.
- */
- 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/JavacFiler.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -564,9 +564,7 @@
/**
* Update internal state for a new round.
*/
- public void newRound(Context context) {
- this.context = context;
- this.log = Log.instance(context);
+ public void newRound() {
clearRoundState();
}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacMessager.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacMessager.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -176,8 +176,7 @@
return warningCount;
}
- public void newRound(Context context) {
- log = Log.instance(context);
+ public void newRound() {
errorCount = 0;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Apr 09 17:18:22 2014 -0700
@@ -38,27 +38,27 @@
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
-import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import static javax.tools.StandardLocation.*;
-import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
-import com.sun.tools.javac.api.BasicJavacTask;
-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;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Check;
+import com.sun.tools.javac.comp.Enter;
+import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
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.parser.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Abort;
@@ -103,6 +103,8 @@
private final JavacMessager messager;
private final JavacElements elementUtils;
private final JavacTypes typeUtils;
+ private final Types types;
+ private final JavaCompiler compiler;
/**
* Holds relevant state history of which processors have been
@@ -131,7 +133,7 @@
/** The log to be used for error reporting.
*/
- Log log;
+ final Log log;
/** Diagnostic factory.
*/
@@ -151,8 +153,13 @@
private JavacMessages messages;
private MultiTaskListener taskListener;
+ private final Symtab symtab;
+ private final Names names;
+ private final Enter enter;
+ private final Completer initialCompleter;
+ private final Check chk;
- private Context context;
+ private final Context context;
/** Get the JavacProcessingEnvironment instance for this context. */
public static JavacProcessingEnvironment instance(Context context) {
@@ -173,8 +180,8 @@
printRounds = options.isSet(XPRINTROUNDS);
verbose = options.isSet(VERBOSE);
lint = Lint.instance(context).isEnabled(PROCESSING);
+ compiler = JavaCompiler.instance(context);
if (options.isSet(PROC, "only") || options.isSet(XPRINT)) {
- JavaCompiler compiler = JavaCompiler.instance(context);
compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
}
fatalErrors = options.isSet("fatalEnterError");
@@ -188,16 +195,22 @@
messager = new JavacMessager(context, this);
elementUtils = JavacElements.instance(context);
typeUtils = JavacTypes.instance(context);
- processorOptions = initProcessorOptions(context);
+ types = Types.instance(context);
+ processorOptions = initProcessorOptions();
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context);
taskListener = MultiTaskListener.instance(context);
+ symtab = Symtab.instance(context);
+ names = Names.instance(context);
+ enter = Enter.instance(context);
+ initialCompleter = ClassReader.instance(context).getCompleter();
+ chk = Check.instance(context);
initProcessorClassLoader();
}
public void setProcessors(Iterable<? extends Processor> processors) {
Assert.checkNull(discoveredProcs);
- initProcessorIterator(context, processors);
+ initProcessorIterator(processors);
}
private Set<String> initPlatformAnnotations() {
@@ -221,7 +234,6 @@
: fileManager.getClassLoader(CLASS_PATH);
if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
- JavaCompiler compiler = JavaCompiler.instance(context);
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
}
} catch (SecurityException e) {
@@ -229,8 +241,7 @@
}
}
- private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) {
- Log log = Log.instance(context);
+ private void initProcessorIterator(Iterable<? extends Processor> processors) {
Iterator<? extends Processor> processorIterator;
if (options.isSet(XPRINT)) {
@@ -447,8 +458,7 @@
return discoveredProcs.iterator().hasNext();
}
- private Map<String, String> initProcessorOptions(Context context) {
- Options options = Options.instance(context);
+ private Map<String, String> initProcessorOptions() {
Set<String> keySet = options.keySet();
Map<String, String> tempOptions = new LinkedHashMap<>();
@@ -653,8 +663,7 @@
}
}
- private void discoverAndRunProcs(Context context,
- Set<TypeElement> annotationsPresent,
+ private void discoverAndRunProcs(Set<TypeElement> annotationsPresent,
List<ClassSymbol> topLevelClasses,
List<PackageSymbol> packageInfoFiles) {
Map<String, TypeElement> unmatchedAnnotations = new HashMap<>(annotationsPresent.size());
@@ -724,7 +733,6 @@
// Remove annotations processed by javac
unmatchedAnnotations.keySet().removeAll(platformAnnotations);
if (unmatchedAnnotations.size() > 0) {
- log = Log.instance(context);
log.warning("proc.annotations.without.processors",
unmatchedAnnotations.keySet());
}
@@ -812,17 +820,13 @@
class Round {
/** The round number. */
final int number;
- /** The context for the round. */
- final Context context;
- /** The compiler for the round. */
- final JavaCompiler compiler;
- /** The log for the round. */
- final Log log;
/** The diagnostic handler for the round. */
final Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
/** The ASTs to be compiled. */
List<JCCompilationUnit> roots;
+ /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */
+ Set<JCCompilationUnit> treesToClean;
/** The classes to be compiler that have were generated. */
Map<String, JavaFileObject> genClassFiles;
@@ -834,39 +838,33 @@
List<PackageSymbol> packageInfoFiles;
/** Create a round (common code). */
- private Round(Context context, int number, int priorErrors, int priorWarnings,
+ private Round(int number, Set<JCCompilationUnit> treesToClean,
Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
- this.context = context;
this.number = number;
- compiler = JavaCompiler.instance(context);
- log = Log.instance(context);
- log.nerrors = priorErrors;
- log.nwarnings = priorWarnings;
if (number == 1) {
Assert.checkNonNull(deferredDiagnosticHandler);
this.deferredDiagnosticHandler = deferredDiagnosticHandler;
} else {
this.deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log);
+ compiler.setDeferredDiagnosticHandler(this.deferredDiagnosticHandler);
}
- // the following is for the benefit of JavacProcessingEnvironment.getContext()
- JavacProcessingEnvironment.this.context = context;
-
// the following will be populated as needed
topLevelClasses = List.nil();
packageInfoFiles = List.nil();
+ this.treesToClean = treesToClean;
}
/** Create the first round. */
- Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols,
- Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
- this(context, 1, 0, 0, deferredDiagnosticHandler);
+ Round(List<JCCompilationUnit> roots,
+ List<ClassSymbol> classSymbols,
+ Set<JCCompilationUnit> treesToClean,
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
+ this(1, treesToClean, deferredDiagnosticHandler);
this.roots = roots;
genClassFiles = new HashMap<>();
- compiler.todo.clear(); // free the compiler's resources
-
// The reverse() in the following line is to maintain behavioural
// compatibility with the previous revision of the code. Strictly speaking,
// it should not be necessary, but a javah golden file test fails without it.
@@ -881,15 +879,12 @@
/** Create a new round. */
private Round(Round prev,
Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) {
- this(prev.nextContext(),
- prev.number+1,
- prev.compiler.log.nerrors,
- prev.compiler.log.nwarnings,
- null);
+ this(prev.number+1, prev.treesToClean, null);
+ prev.newRound();
this.genClassFiles = prev.genClassFiles;
List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles);
- roots = cleanTrees(prev.roots).appendList(parsedFiles);
+ roots = prev.roots.appendList(parsedFiles);
// Check for errors after parsing
if (unrecoverableError())
@@ -916,24 +911,12 @@
/** Create the next round to be used. */
Round next(Set<JavaFileObject> newSourceFiles, Map<String, JavaFileObject> newClassFiles) {
- try {
- return new Round(this, newSourceFiles, newClassFiles);
- } finally {
- compiler.close(false);
- }
+ return new Round(this, newSourceFiles, newClassFiles);
}
- /** Create the compiler to be used for the final compilation. */
- JavaCompiler finalCompiler() {
- try {
- Context nextCtx = nextContext();
- JavacProcessingEnvironment.this.context = nextCtx;
- JavaCompiler c = JavaCompiler.instance(nextCtx);
- c.log.initRound(compiler.log);
- return c;
- } finally {
- compiler.close(false);
- }
+ /** Prepare the compiler for the final compilation. */
+ void finalCompiler() {
+ newRound();
}
/** Return the number of errors found so far in this round.
@@ -984,8 +967,6 @@
/** Enter a set of generated class files. */
private List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) {
- Symtab symtab = Symtab.instance(context);
- Names names = Names.instance(context);
List<ClassSymbol> list = List.nil();
for (Map.Entry<String,JavaFileObject> entry : classFiles.entrySet()) {
@@ -1000,10 +981,16 @@
if (p.package_info == null)
p.package_info = symtab.enterClass(Convert.shortName(name), p);
cs = p.package_info;
+ cs.reset();
if (cs.classfile == null)
cs.classfile = file;
- } else
- cs = symtab.enterClass(name, file);
+ cs.completer = initialCompleter;
+ } else {
+ cs = symtab.enterClass(name);
+ cs.reset();
+ cs.classfile = file;
+ cs.completer = initialCompleter;
+ }
list = list.prepend(cs);
}
return list.reverse();
@@ -1031,7 +1018,7 @@
JavacProcessingEnvironment.this);
discoveredProcs.iterator().runContributingProcs(renv);
} else {
- discoverAndRunProcs(context, annotationsPresent, topLevelClasses, packageInfoFiles);
+ discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles);
}
} catch (Throwable t) {
// we're specifically expecting Abort here, but if any Throwable
@@ -1039,6 +1026,7 @@
// drop them on the ground.
deferredDiagnosticHandler.reportDeferredDiagnostics();
log.popDiagnosticHandler(deferredDiagnosticHandler);
+ compiler.setDeferredDiagnosticHandler(null);
throw t;
} finally {
if (!taskListener.isEmpty())
@@ -1054,6 +1042,7 @@
}
deferredDiagnosticHandler.reportDeferredDiagnostics(kinds);
log.popDiagnosticHandler(deferredDiagnosticHandler);
+ compiler.setDeferredDiagnosticHandler(null);
}
/** Print info about this round. */
@@ -1069,104 +1058,68 @@
}
}
- /** Get the context for the next round of processing.
- * Important values are propagated from round to round;
- * other values are implicitly reset.
+ /** Prepare for new round of annotation processing. Cleans trees, resets symbols, and
+ * asks selected services to prepare to a new round of annotation processing.
*/
- private Context nextContext() {
- Context next = new Context(context);
-
- Options options = Options.instance(context);
- Assert.checkNonNull(options);
- next.put(Options.optionsKey, options);
+ private void newRound() {
+ //ensure treesToClean contains all trees, including implicitly parsed ones
+ for (Env<AttrContext> env : enter.getEnvs()) {
+ treesToClean.add(env.toplevel);
+ }
+ for (JCCompilationUnit node : treesToClean) {
+ treeCleaner.scan(node);
+ }
+ chk.newRound();
+ enter.newRound();
+ filer.newRound();
+ messager.newRound();
+ compiler.newRound();
+ types.newRound();
- Locale locale = context.get(Locale.class);
- if (locale != null)
- next.put(Locale.class, locale);
+ boolean foundError = false;
- Assert.checkNonNull(messages);
- next.put(JavacMessages.messagesKey, messages);
-
- final boolean shareNames = true;
- if (shareNames) {
- Names names = Names.instance(context);
- Assert.checkNonNull(names);
- next.put(Names.namesKey, names);
+ for (ClassSymbol cs : symtab.classes.values()) {
+ if (cs.kind == Kinds.ERR) {
+ foundError = true;
+ break;
+ }
}
- DiagnosticListener<?> dl = context.get(DiagnosticListener.class);
- if (dl != null)
- next.put(DiagnosticListener.class, dl);
-
- MultiTaskListener mtl = context.get(MultiTaskListener.taskListenerKey);
- if (mtl != null)
- next.put(MultiTaskListener.taskListenerKey, mtl);
-
- FSInfo fsInfo = context.get(FSInfo.class);
- if (fsInfo != null)
- next.put(FSInfo.class, fsInfo);
-
- JavaFileManager jfm = context.get(JavaFileManager.class);
- Assert.checkNonNull(jfm);
- next.put(JavaFileManager.class, jfm);
- if (jfm instanceof JavacFileManager) {
- ((JavacFileManager)jfm).setContext(next);
+ if (foundError) {
+ for (ClassSymbol cs : symtab.classes.values()) {
+ if (cs.classfile != null || cs.kind == Kinds.ERR) {
+ cs.reset();
+ cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
+ if (cs.completer == null) {
+ cs.completer = initialCompleter;
+ }
+ }
+ }
}
-
- Names names = Names.instance(context);
- Assert.checkNonNull(names);
- next.put(Names.namesKey, names);
-
- Tokens tokens = Tokens.instance(context);
- Assert.checkNonNull(tokens);
- next.put(Tokens.tokensKey, tokens);
-
- Log nextLog = Log.instance(next);
- nextLog.initRound(log);
-
- JavaCompiler oldCompiler = JavaCompiler.instance(context);
- JavaCompiler nextCompiler = JavaCompiler.instance(next);
- nextCompiler.initRound(oldCompiler);
-
- filer.newRound(next);
- messager.newRound(next);
- elementUtils.setContext(next);
- typeUtils.setContext(next);
-
- JavacTask task = context.get(JavacTask.class);
- if (task != null) {
- next.put(JavacTask.class, task);
- if (task instanceof BasicJavacTask)
- ((BasicJavacTask) task).updateContext(next);
- }
-
- JavacTrees trees = context.get(JavacTrees.class);
- if (trees != null) {
- next.put(JavacTrees.class, trees);
- trees.updateContext(next);
- }
-
- context.clear();
- return next;
}
}
// TODO: internal catch clauses?; catch and rethrow an annotation
// processing error
- public JavaCompiler doProcessing(Context context,
- List<JCCompilationUnit> roots,
- List<ClassSymbol> classSymbols,
- Iterable<? extends PackageSymbol> pckSymbols,
- Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
- log = Log.instance(context);
+ public boolean doProcessing(List<JCCompilationUnit> roots,
+ List<ClassSymbol> classSymbols,
+ Iterable<? extends PackageSymbol> pckSymbols,
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
+ final Set<JCCompilationUnit> treesToClean =
+ Collections.newSetFromMap(new IdentityHashMap<JCCompilationUnit, Boolean>());
+
+ //fill already attributed implicit trees:
+ for (Env<AttrContext> env : enter.getEnvs()) {
+ treesToClean.add(env.toplevel);
+ }
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<>();
for (PackageSymbol psym : pckSymbols)
specifiedPackages.add(psym);
this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
- Round round = new Round(context, roots, classSymbols, deferredDiagnosticHandler);
+ Round round = new Round(roots, classSymbols, treesToClean, deferredDiagnosticHandler);
boolean errorStatus;
boolean moreToDo;
@@ -1217,9 +1170,12 @@
Set<JavaFileObject> newSourceFiles =
new LinkedHashSet<>(filer.getGeneratedSourceFileObjects());
- roots = cleanTrees(round.roots);
+ roots = round.roots;
- JavaCompiler compiler = round.finalCompiler();
+ errorStatus = errorStatus || (compiler.errorCount() > 0);
+
+ if (!errorStatus)
+ round.finalCompiler();
if (newSourceFiles.size() > 0)
roots = roots.appendList(compiler.parseFiles(newSourceFiles));
@@ -1235,12 +1191,12 @@
if (errorStatus) {
if (compiler.errorCount() == 0)
compiler.log.nerrors++;
- return compiler;
+ return true;
}
compiler.enterTreesIfNeeded(roots);
- return compiler;
+ return true;
}
private void warnIfUnmatchedOptions() {
@@ -1342,23 +1298,46 @@
return false;
}
- private static <T extends JCTree> List<T> cleanTrees(List<T> nodes) {
- for (T node : nodes)
- treeCleaner.scan(node);
- return nodes;
+ class ImplicitCompleter implements Completer {
+
+ private final JCCompilationUnit topLevel;
+
+ public ImplicitCompleter(JCCompilationUnit topLevel) {
+ this.topLevel = topLevel;
+ }
+
+ @Override public void complete(Symbol sym) throws CompletionFailure {
+ compiler.complete(topLevel, (ClassSymbol) sym);
+ }
}
- private static final TreeScanner treeCleaner = new TreeScanner() {
+ private final TreeScanner treeCleaner = new TreeScanner() {
public void scan(JCTree node) {
super.scan(node);
if (node != null)
node.type = null;
}
+ JCCompilationUnit topLevel;
public void visitTopLevel(JCCompilationUnit node) {
+ if (node.packge != null) {
+ if (node.packge.package_info != null) {
+ node.packge.package_info.reset();
+ }
+ node.packge.reset();
+ }
node.packge = null;
- super.visitTopLevel(node);
+ topLevel = node;
+ try {
+ super.visitTopLevel(node);
+ } finally {
+ topLevel = null;
+ }
}
public void visitClassDef(JCClassDecl node) {
+ if (node.sym != null) {
+ node.sym.reset();
+ node.sym.completer = new ImplicitCompleter(topLevel);
+ }
node.sym = null;
super.visitClassDef(node);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Apr 09 17:18:22 2014 -0700
@@ -123,6 +123,9 @@
compiler.err.anon.class.impl.intf.no.qual.for.new=\
anonymous class implements interface; cannot have qualifier for new
+compiler.err.cant.inherit.from.anon=\
+ cannot inherit from anonymous class
+
# 0: symbol, 1: symbol, 2: symbol
compiler.err.array.and.varargs=\
cannot declare both {0} and {1} in {2}
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, 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
@@ -147,6 +147,8 @@
final int maxProfile = 4; // Three compact profiles plus full JRE
MakefileProfiles(Properties p) {
+ // consider crypto, only if java/lang package exists
+ boolean foundJavaLang = false;
for (int profile = 1; profile <= maxProfile; profile++) {
String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE");
String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES");
@@ -155,6 +157,8 @@
for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
if (pkg.endsWith("/"))
pkg = pkg.substring(0, pkg.length() - 1);
+ if (foundJavaLang == false && pkg.equals("java/lang"))
+ foundJavaLang = true;
includePackage(profile, pkg);
}
String inclTypes = p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES");
@@ -172,6 +176,15 @@
}
}
}
+ /*
+ * A hack to force javax/crypto package into the compact1 profile,
+ * because this package exists in jce.jar, and therefore not in
+ * ct.sym. Note javax/crypto should exist in a profile along with
+ * javax/net/ssl package. Thus, this package is added to compact1,
+ * implying that it should exist in all three profiles.
+ */
+ if (foundJavaLang)
+ includePackage(1, "javax/crypto");
}
@Override
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Context.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Context.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -119,7 +119,7 @@
* or
* {@literal Key<T> -> Factory<T> }
*/
- private Map<Key<?>,Object> ht = new HashMap<>();
+ private final Map<Key<?>,Object> ht = new HashMap<>();
/** Set the factory for the key in this context. */
public <T> void put(Key<T> key, Factory<T> fac) {
@@ -166,18 +166,12 @@
/**
* The table of preregistered factories.
*/
- private Map<Key<?>,Factory<?>> ft = new HashMap<>();
-
- public Context(Context prev) {
- kt.putAll(prev.kt); // retain all implicit keys
- ft.putAll(prev.ft); // retain all factory objects
- ht.putAll(prev.ft); // init main table with factories
- }
+ private final Map<Key<?>,Factory<?>> ft = new HashMap<>();
/*
* The key table, providing a unique Key<T> for each Class<T>.
*/
- private Map<Class<?>, Key<?>> kt = new HashMap<>();
+ private final Map<Class<?>, Key<?>> kt = new HashMap<>();
private <T> Key<T> key(Class<T> clss) {
checkState(kt);
@@ -214,12 +208,6 @@
System.err.println(value == null ? null : value.getClass());
}
- public void clear() {
- ht = null;
- kt = null;
- ft = null;
- }
-
private static void checkState(Map<?,?> t) {
if (t == null)
throw new IllegalStateException();
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -391,19 +391,6 @@
}
/**
- * Propagate the previous log's information.
- */
- public void initRound(Log other) {
- this.noticeWriter = other.noticeWriter;
- this.warnWriter = other.warnWriter;
- this.errWriter = other.errWriter;
- this.sourceMap = other.sourceMap;
- this.recorded = other.recorded;
- this.nerrors = other.nerrors;
- this.nwarnings = other.nwarnings;
- }
-
- /**
* Replace the specified diagnostic handler with the
* handler that was current at the time this handler was created.
* The given handler must be the currently installed handler;
--- a/langtools/test/tools/javac/6668794/badSource/Test.out Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/6668794/badSource/Test.out Wed Apr 09 17:18:22 2014 -0700
@@ -1,1 +1,2 @@
Test.java:10:6: compiler.err.cant.access: p.A, (compiler.misc.bad.source.file.header: A.java, (compiler.misc.file.doesnt.contain.class: p.A))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/AnonymousSubclassTest.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,91 @@
+/*
+ * 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 8023945
+ * @summary javac wrongly allows a subclass of an anonymous class
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main AnonymousSubclassTest
+ */
+
+import java.util.ArrayList;
+import java.io.IOException;
+
+public class AnonymousSubclassTest {
+ public static void main(String... args) throws Exception {
+ new AnonymousSubclassTest().run();
+ }
+
+ // To trigger the error we want, first we need to compile
+ // a class with an anonymous inner class: Foo$1.
+ final String foo =
+ "public class Foo {" +
+ " void m() { Foo f = new Foo() {}; }" +
+ "}";
+
+ // Then, we try to subclass the anonymous class
+ // Note: we must do this in two classes because a different
+ // error will be generated if we don't load Foo$1 through the
+ // class reader.
+ final String test1 =
+ "public class Test1 {" +
+ " void m() {"+
+ " Foo f1 = new Foo();"+
+ " Foo f2 = new Foo$1(f1) {};"+
+ " }" +
+ "}";
+
+ final String test2 =
+ "public class Test2 {" +
+ " class T extends Foo$1 {" +
+ " public T(Foo f) { super(f); }" +
+ " }"+
+ "}";
+
+ void compOk(String code) throws Exception {
+ ToolBox.javac(new ToolBox.JavaToolArgs().setSources(code));
+ }
+
+ void compFail(String code) throws Exception {
+ ArrayList<String> errors = new ArrayList<>();
+ ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
+ args.setSources(code)
+ .appendArgs("-cp", ".", "-XDrawDiagnostics")
+ .set(ToolBox.Expect.FAIL)
+ .setErrOutput(errors);
+ ToolBox.javac(args);
+
+ if (!errors.get(0).contains("cant.inherit.from.anon")) {
+ System.out.println(errors.get(0));
+ throw new Exception("test failed");
+ }
+ }
+
+ void run() throws Exception {
+ compOk(foo);
+ compFail(test1);
+ compFail(test2);
+ }
+}
--- a/langtools/test/tools/javac/T6358168.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/T6358168.java Wed Apr 09 17:18:22 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
@@ -99,10 +99,9 @@
"-d", "."});
JavaCompiler compiler = JavaCompiler.instance(context);
- compiler.initProcessAnnotations(null);
- JavaCompiler compiler2 = compiler.processAnnotations(compiler.enterTrees(compiler.parseFiles(List.of(f))));
+ compiler.compile(List.of(f));
try {
- compiler2.compile(List.of(f));
+ compiler.compile(List.of(f));
throw new Error("Error: AssertionError not thrown after second call of compile");
} catch (AssertionError e) {
System.err.println("Exception from compiler (expected): " + e);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T7053059/DoubleCastTest.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,76 @@
+/*
+ * 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 8015499
+ * @summary javac, Gen is generating extra checkcast instructions in some corner cases
+ * @run main DoubleCastTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import com.sun.tools.classfile.*;
+import com.sun.tools.javac.util.Assert;
+
+public class DoubleCastTest {
+ class C {
+ Object x;
+ Object m() { return null; }
+ void m1(byte[] b) {}
+ void m2() {
+ Object o;
+ Object[] os = null;
+ m1((byte[])(o = null));
+ m1((byte[])o);
+ m1((byte[])(o == null ? o : o));
+ m1((byte[])m());
+ m1((byte[])os[0]);
+ m1((byte[])this.x);
+ }
+ }
+
+ public static void main(String... cmdline) throws Exception {
+
+ ClassFile cls = ClassFile.read(DoubleCastTest.class.getResourceAsStream("DoubleCastTest$C.class"));
+ for (Method m: cls.methods)
+ check(m);
+ }
+
+ static void check(Method m) throws Exception {
+ boolean last_is_cast = false;
+ int last_ref = 0;
+ Code_attribute ea = (Code_attribute)m.attributes.get(Attribute.Code);
+ for (Instruction i : ea.getInstructions()) {
+ if (i.getOpcode() == Opcode.CHECKCAST) {
+ Assert.check
+ (!(last_is_cast && last_ref == i.getUnsignedShort(1)),
+ "Double cast found - Test failed");
+ last_is_cast = true;
+ last_ref = i.getUnsignedShort(1);
+ } else {
+ last_is_cast = false;
+ }
+ }
+ }
+}
--- a/langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, 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
@@ -135,12 +135,7 @@
args.add(f.getPath());
Main main = new Main("javac", out);
- Context c = new Context() {
- @Override public void clear() {
- ((JavacFileManager) get(JavaFileManager.class)).close();
- super.clear();
- }
- };
+ Context c = new Context();
JavacFileManager.preRegister(c); // can't create it until Log has been set up
ArgTypeJavaCompiler.preRegister(c);
ArgTypeMessages.preRegister(c);
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Apr 09 17:18:22 2014 -0700
@@ -111,4 +111,5 @@
compiler.warn.unknown.enum.constant.reason # in bad class file
compiler.warn.override.equals.but.not.hashcode # when a class overrides equals but not hashCode method from Object
compiler.warn.file.from.future # warning for future modification times on files
+compiler.err.cant.inherit.from.anon # error for subclass of anonymous class
compiler.misc.bad.class.file # class file is malformed
--- a/langtools/test/tools/javac/lib/ToolBox.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/lib/ToolBox.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -22,11 +22,14 @@
*/
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
+import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
@@ -40,15 +43,22 @@
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask;
@@ -454,6 +464,45 @@
}
/**
+ * Run javac and return the resulting classfiles.
+ */
+ public static Map<String, byte[]> compile(JavaToolArgs params)
+ throws CommandExecutionException, IOException {
+ if (params.hasMinParams()) {
+ if (params.argsArr != null) {
+ throw new AssertionError("setAllArgs is not supported for compile");
+ }
+
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+ MemoryFileManager mfm = new MemoryFileManager(fm);
+ StringWriter sw = null;
+ boolean rc;
+
+ try (PrintWriter pw = (params.errOutput == null) ?
+ null : new PrintWriter(sw = new StringWriter())) {
+ JavacTask ct = (JavacTask)comp.getTask(pw, mfm, null,
+ params.args, null, params.sources);
+ rc = ct.call();
+ }
+
+ String out = (sw == null) ? null : sw.toString();
+
+ if (params.errOutput != null && (out != null) && !out.isEmpty()) {
+ params.errOutput.addAll(splitLines(out, lineSeparator));
+ }
+
+ if ( ( rc && params.whatToExpect == Expect.SUCCESS) ||
+ (!rc && params.whatToExpect == Expect.FAIL) ) {
+ return mfm.classes;
+ }
+
+ throw new CommandExecutionException(JavaCMD.JAVAC_API.getExceptionMsgContent(params),
+ params.whatToExpect);
+ }
+ throw new AssertionError("compile command has been invoked with less parameters than needed");
+ }
+
+ /**
* A javap calling method.
*/
public static String javap(JavaToolArgs params)
@@ -964,4 +1013,66 @@
return source;
}
}
+
+ /**
+ * A file manager for compiling strings to byte arrays.
+ * This file manager delegates to another file manager
+ * to lookup classes on boot class path.
+ */
+ public static final class MemoryFileManager extends ForwardingJavaFileManager {
+ /**
+ * Maps binary class names to class files stored as byte arrays.
+ */
+ private final Map<String, byte[]> classes;
+
+ /**
+ * Construct a memory file manager which delegates to the specified
+ * file manager for unknown sources.
+ * @param fileManager a file manager used to look up class files on class path, etc.
+ */
+ public MemoryFileManager(JavaFileManager fileManager) {
+ super(fileManager);
+ classes = new HashMap<>();
+ }
+
+ @java.lang.Override
+ public JavaFileObject getJavaFileForOutput(Location location,
+ String name,
+ Kind kind,
+ FileObject sibling)
+ throws UnsupportedOperationException
+ {
+ return new JavaClassInArray(name);
+ }
+
+ /**
+ * A file object representing a Java class file stored in a byte array.
+ */
+ private class JavaClassInArray extends SimpleJavaFileObject {
+
+ private final String name;
+
+ /**
+ * Constructs a JavaClassInArray object.
+ * @param name binary name of the class to be stored in this file object
+ */
+ JavaClassInArray(String name) {
+ super(URI.create("mfm:///" + name.replace('.','/') + Kind.CLASS.extension),
+ Kind.CLASS);
+ this.name = name;
+ }
+
+ public OutputStream openOutputStream() {
+ return new FilterOutputStream(new ByteArrayOutputStream()) {
+ public void close() throws IOException {
+ out.close();
+ ByteArrayOutputStream bos = (ByteArrayOutputStream)out;
+ classes.put(name, bos.toByteArray());
+ }
+ };
+ }
+ }
+
+ }
+
}
--- a/langtools/test/tools/javac/processing/errors/TestBadProcessor.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/processing/errors/TestBadProcessor.java Wed Apr 09 17:18:22 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -73,8 +73,10 @@
String expect = "error: Bad service configuration file, " +
"or exception thrown while constructing Processor object: " +
"javax.annotation.processing.Processor: " +
- "Provider AnnoProc could not be instantiated: java.lang.Error";
- if (!out.trim().equals(expect)) {
+ "Provider AnnoProc could not be instantiated: java.lang.Error\n" +
+ "1 error";
+ String lineSeparator = System.getProperty("line.separator");
+ if (!out.trim().replace(lineSeparator, "\n").equals(expect)) {
System.err.println("expected: " + expect);
error("output not as expected");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/trees/OnDemandAttribution.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,78 @@
+/*
+ * 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 8038455
+ * @summary Verify that in-method ClassSymbols from one round do not affect ClassSymbols in
+ * following rounds.
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor OnDemandAttribution
+ * @compile/process -processor OnDemandAttribution OnDemandAttribution.java
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import static javax.lang.model.util.ElementFilter.*;
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+
+public class OnDemandAttribution extends JavacTestingAbstractProcessor {
+
+ public OnDemandAttribution() {
+ class Local { }
+ new Object() { };
+ }
+
+ public boolean process(Set<? extends TypeElement> annos,RoundEnvironment rEnv) {
+ TypeElement currentClass = elements.getTypeElement("OnDemandAttribution");
+ ExecutableElement constr = constructorsIn(currentClass.getEnclosedElements()).get(0);
+ Trees trees = Trees.instance(processingEnv);
+ TreePath path = trees.getPath(constr);
+
+ new TreePathScanner<Void, Void>() {
+ @Override public Void visitClass(ClassTree node, Void p) {
+ if (node.getSimpleName().contentEquals("Local")) {
+ //will also attribute the body on demand:
+ Element el = trees.getElement(getCurrentPath());
+ Name binaryName = elements.getBinaryName((TypeElement) el);
+ if (!binaryName.contentEquals("OnDemandAttribution$1Local")) {
+ throw new IllegalStateException("Incorrect binary name=" + binaryName);
+ }
+ }
+ return super.visitClass(node, p);
+ }
+ @Override public Void visitNewClass(NewClassTree node, Void p) {
+ Element el = trees.getElement(getCurrentPath());
+ Name binaryName = elements.getBinaryName((TypeElement) el.getEnclosingElement());
+ if (!binaryName.contentEquals("OnDemandAttribution$1")) {
+ throw new IllegalStateException("Incorrect binary name=" + binaryName);
+ }
+ return super.visitNewClass(node, p);
+ }
+ }.scan(path, null);
+
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/BaseClassesNotReRead.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,166 @@
+/*
+ * 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 8038455
+ * @summary Check that classfiles are read only once in common cases despite several rounds of
+ * annotation processing.
+ * @clean *
+ * @run main BaseClassesNotReRead
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.tools.*;
+import javax.tools.JavaFileObject.Kind;
+import com.sun.source.util.JavacTask;
+
+
+@SupportedAnnotationTypes("*")
+public class BaseClassesNotReRead extends AbstractProcessor {
+ public static void main(String... args) throws IOException {
+ new BaseClassesNotReRead().run();
+ }
+
+ void run() throws IOException {
+ File sources = new File(System.getProperty("test.src"));
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null);
+ Iterable<? extends JavaFileObject> files =
+ fm.getJavaFileObjects(new File(sources, "BaseClassesNotReReadSource.java"));
+ DiagnosticListener<JavaFileObject> noErrors = new DiagnosticListener<JavaFileObject>() {
+ @Override
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ throw new IllegalStateException(diagnostic.toString());
+ }
+ };
+ JavaFileManager manager = new OnlyOneReadFileManager(fm);
+ Iterable<String> options = Arrays.asList("-processor", "BaseClassesNotReRead");
+ JavacTask task = (JavacTask) compiler.getTask(null, manager, noErrors, options, null, files);
+ task.analyze();
+ }
+
+ int round = 1;
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ if (round++ == 1) {
+ for (int c = 1; c <= 6; c++) {
+ generateSource("GenClass" + c,
+ "public class GenClass" + c + " { public void test() { } }");
+ }
+ for (int c = 1; c <= 3; c++) {
+ generateSource("GenIntf" + c,
+ "public interface GenIntf" + c + " { public void test(); }");
+ }
+ generateSource("GenAnnotation",
+ "public @interface GenAnnotation { }");
+ generateSource("GenException",
+ "public class GenException extends Exception { }");
+ }
+
+ return false;
+ }
+
+ private void generateSource(String name, String code) {
+ Filer filer = processingEnv.getFiler();
+ try (Writer out = filer.createSourceFile(name).openWriter()) {
+ out.write(code);
+ out.close();
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
+ }
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ final class OnlyOneReadFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+
+ public OnlyOneReadFileManager(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind)
+ throws IOException {
+ return new OnlyOneReadJavaFileObject(super.getJavaFileForInput(location, className, kind));
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds,
+ boolean recurse) throws IOException {
+ List<JavaFileObject> result = new ArrayList<>();
+ for (JavaFileObject jfo : super.list(location, packageName, kinds, recurse)) {
+ result.add(new OnlyOneReadJavaFileObject(jfo));
+ }
+ return result;
+ }
+
+ @Override
+ public String inferBinaryName(Location location, JavaFileObject file) {
+ return super.inferBinaryName(location,
+ ((OnlyOneReadJavaFileObject) file).getFileObject());
+ }
+
+ }
+
+ final class OnlyOneReadJavaFileObject extends ForwardingJavaFileObject<JavaFileObject> {
+
+ public OnlyOneReadJavaFileObject(JavaFileObject fileObject) {
+ super(fileObject);
+ }
+
+ boolean used;
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ if (used) throw new IllegalStateException("Already read.");
+ used = true;
+ return super.getCharContent(ignoreEncodingErrors);
+ }
+
+ @Override
+ public InputStream openInputStream() throws IOException {
+ if (used) throw new IllegalStateException("Already read.");
+ used = true;
+ return super.openInputStream();
+ }
+
+ @Override
+ public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+ if (used) throw new IllegalStateException("Already read.");
+ used = true;
+ return super.openReader(ignoreEncodingErrors);
+ }
+
+ public JavaFileObject getFileObject() {
+ return fileObject;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/BaseClassesNotReReadSource.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,40 @@
+/*
+ * 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 java.util.List;
+
+public class BaseClassesNotReReadSource<T extends GenClass1&GenIntf1> extends GenClass2
+ implements GenIntf2 {
+ public GenClass3 f;
+ @GenAnnotation
+ public GenClass4 get(GenClass5 i, List<GenClass6> l) throws GenException {
+ return null;
+ }
+ @Override
+ public void test() {
+ }
+ @FunctionalInterface
+ interface FI extends GenIntf3 {
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/ClassDependingOnGenerated.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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 8038455
+ * @summary Verify situation when a classfile depends on another type, which is missing and
+ * generated by an annotation processor, is handled properly
+ * @library /tools/javac/lib/
+ * @clean *
+ * @build ClassWithSuperType ClassDependingOnGenerated JavacTestingAbstractProcessor
+ * @clean SuperClass
+ * @compile -processor ClassDependingOnGenerated ClassDependingOnGeneratedSource.java
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.*;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+
+public class ClassDependingOnGenerated extends JavacTestingAbstractProcessor {
+ int round = 1;
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+
+ try {
+ processingEnv.getElementUtils().getTypeElement("SuperClass");
+ } catch (CompletionFailure cf) {
+ cf.printStackTrace();
+ }
+ if (round++ == 1) {
+ try (Writer out = filer.createSourceFile("SuperClass").openWriter()) {
+ String code = "class SuperClass { public int get() { return 0; } }";
+ out.write(code);
+ out.close();
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
+ }
+ }
+
+ return false;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/ClassDependingOnGeneratedSource.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+public abstract class ClassDependingOnGeneratedSource {
+ ClassWithSuperType f;
+ public int get() {
+ return f.get();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/ClassWithSuperType.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+public class ClassWithSuperType extends SuperClass {
+}
+class SuperClass {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/CompleteOnClosed.java Wed Apr 09 17:18:22 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 8038455
+ * @summary Ensure that formatting diagnostics with an already closed JavaCompiler won't crash
+ * the compiler.
+ * @library /tools/javac/lib
+ * @build CompleteOnClosed ToolBox JavacTestingAbstractProcessor
+ * @run main CompleteOnClosed
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
+
+public class CompleteOnClosed extends JavacTestingAbstractProcessor {
+ public static void main(String... args) {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
+ String source = "class Test extends CompleteOnClosedOther {" +
+ " class Inner extends Undefined { }" +
+ "}";
+ Iterable<JavaFileObject> files = Arrays.<JavaFileObject>asList(new ToolBox.JavaSource(source));
+ Iterable<String> options = Arrays.asList("-processor", "CompleteOnClosed");
+ CompilationTask task = compiler.getTask(null, null, collector, options, null, files);
+ task.call();
+ for (Diagnostic<? extends JavaFileObject> d : collector.getDiagnostics()) {
+ System.out.println(d.toString());
+ }
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/CompleteOnClosedOther.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+class CompleteOnClosedOther {
+ Undefined2 undef;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/MethodsDroppedBetweenRounds.java Wed Apr 09 17:18:22 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 8038455
+ * @summary Ensure that Symbols for members (methods and fields) are dropped across annotation
+ * processing rounds. ClassSymbols need to be kept.
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor MethodsDroppedBetweenRounds
+ * @compile/process -processor MethodsDroppedBetweenRounds MethodsDroppedBetweenRounds.java
+ */
+
+import java.lang.ref.WeakReference;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.ElementFilter;
+
+public class MethodsDroppedBetweenRounds extends JavacTestingAbstractProcessor {
+ private static TypeElement currentClassSymbol;
+ private static WeakReference<ExecutableElement> keptMethod = null;
+ public boolean process(Set<? extends TypeElement> annos,RoundEnvironment rEnv) {
+ if (keptMethod != null) {
+ //force GC:
+ List<byte[]> hold = new ArrayList<>();
+ try {
+ while (true)
+ hold.add(new byte[1024 * 1024 * 1024]);
+ } catch (OutOfMemoryError err) { }
+ hold.clear();
+ if (keptMethod.get() != null) {
+ throw new IllegalStateException("Holds method across rounds.");
+ }
+ }
+
+ TypeElement currentClass = elements.getTypeElement("MethodsDroppedBetweenRounds");
+
+ if (currentClassSymbol != null && currentClassSymbol != currentClass) {
+ throw new IllegalStateException("Different ClassSymbols across rounds");
+ }
+
+ ExecutableElement method = ElementFilter.methodsIn(currentClass.getEnclosedElements()).get(0);
+
+ keptMethod = new WeakReference<>(method);
+
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,118 @@
+/*
+ * 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 8038455
+ * @summary Verify that annotation processor can overwrite source and class files it generated
+ * during previous compilations, and that the Symbols are updated appropriatelly.
+ * @library /tools/javac/lib/
+ * @clean *
+ * @build OverwriteBetweenCompilations ToolBox JavacTestingAbstractProcessor
+ * @compile/ref=OverwriteBetweenCompilations_1.out -processor OverwriteBetweenCompilations -Apass=1 -parameters -XDrawDiagnostics OverwriteBetweenCompilationsSource.java
+ * @compile/ref=OverwriteBetweenCompilations_2.out -processor OverwriteBetweenCompilations -Apass=2 -parameters -XDrawDiagnostics OverwriteBetweenCompilationsSource.java
+ * @compile/ref=OverwriteBetweenCompilations_3.out -processor OverwriteBetweenCompilations -Apass=3 -parameters -XDrawDiagnostics OverwriteBetweenCompilationsSource.java
+ */
+
+import java.io.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.*;
+
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.processing.PrintingProcessor.PrintingElementVisitor;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.WriterKind;
+
+@SupportedOptions("pass")
+public class OverwriteBetweenCompilations extends JavacTestingAbstractProcessor {
+ int round = 1;
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ Log log = Log.instance(((JavacProcessingEnvironment) processingEnv).getContext());
+ PrintWriter pw = log.getWriter(WriterKind.NOTICE);
+
+ pw.println("round: " + round);
+
+ TypeElement generatedSource =
+ processingEnv.getElementUtils().getTypeElement("GeneratedSource");
+
+ if (generatedSource != null) {
+ new PrintingElementVisitor(pw, processingEnv.getElementUtils()).visit(generatedSource);
+ pw.flush();
+ }
+
+ TypeElement generatedClass =
+ processingEnv.getElementUtils().getTypeElement("GeneratedClass");
+
+ if (generatedClass != null) {
+ new PrintingElementVisitor(pw, processingEnv.getElementUtils()).visit(generatedClass);
+ pw.flush();
+ }
+
+ int pass = Integer.parseInt(processingEnv.getOptions().get("pass"));
+
+ if (round++ == 1) {
+ try (Writer out = filer.createSourceFile("GeneratedSource").openWriter()) {
+ String code = pass != 2 ? GENERATED_INIT : GENERATED_UPDATE;
+ code = code.replace("NAME", "GeneratedSource");
+ out.write(code);
+ } catch (IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
+ }
+ try (OutputStream out = filer.createClassFile("GeneratedClass").openOutputStream()) {
+ String code = pass != 2 ? GENERATED_INIT : GENERATED_UPDATE;
+ code = code.replace("NAME", "GeneratedClass");
+ ToolBox.JavaToolArgs args =
+ new ToolBox.JavaToolArgs().appendArgs("-parameters").setSources(code);
+ Map<String, byte[]> codeMap = ToolBox.compile(args);
+ out.write(codeMap.get("GeneratedClass"));
+ } catch (IOException | ToolBox.CommandExecutionException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
+ }
+ }
+
+ return false;
+ }
+
+ //the initial generated class - "NAME" will be replaced with either "GeneratedSource" or
+ //"GeneratedClass" while generating the class:
+ private static final String GENERATED_INIT =
+ "@Deprecated\n" +
+ "public class NAME<T extends CharSequence> extends java.util.ArrayList<String>\n" +
+ " implements Runnable {\n" +
+ " public void test(int a) { }\n" +
+ " public void run() { }\n" +
+ "}";
+
+ //generated class update- "NAME" will be replaced with either "GeneratedSource" or
+ //"GeneratedClass" while generating the class:
+ private static final String GENERATED_UPDATE =
+ "@javax.annotation.processing.SupportedAnnotationTypes(\"*\")\n" +
+ "public abstract class NAME<E extends Number> extends java.util.LinkedList<Number>" +
+ " implements Runnable, CharSequence {\n" +
+ " public void test(long a) { }\n" +
+ "}";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilationsSource.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+public abstract class OverwriteBetweenCompilationsSource extends GeneratedSource {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations_1.out Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,45 @@
+round: 1
+round: 2
+
+@java.lang.Deprecated
+public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedSource();
+
+ public void test(int a);
+
+ public void run();
+}
+
+@java.lang.Deprecated
+public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedClass();
+
+ public void test(int a);
+
+ public void run();
+}
+round: 3
+
+@java.lang.Deprecated
+public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedSource();
+
+ public void test(int a);
+
+ public void run();
+}
+
+@java.lang.Deprecated
+public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedClass();
+
+ public void test(int a);
+
+ public void run();
+}
+- compiler.note.deprecated.filename: OverwriteBetweenCompilationsSource.java
+- compiler.note.deprecated.recompile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations_2.out Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,57 @@
+round: 1
+
+@java.lang.Deprecated
+public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedSource();
+
+ public void test(int a);
+
+ public void run();
+}
+
+@java.lang.Deprecated
+public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedClass();
+
+ public void test(int a);
+
+ public void run();
+}
+round: 2
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedSource();
+
+ public void test(long a);
+}
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedClass();
+
+ public void test(long a);
+}
+round: 3
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedSource();
+
+ public void test(long a);
+}
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedClass();
+
+ public void test(long a);
+}
+- compiler.note.deprecated.filename: OverwriteBetweenCompilationsSource.java
+- compiler.note.deprecated.recompile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations_3.out Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,61 @@
+round: 1
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedSource();
+
+ public void test(long a);
+}
+
+@javax.annotation.processing.SupportedAnnotationTypes({"*"})
+public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
+
+ public GeneratedClass();
+
+ public void test(long a);
+}
+round: 2
+
+@java.lang.Deprecated
+public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedSource();
+
+ public void test(int a);
+
+ public void run();
+}
+
+@java.lang.Deprecated
+public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedClass();
+
+ public void test(int a);
+
+ public void run();
+}
+round: 3
+
+@java.lang.Deprecated
+public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedSource();
+
+ public void test(int a);
+
+ public void run();
+}
+
+@java.lang.Deprecated
+public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
+
+ public GeneratedClass();
+
+ public void test(int a);
+
+ public void run();
+}
+- compiler.note.deprecated.filename: OverwriteBetweenCompilationsSource.java
+- compiler.note.deprecated.recompile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/rounds/TypesCachesCleared.java Wed Apr 09 17:18:22 2014 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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 8038455
+ * @summary Verify that Types caches (in particular MembersClosureCache) get cleared between rounds.
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor TypesCachesCleared
+ * @compile/process -processor TypesCachesCleared TypesCachesCleared.java
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import static javax.lang.model.util.ElementFilter.constructorsIn;
+import javax.lang.model.util.Elements;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+
+public class TypesCachesCleared extends JavacTestingAbstractProcessor {
+ int round = 1;
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ new TestPathScanner<Void>() {
+ @Override
+ public void visit(Void t) {
+ }
+ };
+ TypeElement currentClass = elements.getTypeElement("TypesCachesCleared");
+ Trees trees = Trees.instance(processingEnv);
+ TreePath path = trees.getPath(currentClass);
+ new TreePathScanner<Void, Void>() {
+ @Override public Void visitClass(ClassTree node, Void p) {
+ trees.getElement(getCurrentPath());
+ return super.visitClass(node, p);
+ }
+ }.scan(path, null);
+ return false;
+ }
+
+ public TypesCachesCleared() {
+ class Local { }
+ new Object() { };
+ }
+
+ public boolean process(Elements elements) {
+ TypeElement currentClass = elements.getTypeElement("OnDemandAttribution");
+ ExecutableElement constr = constructorsIn(currentClass.getEnclosedElements()).get(0);
+ Trees trees = Trees.instance(processingEnv);
+ TreePath path = trees.getPath(constr);
+
+ new TreePathScanner<Void, Void>() {
+ @Override public Void visitClass(ClassTree node, Void p) {
+ if (node.getSimpleName().contentEquals("Local")) {
+ //will also attribute the body on demand:
+ Element el = trees.getElement(getCurrentPath());
+ Name binaryName = elements.getBinaryName((TypeElement) el);
+ if (!binaryName.contentEquals("OnDemandAttribution$1Local")) {
+ throw new IllegalStateException("Incorrect binary name=" + binaryName);
+ }
+ }
+ return super.visitClass(node, p);
+ }
+ @Override public Void visitNewClass(NewClassTree node, Void p) {
+ Element el = trees.getElement(getCurrentPath());
+ Name binaryName = elements.getBinaryName((TypeElement) el.getEnclosingElement());
+ if (!binaryName.contentEquals("OnDemandAttribution$1")) {
+ throw new IllegalStateException("Incorrect binary name=" + binaryName);
+ }
+ return super.visitNewClass(node, p);
+ }
+ }.scan(path, null);
+
+ return true;
+ }
+ public static interface TestVisitor<T> {
+ public void visit(T t);
+ }
+
+ public static class TestScanner<T> implements TestVisitor<T> {
+ public void visit(T t) { }
+ }
+
+ public static class TestPathScanner<T> extends TestScanner<T> {
+ public void visit(T t) { }
+ }
+}
--- a/langtools/test/tools/javac/processing/warnings/gold_unsp_warn.out Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/processing/warnings/gold_unsp_warn.out Wed Apr 09 17:18:22 2014 -0700
@@ -1,1 +1,2 @@
- compiler.warn.proc.unmatched.processor.options: [unsupported]
+1 warning
--- a/langtools/test/tools/javac/util/context/T7021650.java Wed Apr 09 09:20:35 2014 -0700
+++ b/langtools/test/tools/javac/util/context/T7021650.java Wed Apr 09 17:18:22 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
@@ -56,7 +56,7 @@
* and verify that corresponding objects are created in each round.
*/
void run() throws Exception {
- Counter demoCounter = new Counter();
+ Counter myDemoCounter = new Counter();
Counter myAttrCounter = new Counter();
Context context = new Context();
@@ -76,7 +76,7 @@
}
});
- Demo.preRegister(context, demoCounter);
+ MyDemo.preRegister(context, myDemoCounter);
MyAttr.preRegister(context, myAttrCounter);
String[] args = {
@@ -88,13 +88,9 @@
compile(context, args);
- // Expect to create Demo for initial round, then MAX_ROUNDS in which
- // GenX files are generated, then standard final round of processing.
- checkEqual("demoCounter", demoCounter.count, MAX_ROUNDS + 2);
-
- // Expect to create MyAttr for same processing rounds as for Demo,
- // plus additional context for final compilation.
- checkEqual("myAttrCounter", myAttrCounter.count, MAX_ROUNDS + 3);
+ // the services should only be created once in the current scheme:
+ checkEqual("demoCounter", myDemoCounter.count, 1);
+ checkEqual("myAttrCounter", myAttrCounter.count, 1);
}
void compile(Context context, String... args) throws Exception {
@@ -123,15 +119,6 @@
* A custom class unknown to javac but nonetheless registered in the context.
*/
static class Demo {
- static void preRegister(Context context, final Counter counter) {
- context.put(Demo.class, new Context.Factory<Demo>() {
- public Demo make(Context c) {
- counter.count++;
- return new Demo(c);
- }
- });
- }
-
Demo(Context c) {
c.put(Demo.class, this);
}
@@ -141,6 +128,21 @@
}
}
+ static class MyDemo extends Demo {
+ static void preRegister(Context context, final Counter counter) {
+ context.put(Demo.class, new Context.Factory<Demo>() {
+ public Demo make(Context c) {
+ counter.count++;
+ return new MyDemo(c);
+ }
+ });
+ }
+
+ MyDemo(Context c) {
+ super(c);
+ }
+ }
+
/**
* A custom version of a standard javac component.
*/
@@ -174,7 +176,7 @@
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
// verify items in context as expected
- check("Demo", Demo.instance(context), Demo.class);
+ check("Demo", Demo.instance(context), MyDemo.class);
check("Attr", Attr.instance(context), MyAttr.class);
// For a few rounds, generate new source files, so that we can check whether