Wed, 23 Jul 2008 19:55:30 -0700
6726015: JavaCompiler: replace desugarLater by compileStates
Reviewed-by: mcimadamore
src/share/classes/com/sun/tools/javac/main/JavaCompiler.java | file | annotate | diff | comparison | revisions | |
test/tools/javac/6199662/Tree.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Jul 22 11:41:45 2008 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 23 19:55:30 2008 -0700 1.3 @@ -63,6 +63,7 @@ 1.4 // TEMP, until we have a more efficient way to save doc comment info 1.5 import com.sun.tools.javac.parser.DocCommentScanner; 1.6 1.7 +import java.util.HashMap; 1.8 import java.util.Queue; 1.9 import javax.lang.model.SourceVersion; 1.10 1.11 @@ -444,7 +445,25 @@ 1.12 */ 1.13 public Todo todo; 1.14 1.15 - private Set<Env<AttrContext>> deferredSugar = new HashSet<Env<AttrContext>>(); 1.16 + protected enum CompileState { 1.17 + TODO(0), 1.18 + ATTR(1), 1.19 + FLOW(2); 1.20 + CompileState(int value) { 1.21 + this.value = value; 1.22 + } 1.23 + boolean isDone(CompileState other) { 1.24 + return value >= other.value; 1.25 + } 1.26 + private int value; 1.27 + }; 1.28 + protected class CompileStates extends HashMap<Env<AttrContext>,CompileState> { 1.29 + boolean isDone(Env<AttrContext> env, CompileState cs) { 1.30 + CompileState ecs = get(env); 1.31 + return ecs != null && ecs.isDone(cs); 1.32 + } 1.33 + } 1.34 + private CompileStates compileStates = new CompileStates(); 1.35 1.36 /** The set of currently compiled inputfiles, needed to ensure 1.37 * we don't accidentally overwrite an input file when -s is set. 1.38 @@ -1039,6 +1058,9 @@ 1.39 * @returns the attributed parse tree 1.40 */ 1.41 public Env<AttrContext> attribute(Env<AttrContext> env) { 1.42 + if (compileStates.isDone(env, CompileState.ATTR)) 1.43 + return env; 1.44 + 1.45 if (verboseCompilePolicy) 1.46 log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]"); 1.47 if (verbose) 1.48 @@ -1055,6 +1077,7 @@ 1.49 env.toplevel.sourcefile); 1.50 try { 1.51 attr.attribClass(env.tree.pos(), env.enclClass.sym); 1.52 + compileStates.put(env, CompileState.ATTR); 1.53 } 1.54 finally { 1.55 log.useSource(prev); 1.56 @@ -1094,7 +1117,7 @@ 1.57 if (errorCount() > 0) 1.58 return; 1.59 1.60 - if (relax || deferredSugar.contains(env)) { 1.61 + if (relax || compileStates.isDone(env, CompileState.FLOW)) { 1.62 results.append(env); 1.63 return; 1.64 } 1.65 @@ -1109,6 +1132,7 @@ 1.66 make.at(Position.FIRSTPOS); 1.67 TreeMaker localMake = make.forToplevel(env.toplevel); 1.68 flow.analyzeTree(env.tree, localMake); 1.69 + compileStates.put(env, CompileState.FLOW); 1.70 1.71 if (errorCount() > 0) 1.72 return; 1.73 @@ -1146,7 +1170,7 @@ 1.74 * the current implicitSourcePolicy is taken into account. 1.75 * The preparation stops as soon as an error is found. 1.76 */ 1.77 - protected void desugar(Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) { 1.78 + protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) { 1.79 if (errorCount() > 0) 1.80 return; 1.81 1.82 @@ -1155,13 +1179,30 @@ 1.83 return; 1.84 } 1.85 1.86 - if (desugarLater(env)) { 1.87 - if (verboseCompilePolicy) 1.88 - log.printLines(log.noticeWriter, "[defer " + env.enclClass.sym + "]"); 1.89 - todo.append(env); 1.90 - return; 1.91 + /** 1.92 + * As erasure (TransTypes) destroys information needed in flow analysis, 1.93 + * including information in supertypes, we need to ensure that supertypes 1.94 + * are processed through attribute and flow before subtypes are translated. 1.95 + */ 1.96 + class ScanNested extends TreeScanner { 1.97 + Set<Env<AttrContext>> dependencies = new HashSet<Env<AttrContext>>(); 1.98 + public void visitClassDef(JCClassDecl node) { 1.99 + Type st = types.supertype(node.sym.type); 1.100 + if (st.tag == TypeTags.CLASS) { 1.101 + ClassSymbol c = st.tsym.outermostClass(); 1.102 + Env<AttrContext> stEnv = enter.getEnv(c); 1.103 + if (stEnv != null && env != stEnv) 1.104 + dependencies.add(stEnv); 1.105 + } 1.106 + super.visitClassDef(node); 1.107 + } 1.108 } 1.109 - deferredSugar.remove(env); 1.110 + ScanNested scanner = new ScanNested(); 1.111 + scanner.scan(env.tree); 1.112 + for (Env<AttrContext> dep: scanner.dependencies) { 1.113 + if (!compileStates.isDone(dep, CompileState.FLOW)) 1.114 + flow(attribute(dep)); 1.115 + } 1.116 1.117 if (verboseCompilePolicy) 1.118 log.printLines(log.noticeWriter, "[desugar " + env.enclClass.sym + "]"); 1.119 @@ -1234,43 +1275,6 @@ 1.120 1.121 } 1.122 1.123 - /** 1.124 - * Determine if a class needs to be desugared later. As erasure 1.125 - * (TransTypes) destroys information needed in flow analysis, we 1.126 - * need to ensure that supertypes are translated before derived 1.127 - * types are translated. 1.128 - */ 1.129 - public boolean desugarLater(final Env<AttrContext> env) { 1.130 - if (compilePolicy == CompilePolicy.BY_FILE) 1.131 - return false; 1.132 - if (!devVerbose && deferredSugar.contains(env)) 1.133 - // guarantee that compiler terminates 1.134 - return false; 1.135 - class ScanNested extends TreeScanner { 1.136 - Set<Symbol> externalSupers = new HashSet<Symbol>(); 1.137 - public void visitClassDef(JCClassDecl node) { 1.138 - Type st = types.supertype(node.sym.type); 1.139 - if (st.tag == TypeTags.CLASS) { 1.140 - ClassSymbol c = st.tsym.outermostClass(); 1.141 - Env<AttrContext> stEnv = enter.getEnv(c); 1.142 - if (stEnv != null && env != stEnv) 1.143 - externalSupers.add(st.tsym); 1.144 - } 1.145 - super.visitClassDef(node); 1.146 - } 1.147 - } 1.148 - ScanNested scanner = new ScanNested(); 1.149 - scanner.scan(env.tree); 1.150 - if (scanner.externalSupers.isEmpty()) 1.151 - return false; 1.152 - if (!deferredSugar.add(env) && devVerbose) { 1.153 - throw new AssertionError(env.enclClass.sym + " was deferred, " + 1.154 - "second time has these external super types " + 1.155 - scanner.externalSupers); 1.156 - } 1.157 - return true; 1.158 - } 1.159 - 1.160 /** Generates the source or class file for a list of classes. 1.161 * The decision to generate a source file or a class file is 1.162 * based upon the compiler's options.
2.1 --- a/test/tools/javac/6199662/Tree.java Tue Jul 22 11:41:45 2008 -0700 2.2 +++ b/test/tools/javac/6199662/Tree.java Wed Jul 23 19:55:30 2008 -0700 2.3 @@ -23,7 +23,7 @@ 2.4 2.5 /* 2.6 * @test 2.7 - * @bug 6199662 6325201 2.8 + * @bug 6199662 6325201 6726015 2.9 * @summary javac: compilation success depends on compilation order 2.10 * 2.11 * @compile Tree.java TreeScanner.java TreeInfo.java