42 import java.util.Map; |
42 import java.util.Map; |
43 import java.util.Queue; |
43 import java.util.Queue; |
44 import java.util.Set; |
44 import java.util.Set; |
45 import java.util.WeakHashMap; |
45 import java.util.WeakHashMap; |
46 |
46 |
47 import static com.sun.tools.javac.code.TypeTags.*; |
47 import static com.sun.tools.javac.code.TypeTag.DEFERRED; |
|
48 import static com.sun.tools.javac.code.TypeTag.NONE; |
48 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
49 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
49 |
50 |
50 /** |
51 /** |
51 * This is an helper class that is used to perform deferred type-analysis. |
52 * This is an helper class that is used to perform deferred type-analysis. |
52 * Each time a poly expression occurs in argument position, javac attributes it |
53 * Each time a poly expression occurs in argument position, javac attributes it |
201 try { |
202 try { |
202 switch (deferredAttrContext.mode) { |
203 switch (deferredAttrContext.mode) { |
203 case SPECULATIVE: |
204 case SPECULATIVE: |
204 Assert.check(mode == null || |
205 Assert.check(mode == null || |
205 (mode == AttrMode.SPECULATIVE && |
206 (mode == AttrMode.SPECULATIVE && |
206 speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).tag == NONE)); |
207 speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).hasTag(NONE))); |
207 JCTree speculativeTree = attribSpeculative(tree, env, resultInfo); |
208 JCTree speculativeTree = attribSpeculative(tree, env, resultInfo); |
208 speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase); |
209 speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase); |
209 return speculativeTree.type; |
210 return speculativeTree.type; |
210 case CHECK: |
211 case CHECK: |
211 Assert.check(mode == AttrMode.SPECULATIVE); |
212 Assert.check(mode == AttrMode.SPECULATIVE); |
440 deferredAttrContext.mode.ordinal() <= dt.mode.ordinal(); |
441 deferredAttrContext.mode.ordinal() <= dt.mode.ordinal(); |
441 } |
442 } |
442 |
443 |
443 @Override |
444 @Override |
444 public Type apply(Type t) { |
445 public Type apply(Type t) { |
445 if (t.tag != DEFERRED) { |
446 if (!t.hasTag(DEFERRED)) { |
446 return t.map(this); |
447 return t.map(this); |
447 } else { |
448 } else { |
448 DeferredType dt = (DeferredType)t; |
449 DeferredType dt = (DeferredType)t; |
449 Assert.check(validState(dt)); |
450 Assert.check(validState(dt)); |
450 return typeOf(dt); |
451 return typeOf(dt); |
477 } |
478 } |
478 |
479 |
479 @Override |
480 @Override |
480 protected Type typeOf(DeferredType dt) { |
481 protected Type typeOf(DeferredType dt) { |
481 Type owntype = super.typeOf(dt); |
482 Type owntype = super.typeOf(dt); |
482 return owntype.tag == NONE ? |
483 return owntype.hasTag(NONE) ? |
483 recover(dt) : owntype; |
484 recover(dt) : owntype; |
484 } |
485 } |
485 |
486 |
486 @Override |
487 @Override |
487 protected boolean validState(DeferredType dt) { |
488 protected boolean validState(DeferredType dt) { |
514 * Retrieves the list of inference variables that need to be inferred before |
515 * Retrieves the list of inference variables that need to be inferred before |
515 * an AST node can be type-checked |
516 * an AST node can be type-checked |
516 */ |
517 */ |
517 @SuppressWarnings("fallthrough") |
518 @SuppressWarnings("fallthrough") |
518 List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) { |
519 List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) { |
519 if (resultInfo.pt.tag == NONE || resultInfo.pt.isErroneous()) { |
520 if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) { |
520 return List.nil(); |
521 return List.nil(); |
521 } else { |
522 } else { |
522 StuckChecker sc = new StuckChecker(resultInfo); |
523 StuckChecker sc = new StuckChecker(resultInfo); |
523 sc.scan(tree); |
524 sc.scan(tree); |
524 return List.from(sc.stuckVars); |
525 return List.from(sc.stuckVars); |