langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 19916 5b5f188dbdd4
parent 19914 d86271bd430a
child 19918 3bdf0c6b869c
equal deleted inserted replaced
19915:8a6dae12e4bd 19916:5b5f188dbdd4
  2317         //create an environment for attribution of the lambda expression
  2317         //create an environment for attribution of the lambda expression
  2318         final Env<AttrContext> localEnv = lambdaEnv(that, env);
  2318         final Env<AttrContext> localEnv = lambdaEnv(that, env);
  2319         boolean needsRecovery =
  2319         boolean needsRecovery =
  2320                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
  2320                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
  2321         try {
  2321         try {
  2322             Type target = pt();
  2322             Type currentTarget = pt();
  2323             List<Type> explicitParamTypes = null;
  2323             List<Type> explicitParamTypes = null;
  2324             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
  2324             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
  2325                 //attribute lambda parameters
  2325                 //attribute lambda parameters
  2326                 attribStats(that.params, localEnv);
  2326                 attribStats(that.params, localEnv);
  2327                 explicitParamTypes = TreeInfo.types(that.params);
  2327                 explicitParamTypes = TreeInfo.types(that.params);
  2328                 target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
       
  2329             }
  2328             }
  2330 
  2329 
  2331             Type lambdaType;
  2330             Type lambdaType;
  2332             if (pt() != Type.recoveryType) {
  2331             if (pt() != Type.recoveryType) {
  2333                 target = targetChecker.visit(target, that);
  2332                 /* We need to adjust the target. If the target is an
  2334                 lambdaType = types.findDescriptorType(target);
  2333                  * intersection type, for example: SAM & I1 & I2 ...
       
  2334                  * the target will be updated to SAM
       
  2335                  */
       
  2336                 currentTarget = targetChecker.visit(currentTarget, that);
       
  2337                 if (explicitParamTypes != null) {
       
  2338                     currentTarget = infer.instantiateFunctionalInterface(that,
       
  2339                             currentTarget, explicitParamTypes, resultInfo.checkContext);
       
  2340                 }
       
  2341                 lambdaType = types.findDescriptorType(currentTarget);
  2335             } else {
  2342             } else {
  2336                 target = Type.recoveryType;
  2343                 currentTarget = Type.recoveryType;
  2337                 lambdaType = fallbackDescriptorType(that);
  2344                 lambdaType = fallbackDescriptorType(that);
  2338             }
  2345             }
  2339 
  2346 
  2340             setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext);
  2347             setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
  2341 
  2348 
  2342             if (lambdaType.hasTag(FORALL)) {
  2349             if (lambdaType.hasTag(FORALL)) {
  2343                 //lambda expression target desc cannot be a generic method
  2350                 //lambda expression target desc cannot be a generic method
  2344                 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
  2351                 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
  2345                         lambdaType, kindName(target.tsym), target.tsym));
  2352                         lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
  2346                 result = that.type = types.createErrorType(pt());
  2353                 result = that.type = types.createErrorType(pt());
  2347                 return;
  2354                 return;
  2348             }
  2355             }
  2349 
  2356 
  2350             if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
  2357             if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
  2374                 //attribute lambda parameters
  2381                 //attribute lambda parameters
  2375                 attribStats(that.params, localEnv);
  2382                 attribStats(that.params, localEnv);
  2376 
  2383 
  2377                 if (arityMismatch) {
  2384                 if (arityMismatch) {
  2378                     resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
  2385                     resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
  2379                         result = that.type = types.createErrorType(target);
  2386                         result = that.type = types.createErrorType(currentTarget);
  2380                         return;
  2387                         return;
  2381                 }
  2388                 }
  2382             }
  2389             }
  2383 
  2390 
  2384             //from this point on, no recovery is needed; if we are in assignment context
  2391             //from this point on, no recovery is needed; if we are in assignment context
  2401             } else {
  2408             } else {
  2402                 JCBlock body = (JCBlock)that.body;
  2409                 JCBlock body = (JCBlock)that.body;
  2403                 attribStats(body.stats, localEnv);
  2410                 attribStats(body.stats, localEnv);
  2404             }
  2411             }
  2405 
  2412 
  2406             result = check(that, target, VAL, resultInfo);
  2413             result = check(that, currentTarget, VAL, resultInfo);
  2407 
  2414 
  2408             boolean isSpeculativeRound =
  2415             boolean isSpeculativeRound =
  2409                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
  2416                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
  2410 
  2417 
  2411             preFlow(that);
  2418             preFlow(that);
  2412             flow.analyzeLambda(env, that, make, isSpeculativeRound);
  2419             flow.analyzeLambda(env, that, make, isSpeculativeRound);
  2413 
  2420 
  2414             checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
  2421             checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
  2415 
  2422 
  2416             if (!isSpeculativeRound) {
  2423             if (!isSpeculativeRound) {
  2417                 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target);
  2424                 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
  2418             }
  2425             }
  2419             result = check(that, target, VAL, resultInfo);
  2426             result = check(that, currentTarget, VAL, resultInfo);
  2420         } catch (Types.FunctionDescriptorLookupError ex) {
  2427         } catch (Types.FunctionDescriptorLookupError ex) {
  2421             JCDiagnostic cause = ex.getDiagnostic();
  2428             JCDiagnostic cause = ex.getDiagnostic();
  2422             resultInfo.checkContext.report(that, cause);
  2429             resultInfo.checkContext.report(that, cause);
  2423             result = that.type = types.createErrorType(pt());
  2430             result = that.type = types.createErrorType(pt());
  2424             return;
  2431             return;