41 import com.sun.tools.javac.code.Symbol.*; |
41 import com.sun.tools.javac.code.Symbol.*; |
42 import com.sun.tools.javac.code.Type.*; |
42 import com.sun.tools.javac.code.Type.*; |
43 import com.sun.tools.javac.comp.Check.CheckContext; |
43 import com.sun.tools.javac.comp.Check.CheckContext; |
44 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; |
44 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; |
45 import com.sun.tools.javac.comp.Infer.InferenceContext; |
45 import com.sun.tools.javac.comp.Infer.InferenceContext; |
46 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; |
46 import com.sun.tools.javac.comp.Infer.FreeTypeListener; |
47 import com.sun.tools.javac.jvm.*; |
47 import com.sun.tools.javac.jvm.*; |
48 import com.sun.tools.javac.tree.*; |
48 import com.sun.tools.javac.tree.*; |
49 import com.sun.tools.javac.tree.JCTree.*; |
49 import com.sun.tools.javac.tree.JCTree.*; |
50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; |
50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; |
51 import com.sun.tools.javac.util.*; |
51 import com.sun.tools.javac.util.*; |
242 if (inferenceContext.free(found)) { |
242 if (inferenceContext.free(found)) { |
243 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { |
243 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { |
244 @Override |
244 @Override |
245 public void typesInferred(InferenceContext inferenceContext) { |
245 public void typesInferred(InferenceContext inferenceContext) { |
246 ResultInfo pendingResult = |
246 ResultInfo pendingResult = |
247 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types)); |
247 resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); |
248 check(tree, inferenceContext.asInstType(found, types), ownkind, pendingResult); |
248 check(tree, inferenceContext.asInstType(found), ownkind, pendingResult); |
249 } |
249 } |
250 }); |
250 }); |
251 return tree.type = resultInfo.pt; |
251 return tree.type = resultInfo.pt; |
252 } else { |
252 } else { |
253 if ((ownkind & ~resultInfo.pkind) == 0) { |
253 if ((ownkind & ~resultInfo.pkind) == 0) { |
2413 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final List<Type> ts) { |
2413 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final List<Type> ts) { |
2414 if (inferenceContext.free(ts)) { |
2414 if (inferenceContext.free(ts)) { |
2415 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() { |
2415 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() { |
2416 @Override |
2416 @Override |
2417 public void typesInferred(InferenceContext inferenceContext) { |
2417 public void typesInferred(InferenceContext inferenceContext) { |
2418 checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts, types)); |
2418 checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts)); |
2419 } |
2419 } |
2420 }); |
2420 }); |
2421 } else { |
2421 } else { |
2422 for (Type t : ts) { |
2422 for (Type t : ts) { |
2423 rs.checkAccessibleType(env, t); |
2423 rs.checkAccessibleType(env, t); |
2438 } |
2438 } |
2439 |
2439 |
2440 @Override |
2440 @Override |
2441 public boolean compatible(Type found, Type req, Warner warn) { |
2441 public boolean compatible(Type found, Type req, Warner warn) { |
2442 //return type must be compatible in both current context and assignment context |
2442 //return type must be compatible in both current context and assignment context |
2443 return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn); |
2443 return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn); |
2444 } |
2444 } |
2445 |
2445 |
2446 @Override |
2446 @Override |
2447 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2447 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2448 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
2448 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
2473 * types must be compatible with the return type of the expected descriptor; |
2473 * types must be compatible with the return type of the expected descriptor; |
2474 * (iii) thrown types must be 'included' in the thrown types list of the expected |
2474 * (iii) thrown types must be 'included' in the thrown types list of the expected |
2475 * descriptor. |
2475 * descriptor. |
2476 */ |
2476 */ |
2477 private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) { |
2477 private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) { |
2478 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types); |
2478 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); |
2479 |
2479 |
2480 //return values have already been checked - but if lambda has no return |
2480 //return values have already been checked - but if lambda has no return |
2481 //values, we must ensure that void/value compatibility is correct; |
2481 //values, we must ensure that void/value compatibility is correct; |
2482 //this amounts at checking that, if a lambda body can complete normally, |
2482 //this amounts at checking that, if a lambda body can complete normally, |
2483 //the descriptor's return type must be void |
2483 //the descriptor's return type must be void |
2485 !returnType.hasTag(VOID) && returnType != Type.recoveryType) { |
2485 !returnType.hasTag(VOID) && returnType != Type.recoveryType) { |
2486 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", |
2486 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", |
2487 diags.fragment("missing.ret.val", returnType))); |
2487 diags.fragment("missing.ret.val", returnType))); |
2488 } |
2488 } |
2489 |
2489 |
2490 List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes(), types); |
2490 List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes()); |
2491 if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { |
2491 if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { |
2492 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); |
2492 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); |
2493 } |
2493 } |
2494 |
2494 |
2495 if (!speculativeAttr) { |
2495 if (!speculativeAttr) { |
2496 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types); |
2496 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); |
2497 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) { |
2497 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) { |
2498 log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes); |
2498 log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes); |
2499 } |
2499 } |
2500 } |
2500 } |
2501 } |
2501 } |
2678 } |
2678 } |
2679 } |
2679 } |
2680 |
2680 |
2681 @SuppressWarnings("fallthrough") |
2681 @SuppressWarnings("fallthrough") |
2682 void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { |
2682 void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { |
2683 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types); |
2683 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); |
2684 |
2684 |
2685 Type resType; |
2685 Type resType; |
2686 switch (tree.getMode()) { |
2686 switch (tree.getMode()) { |
2687 case NEW: |
2687 case NEW: |
2688 if (!tree.expr.type.isRaw()) { |
2688 if (!tree.expr.type.isRaw()) { |
2710 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref", |
2710 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref", |
2711 diags.fragment("inconvertible.types", resType, descriptor.getReturnType()))); |
2711 diags.fragment("inconvertible.types", resType, descriptor.getReturnType()))); |
2712 } |
2712 } |
2713 |
2713 |
2714 if (!speculativeAttr) { |
2714 if (!speculativeAttr) { |
2715 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types); |
2715 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); |
2716 if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { |
2716 if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { |
2717 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); |
2717 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); |
2718 } |
2718 } |
2719 } |
2719 } |
2720 } |
2720 } |
2726 */ |
2726 */ |
2727 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) { |
2727 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) { |
2728 if (inferenceContext.free(descriptorType)) { |
2728 if (inferenceContext.free(descriptorType)) { |
2729 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2729 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2730 public void typesInferred(InferenceContext inferenceContext) { |
2730 public void typesInferred(InferenceContext inferenceContext) { |
2731 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext); |
2731 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext); |
2732 } |
2732 } |
2733 }); |
2733 }); |
2734 } else { |
2734 } else { |
2735 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2735 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2736 if (pt.hasTag(CLASS)) { |
2736 if (pt.hasTag(CLASS)) { |