IDEA-141110 (Allow to modify each repeated occurence in structural search individually.)

This commit is contained in:
Bas Leijdekkers
2015-06-05 15:19:10 +02:00
parent 5499c7f543
commit f62e6ccd5c
4 changed files with 57 additions and 14 deletions
@@ -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<StructuralSearchProfile> list = new ArrayList<StructuralSearchProfile>();
@@ -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<PsiElement> elements = new ArrayList<PsiElement>();
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);
@@ -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
@@ -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();
}
}