langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
changeset 22163 3651128c74eb
parent 21718 74a5882faf79
child 24066 1dfb66929538
equal deleted inserted replaced
22162:3b3e23e67329 22163:3651128c74eb
    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) {
   360                                 tree.pos() == d.getDiagnosticPosition()) {
   358                                 tree.pos() == d.getDiagnosticPosition()) {
   361                             found = true;
   359                             found = true;
   362                         }
   360                         }
   363                         super.scan(tree);
   361                         super.scan(tree);
   364                     }
   362                     }
   365                 };
   363                 }
   366                 PosScanner posScanner = new PosScanner();
   364                 PosScanner posScanner = new PosScanner();
   367                 posScanner.scan(newTree);
   365                 posScanner.scan(newTree);
   368                 return posScanner.found;
   366                 return posScanner.found;
   369             }
   367             }
   370         });
   368         });
   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         }