extract PsiPrecedenceUtil as read-only part of ParenthesisUtils

leave methods to ensure compatibility, to be inlined and deprecated in separate commit (IDEA-CR-30329)
This commit is contained in:
Anna.Kozlova
2018-03-09 15:29:00 +01:00
parent a00d19098c
commit e3f42bdb9b
10 changed files with 364 additions and 259 deletions

View File

@@ -0,0 +1,273 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.util;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class PsiPrecedenceUtil {
public static final int PARENTHESIZED_PRECEDENCE = 0;
public static final int LITERAL_PRECEDENCE = 0;
public static final int METHOD_CALL_PRECEDENCE = 1;
public static final int POSTFIX_PRECEDENCE = 2;
public static final int PREFIX_PRECEDENCE = 3;
public static final int TYPE_CAST_PRECEDENCE = 4;
public static final int MULTIPLICATIVE_PRECEDENCE = 5;
public static final int ADDITIVE_PRECEDENCE = 6;
public static final int SHIFT_PRECEDENCE = 7;
public static final int RELATIONAL_PRECEDENCE = 8;
public static final int EQUALITY_PRECEDENCE = 9;
public static final int BINARY_AND_PRECEDENCE = 10;
public static final int BINARY_XOR_PRECEDENCE = 11;
public static final int BINARY_OR_PRECEDENCE = 12;
public static final int AND_PRECEDENCE = 13;
public static final int OR_PRECEDENCE = 14;
public static final int CONDITIONAL_PRECEDENCE = 15;
public static final int ASSIGNMENT_PRECEDENCE = 16;
public static final int LAMBDA_PRECEDENCE = 17; // jls-15.2
public static final int NUM_PRECEDENCES = 18;
private static final Map<IElementType, Integer> s_binaryOperatorPrecedence = new HashMap<>(NUM_PRECEDENCES);
static {
s_binaryOperatorPrecedence.put(JavaTokenType.PLUS, ADDITIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.MINUS, ADDITIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.ASTERISK, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.DIV, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.PERC, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.ANDAND, AND_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.OROR, OR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.AND, BINARY_AND_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.OR, BINARY_OR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.XOR, BINARY_XOR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LTLT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GTGT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GTGTGT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GT, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GE, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LT, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LE, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.EQEQ, EQUALITY_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.NE, EQUALITY_PRECEDENCE);
}
public static boolean isCommutativeOperator(@NotNull IElementType token) {
return token == JavaTokenType.PLUS || token == JavaTokenType.ASTERISK ||
token == JavaTokenType.EQEQ || token == JavaTokenType.NE ||
token == JavaTokenType.AND || token == JavaTokenType.OR || token == JavaTokenType.XOR;
}
public static boolean isCommutativeOperation(PsiPolyadicExpression expression) {
final IElementType tokenType = expression.getOperationTokenType();
if (!isCommutativeOperator(tokenType)) {
return false;
}
final PsiType type = expression.getType();
return type != null && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING);
}
public static boolean isAssociativeOperation(PsiPolyadicExpression expression) {
final IElementType tokenType = expression.getOperationTokenType();
final PsiType type = expression.getType();
final PsiPrimitiveType primitiveType;
if (type instanceof PsiClassType) {
primitiveType = PsiPrimitiveType.getUnboxedType(type);
if (primitiveType == null) {
return false;
}
}
else if (type instanceof PsiPrimitiveType) {
primitiveType = (PsiPrimitiveType)type;
}
else {
return false;
}
if (JavaTokenType.PLUS == tokenType || JavaTokenType.ASTERISK == tokenType) {
return !PsiType.FLOAT.equals(primitiveType) && !PsiType.DOUBLE.equals(primitiveType);
}
else if (JavaTokenType.EQEQ == tokenType || JavaTokenType.NE == tokenType) {
return PsiType.BOOLEAN.equals(primitiveType);
}
else if (JavaTokenType.AND == tokenType || JavaTokenType.OR == tokenType || JavaTokenType.XOR == tokenType) {
return true;
}
else if (JavaTokenType.OROR == tokenType || JavaTokenType.ANDAND == tokenType) {
return true;
}
return false;
}
public static int getPrecedence(PsiExpression expression) {
if (expression instanceof PsiThisExpression ||
expression instanceof PsiLiteralExpression ||
expression instanceof PsiSuperExpression ||
expression instanceof PsiClassObjectAccessExpression ||
expression instanceof PsiArrayAccessExpression ||
expression instanceof PsiArrayInitializerExpression) {
return LITERAL_PRECEDENCE;
}
if (expression instanceof PsiReferenceExpression) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
if (referenceExpression.getQualifier() != null) {
return METHOD_CALL_PRECEDENCE;
}
else {
return LITERAL_PRECEDENCE;
}
}
if (expression instanceof PsiMethodCallExpression || expression instanceof PsiNewExpression) {
return METHOD_CALL_PRECEDENCE;
}
if (expression instanceof PsiTypeCastExpression) {
return TYPE_CAST_PRECEDENCE;
}
if (expression instanceof PsiPrefixExpression) {
return PREFIX_PRECEDENCE;
}
if (expression instanceof PsiPostfixExpression) {
return POSTFIX_PRECEDENCE;
}
if (expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
return getPrecedenceForOperator(polyadicExpression.getOperationTokenType());
}
if (expression instanceof PsiInstanceOfExpression) {
return RELATIONAL_PRECEDENCE;
}
if (expression instanceof PsiConditionalExpression) {
return CONDITIONAL_PRECEDENCE;
}
if (expression instanceof PsiAssignmentExpression) {
return ASSIGNMENT_PRECEDENCE;
}
if (expression instanceof PsiParenthesizedExpression) {
return PARENTHESIZED_PRECEDENCE;
}
if (expression instanceof PsiLambdaExpression) {
return LAMBDA_PRECEDENCE;
}
return -1;
}
public static int getPrecedenceForOperator(@NotNull IElementType operator) {
final Integer precedence = s_binaryOperatorPrecedence.get(operator);
if (precedence == null) {
throw new IllegalArgumentException("unknown operator: " + operator);
}
return precedence.intValue();
}
public static boolean areParenthesesNeeded(PsiParenthesizedExpression expression, boolean ignoreClarifyingParentheses) {
final PsiElement parent = expression.getParent();
if (!(parent instanceof PsiExpression)) {
return false;
}
final PsiExpression child = expression.getExpression();
return child == null || areParenthesesNeeded(child, (PsiExpression)parent, ignoreClarifyingParentheses);
}
public static boolean areParenthesesNeeded(PsiExpression expression,
PsiExpression parentExpression,
boolean ignoreClarifyingParentheses) {
if (parentExpression instanceof PsiParenthesizedExpression || parentExpression instanceof PsiArrayInitializerExpression) {
return false;
}
if (parentExpression instanceof PsiArrayAccessExpression) {
final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parentExpression;
return PsiTreeUtil.isAncestor(arrayAccessExpression.getArrayExpression(), expression, false);
}
final int parentPrecedence = getPrecedence(parentExpression);
final int childPrecedence = getPrecedence(expression);
if (parentPrecedence > childPrecedence) {
if (ignoreClarifyingParentheses) {
if (expression instanceof PsiPolyadicExpression) {
if (parentExpression instanceof PsiPolyadicExpression ||
parentExpression instanceof PsiConditionalExpression ||
parentExpression instanceof PsiInstanceOfExpression) {
return true;
}
}
else if (expression instanceof PsiInstanceOfExpression) {
return true;
}
}
return false;
}
if (parentExpression instanceof PsiPolyadicExpression && expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression parentPolyadicExpression = (PsiPolyadicExpression)parentExpression;
final PsiType parentType = parentPolyadicExpression.getType();
if (parentType == null) {
return true;
}
final PsiPolyadicExpression childPolyadicExpression = (PsiPolyadicExpression)expression;
final PsiType childType = childPolyadicExpression.getType();
if (!parentType.equals(childType)) {
return true;
}
if (childType.equalsToText(CommonClassNames.JAVA_LANG_STRING) &&
!PsiTreeUtil.isAncestor(parentPolyadicExpression.getOperands()[0], childPolyadicExpression, true)) {
final PsiExpression[] operands = childPolyadicExpression.getOperands();
for (PsiExpression operand : operands) {
if (!childType.equals(operand.getType())) {
return true;
}
}
}
else if (childType.equals(PsiType.BOOLEAN)) {
final PsiExpression[] operands = childPolyadicExpression.getOperands();
for (PsiExpression operand : operands) {
if (!PsiType.BOOLEAN.equals(operand.getType())) {
return true;
}
}
}
final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType();
final IElementType childOperator = childPolyadicExpression.getOperationTokenType();
if (ignoreClarifyingParentheses) {
if (!childOperator.equals(parentOperator)) {
return true;
}
}
final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands();
if (!PsiTreeUtil.isAncestor(parentOperands[0], expression, false)) {
if (!isAssociativeOperation(parentPolyadicExpression) ||
JavaTokenType.DIV == childOperator || JavaTokenType.PERC == childOperator) {
return true;
}
}
}
else if (parentExpression instanceof PsiConditionalExpression && expression instanceof PsiConditionalExpression) {
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
final PsiExpression condition = conditionalExpression.getCondition();
return PsiTreeUtil.isAncestor(condition, expression, true);
}
else if (expression instanceof PsiLambdaExpression) { // jls-15.16
if (parentExpression instanceof PsiTypeCastExpression) {
return false;
}
else if (parentExpression instanceof PsiConditionalExpression) { // jls-15.25
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
return PsiTreeUtil.isAncestor(conditionalExpression.getCondition(), expression, true);
}
}
return parentPrecedence < childPrecedence;
}
public static boolean areParenthesesNeeded(PsiJavaToken compoundAssignmentToken, PsiExpression rhs) {
if (rhs instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs;
final int precedence1 = getPrecedenceForOperator(binaryExpression.getOperationTokenType());
final IElementType signTokenType = compoundAssignmentToken.getTokenType();
final IElementType newOperatorToken = TypeConversionUtil.convertEQtoOperation(signTokenType);
final int precedence2 = getPrecedenceForOperator(newOperatorToken);
return precedence1 >= precedence2 || !isCommutativeOperator(newOperatorToken);
}
else {
return rhs instanceof PsiConditionalExpression;
}
}
}

