DeclarationJoinLinesHandler: more careful precedence fix (IDEA-CR-34859)

This commit is contained in:
Tagir Valeev
2018-07-12 17:18:19 +07:00
parent fa71413378
commit 867968eea8
6 changed files with 48 additions and 65 deletions

View File

@@ -23,10 +23,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiPrecedenceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -121,74 +122,32 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
}
@Nullable
public static PsiExpression getInitializerExpression(PsiExpression initializer,
PsiAssignmentExpression assignment) {
public static PsiExpression getInitializerExpression(PsiExpression initializer, PsiAssignmentExpression assignment) {
PsiExpression initializerExpression;
final IElementType originalOpSign = assignment.getOperationTokenType();
PsiJavaToken sign = assignment.getOperationSign();
final IElementType compoundOp = assignment.getOperationTokenType();
final PsiExpression rExpression = assignment.getRExpression();
if (rExpression == null) return null;
if (originalOpSign == JavaTokenType.EQ) {
initializerExpression = rExpression;
if (compoundOp == JavaTokenType.EQ) {
return rExpression;
}
else {
if (initializer == null) return null;
String opSign = null;
if (originalOpSign == JavaTokenType.ANDEQ) {
opSign = "&";
}
else if (originalOpSign == JavaTokenType.ASTERISKEQ) {
opSign = "*";
}
else if (originalOpSign == JavaTokenType.DIVEQ) {
opSign = "/";
}
else if (originalOpSign == JavaTokenType.GTGTEQ) {
opSign = ">>";
}
else if (originalOpSign == JavaTokenType.GTGTGTEQ) {
opSign = ">>>";
}
else if (originalOpSign == JavaTokenType.LTLTEQ) {
opSign = "<<";
}
else if (originalOpSign == JavaTokenType.MINUSEQ) {
opSign = "-";
}
else if (originalOpSign == JavaTokenType.OREQ) {
opSign = "|";
}
else if (originalOpSign == JavaTokenType.PERCEQ) {
opSign = "%";
}
else if (originalOpSign == JavaTokenType.PLUSEQ) {
opSign = "+";
}
else if (originalOpSign == JavaTokenType.XOREQ) {
opSign = "^";
}
try {
final Project project = assignment.getProject();
String initializerText = initializer.getText() + opSign;
final String rightText = rExpression.getText();
if (ParenthesesUtils.areParenthesesNeeded(assignment.getOperationSign(), rExpression)) {
initializerText += "(" + rightText + ")";
}
else {
initializerText += rightText;
}
if ("+".equals(opSign) && ExpressionUtils.isZero(initializer) ||
"*".equals(opSign) && ExpressionUtils.isOne(initializer)) {
initializerText = rightText;
}
initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, assignment);
initializerExpression = (PsiExpression)CodeStyleManager.getInstance(project).reformat(initializerExpression);
}
catch (IncorrectOperationException e) {
LOG.error(e);
return null;
}
if (initializer == null) return null;
String opSign = sign.getText().replace("=", "");
IElementType simpleOp = TypeConversionUtil.convertEQtoOperation(compoundOp);
if (simpleOp == null) return null;
final Project project = assignment.getProject();
final String rightText = rExpression.getText();
String initializerText;
if ("+".equals(opSign) && ExpressionUtils.isZero(initializer) ||
"*".equals(opSign) && ExpressionUtils.isOne(initializer)) {
initializerText = rightText;
} else {
boolean parenthesesForLhs = PsiPrecedenceUtil.getPrecedence(initializer) > PsiPrecedenceUtil.getPrecedenceForOperator(simpleOp);
boolean parenthesesForRhs = PsiPrecedenceUtil.areParenthesesNeeded(sign, rExpression);
initializerText = (parenthesesForLhs ? "(" + initializer.getText() + ")" : initializer.getText()) + opSign +
(parenthesesForRhs ? "(" + rExpression.getText() + ")" : rExpression.getText());
}
return initializerExpression;
initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, assignment);
return (PsiExpression)CodeStyleManager.getInstance(project).reformat(initializerExpression);
}
}

View File

@@ -0,0 +1,6 @@
class Foo {
{
int a = 1 + 2<caret>;
a *= 2 + 3;
}
}

View File

@@ -0,0 +1,6 @@
class Foo {
{
int a = 1 + 2<caret>;
a -= 2 + 3;
}
}

View File

@@ -0,0 +1,5 @@
class Foo {
{
int a = 1 + 2 - (2 + 3);
}
}

View File

@@ -0,0 +1,5 @@
class Foo {
{
int a = (1 + 2) * (2 + 3);
}
}

View File

@@ -187,6 +187,8 @@ public class JoinLinesTest extends LightCodeInsightTestCase {
public void testAssignmentExpression() { doTest(); }
public void testAssignmentExpression2() { doTest(); }
public void testAssignmentExpressionPrecedence() { doTest(); }
public void testAssignmentExpressionPrecedence2() { doTest(); }
public void testReformatInsertsNewlines() {
CommonCodeStyleSettings settings = getJavaSettings();