replace operator assignment with assignment (IDEA-137214)

This commit is contained in:
Anna Kozlova
2015-06-26 12:24:32 +03:00
parent f7f168a97e
commit db73973674
8 changed files with 71 additions and 34 deletions
@@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.psiutils.ParenthesesUtils;
public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.DeclarationJoinLinesHandler");
@@ -105,8 +106,9 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
PsiAssignmentExpression assignment) {
PsiExpression initializerExpression;
final IElementType originalOpSign = assignment.getOperationTokenType();
final PsiExpression rExpression = assignment.getRExpression();
if (originalOpSign == JavaTokenType.EQ) {
initializerExpression = assignment.getRExpression();
initializerExpression = rExpression;
}
else {
if (var.getInitializer() == null) return null;
@@ -147,7 +149,14 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
try {
final Project project = var.getProject();
final String initializerText = var.getInitializer().getText() + opSign + assignment.getRExpression().getText();
String initializerText = var.getInitializer().getText() + opSign;
final String rightText = rExpression.getText();
if (ParenthesesUtils.areParenthesesNeeded(assignment.getOperationSign(), rExpression)) {
initializerText += "(" + rightText + ")";
}
else {
initializerText += rightText;
}
initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, var);
initializerExpression = (PsiExpression)CodeStyleManager.getInstance(project).reformat(initializerExpression);
}
@@ -0,0 +1,6 @@
// "Join declaration and assignment" "true"
class Test {
{
int i = 4 * (2 + 3);
}
}
@@ -0,0 +1,7 @@
// "Join declaration and assignment" "true"
class Test {
{
int i = 4;
i *<caret>= 2 + 3;
}
}
@@ -26,6 +26,8 @@ import java.util.Map;
public class ParenthesesUtils {
public static final Map<IElementType, IElementType> tokenMap = new HashMap<IElementType, IElementType>();
private ParenthesesUtils() {}
public static final int PARENTHESIZED_PRECEDENCE = 0;
@@ -50,6 +52,21 @@ public class ParenthesesUtils {
private static final Map<IElementType, Integer> s_binaryOperatorPrecedence = new HashMap<IElementType, Integer>(NUM_PRECEDENCES);
static {
tokenMap.put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS);
tokenMap.put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS);
tokenMap.put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK);
tokenMap.put(JavaTokenType.DIVEQ, JavaTokenType.DIV);
tokenMap.put(JavaTokenType.ANDEQ, JavaTokenType.AND);
tokenMap.put(JavaTokenType.OREQ, JavaTokenType.OR);
tokenMap.put(JavaTokenType.XOREQ, JavaTokenType.XOR);
tokenMap.put(JavaTokenType.PERCEQ, JavaTokenType.PERC);
tokenMap.put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT);
tokenMap.put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT);
tokenMap.put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT);
}
static {
s_binaryOperatorPrecedence.put(JavaTokenType.PLUS, ADDITIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.MINUS, ADDITIVE_PRECEDENCE);
@@ -526,4 +543,18 @@ public class ParenthesesUtils {
}
return parentPrecedence < childPrecedence;
}
public static boolean areParenthesesNeeded(PsiJavaToken sign, PsiExpression rhs) {
if (rhs instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs;
final int precedence1 = getPrecedenceForOperator(binaryExpression.getOperationTokenType());
final IElementType signTokenType = sign.getTokenType();
final IElementType newOperatorToken = tokenMap.get(signTokenType);
final int precedence2 = getPrecedenceForOperator(newOperatorToken);
return precedence1 >= precedence2 || !isCommutativeOperator(newOperatorToken);
}
else {
return rhs instanceof PsiConditionalExpression;
}
}
}
@@ -16,7 +16,6 @@
package com.siyeh.ipp.opassign;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ig.PsiReplacementUtil;
@@ -25,27 +24,8 @@ import com.siyeh.ipp.base.MutablyNamedIntention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class ReplaceOperatorAssignmentWithAssignmentIntention extends MutablyNamedIntention {
private static final Map<IElementType, IElementType> tokenMap = new HashMap<IElementType, IElementType>();
static {
tokenMap.put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS);
tokenMap.put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS);
tokenMap.put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK);
tokenMap.put(JavaTokenType.DIVEQ, JavaTokenType.DIV);
tokenMap.put(JavaTokenType.ANDEQ, JavaTokenType.AND);
tokenMap.put(JavaTokenType.OREQ, JavaTokenType.OR);
tokenMap.put(JavaTokenType.XOREQ, JavaTokenType.XOR);
tokenMap.put(JavaTokenType.PERCEQ, JavaTokenType.PERC);
tokenMap.put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT);
tokenMap.put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT);
tokenMap.put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT);
}
@Override
@NotNull
protected PsiElementPredicate getElementPredicate() {
@@ -70,18 +50,7 @@ public class ReplaceOperatorAssignmentWithAssignmentIntention extends MutablyNam
final String newOperator = operator.substring(0, operator.length() - 1);
final String lhsText = lhs.getText();
final String rhsText = (rhs == null) ? "" : rhs.getText();
final boolean parentheses;
if (rhs instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs;
final int precedence1 = ParenthesesUtils.getPrecedenceForOperator(binaryExpression.getOperationTokenType());
final IElementType signTokenType = sign.getTokenType();
final IElementType newOperatorToken = tokenMap.get(signTokenType);
final int precedence2 = ParenthesesUtils.getPrecedenceForOperator(newOperatorToken);
parentheses = precedence1 >= precedence2 || !ParenthesesUtils.isCommutativeOperator(newOperatorToken);
}
else {
parentheses = false;
}
final boolean parentheses = ParenthesesUtils.areParenthesesNeeded(sign, rhs);
final String cast = getCastString(lhs, rhs);
final StringBuilder newExpression = new StringBuilder(lhsText);
newExpression.append('=').append(cast);
@@ -0,0 +1,7 @@
package com.siyeh.ipp.opassign.assignment;
class Conditional {
void x(int i) {
i *= 1<caret>==1 ? 2 : 3;
}
}
@@ -0,0 +1,7 @@
package com.siyeh.ipp.opassign.assignment;
class Conditional {
void x(int i) {
i = i * (1 == 1 ? 2 : 3);
}
}
@@ -13,6 +13,7 @@ public class ReplaceOperatorAssignmentWithAssignmentIntentionTest extends IPPTes
public void testByteOpAssign() { doTest(); }
public void testPrecedence() { doTest(); }
public void testPolyadicAssignment() { doTest(IntentionPowerPackBundle.message("replace.operator.assignment.with.assignment.intention.name", "*=")); }
public void testConditionalAssignment() { doTest(IntentionPowerPackBundle.message("replace.operator.assignment.with.assignment.intention.name", "*=")); }
@Override
protected String getIntentionName() {