2325 |
2325 |
2326 Type lambdaType; |
2326 Type lambdaType; |
2327 if (pt() != Type.recoveryType) { |
2327 if (pt() != Type.recoveryType) { |
2328 target = targetChecker.visit(target, that); |
2328 target = targetChecker.visit(target, that); |
2329 lambdaType = types.findDescriptorType(target); |
2329 lambdaType = types.findDescriptorType(target); |
|
2330 chk.checkFunctionalInterface(that, target); |
2330 } else { |
2331 } else { |
2331 target = Type.recoveryType; |
2332 target = Type.recoveryType; |
2332 lambdaType = fallbackDescriptorType(that); |
2333 lambdaType = fallbackDescriptorType(that); |
2333 } |
2334 } |
2334 |
2335 |
2335 setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); |
2336 setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext()); |
2336 |
2337 |
2337 if (lambdaType.hasTag(FORALL)) { |
2338 if (lambdaType.hasTag(FORALL)) { |
2338 //lambda expression target desc cannot be a generic method |
2339 //lambda expression target desc cannot be a generic method |
2339 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2340 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2340 lambdaType, kindName(target.tsym), target.tsym)); |
2341 lambdaType, kindName(target.tsym), target.tsym)); |
2672 Type target; |
2673 Type target; |
2673 Type desc; |
2674 Type desc; |
2674 if (pt() != Type.recoveryType) { |
2675 if (pt() != Type.recoveryType) { |
2675 target = targetChecker.visit(pt(), that); |
2676 target = targetChecker.visit(pt(), that); |
2676 desc = types.findDescriptorType(target); |
2677 desc = types.findDescriptorType(target); |
|
2678 chk.checkFunctionalInterface(that, target); |
2677 } else { |
2679 } else { |
2678 target = Type.recoveryType; |
2680 target = Type.recoveryType; |
2679 desc = fallbackDescriptorType(that); |
2681 desc = fallbackDescriptorType(that); |
2680 } |
2682 } |
2681 |
2683 |
2682 setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext); |
2684 setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext()); |
2683 List<Type> argtypes = desc.getParameterTypes(); |
2685 List<Type> argtypes = desc.getParameterTypes(); |
2684 |
2686 |
2685 Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = |
2687 Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = |
2686 rs.resolveMemberReference(that.pos(), localEnv, that, |
2688 rs.resolveMemberReference(that.pos(), localEnv, that, |
2687 that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck); |
2689 that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck); |
2879 /** |
2881 /** |
2880 * Set functional type info on the underlying AST. Note: as the target descriptor |
2882 * Set functional type info on the underlying AST. Note: as the target descriptor |
2881 * might contain inference variables, we might need to register an hook in the |
2883 * might contain inference variables, we might need to register an hook in the |
2882 * current inference context. |
2884 * current inference context. |
2883 */ |
2885 */ |
2884 private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr, |
2886 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, |
2885 final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) { |
2887 final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) { |
2886 if (checkContext.inferenceContext().free(descriptorType)) { |
2888 if (inferenceContext.free(descriptorType)) { |
2887 checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2889 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2888 public void typesInferred(InferenceContext inferenceContext) { |
2890 public void typesInferred(InferenceContext inferenceContext) { |
2889 setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType), |
2891 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), |
2890 inferenceContext.asInstType(primaryTarget), checkContext); |
2892 inferenceContext.asInstType(primaryTarget), inferenceContext); |
2891 } |
2893 } |
2892 }); |
2894 }); |
2893 } else { |
2895 } else { |
2894 ListBuffer<Type> targets = ListBuffer.lb(); |
2896 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2895 if (pt.hasTag(CLASS)) { |
2897 if (pt.hasTag(CLASS)) { |
2896 if (pt.isCompound()) { |
2898 if (pt.isCompound()) { |
2897 targets.append(types.removeWildcards(primaryTarget)); //this goes first |
2899 targets.append(primaryTarget.tsym); //this goes first |
2898 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { |
2900 for (Type t : ((IntersectionClassType)pt()).interfaces_field) { |
2899 if (t != primaryTarget) { |
2901 if (t != primaryTarget) { |
2900 targets.append(types.removeWildcards(t)); |
2902 targets.append(t.tsym); |
2901 } |
2903 } |
2902 } |
2904 } |
2903 } else { |
2905 } else { |
2904 targets.append(types.removeWildcards(primaryTarget)); |
2906 targets.append(pt.tsym); |
2905 } |
2907 } |
2906 } |
2908 } |
2907 fExpr.targets = targets.toList(); |
2909 fExpr.targets = targets.toList(); |
2908 if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && |
2910 fExpr.descriptorType = descriptorType; |
2909 pt != Type.recoveryType) { |
|
2910 //check that functional interface class is well-formed |
|
2911 ClassSymbol csym = types.makeFunctionalInterfaceClass(env, |
|
2912 names.empty, List.of(fExpr.targets.head), ABSTRACT); |
|
2913 chk.checkImplementations(env.tree, csym, csym); |
|
2914 } |
|
2915 } |
2911 } |
2916 } |
2912 } |
2917 |
2913 |
2918 public void visitParens(JCParens tree) { |
2914 public void visitParens(JCParens tree) { |
2919 Type owntype = attribTree(tree.expr, env, resultInfo); |
2915 Type owntype = attribTree(tree.expr, env, resultInfo); |
4576 public void visitReference(JCMemberReference that) { |
4575 public void visitReference(JCMemberReference that) { |
4577 super.visitReference(that); |
4576 super.visitReference(that); |
4578 if (that.sym == null) { |
4577 if (that.sym == null) { |
4579 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); |
4578 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); |
4580 } |
4579 } |
|
4580 if (that.descriptorType == null) { |
|
4581 that.descriptorType = syms.unknownType; |
|
4582 } |
4581 if (that.targets == null) { |
4583 if (that.targets == null) { |
4582 that.targets = List.nil(); |
4584 that.targets = List.nil(); |
4583 } |
4585 } |
4584 } |
4586 } |
4585 } |
4587 } |