6726015: JavaCompiler: replace desugarLater by compileStates
Reviewed-by: mcimadamore
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 05 16:39:28 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 23 19:55:30 2008 -0700
@@ -63,6 +63,7 @@
// TEMP, until we have a more efficient way to save doc comment info
import com.sun.tools.javac.parser.DocCommentScanner;
+import java.util.HashMap;
import java.util.Queue;
import javax.lang.model.SourceVersion;
@@ -444,7 +445,25 @@
*/
public Todo todo;
- private Set<Env<AttrContext>> deferredSugar = new HashSet<Env<AttrContext>>();
+ protected enum CompileState {
+ TODO(0),
+ ATTR(1),
+ FLOW(2);
+ CompileState(int value) {
+ this.value = value;
+ }
+ boolean isDone(CompileState other) {
+ return value >= other.value;
+ }
+ private int value;
+ };
+ protected class CompileStates extends HashMap<Env<AttrContext>,CompileState> {
+ boolean isDone(Env<AttrContext> env, CompileState cs) {
+ CompileState ecs = get(env);
+ return ecs != null && ecs.isDone(cs);
+ }
+ }
+ private CompileStates compileStates = new CompileStates();
/** The set of currently compiled inputfiles, needed to ensure
* we don't accidentally overwrite an input file when -s is set.
@@ -1039,6 +1058,9 @@
* @returns the attributed parse tree
*/
public Env<AttrContext> attribute(Env<AttrContext> env) {
+ if (compileStates.isDone(env, CompileState.ATTR))
+ return env;
+
if (verboseCompilePolicy)
log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
if (verbose)
@@ -1055,6 +1077,7 @@
env.toplevel.sourcefile);
try {
attr.attribClass(env.tree.pos(), env.enclClass.sym);
+ compileStates.put(env, CompileState.ATTR);
}
finally {
log.useSource(prev);
@@ -1094,7 +1117,7 @@
if (errorCount() > 0)
return;
- if (relax || deferredSugar.contains(env)) {
+ if (relax || compileStates.isDone(env, CompileState.FLOW)) {
results.append(env);
return;
}
@@ -1109,6 +1132,7 @@
make.at(Position.FIRSTPOS);
TreeMaker localMake = make.forToplevel(env.toplevel);
flow.analyzeTree(env.tree, localMake);
+ compileStates.put(env, CompileState.FLOW);
if (errorCount() > 0)
return;
@@ -1146,7 +1170,7 @@
* the current implicitSourcePolicy is taken into account.
* The preparation stops as soon as an error is found.
*/
- protected void desugar(Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
+ protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
if (errorCount() > 0)
return;
@@ -1155,13 +1179,30 @@
return;
}
- if (desugarLater(env)) {
- if (verboseCompilePolicy)
- log.printLines(log.noticeWriter, "[defer " + env.enclClass.sym + "]");
- todo.append(env);
- return;
+ /**
+ * As erasure (TransTypes) destroys information needed in flow analysis,
+ * including information in supertypes, we need to ensure that supertypes
+ * are processed through attribute and flow before subtypes are translated.
+ */
+ class ScanNested extends TreeScanner {
+ Set<Env<AttrContext>> dependencies = new HashSet<Env<AttrContext>>();
+ public void visitClassDef(JCClassDecl node) {
+ Type st = types.supertype(node.sym.type);
+ if (st.tag == TypeTags.CLASS) {
+ ClassSymbol c = st.tsym.outermostClass();
+ Env<AttrContext> stEnv = enter.getEnv(c);
+ if (stEnv != null && env != stEnv)
+ dependencies.add(stEnv);
+ }
+ super.visitClassDef(node);
+ }
}
- deferredSugar.remove(env);
+ ScanNested scanner = new ScanNested();
+ scanner.scan(env.tree);
+ for (Env<AttrContext> dep: scanner.dependencies) {
+ if (!compileStates.isDone(dep, CompileState.FLOW))
+ flow(attribute(dep));
+ }
if (verboseCompilePolicy)
log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]");
@@ -1234,43 +1275,6 @@
}
- /**
- * Determine if a class needs to be desugared later. As erasure
- * (TransTypes) destroys information needed in flow analysis, we
- * need to ensure that supertypes are translated before derived
- * types are translated.
- */
- public boolean desugarLater(final Env<AttrContext> env) {
- if (compilePolicy == CompilePolicy.BY_FILE)
- return false;
- if (!devVerbose && deferredSugar.contains(env))
- // guarantee that compiler terminates
- return false;
- class ScanNested extends TreeScanner {
- Set<Symbol> externalSupers = new HashSet<Symbol>();
- public void visitClassDef(JCClassDecl node) {
- Type st = types.supertype(node.sym.type);
- if (st.tag == TypeTags.CLASS) {
- ClassSymbol c = st.tsym.outermostClass();
- Env<AttrContext> stEnv = enter.getEnv(c);
- if (stEnv != null && env != stEnv)
- externalSupers.add(st.tsym);
- }
- super.visitClassDef(node);
- }
- }
- ScanNested scanner = new ScanNested();
- scanner.scan(env.tree);
- if (scanner.externalSupers.isEmpty())
- return false;
- if (!deferredSugar.add(env) && devVerbose) {
- throw new AssertionError(env.enclClass.sym + " was deferred, " +
- "second time has these external super types " +
- scanner.externalSupers);
- }
- return true;
- }
-
/** Generates the source or class file for a list of classes.
* The decision to generate a source file or a class file is
* based upon the compiler's options.
--- a/langtools/test/tools/javac/6199662/Tree.java Wed Jul 05 16:39:28 2017 +0200
+++ b/langtools/test/tools/javac/6199662/Tree.java Wed Jul 23 19:55:30 2008 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6199662 6325201
+ * @bug 6199662 6325201 6726015
* @summary javac: compilation success depends on compilation order
*
* @compile Tree.java TreeScanner.java TreeInfo.java