src/share/classes/com/sun/tools/javac/comp/Attr.java

changeset 3001
dcd12fa5b58a
parent 2904
14891e981af0
child 3002
0caab0d65a04
equal deleted inserted replaced
3000:4044eb07194d 3001:dcd12fa5b58a
154 unknownExprInfo = new ResultInfo(VAL, Type.noType); 154 unknownExprInfo = new ResultInfo(VAL, Type.noType);
155 unknownAnyPolyInfo = new ResultInfo(VAL, Infer.anyPoly); 155 unknownAnyPolyInfo = new ResultInfo(VAL, Infer.anyPoly);
156 unknownTypeInfo = new ResultInfo(TYP, Type.noType); 156 unknownTypeInfo = new ResultInfo(TYP, Type.noType);
157 unknownTypeExprInfo = new ResultInfo(Kinds.TYP | Kinds.VAL, Type.noType); 157 unknownTypeExprInfo = new ResultInfo(Kinds.TYP | Kinds.VAL, Type.noType);
158 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext); 158 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
159
160 noCheckTree = make.at(-1).Skip();
159 } 161 }
160 162
161 /** Switch: relax some constraints for retrofit mode. 163 /** Switch: relax some constraints for retrofit mode.
162 */ 164 */
163 boolean relax; 165 boolean relax;
251 * @param resultInfo The expected result of the tree 253 * @param resultInfo The expected result of the tree
252 */ 254 */
253 Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) { 255 Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
254 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); 256 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
255 Type owntype; 257 Type owntype;
256 if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { 258 boolean shouldCheck = !found.hasTag(ERROR) &&
257 if ((ownkind & ~resultInfo.pkind) != 0) { 259 !resultInfo.pt.hasTag(METHOD) &&
258 log.error(tree.pos(), "unexpected.type", 260 !resultInfo.pt.hasTag(FORALL);
261 if (shouldCheck && (ownkind & ~resultInfo.pkind) != 0) {
262 log.error(tree.pos(), "unexpected.type",
259 kindNames(resultInfo.pkind), 263 kindNames(resultInfo.pkind),
260 kindName(ownkind)); 264 kindName(ownkind));
261 owntype = types.createErrorType(found); 265 owntype = types.createErrorType(found);
262 } else if (allowPoly && inferenceContext.free(found)) { 266 } else if (allowPoly && inferenceContext.free(found)) {
263 //delay the check if there are inference variables in the found type 267 //delay the check if there are inference variables in the found type
264 //this means we are dealing with a partially inferred poly expression 268 //this means we are dealing with a partially inferred poly expression
265 owntype = resultInfo.pt; 269 owntype = shouldCheck ? resultInfo.pt : found;
266 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { 270 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
267 @Override 271 @Override
268 public void typesInferred(InferenceContext inferenceContext) { 272 public void typesInferred(InferenceContext inferenceContext) {
269 ResultInfo pendingResult = 273 ResultInfo pendingResult =
270 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); 274 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
271 check(tree, inferenceContext.asInstType(found), ownkind, pendingResult); 275 check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
272 } 276 }
273 }); 277 });
274 } else {
275 owntype = resultInfo.check(tree, found);
276 }
277 } else { 278 } else {
278 owntype = found; 279 owntype = shouldCheck ?
279 } 280 resultInfo.check(tree, found) :
280 tree.type = owntype; 281 found;
282 }
283 if (tree != noCheckTree) {
284 tree.type = owntype;
285 }
281 return owntype; 286 return owntype;
282 } 287 }
283 288
284 /** Is given blank final variable assignable, i.e. in a scope where it 289 /** Is given blank final variable assignable, i.e. in a scope where it
285 * may be assigned to even though it is final? 290 * may be assigned to even though it is final?
547 ResultInfo resultInfo; 552 ResultInfo resultInfo;
548 553
549 /** Visitor result: the computed type. 554 /** Visitor result: the computed type.
550 */ 555 */
551 Type result; 556 Type result;
557
558 /** Synthetic tree to be used during 'fake' checks.
559 */
560 JCTree noCheckTree;
552 561
553 /** Visitor method: attribute a tree, catching any completion failure 562 /** Visitor method: attribute a tree, catching any completion failure
554 * exceptions. Return the tree's type. 563 * exceptions. Return the tree's type.
555 * 564 *
556 * @param tree The tree to be visited. 565 * @param tree The tree to be visited.
2041 enclosingContext.report(tree.clazz, 2050 enclosingContext.report(tree.clazz,
2042 diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details)); 2051 diags.fragment("cant.apply.diamond.1", diags.fragment("diamond", csym), details));
2043 } 2052 }
2044 }); 2053 });
2045 Type constructorType = tree.constructorType = types.createErrorType(clazztype); 2054 Type constructorType = tree.constructorType = types.createErrorType(clazztype);
2046 constructorType = checkId(tree, site, 2055 constructorType = checkId(noCheckTree, site,
2047 constructor, 2056 constructor,
2048 diamondEnv, 2057 diamondEnv,
2049 diamondResult); 2058 diamondResult);
2050 2059
2051 tree.clazz.type = types.createErrorType(clazztype); 2060 tree.clazz.type = types.createErrorType(clazztype);
2067 rsEnv.info.selectSuper = cdef != null; 2076 rsEnv.info.selectSuper = cdef != null;
2068 rsEnv.info.pendingResolutionPhase = null; 2077 rsEnv.info.pendingResolutionPhase = null;
2069 tree.constructor = rs.resolveConstructor( 2078 tree.constructor = rs.resolveConstructor(
2070 tree.pos(), rsEnv, clazztype, argtypes, typeargtypes); 2079 tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
2071 if (cdef == null) { //do not check twice! 2080 if (cdef == null) { //do not check twice!
2072 tree.constructorType = checkId(tree, 2081 tree.constructorType = checkId(noCheckTree,
2073 clazztype, 2082 clazztype,
2074 tree.constructor, 2083 tree.constructor,
2075 rsEnv, 2084 rsEnv,
2076 new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); 2085 new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
2077 if (rsEnv.info.lastResolveVarargs()) 2086 if (rsEnv.info.lastResolveVarargs())
2148 clazztype = cdef.sym.type; 2157 clazztype = cdef.sym.type;
2149 Symbol sym = tree.constructor = rs.resolveConstructor( 2158 Symbol sym = tree.constructor = rs.resolveConstructor(
2150 tree.pos(), localEnv, clazztype, argtypes, typeargtypes); 2159 tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
2151 Assert.check(sym.kind < AMBIGUOUS); 2160 Assert.check(sym.kind < AMBIGUOUS);
2152 tree.constructor = sym; 2161 tree.constructor = sym;
2153 tree.constructorType = checkId(tree, 2162 tree.constructorType = checkId(noCheckTree,
2154 clazztype, 2163 clazztype,
2155 tree.constructor, 2164 tree.constructor,
2156 localEnv, 2165 localEnv,
2157 new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); 2166 new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
2158 } 2167 }
2159 2168
2160 if (tree.constructor != null && tree.constructor.kind == MTH) 2169 if (tree.constructor != null && tree.constructor.kind == MTH)
2161 owntype = clazztype; 2170 owntype = clazztype;
2162 } 2171 }
2163 result = check(tree, owntype, VAL, resultInfo); 2172 result = check(tree, owntype, VAL, resultInfo);
2173 InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
2174 if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) {
2175 //we need to wait for inference to finish and then replace inference vars in the constructor type
2176 inferenceContext.addFreeTypeListener(List.of(tree.constructorType),
2177 new FreeTypeListener() {
2178 @Override
2179 public void typesInferred(InferenceContext instantiatedContext) {
2180 tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
2181 }
2182 });
2183 }
2164 chk.validate(tree.typeargs, localEnv); 2184 chk.validate(tree.typeargs, localEnv);
2165 } 2185 }
2166 //where 2186 //where
2167 void findDiamond(Env<AttrContext> env, JCNewClass tree, Type clazztype) { 2187 void findDiamond(Env<AttrContext> env, JCNewClass tree, Type clazztype) {
2168 JCTypeApply ta = (JCTypeApply)tree.clazz; 2188 JCTypeApply ta = (JCTypeApply)tree.clazz;
2386 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; 2406 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
2387 2407
2388 preFlow(that); 2408 preFlow(that);
2389 flow.analyzeLambda(env, that, make, isSpeculativeRound); 2409 flow.analyzeLambda(env, that, make, isSpeculativeRound);
2390 2410
2411 that.type = currentTarget; //avoids recovery at this stage
2391 checkLambdaCompatible(that, lambdaType, resultInfo.checkContext); 2412 checkLambdaCompatible(that, lambdaType, resultInfo.checkContext);
2392 2413
2393 if (!isSpeculativeRound) { 2414 if (!isSpeculativeRound) {
2394 //add thrown types as bounds to the thrown types free variables if needed: 2415 //add thrown types as bounds to the thrown types free variables if needed:
2395 if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) { 2416 if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) {
2824 resultInfo.dup(newMethodTemplate( 2845 resultInfo.dup(newMethodTemplate(
2825 desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(), 2846 desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
2826 that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes), 2847 that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
2827 new FunctionalReturnContext(resultInfo.checkContext)); 2848 new FunctionalReturnContext(resultInfo.checkContext));
2828 2849
2829 Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo); 2850 Type refType = checkId(noCheckTree, lookupHelper.site, refSym, localEnv, checkInfo);
2830 2851
2831 if (that.kind.isUnbound() && 2852 if (that.kind.isUnbound() &&
2832 resultInfo.checkContext.inferenceContext().free(argtypes.head)) { 2853 resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
2833 //re-generate inference constraints for unbound receiver 2854 //re-generate inference constraints for unbound receiver
2834 if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) { 2855 if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) {
2846 2867
2847 //go ahead with standard method reference compatibility check - note that param check 2868 //go ahead with standard method reference compatibility check - note that param check
2848 //is a no-op (as this has been taken care during method applicability) 2869 //is a no-op (as this has been taken care during method applicability)
2849 boolean isSpeculativeRound = 2870 boolean isSpeculativeRound =
2850 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; 2871 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
2872
2873 that.type = currentTarget; //avoids recovery at this stage
2851 checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound); 2874 checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
2852 if (!isSpeculativeRound) { 2875 if (!isSpeculativeRound) {
2853 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget); 2876 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget);
2854 } 2877 }
2855 result = check(that, currentTarget, VAL, resultInfo); 2878 result = check(that, currentTarget, VAL, resultInfo);
3966 all_multicatchTypes.appendList(multicatchTypes); 3989 all_multicatchTypes.appendList(multicatchTypes);
3967 } 3990 }
3968 all_multicatchTypes.append(ctype); 3991 all_multicatchTypes.append(ctype);
3969 } 3992 }
3970 } 3993 }
3971 Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo); 3994 Type t = check(noCheckTree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
3972 if (t.hasTag(CLASS)) { 3995 if (t.hasTag(CLASS)) {
3973 List<Type> alternatives = 3996 List<Type> alternatives =
3974 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList(); 3997 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
3975 t = new UnionClassType((ClassType) t, alternatives); 3998 t = new UnionClassType((ClassType) t, alternatives);
3976 } 3999 }

mercurial