mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: fix for loop matching (IDEA-208475)
This commit is contained in:
+17
-6
@@ -874,6 +874,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
if (grandParent instanceof PsiAssertStatement) return ((PsiAssertStatement)grandParent).getAssertDescription() == parent;
|
||||
if (grandParent instanceof PsiNameValuePair) return ((PsiNameValuePair)grandParent).getValue() == parent;
|
||||
if (grandParent instanceof PsiBreakStatement) return true;
|
||||
if (grandParent instanceof PsiForStatement) return true;
|
||||
}
|
||||
if (grandParent instanceof PsiExpressionList) {
|
||||
PsiElement label = grandParent.getParent();
|
||||
@@ -894,11 +895,18 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
return type instanceof PsiWildcardType && ((PsiWildcardType)type).isExtends();
|
||||
}
|
||||
}
|
||||
if (grandParent instanceof PsiExpressionStatement && hasSemicolon(grandParent)) {
|
||||
if (grandParent instanceof PsiExpressionStatement) {
|
||||
final PsiElement greatGrandParent = grandParent.getParent();
|
||||
return !(greatGrandParent instanceof PsiCodeBlock) ||
|
||||
!(greatGrandParent.getParent() instanceof JavaDummyHolder) ||
|
||||
PsiTreeUtil.getChildrenOfAnyType(greatGrandParent, PsiStatement.class, PsiComment.class).size() > 1;
|
||||
if (greatGrandParent instanceof PsiForStatement &&
|
||||
!PsiTreeUtil.isAncestor(((PsiForStatement)greatGrandParent).getBody(), variableNode, true)) {
|
||||
return true;
|
||||
}
|
||||
if (hasSemicolon(grandParent)) {
|
||||
if (greatGrandParent instanceof PsiLoopStatement || greatGrandParent instanceof PsiIfStatement) return false;
|
||||
return !(greatGrandParent instanceof PsiCodeBlock) ||
|
||||
!(greatGrandParent.getParent() instanceof JavaDummyHolder) ||
|
||||
PsiTreeUtil.getChildrenOfAnyType(greatGrandParent, PsiStatement.class, PsiComment.class).size() > 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -916,11 +924,14 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiPolyadicExpression) return true;
|
||||
if (grandParent instanceof PsiExpressionList && grandParent.getParent() instanceof PsiSwitchLabelStatementBase) return true;
|
||||
if (grandParent instanceof PsiExpressionStatement && hasSemicolon(grandParent)) return true;
|
||||
if (grandParent instanceof PsiExpressionStatement && hasSemicolon(grandParent)) {
|
||||
final PsiElement greatGrandParent = grandParent.getParent();
|
||||
return greatGrandParent instanceof PsiCodeBlock;
|
||||
}
|
||||
if (grandParent instanceof PsiReferenceList) {
|
||||
final PsiElement greatGrandParent = grandParent.getParent();
|
||||
return !(greatGrandParent instanceof PsiClass) || ((PsiClass)greatGrandParent).getExtendsList() != grandParent ||
|
||||
greatGrandParent instanceof PsiTypeParameter;
|
||||
greatGrandParent instanceof PsiTypeParameter;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+9
-5
@@ -1,4 +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.
|
||||
// Copyright 2000-2019 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;
|
||||
|
||||
import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
|
||||
@@ -47,7 +47,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
}
|
||||
|
||||
public JavaMatchingVisitor(GlobalMatchingVisitor matchingVisitor) {
|
||||
this.myMatchingVisitor = matchingVisitor;
|
||||
myMatchingVisitor = matchingVisitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1195,12 +1195,16 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
public void visitForStatement(final PsiForStatement for1) {
|
||||
final PsiForStatement for2 = (PsiForStatement)myMatchingVisitor.getElement();
|
||||
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(for1.getInitialization(), for2.getInitialization()) &&
|
||||
myMatchingVisitor.match(for1.getCondition(), for2.getCondition()) &&
|
||||
myMatchingVisitor.match(for1.getUpdate(), for2.getUpdate()) &&
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchOptionally(notEmpty(for1.getInitialization()), notEmpty(for2.getInitialization())) &&
|
||||
myMatchingVisitor.matchOptionally(for1.getCondition(), for2.getCondition()) &&
|
||||
myMatchingVisitor.matchOptionally(for1.getUpdate(), for2.getUpdate()) &&
|
||||
matchBody(for1.getBody(), for2.getBody()));
|
||||
}
|
||||
|
||||
private static PsiStatement notEmpty(PsiStatement statement) {
|
||||
return statement instanceof PsiEmptyStatement ? null : statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitForeachStatement(PsiForeachStatement for1) {
|
||||
final PsiForeachStatement for2 = (PsiForeachStatement)myMatchingVisitor.getElement();
|
||||
|
||||
+6
-4
@@ -6,6 +6,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.JavaDummyHolder;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -482,11 +483,13 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
public void visitExpressionStatement(PsiExpressionStatement expressionStatement) {
|
||||
super.visitExpressionStatement(expressionStatement);
|
||||
|
||||
final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
|
||||
final PsiElement child = expressionStatement.getLastChild();
|
||||
if (!(child instanceof PsiJavaToken) && !(child instanceof PsiComment)) {
|
||||
final PsiElement parent = expressionStatement.getParent();
|
||||
if (!(child instanceof PsiJavaToken) && !(child instanceof PsiComment) &&
|
||||
parent instanceof PsiCodeBlock && parent.getParent() instanceof JavaDummyHolder) {
|
||||
// search for expression or symbol
|
||||
final PsiElement reference = expressionStatement.getFirstChild();
|
||||
final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
|
||||
MatchingHandler referenceHandler = pattern.getHandler(reference);
|
||||
|
||||
if (referenceHandler instanceof SubstitutionHandler && (reference instanceof PsiReferenceExpression)) {
|
||||
@@ -510,10 +513,9 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
|
||||
if (expressionStatement.getExpression() instanceof PsiReferenceExpression && pattern.isRealTypedVar(expressionStatement)) {
|
||||
// search for statement
|
||||
final MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(expressionStatement);
|
||||
final MatchingHandler handler = pattern.getHandler(expressionStatement);
|
||||
if (handler instanceof SubstitutionHandler) {
|
||||
final SubstitutionHandler substitutionHandler = (SubstitutionHandler)handler;
|
||||
substitutionHandler.setFilter(new StatementFilter());
|
||||
|
||||
+23
@@ -2490,6 +2490,12 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
|
||||
options.fillSearchCriteria("void '_a:* ();");
|
||||
assertEquals("TEXT HIERARCHY not applicable for a", checkApplicableConstraints(options));
|
||||
|
||||
options.fillSearchCriteria("if (true) '_st{0,0};");
|
||||
assertEquals("MINIMUM ZERO not applicable for st", checkApplicableConstraints(options));
|
||||
|
||||
options.fillSearchCriteria("while (true) '_st+;");
|
||||
assertEquals("MAXIMUM UNLIMITED not applicable for st", checkApplicableConstraints(options));
|
||||
}
|
||||
|
||||
public void testFindInnerClass() {
|
||||
@@ -3159,4 +3165,21 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" '_FieldType2 'field2 = '_init2?;\n" +
|
||||
"}"));
|
||||
}
|
||||
|
||||
public void testForStatement() {
|
||||
String in = "class X {{" +
|
||||
" for (int i = 0; i < 10; i++) {}" +
|
||||
" " +
|
||||
" for (;;) {}" +
|
||||
" for (int i = 0; ;) {}" +
|
||||
" for (int i = 0; true; ) {}" +
|
||||
"}}";
|
||||
assertEquals("find all for loops", 4, findMatchesCount(in, "for(;;) '_st;"));
|
||||
assertEquals("find loops without initializers", 1, findMatchesCount(in, "for('_init{0,0};;) '_st;"));
|
||||
assertEquals("find loops without condition", 2, findMatchesCount(in, "for(;'_cond{0,0};) '_st;"));
|
||||
assertEquals("find loops without update", 3, findMatchesCount(in, "for(;;'_update{0,0}) '_st;"));
|
||||
assertEquals("find all for loops 2", 4, findMatchesCount(in, "for('_init?;;) '_st;"));
|
||||
assertEquals("find all for loops 3", 4, findMatchesCount(in, "for(;;'_update?) '_st;"));
|
||||
assertEquals("find all for loops 4", 4, findMatchesCount(in, "for(;'_cond?;) '_st;"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user