2328 |
2328 |
2329 Type lambdaType; |
2329 Type lambdaType; |
2330 if (pt() != Type.recoveryType) { |
2330 if (pt() != Type.recoveryType) { |
2331 target = targetChecker.visit(target, that); |
2331 target = targetChecker.visit(target, that); |
2332 lambdaType = types.findDescriptorType(target); |
2332 lambdaType = types.findDescriptorType(target); |
2333 chk.checkFunctionalInterface(that, target); |
|
2334 } else { |
2333 } else { |
2335 target = Type.recoveryType; |
2334 target = Type.recoveryType; |
2336 lambdaType = fallbackDescriptorType(that); |
2335 lambdaType = fallbackDescriptorType(that); |
2337 } |
2336 } |
2338 |
2337 |
2339 setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext()); |
2338 setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); |
2340 |
2339 |
2341 if (lambdaType.hasTag(FORALL)) { |
2340 if (lambdaType.hasTag(FORALL)) { |
2342 //lambda expression target desc cannot be a generic method |
2341 //lambda expression target desc cannot be a generic method |
2343 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2342 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2344 lambdaType, kindName(target.tsym), target.tsym)); |
2343 lambdaType, kindName(target.tsym), target.tsym)); |
2713 Type target; |
2712 Type target; |
2714 Type desc; |
2713 Type desc; |
2715 if (pt() != Type.recoveryType) { |
2714 if (pt() != Type.recoveryType) { |
2716 target = targetChecker.visit(pt(), that); |
2715 target = targetChecker.visit(pt(), that); |
2717 desc = types.findDescriptorType(target); |
2716 desc = types.findDescriptorType(target); |
2718 chk.checkFunctionalInterface(that, target); |
|
2719 } else { |
2717 } else { |
2720 target = Type.recoveryType; |
2718 target = Type.recoveryType; |
2721 desc = fallbackDescriptorType(that); |
2719 desc = fallbackDescriptorType(that); |
2722 } |
2720 } |
2723 |
2721 |
2724 setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext()); |
2722 setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext); |
2725 List<Type> argtypes = desc.getParameterTypes(); |
2723 List<Type> argtypes = desc.getParameterTypes(); |
2726 Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck; |
2724 Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck; |
2727 |
2725 |
2728 if (resultInfo.checkContext.inferenceContext().free(argtypes)) { |
2726 if (resultInfo.checkContext.inferenceContext().free(argtypes)) { |
2729 referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); |
2727 referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); |
2939 /** |
2937 /** |
2940 * Set functional type info on the underlying AST. Note: as the target descriptor |
2938 * Set functional type info on the underlying AST. Note: as the target descriptor |
2941 * might contain inference variables, we might need to register an hook in the |
2939 * might contain inference variables, we might need to register an hook in the |
2942 * current inference context. |
2940 * current inference context. |
2943 */ |
2941 */ |
2944 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, |
2942 private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr, |
2945 final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) { |
2943 final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) { |
2946 if (inferenceContext.free(descriptorType)) { |
2944 if (checkContext.inferenceContext().free(descriptorType)) { |
2947 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2945 checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2948 public void typesInferred(InferenceContext inferenceContext) { |
2946 public void typesInferred(InferenceContext inferenceContext) { |
2949 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), |
2947 setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType), |
2950 inferenceContext.asInstType(primaryTarget), inferenceContext); |
2948 inferenceContext.asInstType(primaryTarget), checkContext); |
2951 } |
2949 } |
2952 }); |
2950 }); |
2953 } else { |
2951 } else { |
2954 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2952 ListBuffer<Type> targets = ListBuffer.lb(); |
2955 if (pt.hasTag(CLASS)) { |
2953 if (pt.hasTag(CLASS)) { |
2956 if (pt.isCompound()) { |
2954 if (pt.isCompound()) { |
2957 targets.append(primaryTarget.tsym); //this goes first |
2955 targets.append(types.removeWildcards(primaryTarget)); //this goes first |
2958 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { |
2956 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { |
2959 if (t != primaryTarget) { |
2957 if (t != primaryTarget) { |
2960 targets.append(t.tsym); |
2958 targets.append(types.removeWildcards(t)); |
2961 } |
2959 } |
2962 } |
2960 } |
2963 } else { |
2961 } else { |
2964 targets.append(pt.tsym); |
2962 targets.append(types.removeWildcards(primaryTarget)); |
2965 } |
2963 } |
2966 } |
2964 } |
2967 fExpr.targets = targets.toList(); |
2965 fExpr.targets = targets.toList(); |
2968 fExpr.descriptorType = descriptorType; |
2966 if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && |
|
2967 pt != Type.recoveryType) { |
|
2968 //check that functional interface class is well-formed |
|
2969 ClassSymbol csym = types.makeFunctionalInterfaceClass(env, |
|
2970 names.empty, List.of(fExpr.targets.head), ABSTRACT); |
|
2971 chk.checkImplementations(env.tree, csym, csym); |
|
2972 } |
2969 } |
2973 } |
2970 } |
2974 } |
2971 |
2975 |
2972 public void visitParens(JCParens tree) { |
2976 public void visitParens(JCParens tree) { |
2973 Type owntype = attribTree(tree.expr, env, resultInfo); |
2977 Type owntype = attribTree(tree.expr, env, resultInfo); |
4656 public void visitReference(JCMemberReference that) { |
4657 public void visitReference(JCMemberReference that) { |
4657 super.visitReference(that); |
4658 super.visitReference(that); |
4658 if (that.sym == null) { |
4659 if (that.sym == null) { |
4659 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); |
4660 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); |
4660 } |
4661 } |
4661 if (that.descriptorType == null) { |
|
4662 that.descriptorType = syms.unknownType; |
|
4663 } |
|
4664 if (that.targets == null) { |
4662 if (that.targets == null) { |
4665 that.targets = List.nil(); |
4663 that.targets = List.nil(); |
4666 } |
4664 } |
4667 } |
4665 } |
4668 } |
4666 } |