View File

@@ -61,16 +61,18 @@ public class RedundantCastUtil {
public static PsiExpression removeCast(PsiTypeCastExpression castExpression) {
if (castExpression == null) return null;
PsiElement parent = castExpression.getParent();
PsiExpression operand = castExpression.getOperand();
if (operand instanceof PsiParenthesizedExpression) {
final PsiParenthesizedExpression parExpr = (PsiParenthesizedExpression)operand;
operand = parExpr.getExpression();
if (parent instanceof PsiExpression && !PsiPrecedenceUtil.areParenthesesNeeded(parExpr.getExpression(), (PsiExpression)parent, true)) {
operand = parExpr.getExpression();
}
}
if (operand == null) return null;
PsiExpression toBeReplaced = castExpression;
PsiElement parent = castExpression.getParent();
while (parent instanceof PsiParenthesizedExpression) {
toBeReplaced = (PsiExpression)parent;
parent = parent.getParent();

View File

@@ -56,7 +56,7 @@ public class ReplaceExpressionUtil {
IElementType newI = newExpr.getElementType();
if (newI == JavaElementType.BINARY_EXPRESSION || newI == JavaElementType.POLYADIC_EXPRESSION) {
IElementType newType = ((PsiPolyadicExpression)newExpr).getOperationTokenType();
if (newType == JavaTokenType.DIV) return true;
if (newType == JavaTokenType.DIV || newExpr == JavaTokenType.PERC) return true;
}
return ((CompositeElement)oldParent).getChildRole(oldExpr) != ChildRole.LOPERAND &&
opType != JavaTokenType.PLUS &&

View File

@@ -0,0 +1,6 @@
// "Remove redundant cast(s)" "true"
class Test {
{
double d = -1e20 + (1e20 - 1);
}
}

View File

@@ -0,0 +1,8 @@
// "Remove redundant cast(s)" "true"
class Test {
{
int i = 1;
int j = 2;
System.out.println(j * (i % j));
}
}

View File

@@ -0,0 +1,6 @@
// "Remove redundant cast(s)" "true"
class Test {
{
String s = "" + (1 + 2);
}
}

View File

@@ -0,0 +1,6 @@
// "Remove redundant cast(s)" "true"
class Test {
{
double d = -1e20 + (do<caret>uble)(1e20 - 1);
}
}

View File

@@ -0,0 +1,8 @@
// "Remove redundant cast(s)" "true"
class Test {
{
int i = 1;
int j = 2;
System.out.println(j * (i<caret>nt)(i % j));
}
}

View File

@@ -0,0 +1,6 @@
// "Remove redundant cast(s)" "true"
class Test {
{
String s = "" + (in<caret>t) (1 + 2);
}
}

View File

@@ -17,63 +17,63 @@ package com.siyeh.ig.psiutils;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.PsiPrecedenceUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class ParenthesesUtils {
public static final int METHOD_CALL_PRECEDENCE = PsiPrecedenceUtil.METHOD_CALL_PRECEDENCE;
public static final int POSTFIX_PRECEDENCE = PsiPrecedenceUtil.POSTFIX_PRECEDENCE;
public static final int PREFIX_PRECEDENCE = PsiPrecedenceUtil.PREFIX_PRECEDENCE;
public static final int TYPE_CAST_PRECEDENCE = PsiPrecedenceUtil.TYPE_CAST_PRECEDENCE;
public static final int MULTIPLICATIVE_PRECEDENCE = PsiPrecedenceUtil.MULTIPLICATIVE_PRECEDENCE;
public static final int ADDITIVE_PRECEDENCE = PsiPrecedenceUtil.ADDITIVE_PRECEDENCE;
public static final int SHIFT_PRECEDENCE = PsiPrecedenceUtil.SHIFT_PRECEDENCE;
public static final int EQUALITY_PRECEDENCE = PsiPrecedenceUtil.EQUALITY_PRECEDENCE;
public static final int BINARY_AND_PRECEDENCE = PsiPrecedenceUtil.BINARY_AND_PRECEDENCE;
public static final int BINARY_OR_PRECEDENCE = PsiPrecedenceUtil.BINARY_OR_PRECEDENCE;
public static final int AND_PRECEDENCE = PsiPrecedenceUtil.AND_PRECEDENCE;
public static final int OR_PRECEDENCE = PsiPrecedenceUtil.OR_PRECEDENCE;
public static final int CONDITIONAL_PRECEDENCE = PsiPrecedenceUtil.CONDITIONAL_PRECEDENCE;
public static final int ASSIGNMENT_PRECEDENCE = PsiPrecedenceUtil.ASSIGNMENT_PRECEDENCE;
public static final int NUM_PRECEDENCES = PsiPrecedenceUtil.NUM_PRECEDENCES;
private ParenthesesUtils() {}
public static final int PARENTHESIZED_PRECEDENCE = 0;
public static final int LITERAL_PRECEDENCE = 0;
public static final int METHOD_CALL_PRECEDENCE = 1;
public static final int POSTFIX_PRECEDENCE = 2;
public static final int PREFIX_PRECEDENCE = 3;
public static final int TYPE_CAST_PRECEDENCE = 4;
public static final int MULTIPLICATIVE_PRECEDENCE = 5;
public static final int ADDITIVE_PRECEDENCE = 6;
public static final int SHIFT_PRECEDENCE = 7;
public static final int RELATIONAL_PRECEDENCE = 8;
public static final int EQUALITY_PRECEDENCE = 9;
public static final int BINARY_AND_PRECEDENCE = 10;
public static final int BINARY_XOR_PRECEDENCE = 11;
public static final int BINARY_OR_PRECEDENCE = 12;
public static final int AND_PRECEDENCE = 13;
public static final int OR_PRECEDENCE = 14;
public static final int CONDITIONAL_PRECEDENCE = 15;
public static final int ASSIGNMENT_PRECEDENCE = 16;
public static final int LAMBDA_PRECEDENCE = 17; // jls-15.2
public static final int NUM_PRECEDENCES = 18;
public static boolean isCommutativeOperator(@NotNull IElementType token) {
return PsiPrecedenceUtil.isCommutativeOperator(token);
}
private static final Map<IElementType, Integer> s_binaryOperatorPrecedence = new HashMap<>(NUM_PRECEDENCES);
public static boolean isCommutativeOperation(PsiPolyadicExpression expression) {
return PsiPrecedenceUtil.isCommutativeOperation(expression);
}
public static boolean isAssociativeOperation(PsiPolyadicExpression expression) {
return PsiPrecedenceUtil.isAssociativeOperation(expression);
}
public static int getPrecedence(PsiExpression expression) {
return PsiPrecedenceUtil.getPrecedence(expression);
}
public static int getPrecedenceForOperator(@NotNull IElementType operator) {
return PsiPrecedenceUtil.getPrecedenceForOperator(operator);
}
public static boolean areParenthesesNeeded(PsiParenthesizedExpression expression, boolean ignoreClarifyingParentheses) {
return PsiPrecedenceUtil.areParenthesesNeeded(expression, ignoreClarifyingParentheses);
}
static {
s_binaryOperatorPrecedence.put(JavaTokenType.PLUS, ADDITIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.MINUS, ADDITIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.ASTERISK, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.DIV, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.PERC, MULTIPLICATIVE_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.ANDAND, AND_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.OROR, OR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.AND, BINARY_AND_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.OR, BINARY_OR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.XOR, BINARY_XOR_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LTLT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GTGT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GTGTGT, SHIFT_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GT, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.GE, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LT, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.LE, RELATIONAL_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.EQEQ, EQUALITY_PRECEDENCE);
s_binaryOperatorPrecedence.put(JavaTokenType.NE, EQUALITY_PRECEDENCE);
public static boolean areParenthesesNeeded(PsiExpression expression,
PsiExpression parentExpression,
boolean ignoreClarifyingParentheses) {
return PsiPrecedenceUtil.areParenthesesNeeded(expression, parentExpression, ignoreClarifyingParentheses);
}
public static boolean areParenthesesNeeded(PsiJavaToken compoundAssignmentToken, PsiExpression rhs) {
return PsiPrecedenceUtil.areParenthesesNeeded(compoundAssignmentToken, rhs);
}
public static String getText(@NotNull PsiExpression expression, int precedence) {
@@ -100,107 +100,6 @@ public class ParenthesesUtils {
return expression;
}
public static boolean isCommutativeOperator(@NotNull IElementType token) {
return token == JavaTokenType.PLUS || token == JavaTokenType.ASTERISK ||
token == JavaTokenType.EQEQ || token == JavaTokenType.NE ||
token == JavaTokenType.AND || token == JavaTokenType.OR || token == JavaTokenType.XOR;
}
public static boolean isCommutativeOperation(PsiPolyadicExpression expression) {
final IElementType tokenType = expression.getOperationTokenType();
if (!isCommutativeOperator(tokenType)) {
return false;
}
final PsiType type = expression.getType();
return type != null && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING);
}
public static boolean isAssociativeOperation(PsiPolyadicExpression expression) {
final IElementType tokenType = expression.getOperationTokenType();
final PsiType type = expression.getType();
final PsiPrimitiveType primitiveType;
if (type instanceof PsiClassType) {
primitiveType = PsiPrimitiveType.getUnboxedType(type);
if (primitiveType == null) {
return false;
}
} else if (type instanceof PsiPrimitiveType) {
primitiveType = (PsiPrimitiveType)type;
} else {
return false;
}
if (JavaTokenType.PLUS == tokenType || JavaTokenType.ASTERISK == tokenType) {
return !PsiType.FLOAT.equals(primitiveType) && !PsiType.DOUBLE.equals(primitiveType);
} else if (JavaTokenType.EQEQ == tokenType || JavaTokenType.NE == tokenType) {
return PsiType.BOOLEAN.equals(primitiveType);
} else if (JavaTokenType.AND == tokenType || JavaTokenType.OR == tokenType || JavaTokenType.XOR == tokenType) {
return true;
} else if (JavaTokenType.OROR == tokenType || JavaTokenType.ANDAND == tokenType) {
return true;
}
return false;
}
public static int getPrecedence(PsiExpression expression) {
if (expression instanceof PsiThisExpression ||
expression instanceof PsiLiteralExpression ||
expression instanceof PsiSuperExpression ||
expression instanceof PsiClassObjectAccessExpression ||
expression instanceof PsiArrayAccessExpression ||
expression instanceof PsiArrayInitializerExpression) {
return LITERAL_PRECEDENCE;
}
if (expression instanceof PsiReferenceExpression) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
if (referenceExpression.getQualifier() != null) {
return METHOD_CALL_PRECEDENCE;
}
else {
return LITERAL_PRECEDENCE;
}
}
if (expression instanceof PsiMethodCallExpression || expression instanceof PsiNewExpression) {
return METHOD_CALL_PRECEDENCE;
}
if (expression instanceof PsiTypeCastExpression) {
return TYPE_CAST_PRECEDENCE;
}
if (expression instanceof PsiPrefixExpression) {
return PREFIX_PRECEDENCE;
}
if (expression instanceof PsiPostfixExpression) {
return POSTFIX_PRECEDENCE;
}
if (expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
return getPrecedenceForOperator(polyadicExpression.getOperationTokenType());
}
if (expression instanceof PsiInstanceOfExpression) {
return RELATIONAL_PRECEDENCE;
}
if (expression instanceof PsiConditionalExpression) {
return CONDITIONAL_PRECEDENCE;
}
if (expression instanceof PsiAssignmentExpression) {
return ASSIGNMENT_PRECEDENCE;
}
if (expression instanceof PsiParenthesizedExpression) {
return PARENTHESIZED_PRECEDENCE;
}
if (expression instanceof PsiLambdaExpression) {
return LAMBDA_PRECEDENCE;
}
return -1;
}
public static int getPrecedenceForOperator(@NotNull IElementType operator) {
final Integer precedence = s_binaryOperatorPrecedence.get(operator);
if (precedence == null) {
throw new IllegalArgumentException("unknown operator: " + operator);
}
return precedence.intValue();
}
public static void removeParentheses(@NotNull PsiExpression expression, boolean ignoreClarifyingParentheses) {
if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
@@ -400,113 +299,4 @@ public class ParenthesesUtils {
removeParentheses(argument, ignoreClarifyingParentheses);
}
}
public static boolean areParenthesesNeeded(PsiParenthesizedExpression expression, boolean ignoreClarifyingParentheses) {
final PsiElement parent = expression.getParent();
if (!(parent instanceof PsiExpression)) {
return false;
}
final PsiExpression child = expression.getExpression();
return child == null || areParenthesesNeeded(child, (PsiExpression)parent, ignoreClarifyingParentheses);
}
public static boolean areParenthesesNeeded(PsiExpression expression, PsiExpression parentExpression,
boolean ignoreClarifyingParentheses) {
if (parentExpression instanceof PsiParenthesizedExpression || parentExpression instanceof PsiArrayInitializerExpression) {
return false;
}
if (parentExpression instanceof PsiArrayAccessExpression) {
final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)parentExpression;
return PsiTreeUtil.isAncestor(arrayAccessExpression.getArrayExpression(), expression, false);
}
final int parentPrecedence = getPrecedence(parentExpression);
final int childPrecedence = getPrecedence(expression);
if (parentPrecedence > childPrecedence) {
if (ignoreClarifyingParentheses) {
if (expression instanceof PsiPolyadicExpression) {
if (parentExpression instanceof PsiPolyadicExpression ||
parentExpression instanceof PsiConditionalExpression ||
parentExpression instanceof PsiInstanceOfExpression) {
return true;
}
}
else if (expression instanceof PsiInstanceOfExpression) {
return true;
}
}
return false;
}
if (parentExpression instanceof PsiPolyadicExpression && expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression parentPolyadicExpression = (PsiPolyadicExpression)parentExpression;
final PsiType parentType = parentPolyadicExpression.getType();
if (parentType == null) {
return true;
}
final PsiPolyadicExpression childPolyadicExpression = (PsiPolyadicExpression)expression;
final PsiType childType = childPolyadicExpression.getType();
if (!parentType.equals(childType)) {
return true;
}
if (childType.equalsToText(CommonClassNames.JAVA_LANG_STRING) &&
!PsiTreeUtil.isAncestor(parentPolyadicExpression.getOperands()[0], childPolyadicExpression, true)) {
final PsiExpression[] operands = childPolyadicExpression.getOperands();
for (PsiExpression operand : operands) {
if (!childType.equals(operand.getType())) {
return true;
}
}
}
else if (childType.equals(PsiType.BOOLEAN)) {
final PsiExpression[] operands = childPolyadicExpression.getOperands();
for (PsiExpression operand : operands) {
if (!PsiType.BOOLEAN.equals(operand.getType())) {
return true;
}
}
}
final IElementType parentOperator = parentPolyadicExpression.getOperationTokenType();
final IElementType childOperator = childPolyadicExpression.getOperationTokenType();
if (ignoreClarifyingParentheses) {
if (!childOperator.equals(parentOperator)) {
return true;
}
}
final PsiExpression[] parentOperands = parentPolyadicExpression.getOperands();
if (!PsiTreeUtil.isAncestor(parentOperands[0], expression, false)) {
if (!isAssociativeOperation(parentPolyadicExpression) ||
JavaTokenType.DIV == childOperator || JavaTokenType.PERC == childOperator) {
return true;
}
}
}
else if (parentExpression instanceof PsiConditionalExpression && expression instanceof PsiConditionalExpression) {
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
final PsiExpression condition = conditionalExpression.getCondition();
return PsiTreeUtil.isAncestor(condition, expression, true);
}
else if (expression instanceof PsiLambdaExpression) { // jls-15.16
if (parentExpression instanceof PsiTypeCastExpression) {
return false;
}
else if (parentExpression instanceof PsiConditionalExpression) { // jls-15.25
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
return PsiTreeUtil.isAncestor(conditionalExpression.getCondition(), expression, true);
}
}
return parentPrecedence < childPrecedence;
}
public static boolean areParenthesesNeeded(PsiJavaToken compoundAssignmentToken, PsiExpression rhs) {
if (rhs instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)rhs;
final int precedence1 = getPrecedenceForOperator(binaryExpression.getOperationTokenType());
final IElementType signTokenType = compoundAssignmentToken.getTokenType();
final IElementType newOperatorToken = TypeConversionUtil.convertEQtoOperation(signTokenType);
final int precedence2 = getPrecedenceForOperator(newOperatorToken);
return precedence1 >= precedence2 || !isCommutativeOperator(newOperatorToken);
}
else {
return rhs instanceof PsiConditionalExpression;
}
}
}