2 * Copyright 2007-2009 Bas Leijdekkers
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.siyeh
.ipp
.opassign
;
18 import com
.intellij
.psi
.*;
19 import com
.intellij
.psi
.tree
.IElementType
;
20 import com
.intellij
.util
.IncorrectOperationException
;
21 import com
.siyeh
.IntentionPowerPackBundle
;
22 import com
.siyeh
.ipp
.base
.MutablyNamedIntention
;
23 import com
.siyeh
.ipp
.base
.PsiElementPredicate
;
24 import com
.siyeh
.ipp
.psiutils
.ParenthesesUtils
;
25 import org
.jetbrains
.annotations
.NotNull
;
28 import java
.util
.HashMap
;
30 public class ReplaceOperatorAssignmentWithAssignmentIntention
31 extends MutablyNamedIntention
{
33 private static final Map
<IElementType
, IElementType
> tokenMap
= new HashMap();
35 tokenMap
.put(JavaTokenType
.PLUSEQ
, JavaTokenType
.PLUS
);
36 tokenMap
.put(JavaTokenType
.MINUSEQ
, JavaTokenType
.MINUS
);
37 tokenMap
.put(JavaTokenType
.ASTERISKEQ
, JavaTokenType
.ASTERISK
);
38 tokenMap
.put(JavaTokenType
.DIVEQ
, JavaTokenType
.DIV
);
39 tokenMap
.put(JavaTokenType
.ANDEQ
, JavaTokenType
.AND
);
40 tokenMap
.put(JavaTokenType
.OREQ
, JavaTokenType
.OR
);
41 tokenMap
.put(JavaTokenType
.XOREQ
, JavaTokenType
.XOR
);
42 tokenMap
.put(JavaTokenType
.PERCEQ
, JavaTokenType
.PERC
);
43 tokenMap
.put(JavaTokenType
.LTLTEQ
, JavaTokenType
.LTLT
);
44 tokenMap
.put(JavaTokenType
.GTGTEQ
, JavaTokenType
.GTGT
);
45 tokenMap
.put(JavaTokenType
.GTGTGTEQ
, JavaTokenType
.GTGTGT
);
50 protected PsiElementPredicate
getElementPredicate() {
51 return new OperatorAssignmentPredicate();
55 protected String
getTextForElement(PsiElement element
) {
56 final PsiAssignmentExpression assignmentExpression
=
57 (PsiAssignmentExpression
)element
;
58 final PsiJavaToken sign
= assignmentExpression
.getOperationSign();
59 final String operator
= sign
.getText();
60 return IntentionPowerPackBundle
.message(
61 "replace.operator.assignment.with.assignment.intention.name",
66 protected void processIntention(@NotNull PsiElement element
)
67 throws IncorrectOperationException
{
68 final PsiAssignmentExpression assignmentExpression
=
69 (PsiAssignmentExpression
)element
;
70 final PsiJavaToken sign
= assignmentExpression
.getOperationSign();
71 final PsiExpression lhs
= assignmentExpression
.getLExpression();
72 final PsiExpression rhs
= assignmentExpression
.getRExpression();
73 final String operator
= sign
.getText();
74 final String newOperator
= operator
.substring(0, operator
.length() - 1);
75 final String lhsText
= lhs
.getText();
80 rhsText
= rhs
.getText();
82 if (rhs
instanceof PsiBinaryExpression
) {
83 final PsiBinaryExpression binaryExpression
=
84 (PsiBinaryExpression
)rhs
;
85 final PsiJavaToken javaToken
= binaryExpression
.getOperationSign();
86 final int precedence1
=
87 ParenthesesUtils
.getPrecedenceForBinaryOperator(javaToken
);
88 final IElementType signTokenType
= sign
.getTokenType();
89 final IElementType newOperatorToken
= tokenMap
.get(signTokenType
);
90 final int precedence2
=
91 ParenthesesUtils
.getPrecedenceForBinaryOperator(
93 if (precedence1
> precedence2
||
94 !ParenthesesUtils
.isCommutativeBinaryOperator(
96 final String expString
;
98 expString
= lhsText
+ "=(int)" + lhsText
+ newOperator
99 + '(' + rhsText
+ "))";
101 expString
= lhsText
+ '=' + lhsText
+ newOperator
102 + '(' + rhsText
+ ')';
104 replaceExpression(expString
, assignmentExpression
);
108 final String expString
;
109 if (needsCast(rhs
)) {
110 expString
= lhsText
+ "=(int)(" + lhsText
+ newOperator
+ rhsText
113 expString
= lhsText
+ '=' + lhsText
+ newOperator
+ rhsText
;
115 replaceExpression(expString
, assignmentExpression
);
118 private static boolean needsCast(PsiExpression expression
) {
119 final PsiType type
= expression
.getType();
120 return PsiType
.LONG
.equals(type
) || PsiType
.DOUBLE
.equals(type
) ||
121 PsiType
.FLOAT
.equals(type
);