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

changeset 1433
4f9853659bf1
parent 1415
01c9d4161882
child 1434
34d1ebaf4645
equal deleted inserted replaced
1432:969c96b980b7 1433:4f9853659bf1
2242 //we will be able to attribute the whole lambda body, regardless of errors; 2242 //we will be able to attribute the whole lambda body, regardless of errors;
2243 //if we are in a 'check' method context, and the lambda is not compatible 2243 //if we are in a 'check' method context, and the lambda is not compatible
2244 //with the target-type, it will be recovered anyway in Attr.checkId 2244 //with the target-type, it will be recovered anyway in Attr.checkId
2245 needsRecovery = false; 2245 needsRecovery = false;
2246 2246
2247 FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
2248 new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) :
2249 new FunctionalReturnContext(resultInfo.checkContext);
2250
2247 ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ? 2251 ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ?
2248 recoveryInfo : 2252 recoveryInfo :
2249 new ResultInfo(VAL, lambdaType.getReturnType(), new LambdaReturnContext(resultInfo.checkContext)); 2253 new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
2250 localEnv.info.returnResult = bodyResultInfo; 2254 localEnv.info.returnResult = bodyResultInfo;
2251 2255
2252 if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { 2256 if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
2253 attribTree(that.getBody(), localEnv, bodyResultInfo); 2257 attribTree(that.getBody(), localEnv, bodyResultInfo);
2254 } else { 2258 } else {
2325 * Lambda/method reference have a special check context that ensures 2329 * Lambda/method reference have a special check context that ensures
2326 * that i.e. a lambda return type is compatible with the expected 2330 * that i.e. a lambda return type is compatible with the expected
2327 * type according to both the inherited context and the assignment 2331 * type according to both the inherited context and the assignment
2328 * context. 2332 * context.
2329 */ 2333 */
2330 class LambdaReturnContext extends Check.NestedCheckContext { 2334 class FunctionalReturnContext extends Check.NestedCheckContext {
2331 public LambdaReturnContext(CheckContext enclosingContext) { 2335
2336 FunctionalReturnContext(CheckContext enclosingContext) {
2332 super(enclosingContext); 2337 super(enclosingContext);
2333 } 2338 }
2334 2339
2335 @Override 2340 @Override
2336 public boolean compatible(Type found, Type req, Warner warn) { 2341 public boolean compatible(Type found, Type req, Warner warn) {
2339 super.compatible(found, req, warn); 2344 super.compatible(found, req, warn);
2340 } 2345 }
2341 @Override 2346 @Override
2342 public void report(DiagnosticPosition pos, JCDiagnostic details) { 2347 public void report(DiagnosticPosition pos, JCDiagnostic details) {
2343 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); 2348 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details));
2349 }
2350 }
2351
2352 class ExpressionLambdaReturnContext extends FunctionalReturnContext {
2353
2354 JCExpression expr;
2355
2356 ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
2357 super(enclosingContext);
2358 this.expr = expr;
2359 }
2360
2361 @Override
2362 public boolean compatible(Type found, Type req, Warner warn) {
2363 //a void return is compatible with an expression statement lambda
2364 return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) ||
2365 super.compatible(found, req, warn);
2344 } 2366 }
2345 } 2367 }
2346 2368
2347 /** 2369 /**
2348 * Lambda compatibility. Check that given return types, thrown types, parameter types 2370 * Lambda compatibility. Check that given return types, thrown types, parameter types
2558 incompatibleReturnType = null; 2580 incompatibleReturnType = null;
2559 } 2581 }
2560 2582
2561 if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) { 2583 if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
2562 if (resType.isErroneous() || 2584 if (resType.isErroneous() ||
2563 new LambdaReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) { 2585 new FunctionalReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
2564 incompatibleReturnType = null; 2586 incompatibleReturnType = null;
2565 } 2587 }
2566 } 2588 }
2567 2589
2568 if (incompatibleReturnType != null) { 2590 if (incompatibleReturnType != null) {

mercurial