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) { |
764 |
764 |
765 Lint prevLint = chk.setLint(env.info.lint); |
765 Lint prevLint = chk.setLint(env.info.lint); |
766 JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); |
766 JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); |
767 |
767 |
768 try { |
768 try { |
|
769 memberEnter.typeAnnotate(initializer, env, env.info.enclVar); |
|
770 annotate.flush(); |
769 Type itype = attribExpr(initializer, env, type); |
771 Type itype = attribExpr(initializer, env, type); |
770 if (itype.constValue() != null) |
772 if (itype.constValue() != null) |
771 return coerce(itype, type).constValue(); |
773 return coerce(itype, type).constValue(); |
772 else |
774 else |
773 return null; |
775 return null; |
1097 // let the owner of the environment be a freshly |
1099 // let the owner of the environment be a freshly |
1098 // created BLOCK-method. |
1100 // created BLOCK-method. |
1099 Env<AttrContext> localEnv = |
1101 Env<AttrContext> localEnv = |
1100 env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); |
1102 env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); |
1101 localEnv.info.scope.owner = |
1103 localEnv.info.scope.owner = |
1102 new MethodSymbol(tree.flags | BLOCK, names.empty, null, |
1104 new MethodSymbol(tree.flags | BLOCK | |
1103 env.info.scope.owner); |
1105 env.info.scope.owner.flags() & STRICTFP, names.empty, null, |
|
1106 env.info.scope.owner); |
1104 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; |
1107 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; |
1105 |
1108 |
1106 // Attribute all type annotations in the block |
1109 // Attribute all type annotations in the block |
1107 memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner); |
1110 memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner); |
1108 annotate.flush(); |
1111 annotate.flush(); |
2413 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final List<Type> ts) { |
2416 private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final List<Type> ts) { |
2414 if (inferenceContext.free(ts)) { |
2417 if (inferenceContext.free(ts)) { |
2415 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() { |
2418 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() { |
2416 @Override |
2419 @Override |
2417 public void typesInferred(InferenceContext inferenceContext) { |
2420 public void typesInferred(InferenceContext inferenceContext) { |
2418 checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts, types)); |
2421 checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts)); |
2419 } |
2422 } |
2420 }); |
2423 }); |
2421 } else { |
2424 } else { |
2422 for (Type t : ts) { |
2425 for (Type t : ts) { |
2423 rs.checkAccessibleType(env, t); |
2426 rs.checkAccessibleType(env, t); |
2438 } |
2441 } |
2439 |
2442 |
2440 @Override |
2443 @Override |
2441 public boolean compatible(Type found, Type req, Warner warn) { |
2444 public boolean compatible(Type found, Type req, Warner warn) { |
2442 //return type must be compatible in both current context and assignment context |
2445 //return type must be compatible in both current context and assignment context |
2443 return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn); |
2446 return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn); |
2444 } |
2447 } |
2445 |
2448 |
2446 @Override |
2449 @Override |
2447 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2450 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2448 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
2451 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
2473 * types must be compatible with the return type of the expected descriptor; |
2476 * 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 |
2477 * (iii) thrown types must be 'included' in the thrown types list of the expected |
2475 * descriptor. |
2478 * descriptor. |
2476 */ |
2479 */ |
2477 private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) { |
2480 private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) { |
2478 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types); |
2481 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); |
2479 |
2482 |
2480 //return values have already been checked - but if lambda has no return |
2483 //return values have already been checked - but if lambda has no return |
2481 //values, we must ensure that void/value compatibility is correct; |
2484 //values, we must ensure that void/value compatibility is correct; |
2482 //this amounts at checking that, if a lambda body can complete normally, |
2485 //this amounts at checking that, if a lambda body can complete normally, |
2483 //the descriptor's return type must be void |
2486 //the descriptor's return type must be void |
2485 !returnType.hasTag(VOID) && returnType != Type.recoveryType) { |
2488 !returnType.hasTag(VOID) && returnType != Type.recoveryType) { |
2486 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", |
2489 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda", |
2487 diags.fragment("missing.ret.val", returnType))); |
2490 diags.fragment("missing.ret.val", returnType))); |
2488 } |
2491 } |
2489 |
2492 |
2490 List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes(), types); |
2493 List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes()); |
2491 if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { |
2494 if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { |
2492 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); |
2495 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); |
2493 } |
2496 } |
2494 |
2497 |
2495 if (!speculativeAttr) { |
2498 if (!speculativeAttr) { |
2496 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types); |
2499 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); |
2497 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) { |
2500 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) { |
2498 log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes); |
2501 log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes); |
2499 } |
2502 } |
2500 } |
2503 } |
2501 } |
2504 } |
2536 exprType = chk.checkConstructorRefType(that.expr, exprType); |
2539 exprType = chk.checkConstructorRefType(that.expr, exprType); |
2537 } |
2540 } |
2538 |
2541 |
2539 if (exprType.isErroneous()) { |
2542 if (exprType.isErroneous()) { |
2540 //if the qualifier expression contains problems, |
2543 //if the qualifier expression contains problems, |
2541 //give up atttribution of method reference |
2544 //give up attribution of method reference |
2542 result = that.type = exprType; |
2545 result = that.type = exprType; |
2543 return; |
2546 return; |
2544 } |
2547 } |
2545 |
2548 |
2546 if (TreeInfo.isStaticSelector(that.expr, names) && |
2549 if (TreeInfo.isStaticSelector(that.expr, names) && |
2678 } |
2681 } |
2679 } |
2682 } |
2680 |
2683 |
2681 @SuppressWarnings("fallthrough") |
2684 @SuppressWarnings("fallthrough") |
2682 void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { |
2685 void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { |
2683 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types); |
2686 Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); |
2684 |
2687 |
2685 Type resType; |
2688 Type resType; |
2686 switch (tree.getMode()) { |
2689 switch (tree.getMode()) { |
2687 case NEW: |
2690 case NEW: |
2688 if (!tree.expr.type.isRaw()) { |
2691 if (!tree.expr.type.isRaw()) { |
2710 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref", |
2713 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref", |
2711 diags.fragment("inconvertible.types", resType, descriptor.getReturnType()))); |
2714 diags.fragment("inconvertible.types", resType, descriptor.getReturnType()))); |
2712 } |
2715 } |
2713 |
2716 |
2714 if (!speculativeAttr) { |
2717 if (!speculativeAttr) { |
2715 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types); |
2718 List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); |
2716 if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { |
2719 if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { |
2717 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); |
2720 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); |
2718 } |
2721 } |
2719 } |
2722 } |
2720 } |
2723 } |
2726 */ |
2729 */ |
2727 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) { |
2730 private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) { |
2728 if (inferenceContext.free(descriptorType)) { |
2731 if (inferenceContext.free(descriptorType)) { |
2729 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2732 inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { |
2730 public void typesInferred(InferenceContext inferenceContext) { |
2733 public void typesInferred(InferenceContext inferenceContext) { |
2731 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext); |
2734 setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext); |
2732 } |
2735 } |
2733 }); |
2736 }); |
2734 } else { |
2737 } else { |
2735 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2738 ListBuffer<TypeSymbol> targets = ListBuffer.lb(); |
2736 if (pt.hasTag(CLASS)) { |
2739 if (pt.hasTag(CLASS)) { |
4150 log.warning(LintCategory.SERIAL, |
4153 log.warning(LintCategory.SERIAL, |
4151 TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c); |
4154 TreeInfo.diagnosticPositionFor(svuid, tree), "constant.SVUID", c); |
4152 } |
4155 } |
4153 |
4156 |
4154 private Type capture(Type type) { |
4157 private Type capture(Type type) { |
4155 return types.capture(type); |
4158 //do not capture free types |
|
4159 return resultInfo.checkContext.inferenceContext().free(type) ? |
|
4160 type : types.capture(type); |
4156 } |
4161 } |
4157 |
4162 |
4158 private void validateTypeAnnotations(JCTree tree) { |
4163 private void validateTypeAnnotations(JCTree tree) { |
4159 tree.accept(typeAnnotationsValidator); |
4164 tree.accept(typeAnnotationsValidator); |
4160 } |
4165 } |