mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: ignore parentheses if possible & care for them if not (IDEA-185614)
This commit is contained in:
+66
-61
@@ -237,11 +237,11 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
final PsiArrayInitializerExpression expr2 = (PsiArrayInitializerExpression)myMatchingVisitor.getElement();
|
||||
|
||||
final PsiArrayInitializerExpression other = getExpression(PsiArrayInitializerExpression.class);
|
||||
if (other == null) return;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(
|
||||
new ArrayBackedNodeIterator(expression.getInitializers()),
|
||||
new ArrayBackedNodeIterator(expr2.getInitializers())
|
||||
new ArrayBackedNodeIterator(other.getInitializers())
|
||||
));
|
||||
}
|
||||
|
||||
@@ -351,14 +351,13 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (!myMatchingVisitor.setResult(other instanceof PsiLambdaExpression)) return;
|
||||
final PsiLambdaExpression expression2 = (PsiLambdaExpression)other;
|
||||
final PsiLambdaExpression other = getExpression(PsiLambdaExpression.class);
|
||||
if (other == null) return;
|
||||
final PsiParameterList parameterList1 = expression.getParameterList();
|
||||
if (!myMatchingVisitor.setResult(
|
||||
parameterList1.isEmpty() || myMatchingVisitor.matchSons(parameterList1, expression2.getParameterList()))) return;
|
||||
parameterList1.isEmpty() || myMatchingVisitor.matchSons(parameterList1, other.getParameterList()))) return;
|
||||
final PsiElement body1 = getElementToMatch(expression.getBody());
|
||||
myMatchingVisitor.setResult(body1 == null || myMatchingVisitor.matchSequentially(body1, getElementToMatch(expression2.getBody())));
|
||||
myMatchingVisitor.setResult(body1 == null || myMatchingVisitor.matchSequentially(body1, getElementToMatch(other.getBody())));
|
||||
}
|
||||
|
||||
private static PsiElement getElementToMatch(PsiElement element) {
|
||||
@@ -514,17 +513,16 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitArrayAccessExpression(final PsiArrayAccessExpression slice) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (myMatchingVisitor.setResult(other instanceof PsiArrayAccessExpression)) {
|
||||
final PsiArrayAccessExpression slice2 = (PsiArrayAccessExpression)other;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(slice.getArrayExpression(), slice2.getArrayExpression()) &&
|
||||
myMatchingVisitor.match(slice.getIndexExpression(), slice2.getIndexExpression()));
|
||||
final PsiArrayAccessExpression other = getExpression(PsiArrayAccessExpression.class);
|
||||
if (other != null) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(slice.getArrayExpression(), other.getArrayExpression()) &&
|
||||
myMatchingVisitor.match(slice.getIndexExpression(), other.getIndexExpression()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
|
||||
if (!myMatchingVisitor.setResult(myMatchingVisitor.getElement() instanceof PsiMethodReferenceExpression)) return;
|
||||
if (getExpression(PsiMethodReferenceExpression.class) == null) return;
|
||||
super.visitMethodReferenceExpression(expression);
|
||||
}
|
||||
|
||||
@@ -539,10 +537,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
special = true;
|
||||
}
|
||||
|
||||
final PsiElement element = myMatchingVisitor.getElement();
|
||||
PsiElement other = element instanceof PsiExpression && context.getOptions().isLooseMatching() ?
|
||||
PsiUtil.skipParenthesizedExprDown((PsiExpression)element) :
|
||||
element;
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
final PsiExpression qualifier = reference.getQualifierExpression();
|
||||
if (_handler instanceof SubstitutionHandler && (qualifier == null || special)) {
|
||||
final SubstitutionHandler handler = (SubstitutionHandler)_handler;
|
||||
@@ -550,7 +545,12 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
myMatchingVisitor.setResult(checkMatchWithinHierarchy(other, handler, reference));
|
||||
}
|
||||
else {
|
||||
myMatchingVisitor.setResult(handler.handle(other, context));
|
||||
final PsiElement deparenthesized = other instanceof PsiExpression && context.getOptions().isLooseMatching() ?
|
||||
PsiUtil.skipParenthesizedExprDown((PsiExpression)other) : other;
|
||||
myMatchingVisitor.setResult(handler.validate(deparenthesized, 0, -1, context));
|
||||
if (myMatchingVisitor.getResult()) {
|
||||
handler.addResult(other, 0, -1, context);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -877,16 +877,16 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitConditionalExpression(final PsiConditionalExpression cond) {
|
||||
final PsiConditionalExpression cond2 = (PsiConditionalExpression)myMatchingVisitor.getElement();
|
||||
|
||||
final PsiConditionalExpression cond2 = getExpression(PsiConditionalExpression.class);
|
||||
if (cond2 == null) return;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(cond.getCondition(), cond2.getCondition()) &&
|
||||
myMatchingVisitor.matchSons(cond, cond2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPolyadicExpression(PsiPolyadicExpression expression) {
|
||||
final PsiPolyadicExpression expr2 = (PsiPolyadicExpression)myMatchingVisitor.getElement();
|
||||
|
||||
final PsiPolyadicExpression expr2 = getExpression(PsiPolyadicExpression.class);
|
||||
if (expr2 == null) return;
|
||||
if (myMatchingVisitor.setResult(expression.getOperationTokenType().equals(expr2.getOperationTokenType()))) {
|
||||
final PsiExpression[] operands1 = expression.getOperands();
|
||||
final PsiExpression[] operands2 = expr2.getOperands();
|
||||
@@ -988,9 +988,8 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(final PsiMethodCallExpression mcall) {
|
||||
final PsiElement element = myMatchingVisitor.getElement();
|
||||
if (!myMatchingVisitor.setResult(element instanceof PsiMethodCallExpression)) return;
|
||||
final PsiMethodCallExpression mcall2 = (PsiMethodCallExpression)element;
|
||||
final PsiMethodCallExpression mcall2 = getExpression(PsiMethodCallExpression.class);
|
||||
if (mcall2 == null) return;
|
||||
final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
|
||||
final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
|
||||
|
||||
@@ -1078,8 +1077,8 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitLiteralExpression(final PsiLiteralExpression const1) {
|
||||
final PsiLiteralExpression const2 = (PsiLiteralExpression)myMatchingVisitor.getElement();
|
||||
|
||||
final PsiLiteralExpression const2 = getExpression(PsiLiteralExpression.class);
|
||||
if (const2 == null) return;
|
||||
final MatchingHandler handler = (MatchingHandler)const1.getUserData(CompiledPattern.HANDLER_KEY);
|
||||
if (handler instanceof SubstitutionHandler) {
|
||||
final PsiType type1 = const1.getType();
|
||||
@@ -1119,13 +1118,11 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(final PsiAssignmentExpression assign) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (myMatchingVisitor.setResult(other instanceof PsiAssignmentExpression)) {
|
||||
final PsiAssignmentExpression assign2 = (PsiAssignmentExpression)other;
|
||||
|
||||
myMatchingVisitor.setResult(assign.getOperationTokenType().equals(assign2.getOperationTokenType()) &&
|
||||
myMatchingVisitor.match(assign.getLExpression(), assign2.getLExpression()) &&
|
||||
myMatchingVisitor.match(assign.getRExpression(), assign2.getRExpression()));
|
||||
final PsiAssignmentExpression other = getExpression(PsiAssignmentExpression.class);
|
||||
if (other != null) {
|
||||
myMatchingVisitor.setResult(assign.getOperationTokenType().equals(other.getOperationTokenType()) &&
|
||||
myMatchingVisitor.match(assign.getLExpression(), other.getLExpression()) &&
|
||||
myMatchingVisitor.match(assign.getRExpression(), other.getRExpression()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,18 +1207,18 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitPostfixExpression(final PsiPostfixExpression postfix) {
|
||||
final PsiPostfixExpression postfix2 = (PsiPostfixExpression)myMatchingVisitor.getElement();
|
||||
|
||||
myMatchingVisitor.setResult(postfix.getOperationTokenType().equals(postfix2.getOperationTokenType())
|
||||
&& myMatchingVisitor.match(postfix.getOperand(), postfix2.getOperand()));
|
||||
final PsiPostfixExpression postfix2 = getExpression(PsiPostfixExpression.class);
|
||||
if (postfix2 == null) return;
|
||||
myMatchingVisitor.setResult(postfix.getOperationTokenType().equals(postfix2.getOperationTokenType()) &&
|
||||
myMatchingVisitor.match(postfix.getOperand(), postfix2.getOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrefixExpression(final PsiPrefixExpression prefix) {
|
||||
final PsiPrefixExpression prefix2 = (PsiPrefixExpression)myMatchingVisitor.getElement();
|
||||
|
||||
myMatchingVisitor.setResult(prefix.getOperationTokenType().equals(prefix2.getOperationTokenType())
|
||||
&& myMatchingVisitor.match(prefix.getOperand(), prefix2.getOperand()));
|
||||
final PsiPrefixExpression prefix2 = getExpression(PsiPrefixExpression.class);
|
||||
if (prefix2 == null) return;
|
||||
myMatchingVisitor.setResult(prefix.getOperationTokenType().equals(prefix2.getOperationTokenType()) &&
|
||||
myMatchingVisitor.match(prefix.getOperand(), prefix2.getOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1248,12 +1245,12 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitSuperExpression(final PsiSuperExpression super1) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.getElement() instanceof PsiSuperExpression);
|
||||
getExpression(PsiSuperExpression.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThisExpression(final PsiThisExpression this1) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.getElement() instanceof PsiThisExpression);
|
||||
getExpression(PsiThisExpression.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1355,16 +1352,15 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitInstanceOfExpression(final PsiInstanceOfExpression instanceOf) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (!myMatchingVisitor.setResult(other instanceof PsiInstanceOfExpression)) return;
|
||||
final PsiInstanceOfExpression instanceOf2 = (PsiInstanceOfExpression)other;
|
||||
if (!myMatchingVisitor.setResult(myMatchingVisitor.match(instanceOf.getOperand(), instanceOf2.getOperand()))) return;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(instanceOf.getCheckType(), instanceOf2.getCheckType()));
|
||||
final PsiInstanceOfExpression other = getExpression(PsiInstanceOfExpression.class);
|
||||
if (other == null) return;
|
||||
if (!myMatchingVisitor.setResult(myMatchingVisitor.match(instanceOf.getOperand(), other.getOperand()))) return;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(instanceOf.getCheckType(), other.getCheckType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(final PsiNewExpression new1) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
final PsiExpression other = getExpression();
|
||||
final PsiJavaCodeReferenceElement classReference = new1.getClassReference();
|
||||
if (other instanceof PsiArrayInitializerExpression &&
|
||||
other.getParent() instanceof PsiVariable &&
|
||||
@@ -1378,7 +1374,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
myMatchingVisitor.setResult(false);
|
||||
return;
|
||||
}
|
||||
final PsiType otherType = ((PsiArrayInitializerExpression)other).getType();
|
||||
final PsiType otherType = other.getType();
|
||||
if (handler instanceof SubstitutionHandler && otherType != null) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(other.getProject());
|
||||
final PsiTypeElement otherTypeElement = factory.createTypeElement(otherType.getDeepComponentType());
|
||||
@@ -1450,20 +1446,18 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(final PsiTypeCastExpression cast) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (myMatchingVisitor.setResult(other instanceof PsiTypeCastExpression)) {
|
||||
final PsiTypeCastExpression cast2 = (PsiTypeCastExpression)other;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(cast.getCastType(), cast2.getCastType()) &&
|
||||
myMatchingVisitor.match(cast.getOperand(), cast2.getOperand()));
|
||||
final PsiTypeCastExpression other = getExpression(PsiTypeCastExpression.class);
|
||||
if (other != null) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(cast.getCastType(), other.getCastType()) &&
|
||||
myMatchingVisitor.match(cast.getOperand(), other.getOperand()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(final PsiClassObjectAccessExpression expr) {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
if (myMatchingVisitor.setResult(other instanceof PsiClassObjectAccessExpression)) {
|
||||
final PsiClassObjectAccessExpression expr2 = (PsiClassObjectAccessExpression)other;
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(expr.getOperand(), expr2.getOperand()));
|
||||
final PsiClassObjectAccessExpression other = getExpression(PsiClassObjectAccessExpression.class);
|
||||
if (other != null) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(expr.getOperand(), other.getOperand()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1591,4 +1585,15 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
saveOrDropResult(methodNameNode, isTypedVar, method2.getNameIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends PsiExpression> T getExpression(Class<T> aClass) {
|
||||
final PsiExpression other = getExpression();
|
||||
return myMatchingVisitor.setResult(aClass.isInstance(other)) ? (T)other : null;
|
||||
}
|
||||
|
||||
private PsiExpression getExpression() {
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
return (other instanceof PsiExpression) ? PsiUtil.skipParenthesizedExprDown((PsiExpression)other) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -1,4 +1,4 @@
|
||||
// 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 com.intellij.structuralsearch.impl.matcher.compiler;
|
||||
|
||||
import com.intellij.dupLocator.iterators.NodeIterator;
|
||||
@@ -12,6 +12,7 @@ import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.structuralsearch.MalformedPatternException;
|
||||
import com.intellij.structuralsearch.StructuralSearchUtil;
|
||||
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
|
||||
@@ -194,6 +195,17 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(PsiExpression expression) {
|
||||
super.visitExpression(expression);
|
||||
if (!(expression.getParent() instanceof PsiExpressionStatement) && !(expression instanceof PsiParenthesizedExpression)) {
|
||||
final MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(expression);
|
||||
if (handler.getFilter() == null) {
|
||||
handler.setFilter(e -> DefaultFilter.accepts((e instanceof PsiExpression) ? PsiUtil.skipParenthesizedExprDown((PsiExpression)e) : e, expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
String text = expression.getText();
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ class Test {
|
||||
System.out.println(a.incrementAndGet(0));
|
||||
a.getAndDecrement(0);
|
||||
if (a.decrementAndGet(0) == 0) {
|
||||
a.getAndAdd(0, (2));
|
||||
a.getAndAdd(0, ((2)));
|
||||
a.set(0, a.get(0) * 2);
|
||||
if (a.get(0) == 0) {
|
||||
System.out.println(a.get(0) + 7);
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ class Test {
|
||||
System.out.println(++a[0]);
|
||||
a[0]--;
|
||||
if (--a[0] == 0) {
|
||||
a[0] += 2;
|
||||
a[0] += ((2));
|
||||
a[0] = a[0] * 2;
|
||||
if (a[0] == 0) {
|
||||
System.out.println(a[0] + 7);
|
||||
|
||||
+30
-1
@@ -1,4 +1,4 @@
|
||||
// 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 com.intellij.structuralsearch;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
@@ -2276,4 +2276,33 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
|
||||
"}",
|
||||
replacer.testReplace(in, what, by, options, true));
|
||||
}
|
||||
|
||||
public void testReplaceParentheses() {
|
||||
String in = "public class MyFile {\n" +
|
||||
" void test(String a, Object b) {\n" +
|
||||
" if(a.length() == 0) {\n" +
|
||||
" System.out.println(\"empty\");\n" +
|
||||
" }\n" +
|
||||
" if(((String) b).length() == 0) {\n" +
|
||||
" System.out.println(\"empty\");\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
String what = "'_expr:[exprtype( String )].length() == 0";
|
||||
String by = "$expr$.isEmpty()";
|
||||
assertEquals("parentheses should remain",
|
||||
|
||||
"public class MyFile {\n" +
|
||||
" void test(String a, Object b) {\n" +
|
||||
" if(a.isEmpty()) {\n" +
|
||||
" System.out.println(\"empty\");\n" +
|
||||
" }\n" +
|
||||
" if(((String) b).isEmpty()) {\n" +
|
||||
" System.out.println(\"empty\");\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
replacer.testReplace(in, what, by, options, true));
|
||||
}
|
||||
}
|
||||
+6
@@ -2215,6 +2215,12 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
String pattern2 = "System.out.println('_v);" +
|
||||
"System.out.println('_v);";
|
||||
assertEquals(1, findMatchesCount(source, pattern2));
|
||||
|
||||
String source2 = "class B {{" +
|
||||
" System.out.println((3 * 8) + 2 + (((2))));" +
|
||||
"}}";
|
||||
String pattern3 = "3 * 8 + 2 + 2";
|
||||
assertEquals(1, findMatchesCount(source2, pattern3));
|
||||
}
|
||||
|
||||
public void testFindSelfAssignment() {
|
||||
|
||||
Reference in New Issue
Block a user