6726015: JavaCompiler: replace desugarLater by compileStates
Reviewed-by: mcimadamore
This commit is contained in:
parent
f42262c039
commit
f3eff961d3
@ -63,6 +63,7 @@ import static com.sun.tools.javac.util.ListBuffer.lb;
|
|||||||
// TEMP, until we have a more efficient way to save doc comment info
|
// TEMP, until we have a more efficient way to save doc comment info
|
||||||
import com.sun.tools.javac.parser.DocCommentScanner;
|
import com.sun.tools.javac.parser.DocCommentScanner;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import javax.lang.model.SourceVersion;
|
import javax.lang.model.SourceVersion;
|
||||||
|
|
||||||
@ -444,7 +445,25 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
*/
|
*/
|
||||||
public Todo todo;
|
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
|
/** The set of currently compiled inputfiles, needed to ensure
|
||||||
* we don't accidentally overwrite an input file when -s is set.
|
* we don't accidentally overwrite an input file when -s is set.
|
||||||
@ -1039,6 +1058,9 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
* @returns the attributed parse tree
|
* @returns the attributed parse tree
|
||||||
*/
|
*/
|
||||||
public Env<AttrContext> attribute(Env<AttrContext> env) {
|
public Env<AttrContext> attribute(Env<AttrContext> env) {
|
||||||
|
if (compileStates.isDone(env, CompileState.ATTR))
|
||||||
|
return env;
|
||||||
|
|
||||||
if (verboseCompilePolicy)
|
if (verboseCompilePolicy)
|
||||||
log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
|
log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@ -1055,6 +1077,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
env.toplevel.sourcefile);
|
env.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
attr.attribClass(env.tree.pos(), env.enclClass.sym);
|
attr.attribClass(env.tree.pos(), env.enclClass.sym);
|
||||||
|
compileStates.put(env, CompileState.ATTR);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
log.useSource(prev);
|
log.useSource(prev);
|
||||||
@ -1094,7 +1117,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
if (errorCount() > 0)
|
if (errorCount() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (relax || deferredSugar.contains(env)) {
|
if (relax || compileStates.isDone(env, CompileState.FLOW)) {
|
||||||
results.append(env);
|
results.append(env);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1109,6 +1132,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
make.at(Position.FIRSTPOS);
|
make.at(Position.FIRSTPOS);
|
||||||
TreeMaker localMake = make.forToplevel(env.toplevel);
|
TreeMaker localMake = make.forToplevel(env.toplevel);
|
||||||
flow.analyzeTree(env.tree, localMake);
|
flow.analyzeTree(env.tree, localMake);
|
||||||
|
compileStates.put(env, CompileState.FLOW);
|
||||||
|
|
||||||
if (errorCount() > 0)
|
if (errorCount() > 0)
|
||||||
return;
|
return;
|
||||||
@ -1146,7 +1170,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
* the current implicitSourcePolicy is taken into account.
|
* the current implicitSourcePolicy is taken into account.
|
||||||
* The preparation stops as soon as an error is found.
|
* 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)
|
if (errorCount() > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1155,13 +1179,30 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desugarLater(env)) {
|
/**
|
||||||
if (verboseCompilePolicy)
|
* As erasure (TransTypes) destroys information needed in flow analysis,
|
||||||
log.printLines(log.noticeWriter, "[defer " + env.enclClass.sym + "]");
|
* including information in supertypes, we need to ensure that supertypes
|
||||||
todo.append(env);
|
* are processed through attribute and flow before subtypes are translated.
|
||||||
return;
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScanNested scanner = new ScanNested();
|
||||||
|
scanner.scan(env.tree);
|
||||||
|
for (Env<AttrContext> dep: scanner.dependencies) {
|
||||||
|
if (!compileStates.isDone(dep, CompileState.FLOW))
|
||||||
|
flow(attribute(dep));
|
||||||
}
|
}
|
||||||
deferredSugar.remove(env);
|
|
||||||
|
|
||||||
if (verboseCompilePolicy)
|
if (verboseCompilePolicy)
|
||||||
log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]");
|
log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]");
|
||||||
@ -1234,43 +1275,6 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
/** Generates the source or class file for a list of classes.
|
||||||
* The decision to generate a source file or a class file is
|
* The decision to generate a source file or a class file is
|
||||||
* based upon the compiler's options.
|
* based upon the compiler's options.
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6199662 6325201
|
* @bug 6199662 6325201 6726015
|
||||||
* @summary javac: compilation success depends on compilation order
|
* @summary javac: compilation success depends on compilation order
|
||||||
*
|
*
|
||||||
* @compile Tree.java TreeScanner.java TreeInfo.java
|
* @compile Tree.java TreeScanner.java TreeInfo.java
|
||||||
|
Loading…
x
Reference in New Issue
Block a user