langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 15726 27bb87e628ae
parent 15725 e0516b913894
parent 15718 8e54c8e43d38
child 16316 1150b1b2f5c2
equal deleted inserted replaced
15725:e0516b913894 15726:27bb87e628ae
    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     }