From 0ffa0c36a03a484ceb4aacce0a17a91adfe2dd94 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 2 Nov 2020 11:51:56 +0100 Subject: [PATCH] SSR: match repeated variables correctly (IDEA-254329) GitOrigin-RevId: 12514c6e4f3fa8c971e3f84d2439a68bd8a8eb31 --- .../impl/matcher/MatchResultImpl.java | 12 ++++++------ .../impl/matcher/handlers/SubstitutionHandler.java | 10 +++++----- .../structuralsearch/StructuralSearchTest.java | 10 ++++++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java index df0812d8c52d..a4c8ced18686 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java @@ -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; } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java index 8ca144b1d425..c0e3192ca8e3 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java @@ -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; } diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java index 1db09344acd3..8fa0c4c33bf1 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -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() {