From a3970e6a5a976e69b800aa3511d24dec289e45d6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 21 Oct 2016 17:53:10 +0200 Subject: [PATCH] SSR: fix repeated substitution variable with nested match matching problem --- .../matcher/handlers/SubstitutionHandler.java | 37 ++++++++++++++----- .../StructuralSearchTest.java | 8 ++++ 2 files changed, 36 insertions(+), 9 deletions(-) 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 0c4023daef1b..73dad2f2d9d9 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 @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2016 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. + */ package com.intellij.structuralsearch.impl.matcher.handlers; import com.intellij.dupLocator.iterators.FilteringNodeIterator; @@ -119,22 +134,26 @@ public class SubstitutionHandler extends MatchingHandler { return false; } - MatchResultImpl result = context.getResult().findSon(name); - + MatchResultImpl result = context.hasResult() ? context.getResult().findSon(name) : null; + if (result == null && context.getPreviousResult() != null) { result = context.getPreviousResult().findSon(name); } - if (result!=null) { + if (result != null) { if (minOccurs == 1 && maxOccurs == 1) { // check if they are the same return validateOneMatch(match, start, end, result,context); - } else if (maxOccurs > 1 && totalMatchedOccurs!=-1) { - final int size = result.getAllSons().size(); - if (matchedOccurs >= size) { - return false; + } else if (maxOccurs > 1 && totalMatchedOccurs != -1) { + if (result.isMultipleMatch()) { + final int size = result.getAllSons().size(); + if (matchedOccurs >= size) { + return false; + } + if (size != 0) { + result = (MatchResultImpl)result.getAllSons().get(matchedOccurs); + } } - result = size == 0 ?result:(MatchResultImpl)result.getAllSons().get(matchedOccurs); // check if they are the same return validateOneMatch(match, start, end, result, context); } @@ -241,7 +260,7 @@ public class SubstitutionHandler extends MatchingHandler { } boolean validate(MatchContext context, Class elementContext) { - MatchResult substitution = context.getResult().findSon(name); + MatchResult substitution = context.hasResult() ? context.getResult().findSon(name) : null; if (minOccurs >= 1 && ( substitution == null || diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java index 3e4da10a1c67..32e757e98e1f 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -2389,5 +2389,13 @@ public class StructuralSearchTest extends StructuralSearchTestCase { "}"; assertEquals("find super call", 1, findMatchesCount(source, "super.'_m()")); assertEquals("find super and non super call", 2, findMatchesCount(source, "'_q:[regex( super|this )].'_m()")); + + String source2 = "class A {" + + " public boolean equals(Object o) {" + + " return super.equals(o);" + + " }" + + "}"; + assertEquals("find method with super call and matching parameter", 1, + findMatchesCount(source2, "'_rt '_m('_t '_p*) { return super.'_m('_p); }")); } }