2974 } 2975 } 2976 } 2977 result = check(tree, owntype, VAL, resultInfo); 2978 } 2979 2980 public void visitBinary(JCBinary tree) { 2981 // Attribute arguments. 2982 Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); 2983 Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env)); 2984 2985 // Find operator. 2986 Symbol operator = tree.operator = 2987 rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right); 2988 2989 Type owntype = types.createErrorType(tree.type); 2990 if (operator.kind == MTH && 2991 !left.isErroneous() && 2992 !right.isErroneous()) { 2993 owntype = operator.type.getReturnType(); 2994 int opc = chk.checkOperator(tree.lhs.pos(), 2995 (OperatorSymbol)operator, 2996 tree.getTag(), 2997 left, 2998 right); 2999 3000 // If both arguments are constants, fold them. 3001 if (left.constValue() != null && right.constValue() != null) { 3002 Type ctype = cfolder.fold2(opc, left, right); 3003 if (ctype != null) { 3004 owntype = cfolder.coerce(ctype, owntype); 3005 3006 // Remove constant types from arguments to 3007 // conserve space. The parser will fold concatenations 3008 // of string literals; the code here also 3009 // gets rid of intermediate results when some of the 3010 // operands are constant identifiers. 3011 if (tree.lhs.type.tsym == syms.stringType.tsym) { 3012 tree.lhs.type = syms.stringType; 3013 } 3014 if (tree.rhs.type.tsym == syms.stringType.tsym) { 3015 tree.rhs.type = syms.stringType; 3016 } 3017 } 3018 } 3019 3020 // Check that argument types of a reference ==, != are 3021 // castable to each other, (JLS???). 3022 if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { 3023 if (!types.isCastable(left, right, new Warner(tree.pos()))) { 3024 log.error(tree.pos(), "incomparable.types", left, right); 3025 } 3026 } 3027 3028 chk.checkDivZero(tree.rhs.pos(), operator, right); 3029 } 3030 result = check(tree, owntype, VAL, resultInfo); 3031 } 3032 3033 public void visitTypeCast(final JCTypeCast tree) { 3034 Type clazztype = attribType(tree.clazz, env); 3035 chk.validate(tree.clazz, env, false); 3036 //a fresh environment is required for 292 inference to work properly --- 3037 //see Infer.instantiatePolymorphicSignatureInstance() 3038 Env<AttrContext> localEnv = env.dup(tree); 3039 //should we propagate the target type? 3040 final ResultInfo castInfo; 3041 JCExpression expr = TreeInfo.skipParens(tree.expr); 3042 boolean isPoly = expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE); 3043 if (isPoly) { | 2974 } 2975 } 2976 } 2977 result = check(tree, owntype, VAL, resultInfo); 2978 } 2979 2980 public void visitBinary(JCBinary tree) { 2981 // Attribute arguments. 2982 Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); 2983 Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env)); 2984 2985 // Find operator. 2986 Symbol operator = tree.operator = 2987 rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right); 2988 2989 Type owntype = types.createErrorType(tree.type); 2990 if (operator.kind == MTH && 2991 !left.isErroneous() && 2992 !right.isErroneous()) { 2993 owntype = operator.type.getReturnType(); 2994 // This will figure out when unboxing can happen and 2995 // choose the right comparison operator. 2996 int opc = chk.checkOperator(tree.lhs.pos(), 2997 (OperatorSymbol)operator, 2998 tree.getTag(), 2999 left, 3000 right); 3001 3002 // If both arguments are constants, fold them. 3003 if (left.constValue() != null && right.constValue() != null) { 3004 Type ctype = cfolder.fold2(opc, left, right); 3005 if (ctype != null) { 3006 owntype = cfolder.coerce(ctype, owntype); 3007 3008 // Remove constant types from arguments to 3009 // conserve space. The parser will fold concatenations 3010 // of string literals; the code here also 3011 // gets rid of intermediate results when some of the 3012 // operands are constant identifiers. 3013 if (tree.lhs.type.tsym == syms.stringType.tsym) { 3014 tree.lhs.type = syms.stringType; 3015 } 3016 if (tree.rhs.type.tsym == syms.stringType.tsym) { 3017 tree.rhs.type = syms.stringType; 3018 } 3019 } 3020 } 3021 3022 // Check that argument types of a reference ==, != are 3023 // castable to each other, (JLS 15.21). Note: unboxing 3024 // comparisons will not have an acmp* opc at this point. 3025 if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { 3026 if (!types.isEqualityComparable(left, right, 3027 new Warner(tree.pos()))) { 3028 log.error(tree.pos(), "incomparable.types", left, right); 3029 } 3030 } 3031 3032 chk.checkDivZero(tree.rhs.pos(), operator, right); 3033 } 3034 result = check(tree, owntype, VAL, resultInfo); 3035 } 3036 3037 public void visitTypeCast(final JCTypeCast tree) { 3038 Type clazztype = attribType(tree.clazz, env); 3039 chk.validate(tree.clazz, env, false); 3040 //a fresh environment is required for 292 inference to work properly --- 3041 //see Infer.instantiatePolymorphicSignatureInstance() 3042 Env<AttrContext> localEnv = env.dup(tree); 3043 //should we propagate the target type? 3044 final ResultInfo castInfo; 3045 JCExpression expr = TreeInfo.skipParens(tree.expr); 3046 boolean isPoly = expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE); 3047 if (isPoly) { |