1.1 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 17 14:04:01 2013 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 17 14:09:46 2013 +0100 1.3 @@ -34,15 +34,14 @@ 1.4 import com.sun.tools.javac.comp.Attr.ResultInfo; 1.5 import com.sun.tools.javac.comp.Infer.InferenceContext; 1.6 import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; 1.7 +import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper; 1.8 import com.sun.tools.javac.tree.JCTree.*; 1.9 1.10 -import javax.tools.JavaFileObject; 1.11 1.12 import java.util.ArrayList; 1.13 import java.util.EnumSet; 1.14 import java.util.LinkedHashSet; 1.15 import java.util.Map; 1.16 -import java.util.Queue; 1.17 import java.util.Set; 1.18 import java.util.WeakHashMap; 1.19 1.20 @@ -96,6 +95,17 @@ 1.21 types = Types.instance(context); 1.22 Names names = Names.instance(context); 1.23 stuckTree = make.Ident(names.empty).setType(Type.stuckType); 1.24 + emptyDeferredAttrContext = 1.25 + new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { 1.26 + @Override 1.27 + void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) { 1.28 + Assert.error("Empty deferred context!"); 1.29 + } 1.30 + @Override 1.31 + void complete() { 1.32 + Assert.error("Empty deferred context!"); 1.33 + } 1.34 + }; 1.35 } 1.36 1.37 /** shared tree for stuck expressions */ 1.38 @@ -479,12 +489,10 @@ 1.39 1.40 ResultInfo resultInfo; 1.41 InferenceContext inferenceContext; 1.42 - Env<AttrContext> env; 1.43 1.44 public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { 1.45 this.resultInfo = resultInfo; 1.46 this.inferenceContext = deferredAttrContext.inferenceContext; 1.47 - this.env = dt.env.dup(dt.tree, dt.env.info.dup()); 1.48 dt.tree.accept(this); 1.49 dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase); 1.50 return Type.noType; 1.51 @@ -533,18 +541,7 @@ 1.52 } catch (Types.FunctionDescriptorLookupError ex) { 1.53 checkContext.report(null, ex.getDiagnostic()); 1.54 } 1.55 - JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), env, 1.56 - attr.memberReferenceQualifierResult(tree)); 1.57 - ListBuffer<Type> argtypes = ListBuffer.lb(); 1.58 - for (Type t : types.findDescriptorType(pt).getParameterTypes()) { 1.59 - argtypes.append(Type.noType); 1.60 - } 1.61 - JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree); 1.62 - mref2.expr = exprTree; 1.63 - Pair<Symbol, ?> lookupRes = 1.64 - rs.resolveMemberReference(tree, env, mref2, exprTree.type, 1.65 - tree.name, argtypes.toList(), null, true, rs.arityMethodCheck); 1.66 - switch (lookupRes.fst.kind) { 1.67 + switch (tree.sym.kind) { 1.68 //note: as argtypes are erroneous types, type-errors must 1.69 //have been caused by arity mismatch 1.70 case Kinds.ABSENT_MTH: 1.71 @@ -560,17 +557,7 @@ 1.72 } 1.73 1.74 /** an empty deferred attribution context - all methods throw exceptions */ 1.75 - final DeferredAttrContext emptyDeferredAttrContext = 1.76 - new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null, null, null) { 1.77 - @Override 1.78 - void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) { 1.79 - Assert.error("Empty deferred context!"); 1.80 - } 1.81 - @Override 1.82 - void complete() { 1.83 - Assert.error("Empty deferred context!"); 1.84 - } 1.85 - }; 1.86 + final DeferredAttrContext emptyDeferredAttrContext; 1.87 1.88 /** 1.89 * Map a list of types possibly containing one or more deferred types 1.90 @@ -668,12 +655,12 @@ 1.91 if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) { 1.92 return List.nil(); 1.93 } else { 1.94 - return stuckVarsInternal(tree, resultInfo.pt, resultInfo.checkContext.inferenceContext()); 1.95 + return stuckVarsInternal(tree, resultInfo.pt, env, resultInfo.checkContext.inferenceContext()); 1.96 } 1.97 } 1.98 //where 1.99 - private List<Type> stuckVarsInternal(JCTree tree, Type pt, Infer.InferenceContext inferenceContext) { 1.100 - StuckChecker sc = new StuckChecker(pt, inferenceContext); 1.101 + private List<Type> stuckVarsInternal(JCTree tree, Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) { 1.102 + StuckChecker sc = new StuckChecker(pt, env, inferenceContext); 1.103 sc.scan(tree); 1.104 return List.from(sc.stuckVars); 1.105 } 1.106 @@ -753,11 +740,13 @@ 1.107 class StuckChecker extends PolyScanner { 1.108 1.109 Type pt; 1.110 + Env<AttrContext> env; 1.111 Infer.InferenceContext inferenceContext; 1.112 Set<Type> stuckVars = new LinkedHashSet<Type>(); 1.113 1.114 - StuckChecker(Type pt, Infer.InferenceContext inferenceContext) { 1.115 + StuckChecker(Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) { 1.116 this.pt = pt; 1.117 + this.env = env; 1.118 this.inferenceContext = inferenceContext; 1.119 } 1.120 1.121 @@ -791,18 +780,41 @@ 1.122 1.123 Type descType = types.findDescriptorType(pt); 1.124 List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); 1.125 - stuckVars.addAll(freeArgVars); 1.126 + Env<AttrContext> localEnv = env.dup(tree, env.info.dup()); 1.127 + if (freeArgVars.nonEmpty()) { 1.128 + //perform arity-based check 1.129 + JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, 1.130 + attr.memberReferenceQualifierResult(tree)); 1.131 + ListBuffer<Type> argtypes = ListBuffer.lb(); 1.132 + for (Type t : descType.getParameterTypes()) { 1.133 + argtypes.append(Type.noType); 1.134 + } 1.135 + JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree); 1.136 + mref2.expr = exprTree; 1.137 + Pair<Symbol, ReferenceLookupHelper> lookupRes = 1.138 + rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, 1.139 + tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, 1.140 + inferenceContext); 1.141 + Symbol res = tree.sym = lookupRes.fst; 1.142 + if (res.kind >= Kinds.ERRONEOUS || 1.143 + res.type.hasTag(FORALL) || 1.144 + (res.flags() & Flags.VARARGS) != 0 || 1.145 + (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) && 1.146 + exprTree.type.isRaw())) { 1.147 + stuckVars.addAll(freeArgVars); 1.148 + } 1.149 + } 1.150 } 1.151 1.152 void scanLambdaBody(JCLambda lambda, final Type pt) { 1.153 if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { 1.154 - stuckVars.addAll(stuckVarsInternal(lambda.body, pt, inferenceContext)); 1.155 + stuckVars.addAll(stuckVarsInternal(lambda.body, pt, env, inferenceContext)); 1.156 } else { 1.157 LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() { 1.158 @Override 1.159 public void visitReturn(JCReturn tree) { 1.160 if (tree.expr != null) { 1.161 - stuckVars.addAll(stuckVarsInternal(tree.expr, pt, inferenceContext)); 1.162 + stuckVars.addAll(stuckVarsInternal(tree.expr, pt, env, inferenceContext)); 1.163 } 1.164 } 1.165 }; 1.166 @@ -950,12 +962,9 @@ 1.167 site = site.getUpperBound(); 1.168 } 1.169 1.170 - ListBuffer<Type> args = ListBuffer.lb(); 1.171 - for (int i = 0; i < tree.args.length(); i ++) { 1.172 - args.append(Type.noType); 1.173 - } 1.174 + List<Type> args = rs.dummyArgs(tree.args.length()); 1.175 1.176 - Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args.toList(), List.<Type>nil(), MethodResolutionPhase.VARARITY) { 1.177 + Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.<Type>nil(), MethodResolutionPhase.VARARITY) { 1.178 @Override 1.179 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.180 return rec == null ?