diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java b/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java index c8033c781b13..b4b9747da6a4 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java @@ -37,6 +37,10 @@ public class StructuralSearchUtil { return profile != null && profile.isIdentifier(element); } + public static PsiElement getParentIfIdentifier(PsiElement element) { + return !isIdentifier(element) ? element : element.getParent(); + } + private static StructuralSearchProfile[] getNewStyleProfiles() { if (ourNewStyleProfiles == null) { final List list = new ArrayList(); diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java index c89dd961a3a8..364052e11453 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java @@ -6,7 +6,6 @@ import com.intellij.structuralsearch.MatchResult; import com.intellij.structuralsearch.SSRBundle; import com.intellij.structuralsearch.StructuralSearchException; import com.intellij.structuralsearch.StructuralSearchUtil; -import com.intellij.structuralsearch.impl.matcher.MatchResultImpl; import groovy.lang.Binding; import groovy.lang.GroovyRuntimeException; import groovy.lang.GroovyShell; @@ -20,6 +19,7 @@ import org.codehaus.groovy.syntax.SyntaxException; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; /** @@ -41,20 +41,29 @@ public class ScriptSupport { } } - public String evaluate(MatchResultImpl result, PsiElement context) { + public String evaluate(MatchResult result, PsiElement context) { try { - Binding binding = new Binding(); + final Binding binding = new Binding(); if (result != null) { - for(MatchResult r:result.getMatches()) { - binding.setVariable(r.getName(),r.getMatchRef().getElement()); + for(MatchResult r:result.getAllSons()) { + if (r.isMultipleMatch()) { + final ArrayList elements = new ArrayList(); + for (MatchResult r2 : r.getAllSons()) { + elements.add(StructuralSearchUtil.getParentIfIdentifier(r2.getMatch())); + } + binding.setVariable(r.getName(), elements); + } + else { + binding.setVariable(r.getName(), StructuralSearchUtil.getParentIfIdentifier(r.getMatch())); + } } } if (context == null) { - context = result.getMatchRef().getElement(); + context = result.getMatch(); } - if (StructuralSearchUtil.isIdentifier(context)) context = context.getParent(); + context = StructuralSearchUtil.getParentIfIdentifier(context); binding.setVariable("__context__", context); script.setBinding(binding); diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java index ec9ff6103211..2ec2c6ed3175 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java @@ -5,12 +5,12 @@ import com.intellij.codeInsight.template.TemplateManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiRecursiveElementWalkingVisitor; import com.intellij.structuralsearch.MalformedPatternException; import com.intellij.structuralsearch.MatchResult; import com.intellij.structuralsearch.StructuralSearchProfile; import com.intellij.structuralsearch.StructuralSearchUtil; -import com.intellij.structuralsearch.impl.matcher.MatchResultImpl; import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil; import com.intellij.structuralsearch.impl.matcher.PatternTreeContext; import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport; @@ -19,7 +19,10 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author maxim @@ -177,7 +180,7 @@ public final class ReplacementBuilder { scriptSupport = new ScriptSupport(StringUtil.stripQuotesAroundValue(constraint), info.getName()); replacementVarsMap.put(info.getName(), scriptSupport); } - return scriptSupport.evaluate((MatchResultImpl)match, null); + return scriptSupport.evaluate(match, null); } @Nullable diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java index bd8b827f9418..6c204de6ea05 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java @@ -1296,7 +1296,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { actualResult ); } - + public void testClassReplacement5() { final String actualResult; String s1 = "public class X {\n" + @@ -2078,7 +2078,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { String expected_2 = "if (args == null) return ;\n" + " while(true) return ;\n" + " System.out.println(\"blah2\");"; - + actualResult = replacer.testReplace(s1_2,s2,replacement,options); assertEquals( @@ -2176,7 +2176,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { String s3_2 = "$st$;\n" + "int $c$ = $i$;"; String expected_2 = "a = 2;\nint b = 1;\nb2 = 3;"; - + actualResult = replacer.testReplace(s1,s2_2,s3_2,options); assertEquals( @@ -2334,4 +2334,31 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { final String by2 = "float $a$, $b$, $c$ = $d$;"; assertEquals("class A { private float i, j, k ; void m() { float i, j, k ; }}", replacer.testReplace(in, what2, by2, options)); } + + public void testReplaceWithScriptedVariable() { + final String in = "class A {\n" + + " void method(Object... os) {}\n" + + " void f(Object a, Object b, Object c) {\n" + + " method(a, b, c, \"one\" + \"two\");\n" + + " method(a);\n" + + " }\n" + + "}"; + final String what = "method('_arg+)"; + final String by = "method($newarg$)"; + final ReplacementVariableDefinition variable = new ReplacementVariableDefinition(); + variable.setName("newarg"); + variable.setScriptCodeConstraint("arg.collect { \"(String)\" + it.getText() }.join(',')"); + options.addVariableDefinition(variable); + + final String expected = "class A {\n" + + " void method(Object... os) {}\n" + + " void f(Object a, Object b, Object c) {\n" + + " method((String)a,(String)b,(String)c,(String)\"one\" + \"two\");\n" + + " method((String)a);\n" + + " }\n" + + "}"; + assertEquals(expected, replacer.testReplace(in, what, by, options)); + + options.clearVariableDefinitions(); + } } \ No newline at end of file