[groovy] ensure tree consistency after Change To Operator fixes

Add parentheses for rhs in binary expressions with same priority: e.g. `a + b.plus(c)` -> `a + (b + c)`.
There are no associative operators because of overloading.
This commit is contained in:
Daniil Ovchinnikov
2018-07-04 17:44:35 +03:00
parent e3338d5958
commit 75d6a265fe
5 changed files with 19 additions and 46 deletions
@@ -1,5 +1,4 @@
// 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 org.jetbrains.plugins.groovy.lang.lexer;
import com.intellij.psi.TokenType;
@@ -160,10 +159,6 @@ public interface TokenSets {
TokenSet POSTFIX_UNARY_OP_SET = TokenSet.create(mDEC, mINC);
TokenSet PARENTHESIZED_BINARY_OP_SET = TokenSet.create(mEQUAL, mNOT_EQUAL);
TokenSet ASSOCIATIVE_BINARY_OP_SET = TokenSet.create(mBAND, mBOR, mBXOR, mLOR, mPLUS, mSTAR, mLAND);
TokenSet BINARY_EXPRESSIONS = TokenSet.create(ADDITIVE_EXPRESSION,
MULTIPLICATIVE_EXPRESSION,
POWER_EXPRESSION,
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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 org.jetbrains.plugins.groovy.lang.psi.impl.utils;
import com.intellij.psi.PsiElement;
@@ -27,9 +13,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import java.util.HashMap;
import java.util.Map;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.ASSOCIATIVE_BINARY_OP_SET;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.PARENTHESIZED_BINARY_OP_SET;
/**
* Precedence documentation - http://groovy-lang.org/operators.html#_operator_precedence
*/
@@ -177,16 +160,16 @@ public class ParenthesesUtils {
return currentExpression;
}
public static boolean checkPrecedenceForBinaryOps(int precedence, @NotNull IElementType parentToken, boolean isRhs) {
/**
* @return {@code true} if operator with childPrecedence
* on the right or left (isRhs) side
* inside operator with parentToken
* should be parenthesized
*/
public static boolean checkPrecedenceForBinaryOps(int childPrecedence, @NotNull IElementType parentToken, boolean isRhs) {
int parentPrecedence = precedenceForBinaryOperator(parentToken);
if (precedence > parentPrecedence) return true;
if (precedence == parentPrecedence && parentPrecedence != 0) {
if (!ASSOCIATIVE_BINARY_OP_SET.contains(parentToken) && isRhs ||
PARENTHESIZED_BINARY_OP_SET.contains(parentToken)) {
return true;
}
}
return false;
return parentPrecedence < childPrecedence ||
parentPrecedence == childPrecedence && parentPrecedence != 0 && isRhs;
}
public static boolean checkPrecedenceForNonBinaryOps(@NotNull GrExpression newExpr, int parentPrecedence) {
@@ -1,10 +1,7 @@
// Copyright 2000-2017 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.
// 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 org.jetbrains.plugins.groovy.inspections
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.PsiTestUtil
import groovy.transform.CompileStatic
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
import org.jetbrains.plugins.groovy.LightGroovyTestCase
@@ -174,16 +171,14 @@ class Operators {
}
void testSamePrioritiesExpression() {
PsiTestUtil.disablePsiTextConsistencyChecks(getTestRootDisposable())
doTest "a.eq<caret>uals(b) == 1", "(a == b) == 1"
doTest "a.eq<caret>uals(b) == 1", "a == b == 1"
doTest "(a == b).eq<caret>uals(1)", "(a == b) == 1"
doTest "1 == a.eq<caret>uals(b)", "1 == (a == b)"
doTest "!a.eq<caret>uals(b) == 1", "(a != b) == 1"
doTest "!a.eq<caret>uals(b) == 1", "a != b == 1"
doTest "1 == !a.eq<caret>uals(b)", "1 == (a != b)"
doTest "1 + a.p<caret>lus(b)", "1 + a + b"
doTest "1 + a.m<caret>inus(b)", "1 + a - b"
doTest "1 + a.p<caret>lus(b)", "1 + (a + b)"
doTest "1 + a.m<caret>inus(b)", "1 + (a - b)"
doTest "1 - a.m<caret>inus(b)", "1 - (a - b)"
doTest "a.m<caret>inus(1 - b)", "a - (1 - b)"
doTest "1 - a.p<caret>lus(b)", "1 - (a + b)"
@@ -203,7 +198,7 @@ class Operators {
}
void testComplex() {
doTest "a.eq<caret>uals(b * c) == 1", "(a == b * c) == 1"
doTest "a.eq<caret>uals(b * c) == 1", "a == b * c == 1"
doTest "a.eq<caret>uals(b * c)", "a == b * c"
doTest "(Boolean) a.eq<caret>uals(b)", "(Boolean) (a == b)"
@@ -258,7 +253,7 @@ class Operators {
void testWithoutAdditionalParenthesesOption() {
inspection.withoutAdditionalParentheses = true
doTest "a.eq<caret>uals(b) == 1"
doTest "a.eq<caret>uals(b) == 1", 'a == b == 1'
doTest "1 == !a.eq<caret>uals(b)"
doTest "a.eq<caret>uals(b) && c", "a == b && c"
@@ -14,4 +14,4 @@ int bar(i = 8, k = i + 1, j = k) {
def q = 6
print 8 + 1
def t = 8 + 8 + 1 + 8 + 1 + q + q + q
def t = 8 + (8 + 1) + (8 + 1) + q + q + q
@@ -14,4 +14,4 @@ int bar(i = 8, k = i + 1, j = k) {
def q = 6
print 8 + 1
println(8 + 8 + 1 + 8 + 1 + q + q + q)
println(8 + (8 + 1) + (8 + 1) + q + q + q)