61 * If you write code that depends on this, you do so at your own risk. |
61 * If you write code that depends on this, you do so at your own risk. |
62 * This code and its internal interfaces are subject to change or |
62 * This code and its internal interfaces are subject to change or |
63 * deletion without notice.</b> |
63 * deletion without notice.</b> |
64 */ |
64 */ |
65 public class DeferredAttr extends JCTree.Visitor { |
65 public class DeferredAttr extends JCTree.Visitor { |
66 protected static final Context.Key<DeferredAttr> deferredAttrKey = |
66 protected static final Context.Key<DeferredAttr> deferredAttrKey = new Context.Key<>(); |
67 new Context.Key<DeferredAttr>(); |
|
68 |
67 |
69 final Attr attr; |
68 final Attr attr; |
70 final Check chk; |
69 final Check chk; |
71 final JCDiagnostic.Factory diags; |
70 final JCDiagnostic.Factory diags; |
72 final Enter enter; |
71 final Enter enter; |
145 * stores a pointer to the speculative tree and the resolution phase in which the entry |
144 * stores a pointer to the speculative tree and the resolution phase in which the entry |
146 * has been added. |
145 * has been added. |
147 */ |
146 */ |
148 class SpeculativeCache { |
147 class SpeculativeCache { |
149 |
148 |
150 private Map<Symbol, List<Entry>> cache = |
149 private Map<Symbol, List<Entry>> cache = new WeakHashMap<>(); |
151 new WeakHashMap<Symbol, List<Entry>>(); |
|
152 |
150 |
153 class Entry { |
151 class Entry { |
154 JCTree speculativeTree; |
152 JCTree speculativeTree; |
155 ResultInfo resultInfo; |
153 ResultInfo resultInfo; |
156 |
154 |
333 */ |
331 */ |
334 SPECULATIVE, |
332 SPECULATIVE, |
335 /** |
333 /** |
336 * This is the plain type-checking mode. Produces side-effects on the underlying AST node |
334 * This is the plain type-checking mode. Produces side-effects on the underlying AST node |
337 */ |
335 */ |
338 CHECK; |
336 CHECK |
339 } |
337 } |
340 |
338 |
341 /** |
339 /** |
342 * Routine that performs speculative type-checking; the input AST node is |
340 * Routine that performs speculative type-checking; the input AST node is |
343 * cloned (to avoid side-effects cause by Attr) and compiler state is |
341 * cloned (to avoid side-effects cause by Attr) and compiler state is |
344 * restored after type-checking. All diagnostics (but critical ones) are |
342 * restored after type-checking. All diagnostics (but critical ones) are |
345 * disabled during speculative type-checking. |
343 * disabled during speculative type-checking. |
346 */ |
344 */ |
347 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { |
345 JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) { |
348 final JCTree newTree = new TreeCopier<Object>(make).copy(tree); |
346 final JCTree newTree = new TreeCopier<>(make).copy(tree); |
349 Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared())); |
347 Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared())); |
350 speculativeEnv.info.scope.owner = env.info.scope.owner; |
348 speculativeEnv.info.scope.owner = env.info.scope.owner; |
351 Log.DeferredDiagnosticHandler deferredDiagnosticHandler = |
349 Log.DeferredDiagnosticHandler deferredDiagnosticHandler = |
352 new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() { |
350 new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() { |
353 public boolean accepts(final JCDiagnostic d) { |
351 public boolean accepts(final JCDiagnostic d) { |
423 |
421 |
424 /** Warner object to report warnings */ |
422 /** Warner object to report warnings */ |
425 final Warner warn; |
423 final Warner warn; |
426 |
424 |
427 /** list of deferred attribution nodes to be processed */ |
425 /** list of deferred attribution nodes to be processed */ |
428 ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<DeferredAttrNode>(); |
426 ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<>(); |
429 |
427 |
430 DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, |
428 DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, |
431 InferenceContext inferenceContext, DeferredAttrContext parent, Warner warn) { |
429 InferenceContext inferenceContext, DeferredAttrContext parent, Warner warn) { |
432 this.mode = mode; |
430 this.mode = mode; |
433 this.msym = msym; |
431 this.msym = msym; |
452 * some inference variable might get eagerly instantiated so that all nodes |
450 * some inference variable might get eagerly instantiated so that all nodes |
453 * can be type-checked. |
451 * can be type-checked. |
454 */ |
452 */ |
455 void complete() { |
453 void complete() { |
456 while (!deferredAttrNodes.isEmpty()) { |
454 while (!deferredAttrNodes.isEmpty()) { |
457 Map<Type, Set<Type>> depVarsMap = new LinkedHashMap<Type, Set<Type>>(); |
455 Map<Type, Set<Type>> depVarsMap = new LinkedHashMap<>(); |
458 List<Type> stuckVars = List.nil(); |
456 List<Type> stuckVars = List.nil(); |
459 boolean progress = false; |
457 boolean progress = false; |
460 //scan a defensive copy of the node list - this is because a deferred |
458 //scan a defensive copy of the node list - this is because a deferred |
461 //attribution round can add new nodes to the list |
459 //attribution round can add new nodes to the list |
462 for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) { |
460 for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) { |
468 //update dependency map |
466 //update dependency map |
469 for (Type t : List.from(deferredAttrNode.deferredStuckPolicy.depVars()) |
467 for (Type t : List.from(deferredAttrNode.deferredStuckPolicy.depVars()) |
470 .intersect(inferenceContext.restvars())) { |
468 .intersect(inferenceContext.restvars())) { |
471 Set<Type> prevDeps = depVarsMap.get(t); |
469 Set<Type> prevDeps = depVarsMap.get(t); |
472 if (prevDeps == null) { |
470 if (prevDeps == null) { |
473 prevDeps = new LinkedHashSet<Type>(); |
471 prevDeps = new LinkedHashSet<>(); |
474 depVarsMap.put(t, prevDeps); |
472 depVarsMap.put(t, prevDeps); |
475 } |
473 } |
476 prevDeps.addAll(restStuckVars); |
474 prevDeps.addAll(restStuckVars); |
477 } |
475 } |
478 } else { |
476 } else { |
813 */ |
811 */ |
814 class CheckStuckPolicy extends PolyScanner implements DeferredStuckPolicy, Infer.FreeTypeListener { |
812 class CheckStuckPolicy extends PolyScanner implements DeferredStuckPolicy, Infer.FreeTypeListener { |
815 |
813 |
816 Type pt; |
814 Type pt; |
817 Infer.InferenceContext inferenceContext; |
815 Infer.InferenceContext inferenceContext; |
818 Set<Type> stuckVars = new LinkedHashSet<Type>(); |
816 Set<Type> stuckVars = new LinkedHashSet<>(); |
819 Set<Type> depVars = new LinkedHashSet<Type>(); |
817 Set<Type> depVars = new LinkedHashSet<>(); |
820 |
818 |
821 @Override |
819 @Override |
822 public boolean isStuck() { |
820 public boolean isStuck() { |
823 return !stuckVars.isEmpty(); |
821 return !stuckVars.isEmpty(); |
824 } |
822 } |