< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Print this page




1684             resultInfo.checkContext.report(tree, diags.fragment(Fragments.ConditionalTargetCantBeVoid));
1685             result = tree.type = types.createErrorType(resultInfo.pt);
1686             return;
1687         }
1688 
1689         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
1690                 unknownExprInfo :
1691                 resultInfo.dup(conditionalContext(resultInfo.checkContext));
1692 
1693         Type truetype = attribTree(tree.truepart, env, condInfo);
1694         Type falsetype = attribTree(tree.falsepart, env, condInfo);
1695 
1696         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ?
1697                 condType(List.of(tree.truepart.pos(), tree.falsepart.pos()),
1698                          List.of(truetype, falsetype)) : pt();
1699         if (condtype.constValue() != null &&
1700                 truetype.constValue() != null &&
1701                 falsetype.constValue() != null &&
1702                 !owntype.hasTag(NONE)) {
1703             //constant folding
1704             owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
1705         }
1706         result = check(tree, owntype, KindSelector.VAL, resultInfo);
1707     }
1708     //where
1709         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
1710             switch (tree.getTag()) {
1711                 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
1712                               ((JCLiteral)tree).typetag == BOOLEAN ||
1713                               ((JCLiteral)tree).typetag == BOT;
1714                 case LAMBDA: case REFERENCE: return false;
1715                 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
1716                 case CONDEXPR:
1717                     JCConditional condTree = (JCConditional)tree;
1718                     return isBooleanOrNumeric(env, condTree.truepart) &&
1719                             isBooleanOrNumeric(env, condTree.falsepart);
1720                 case APPLY:
1721                     JCMethodInvocation speculativeMethodTree =
1722                             (JCMethodInvocation)deferredAttr.attribSpeculative(
1723                                     tree, env, unknownExprInfo,
1724                                     argumentAttr.withLocalCacheContext());


2897             new PostAttrAnalyzer() {
2898                 @Override
2899                 public void scan(JCTree tree) {
2900                     if (tree == null ||
2901                             (tree.type != null &&
2902                             tree.type == Type.stuckType)) {
2903                         //don't touch stuck expressions!
2904                         return;
2905                     }
2906                     super.scan(tree);
2907                 }
2908 
2909                 @Override
2910                 public void visitClassDef(JCClassDecl that) {
2911                     // or class declaration trees!
2912                 }
2913 
2914                 public void visitLambda(JCLambda that) {
2915                     // or lambda expressions!
2916                 }
2917             }.scan(tree.body);
2918         }
2919 
2920         Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
2921 
2922             @Override
2923             public Type visitClassType(ClassType t, DiagnosticPosition pos) {
2924                 return t.isIntersection() ?
2925                         visitIntersectionClassType((IntersectionClassType)t, pos) : t;
2926             }
2927 
2928             public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
2929                 types.findDescriptorSymbol(makeNotionalInterface(ict, pos));
2930                 return ict;
2931             }
2932 
2933             private TypeSymbol makeNotionalInterface(IntersectionClassType ict, DiagnosticPosition pos) {
2934                 ListBuffer<Type> targs = new ListBuffer<>();
2935                 ListBuffer<Type> supertypes = new ListBuffer<>();
2936                 for (Type i : ict.interfaces_field) {
2937                     if (i.isParameterized()) {


3555     }
3556 
3557     public void visitUnary(JCUnary tree) {
3558         // Attribute arguments.
3559         Type argtype = (tree.getTag().isIncOrDecUnaryOp())
3560             ? attribTree(tree.arg, env, varAssignmentInfo)
3561             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
3562 
3563         // Find operator.
3564         Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype);
3565         Type owntype = types.createErrorType(tree.type);
3566         if (operator != operators.noOpSymbol &&
3567                 !argtype.isErroneous()) {
3568             owntype = (tree.getTag().isIncOrDecUnaryOp())
3569                 ? tree.arg.type
3570                 : operator.type.getReturnType();
3571             int opc = ((OperatorSymbol)operator).opcode;
3572 
3573             // If the argument is constant, fold it.
3574             if (argtype.constValue() != null) {
3575                 Type ctype = cfolder.fold1(opc, argtype);
3576                 if (ctype != null) {
3577                     owntype = cfolder.coerce(ctype, owntype);
3578                 }
3579             }
3580         }
3581         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3582     }
3583 
3584     public void visitBinary(JCBinary tree) {
3585         // Attribute arguments.
3586         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
3587         Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));
3588         // Find operator.
3589         Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
3590         Type owntype = types.createErrorType(tree.type);
3591         if (operator != operators.noOpSymbol &&
3592                 !left.isErroneous() &&
3593                 !right.isErroneous()) {
3594             owntype = operator.type.getReturnType();
3595             int opc = ((OperatorSymbol)operator).opcode;
3596             // If both arguments are constants, fold them.
3597             if (left.constValue() != null && right.constValue() != null) {
3598                 Type ctype = cfolder.fold2(opc, left, right);
3599                 if (ctype != null) {
3600                     owntype = cfolder.coerce(ctype, owntype);
3601                 }
3602             }
3603 
3604             // Check that argument types of a reference ==, != are
3605             // castable to each other, (JLS 15.21).  Note: unboxing
3606             // comparisons will not have an acmp* opc at this point.
3607             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
3608                 if (!types.isCastable(left, right, new Warner(tree.pos()))) {
3609                     log.error(tree.pos(), Errors.IncomparableTypes(left, right));
3610                 }
3611             }
3612 
3613             chk.checkDivZero(tree.rhs.pos(), operator, right);
3614         }
3615         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3616     }
3617 
3618     public void visitTypeCast(final JCTypeCast tree) {


4205                         }
4206                         break;
4207                     case METHODDEF:
4208                     case CLASSDEF:
4209                     case TOPLEVEL:
4210                         return null;
4211                 }
4212                 Assert.checkNonNull(env.next);
4213                 env = env.next;
4214             }
4215         }
4216 
4217         /**
4218          * Check for illegal references to static members of enum.  In
4219          * an enum type, constructors and initializers may not
4220          * reference its static members unless they are constant.
4221          *
4222          * @param tree    The tree making up the variable reference.
4223          * @param env     The current environment.
4224          * @param v       The variable's symbol.
4225          * @jls 8.9 Enum Types
4226          */
4227         private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
4228             // JLS:
4229             //
4230             // "It is a compile-time error to reference a static field
4231             // of an enum type that is not a compile-time constant
4232             // (15.28) from constructors, instance initializer blocks,
4233             // or instance variable initializer expressions of that
4234             // type. It is a compile-time error for the constructors,
4235             // instance initializer blocks, or instance variable
4236             // initializer expressions of an enum constant e to refer
4237             // to itself or to an enum constant of the same type that
4238             // is declared to the right of e."
4239             if (isStaticEnumField(v)) {
4240                 ClassSymbol enclClass = env.info.scope.owner.enclClass();
4241 
4242                 if (enclClass == null || enclClass.owner == null)
4243                     return;
4244 
4245                 // See if the enclosing class is the enum (or a




1684             resultInfo.checkContext.report(tree, diags.fragment(Fragments.ConditionalTargetCantBeVoid));
1685             result = tree.type = types.createErrorType(resultInfo.pt);
1686             return;
1687         }
1688 
1689         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
1690                 unknownExprInfo :
1691                 resultInfo.dup(conditionalContext(resultInfo.checkContext));
1692 
1693         Type truetype = attribTree(tree.truepart, env, condInfo);
1694         Type falsetype = attribTree(tree.falsepart, env, condInfo);
1695 
1696         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ?
1697                 condType(List.of(tree.truepart.pos(), tree.falsepart.pos()),
1698                          List.of(truetype, falsetype)) : pt();
1699         if (condtype.constValue() != null &&
1700                 truetype.constValue() != null &&
1701                 falsetype.constValue() != null &&
1702                 !owntype.hasTag(NONE)) {
1703             //constant folding
1704             owntype = cfolder.coerce(ConstFold.isTrue(condtype.getTag(), condtype.constValue()) ? truetype : falsetype, owntype);
1705         }
1706         result = check(tree, owntype, KindSelector.VAL, resultInfo);
1707     }
1708     //where
1709         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
1710             switch (tree.getTag()) {
1711                 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
1712                               ((JCLiteral)tree).typetag == BOOLEAN ||
1713                               ((JCLiteral)tree).typetag == BOT;
1714                 case LAMBDA: case REFERENCE: return false;
1715                 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
1716                 case CONDEXPR:
1717                     JCConditional condTree = (JCConditional)tree;
1718                     return isBooleanOrNumeric(env, condTree.truepart) &&
1719                             isBooleanOrNumeric(env, condTree.falsepart);
1720                 case APPLY:
1721                     JCMethodInvocation speculativeMethodTree =
1722                             (JCMethodInvocation)deferredAttr.attribSpeculative(
1723                                     tree, env, unknownExprInfo,
1724                                     argumentAttr.withLocalCacheContext());


2897             new PostAttrAnalyzer() {
2898                 @Override
2899                 public void scan(JCTree tree) {
2900                     if (tree == null ||
2901                             (tree.type != null &&
2902                             tree.type == Type.stuckType)) {
2903                         //don't touch stuck expressions!
2904                         return;
2905                     }
2906                     super.scan(tree);
2907                 }
2908 
2909                 @Override
2910                 public void visitClassDef(JCClassDecl that) {
2911                     // or class declaration trees!
2912                 }
2913 
2914                 public void visitLambda(JCLambda that) {
2915                     // or lambda expressions!
2916                 }
2917             }.scan(tree);
2918         }
2919 
2920         Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
2921 
2922             @Override
2923             public Type visitClassType(ClassType t, DiagnosticPosition pos) {
2924                 return t.isIntersection() ?
2925                         visitIntersectionClassType((IntersectionClassType)t, pos) : t;
2926             }
2927 
2928             public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
2929                 types.findDescriptorSymbol(makeNotionalInterface(ict, pos));
2930                 return ict;
2931             }
2932 
2933             private TypeSymbol makeNotionalInterface(IntersectionClassType ict, DiagnosticPosition pos) {
2934                 ListBuffer<Type> targs = new ListBuffer<>();
2935                 ListBuffer<Type> supertypes = new ListBuffer<>();
2936                 for (Type i : ict.interfaces_field) {
2937                     if (i.isParameterized()) {


3555     }
3556 
3557     public void visitUnary(JCUnary tree) {
3558         // Attribute arguments.
3559         Type argtype = (tree.getTag().isIncOrDecUnaryOp())
3560             ? attribTree(tree.arg, env, varAssignmentInfo)
3561             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
3562 
3563         // Find operator.
3564         Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype);
3565         Type owntype = types.createErrorType(tree.type);
3566         if (operator != operators.noOpSymbol &&
3567                 !argtype.isErroneous()) {
3568             owntype = (tree.getTag().isIncOrDecUnaryOp())
3569                 ? tree.arg.type
3570                 : operator.type.getReturnType();
3571             int opc = ((OperatorSymbol)operator).opcode;
3572 
3573             // If the argument is constant, fold it.
3574             if (argtype.constValue() != null) {
3575                 Type ctype = cfolder.fold1((OperatorSymbol)operator, argtype);
3576                 if (ctype != null) {
3577                     owntype = cfolder.coerce(ctype, owntype);
3578                 }
3579             }
3580         }
3581         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3582     }
3583 
3584     public void visitBinary(JCBinary tree) {
3585         // Attribute arguments.
3586         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
3587         Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));
3588         // Find operator.
3589         Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
3590         Type owntype = types.createErrorType(tree.type);
3591         if (operator != operators.noOpSymbol &&
3592                 !left.isErroneous() &&
3593                 !right.isErroneous()) {
3594             owntype = operator.type.getReturnType();
3595             int opc = ((OperatorSymbol)operator).opcode;
3596             // If both arguments are constants, fold them.
3597             if (left.constValue() != null && right.constValue() != null) {
3598                 Type ctype = cfolder.fold2((OperatorSymbol)operator, left, right);
3599                 if (ctype != null) {
3600                     owntype = cfolder.coerce(ctype, owntype);
3601                 }
3602             }
3603 
3604             // Check that argument types of a reference ==, != are
3605             // castable to each other, (JLS 15.21).  Note: unboxing
3606             // comparisons will not have an acmp* opc at this point.
3607             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
3608                 if (!types.isCastable(left, right, new Warner(tree.pos()))) {
3609                     log.error(tree.pos(), Errors.IncomparableTypes(left, right));
3610                 }
3611             }
3612 
3613             chk.checkDivZero(tree.rhs.pos(), operator, right);
3614         }
3615         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3616     }
3617 
3618     public void visitTypeCast(final JCTypeCast tree) {


4205                         }
4206                         break;
4207                     case METHODDEF:
4208                     case CLASSDEF:
4209                     case TOPLEVEL:
4210                         return null;
4211                 }
4212                 Assert.checkNonNull(env.next);
4213                 env = env.next;
4214             }
4215         }
4216 
4217         /**
4218          * Check for illegal references to static members of enum.  In
4219          * an enum type, constructors and initializers may not
4220          * reference its static members unless they are constant.
4221          *
4222          * @param tree    The tree making up the variable reference.
4223          * @param env     The current environment.
4224          * @param v       The variable's symbol.
4225          * @jls  section 8.9 Enums
4226          */
4227         private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
4228             // JLS:
4229             //
4230             // "It is a compile-time error to reference a static field
4231             // of an enum type that is not a compile-time constant
4232             // (15.28) from constructors, instance initializer blocks,
4233             // or instance variable initializer expressions of that
4234             // type. It is a compile-time error for the constructors,
4235             // instance initializer blocks, or instance variable
4236             // initializer expressions of an enum constant e to refer
4237             // to itself or to an enum constant of the same type that
4238             // is declared to the right of e."
4239             if (isStaticEnumField(v)) {
4240                 ClassSymbol enclClass = env.info.scope.owner.enclClass();
4241 
4242                 if (enclClass == null || enclClass.owner == null)
4243                     return;
4244 
4245                 // See if the enclosing class is the enum (or a


< prev index next >