8007479: Refactor DeferredAttrContext so that it points to parent context

Wed, 06 Feb 2013 14:04:43 +0000

author
mcimadamore
date
Wed, 06 Feb 2013 14:04:43 +0000
changeset 1551
8cdd96f2fdb9
parent 1550
1df20330f6bd
child 1552
153d20d0cac5

8007479: Refactor DeferredAttrContext so that it points to parent context
Summary: Move DeferredAttrNode out of DeferredAttrContext; add support for nested deferred contexts
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Infer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Feb 06 14:03:39 2013 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Feb 06 14:04:43 2013 +0000
     1.3 @@ -332,13 +332,22 @@
     1.4          /** inference context */
     1.5          final InferenceContext inferenceContext;
     1.6  
     1.7 +        /** parent deferred context */
     1.8 +        final DeferredAttrContext parent;
     1.9 +
    1.10 +        /** Warner object to report warnings */
    1.11 +        final Warner warn;
    1.12 +
    1.13          /** list of deferred attribution nodes to be processed */
    1.14          ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<DeferredAttrNode>();
    1.15  
    1.16 -        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, InferenceContext inferenceContext) {
    1.17 +        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase,
    1.18 +                InferenceContext inferenceContext, DeferredAttrContext parent, Warner warn) {
    1.19              this.mode = mode;
    1.20              this.msym = msym;
    1.21              this.phase = phase;
    1.22 +            this.parent = parent;
    1.23 +            this.warn = warn;
    1.24              this.inferenceContext = inferenceContext;
    1.25          }
    1.26  
    1.27 @@ -363,7 +372,7 @@
    1.28                  //scan a defensive copy of the node list - this is because a deferred
    1.29                  //attribution round can add new nodes to the list
    1.30                  for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
    1.31 -                    if (!deferredAttrNode.process()) {
    1.32 +                    if (!deferredAttrNode.process(this)) {
    1.33                          stuckVars.addAll(deferredAttrNode.stuckVars);
    1.34                      } else {
    1.35                          deferredAttrNodes.remove(deferredAttrNode);
    1.36 @@ -378,118 +387,120 @@
    1.37                  }
    1.38              }
    1.39          }
    1.40 +    }
    1.41 +
    1.42 +    /**
    1.43 +     * Class representing a deferred attribution node. It keeps track of
    1.44 +     * a deferred type, along with the expected target type information.
    1.45 +     */
    1.46 +    class DeferredAttrNode implements Infer.FreeTypeListener {
    1.47 +
    1.48 +        /** underlying deferred type */
    1.49 +        DeferredType dt;
    1.50 +
    1.51 +        /** underlying target type information */
    1.52 +        ResultInfo resultInfo;
    1.53 +
    1.54 +        /** list of uninferred inference variables causing this node to be stuck */
    1.55 +        List<Type> stuckVars;
    1.56 +
    1.57 +        DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
    1.58 +            this.dt = dt;
    1.59 +            this.resultInfo = resultInfo;
    1.60 +            this.stuckVars = stuckVars;
    1.61 +            if (!stuckVars.isEmpty()) {
    1.62 +                resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
    1.63 +            }
    1.64 +        }
    1.65 +
    1.66 +        @Override
    1.67 +        public void typesInferred(InferenceContext inferenceContext) {
    1.68 +            stuckVars = List.nil();
    1.69 +            resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
    1.70 +        }
    1.71  
    1.72          /**
    1.73 -         * Class representing a deferred attribution node. It keeps track of
    1.74 -         * a deferred type, along with the expected target type information.
    1.75 +         * Process a deferred attribution node.
    1.76 +         * Invariant: a stuck node cannot be processed.
    1.77           */
    1.78 -        class DeferredAttrNode implements Infer.FreeTypeListener {
    1.79 +        @SuppressWarnings("fallthrough")
    1.80 +        boolean process(DeferredAttrContext deferredAttrContext) {
    1.81 +            switch (deferredAttrContext.mode) {
    1.82 +                case SPECULATIVE:
    1.83 +                    dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
    1.84 +                    return true;
    1.85 +                case CHECK:
    1.86 +                    if (stuckVars.nonEmpty()) {
    1.87 +                        return false;
    1.88 +                    } else {
    1.89 +                        dt.check(resultInfo, stuckVars, basicCompleter);
    1.90 +                        return true;
    1.91 +                    }
    1.92 +                default:
    1.93 +                    throw new AssertionError("Bad mode");
    1.94 +            }
    1.95 +        }
    1.96  
    1.97 -            /** underlying deferred type */
    1.98 -            DeferredType dt;
    1.99 +        /**
   1.100 +         * Structural checker for stuck expressions
   1.101 +         */
   1.102 +        class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
   1.103  
   1.104 -            /** underlying target type information */
   1.105              ResultInfo resultInfo;
   1.106 +            InferenceContext inferenceContext;
   1.107  
   1.108 -            /** list of uninferred inference variables causing this node to be stuck */
   1.109 -            List<Type> stuckVars;
   1.110 +            public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
   1.111 +                this.resultInfo = resultInfo;
   1.112 +                this.inferenceContext = deferredAttrContext.inferenceContext;
   1.113 +                dt.tree.accept(this);
   1.114 +                dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
   1.115 +                return Type.noType;
   1.116 +            }
   1.117  
   1.118 -            DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
   1.119 -                this.dt = dt;
   1.120 -                this.resultInfo = resultInfo;
   1.121 -                this.stuckVars = stuckVars;
   1.122 -                if (!stuckVars.isEmpty()) {
   1.123 -                    resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
   1.124 +            @Override
   1.125 +            public void visitLambda(JCLambda tree) {
   1.126 +                Check.CheckContext checkContext = resultInfo.checkContext;
   1.127 +                Type pt = resultInfo.pt;
   1.128 +                if (inferenceContext.inferencevars.contains(pt)) {
   1.129 +                    //ok
   1.130 +                    return;
   1.131 +                } else {
   1.132 +                    //must be a functional descriptor
   1.133 +                    try {
   1.134 +                        Type desc = types.findDescriptorType(pt);
   1.135 +                        if (desc.getParameterTypes().length() != tree.params.length()) {
   1.136 +                            checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
   1.137 +                        }
   1.138 +                    } catch (Types.FunctionDescriptorLookupError ex) {
   1.139 +                        checkContext.report(null, ex.getDiagnostic());
   1.140 +                    }
   1.141                  }
   1.142              }
   1.143  
   1.144              @Override
   1.145 -            public void typesInferred(InferenceContext inferenceContext) {
   1.146 -                stuckVars = List.nil();
   1.147 -                resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
   1.148 +            public void visitNewClass(JCNewClass tree) {
   1.149 +                //do nothing
   1.150              }
   1.151  
   1.152 -            /**
   1.153 -             * Process a deferred attribution node.
   1.154 -             * Invariant: a stuck node cannot be processed.
   1.155 -             */
   1.156 -            @SuppressWarnings("fallthrough")
   1.157 -            boolean process() {
   1.158 -                switch (mode) {
   1.159 -                    case SPECULATIVE:
   1.160 -                        dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
   1.161 -                        return true;
   1.162 -                    case CHECK:
   1.163 -                        if (stuckVars.nonEmpty()) {
   1.164 -                            return false;
   1.165 -                        } else {
   1.166 -                            dt.check(resultInfo, stuckVars, basicCompleter);
   1.167 -                            return true;
   1.168 -                        }
   1.169 -                    default:
   1.170 -                        throw new AssertionError("Bad mode");
   1.171 -                }
   1.172 +            @Override
   1.173 +            public void visitApply(JCMethodInvocation tree) {
   1.174 +                //do nothing
   1.175              }
   1.176  
   1.177 -            /**
   1.178 -             * Structural checker for stuck expressions
   1.179 -             */
   1.180 -            class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
   1.181 -
   1.182 -                ResultInfo resultInfo;
   1.183 -
   1.184 -                public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
   1.185 -                    this.resultInfo = resultInfo;
   1.186 -                    dt.tree.accept(this);
   1.187 -                    dt.speculativeCache.put(msym, stuckTree, phase);
   1.188 -                    return Type.noType;
   1.189 -                }
   1.190 -
   1.191 -                @Override
   1.192 -                public void visitLambda(JCLambda tree) {
   1.193 -                    Check.CheckContext checkContext = resultInfo.checkContext;
   1.194 -                    Type pt = resultInfo.pt;
   1.195 -                    if (inferenceContext.inferencevars.contains(pt)) {
   1.196 -                        //ok
   1.197 -                        return;
   1.198 -                    } else {
   1.199 -                        //must be a functional descriptor
   1.200 -                        try {
   1.201 -                            Type desc = types.findDescriptorType(pt);
   1.202 -                            if (desc.getParameterTypes().length() != tree.params.length()) {
   1.203 -                                checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
   1.204 -                            }
   1.205 -                        } catch (Types.FunctionDescriptorLookupError ex) {
   1.206 -                            checkContext.report(null, ex.getDiagnostic());
   1.207 -                        }
   1.208 -                    }
   1.209 -                }
   1.210 -
   1.211 -                @Override
   1.212 -                public void visitNewClass(JCNewClass tree) {
   1.213 -                    //do nothing
   1.214 -                }
   1.215 -
   1.216 -                @Override
   1.217 -                public void visitApply(JCMethodInvocation tree) {
   1.218 -                    //do nothing
   1.219 -                }
   1.220 -
   1.221 -                @Override
   1.222 -                public void visitReference(JCMemberReference tree) {
   1.223 -                    Check.CheckContext checkContext = resultInfo.checkContext;
   1.224 -                    Type pt = resultInfo.pt;
   1.225 -                    if (inferenceContext.inferencevars.contains(pt)) {
   1.226 -                        //ok
   1.227 -                        return;
   1.228 -                    } else {
   1.229 -                        try {
   1.230 -                            //TODO: we should speculative determine if there's a match
   1.231 -                            //based on arity - if yes, method is applicable.
   1.232 -                            types.findDescriptorType(pt);
   1.233 -                        } catch (Types.FunctionDescriptorLookupError ex) {
   1.234 -                            checkContext.report(null, ex.getDiagnostic());
   1.235 -                        }
   1.236 +            @Override
   1.237 +            public void visitReference(JCMemberReference tree) {
   1.238 +                Check.CheckContext checkContext = resultInfo.checkContext;
   1.239 +                Type pt = resultInfo.pt;
   1.240 +                if (inferenceContext.inferencevars.contains(pt)) {
   1.241 +                    //ok
   1.242 +                    return;
   1.243 +                } else {
   1.244 +                    try {
   1.245 +                        //TODO: we should speculative determine if there's a match
   1.246 +                        //based on arity - if yes, method is applicable.
   1.247 +                        types.findDescriptorType(pt);
   1.248 +                    } catch (Types.FunctionDescriptorLookupError ex) {
   1.249 +                        checkContext.report(null, ex.getDiagnostic());
   1.250                      }
   1.251                  }
   1.252              }
   1.253 @@ -498,7 +509,7 @@
   1.254  
   1.255      /** an empty deferred attribution context - all methods throw exceptions */
   1.256      final DeferredAttrContext emptyDeferredAttrContext =
   1.257 -            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null) {
   1.258 +            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null, null, null) {
   1.259                  @Override
   1.260                  void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
   1.261                      Assert.error("Empty deferred context!");
   1.262 @@ -521,7 +532,8 @@
   1.263  
   1.264          protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
   1.265              super(String.format("deferredTypeMap[%s]", mode));
   1.266 -            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext);
   1.267 +            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase,
   1.268 +                    infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
   1.269          }
   1.270  
   1.271          protected boolean validState(DeferredType dt) {
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Feb 06 14:03:39 2013 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Feb 06 14:04:43 2013 +0000
     2.3 @@ -269,7 +269,7 @@
     2.4          inferenceException.clear();
     2.5  
     2.6          DeferredAttr.DeferredAttrContext deferredAttrContext =
     2.7 -                resolveContext.deferredAttrContext(msym, inferenceContext);
     2.8 +                resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
     2.9  
    2.10          try {
    2.11              methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Feb 06 14:03:39 2013 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Feb 06 14:04:43 2013 +0000
     3.3 @@ -564,7 +564,7 @@
     3.4                                      methodCheck,
     3.5                                      warn);
     3.6  
     3.7 -        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext),
     3.8 +        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
     3.9                                  argtypes, mt.getParameterTypes(), warn);
    3.10          return mt;
    3.11      }
    3.12 @@ -3589,8 +3589,8 @@
    3.13              candidates = candidates.append(c);
    3.14          }
    3.15  
    3.16 -        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext) {
    3.17 -            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext);
    3.18 +        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
    3.19 +            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
    3.20          }
    3.21  
    3.22          /**

mercurial