SSR: match repeated variables correctly (IDEA-254329)

GitOrigin-RevId: 12514c6e4f3fa8c971e3f84d2439a68bd8a8eb31
This commit is contained in:
Bas Leijdekkers
2020-11-02 11:48:51 +00:00
committed by intellij-monorepo-bot
parent 28ffbf6a0d
commit 0ffa0c36a0
3 changed files with 21 additions and 11 deletions
@@ -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-2020 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.psi.PsiElement;
@@ -114,7 +114,7 @@ public final class MatchResultImpl extends MatchResult {
myMultipleMatch = multipleMatch;
}
public MatchResultImpl findChild(@NotNull String name) {
public MatchResultImpl getChild(@NotNull String name) {
// @todo this could be performance bottleneck, replace with hash lookup!
for (final MatchResult match : myChildren) {
final MatchResultImpl res = (MatchResultImpl)match;
@@ -126,12 +126,12 @@ public final class MatchResultImpl extends MatchResult {
return null;
}
public static MatchResultImpl findChildDeep(@NotNull MatchResult match, @NotNull String name) {
for (MatchResult child : match.getChildren()) {
public MatchResult findChild(@NotNull String name) {
for (MatchResult child : myChildren) {
if (name.equals(child.getName())) {
return (MatchResultImpl)child;
return child;
}
final MatchResultImpl deep = findChildDeep(child, name);
final MatchResult deep = ((MatchResultImpl)child).findChild(name);
if (deep != null) {
return deep;
}
@@ -143,7 +143,7 @@ public class SubstitutionHandler extends MatchingHandler {
if (result == null) {
final MatchResultImpl previous = context.getPreviousResult();
if (previous != null) {
result = MatchResultImpl.findChildDeep(previous, name);
result = previous.findChild(name);
}
}
@@ -187,7 +187,7 @@ public class SubstitutionHandler extends MatchingHandler {
public void addResult(@NotNull PsiElement match, int start, int end, @NotNull MatchContext context) {
if (totalMatchedOccurs == -1) {
final MatchResultImpl matchResult = context.getResult();
final MatchResultImpl substitution = matchResult.findChild(name);
final MatchResultImpl substitution = matchResult.getChild(name);
if (substitution == null) {
matchResult.addChild(createMatch(match, start, end) );
@@ -294,7 +294,7 @@ public class SubstitutionHandler extends MatchingHandler {
private void removeLastResults(int numberOfResults, @NotNull MatchContext context) {
if (numberOfResults == 0) return;
final MatchResultImpl substitution = context.getResult().findChild(name);
final MatchResultImpl substitution = context.getResult().getChild(name);
if (substitution != null) {
if (substitution.hasChildren()) {
@@ -469,9 +469,9 @@ public class SubstitutionHandler extends MatchingHandler {
totalMatchedOccurs = matchedOccurs;
return true;
}
MatchResult result = context.hasResult() ? context.getResult().findChild(name) : null;
MatchResult result = context.hasResult() ? context.getResult().getChild(name) : null;
if (result == null && context.getPreviousResult() != null) {
result = context.getPreviousResult().findChild(name);
result = context.getPreviousResult().getChild(name);
}
return result == null || result.size() == matchedOccurs;
}
@@ -3380,6 +3380,16 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
" @FindBy(name='_value)\n" +
" '_FieldType2 'field2 = '_init2?;\n" +
"}"));
in = "class X {{" +
" int[] newQueue = new int[queue.length * 2 - fwd];\n" +
" System.arraycopy(queue, fwd, newQueue, 0, queue.length - fwd);" +
"}}";
assertEquals("should not match because the p var differs", 0,
findMatchesCount(in, "int[] '_params = new int['_p - '_i];\n" +
"System.arraycopy('_a, '_i, '_params, 0, '_p - '_i);"));
assertEquals(1, findMatchesCount(in, "int[] '_params = new int['_p * 2 - '_i];\n" +
"System.arraycopy('_a, '_i, '_params, 0, '_p - '_i);"));
}
public void testForStatement() {