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
|
||||
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 class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
*/
|
||||
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
* @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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
if (errorCount() > 0)
|
||||
return;
|
||||
|
||||
if (relax || deferredSugar.contains(env)) {
|
||||
if (relax || compileStates.isDone(env, CompileState.FLOW)) {
|
||||
results.append(env);
|
||||
return;
|
||||
}
|
||||
@ -1109,6 +1132,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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)
|
||||
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.
|
||||
* The decision to generate a source file or a class file is
|
||||
* based upon the compiler's options.
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user