3156 result = tree; |
3156 result = tree; |
3157 } |
3157 } |
3158 } |
3158 } |
3159 |
3159 |
3160 public void visitAssignop(final JCAssignOp tree) { |
3160 public void visitAssignop(final JCAssignOp tree) { |
|
3161 JCTree lhsAccess = access(TreeInfo.skipParens(tree.lhs)); |
3161 final boolean boxingReq = !tree.lhs.type.isPrimitive() && |
3162 final boolean boxingReq = !tree.lhs.type.isPrimitive() && |
3162 tree.operator.type.getReturnType().isPrimitive(); |
3163 tree.operator.type.getReturnType().isPrimitive(); |
3163 |
3164 |
3164 // boxing required; need to rewrite as x = (unbox typeof x)(x op y); |
3165 if (boxingReq || lhsAccess.hasTag(APPLY)) { |
3165 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y) |
3166 // boxing required; need to rewrite as x = (unbox typeof x)(x op y); |
3166 // (but without recomputing x) |
3167 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y) |
3167 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { |
3168 // (but without recomputing x) |
3168 public JCTree build(final JCTree lhs) { |
3169 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { |
3169 JCTree.Tag newTag = tree.getTag().noAssignOp(); |
3170 public JCTree build(final JCTree lhs) { |
3170 // Erasure (TransTypes) can change the type of |
3171 JCTree.Tag newTag = tree.getTag().noAssignOp(); |
3171 // tree.lhs. However, we can still get the |
3172 // Erasure (TransTypes) can change the type of |
3172 // unerased type of tree.lhs as it is stored |
3173 // tree.lhs. However, we can still get the |
3173 // in tree.type in Attr. |
3174 // unerased type of tree.lhs as it is stored |
3174 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(), |
3175 // in tree.type in Attr. |
3175 newTag, |
3176 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(), |
3176 attrEnv, |
3177 newTag, |
3177 tree.type, |
3178 attrEnv, |
3178 tree.rhs.type); |
3179 tree.type, |
3179 JCExpression expr = (JCExpression)lhs; |
3180 tree.rhs.type); |
3180 if (expr.type != tree.type) |
3181 JCExpression expr = (JCExpression)lhs; |
3181 expr = make.TypeCast(tree.type, expr); |
3182 if (expr.type != tree.type) |
3182 JCBinary opResult = make.Binary(newTag, expr, tree.rhs); |
3183 expr = make.TypeCast(tree.type, expr); |
3183 opResult.operator = newOperator; |
3184 JCBinary opResult = make.Binary(newTag, expr, tree.rhs); |
3184 opResult.type = newOperator.type.getReturnType(); |
3185 opResult.operator = newOperator; |
3185 JCExpression newRhs = boxingReq ? |
3186 opResult.type = newOperator.type.getReturnType(); |
3186 make.TypeCast(types.unboxedType(tree.type), |
3187 JCExpression newRhs = boxingReq ? |
3187 opResult) : |
3188 make.TypeCast(types.unboxedType(tree.type), opResult) : |
3188 opResult; |
3189 opResult; |
3189 return make.Assign((JCExpression)lhs, newRhs).setType(tree.type); |
3190 return make.Assign((JCExpression)lhs, newRhs).setType(tree.type); |
3190 } |
3191 } |
3191 }); |
3192 }); |
3192 result = translate(newTree); |
3193 result = translate(newTree); |
|
3194 return; |
|
3195 } |
|
3196 tree.lhs = translate(tree.lhs, tree); |
|
3197 tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head); |
|
3198 |
|
3199 // If translated left hand side is an Apply, we are |
|
3200 // seeing an access method invocation. In this case, append |
|
3201 // right hand side as last argument of the access method. |
|
3202 if (tree.lhs.hasTag(APPLY)) { |
|
3203 JCMethodInvocation app = (JCMethodInvocation)tree.lhs; |
|
3204 // if operation is a += on strings, |
|
3205 // make sure to convert argument to string |
|
3206 JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add) |
|
3207 ? makeString(tree.rhs) |
|
3208 : tree.rhs; |
|
3209 app.args = List.of(rhs).prependList(app.args); |
|
3210 result = app; |
|
3211 } else { |
|
3212 result = tree; |
|
3213 } |
3193 } |
3214 } |
3194 |
3215 |
3195 /** Lower a tree of the form e++ or e-- where e is an object type */ |
3216 /** Lower a tree of the form e++ or e-- where e is an object type */ |
3196 JCTree lowerBoxedPostop(final JCUnary tree) { |
3217 JCTree lowerBoxedPostop(final JCUnary tree) { |
3197 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2 |
3218 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2 |