mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Remove redundant cast(s)" "true"
|
||||
class Test {
|
||||
{
|
||||
double d = -1e20 + (1e20 - 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Remove redundant cast(s)" "true"
|
||||
class Test {
|
||||
{
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
System.out.println(j * (i % j));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Remove redundant cast(s)" "true"
|
||||
class Test {
|
||||
{
|
||||
String s = "" + (1 + 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Remove redundant cast(s)" "true"
|
||||
class Test {
|
||||
{
|
||||
double d = -1e20 + (do<caret>uble)(1e20 - 1);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Remove redundant cast(s)" "true"
|
||||
class Test {
|
||||
{
|
||||
String s = "" + (in<caret>t) (1 + 2);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user