KTIJ-30925 [ssr] Refactor typed variable handling in ReplacementBuilder

Moved typed variable utility methods from MatchUtil and Replacer to StructuralSearchProfile

GitOrigin-RevId: 0a80d063ea663bb708de118a6db0b6268b3b6147
This commit is contained in:
Aleksandr.Govenko
2024-08-08 15:17:59 +02:00
committed by intellij-monorepo-bot
parent 167e5654a6
commit 86e037e396
5 changed files with 46 additions and 14 deletions

View File

@@ -628,6 +628,7 @@ public final class JavaStructuralSearchProfile extends StructuralSearchProfile {
@Override
public void provideAdditionalReplaceOptions(@NotNull PsiElement node, @NotNull ReplaceOptions options, @NotNull ReplacementBuilder builder) {
final StructuralSearchProfile profile = this;
node.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
@@ -663,7 +664,7 @@ public final class JavaStructuralSearchProfile extends StructuralSearchProfile {
@Override
public void visitElement(@NotNull PsiElement element) {
final String type = element.getText();
if (MatchUtil.isTypedVariable(type)) {
if (profile.isReplacementTypedVariable(type)) {
final ParameterInfo typeInfo = builder.findParameterization(element);
if (typeInfo != null) {
typeInfo.setArgumentContext(false);

View File

@@ -14,10 +14,6 @@ public final class MatchUtil {
private static final String REG_EXP_META_CHARS = ".$|()[]{}^?*+\\";
private static final Pattern ACCENTS = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
public static boolean isTypedVariable(@NotNull String name) {
return name.length() > 1 && name.charAt(0) == '$' && name.charAt(name.length() - 1) == '$';
}
public static boolean containsRegExpMetaChar(String s) {
return s.chars().anyMatch(MatchUtil::isRegExpMetaChar);
}

View File

@@ -421,4 +421,18 @@ public abstract class StructuralSearchProfile {
public boolean isApplicableContextConfiguration(@NotNull Configuration configuration) {
return !configuration.isPredefined();
}
public boolean isReplacementTypedVariable(@NotNull String name) {
return name.length() > 1 && name.charAt(0) == '$' && name.charAt(name.length() - 1) == '$';
}
@NotNull
public String compileReplacementTypedVariable(@NotNull String name) {
return "$" + name + "$";
}
@NotNull
public String stripReplacementTypedVariableDecorations(@NotNull String name) {
return name.substring(1, name.length() - 1);
}
}

View File

@@ -94,15 +94,15 @@ public final class ReplacementBuilder {
assert dialect != null;
final PatternContextInfo context = new PatternContextInfo(PatternTreeContext.Block, options.getMatchOptions().getPatternContext());
final PsiElement[] elements =
MatcherImplUtil.createTreeFromText(options.getReplacement(), context, fileType, dialect, project, false);
MatcherImplUtil.createTreeFromText(prepareReplacementPattern(), context, fileType, dialect, project, false);
if (elements.length > 0) {
final PsiElement patternNode = elements[0].getParent();
patternNode.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(@NotNull PsiElement element) {
final String text = element.getText();
if (MatchUtil.isTypedVariable(text)) {
final Collection<ParameterInfo> infos = findParameterization(Replacer.stripTypedVariableDecoration(text));
if (profile.isReplacementTypedVariable(text)) {
final Collection<ParameterInfo> infos = findParameterization(profile.stripReplacementTypedVariableDecorations(text));
for (ParameterInfo info : infos) {
if (info.getElement() == null) {
info.setElement(element);
@@ -181,8 +181,33 @@ public final class ReplacementBuilder {
public ParameterInfo findParameterization(PsiElement element) {
if (element == null) return null;
StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
assert profile != null;
final String text = element.getText();
if (!MatchUtil.isTypedVariable(text)) return null;
return ContainerUtil.find(findParameterization(Replacer.stripTypedVariableDecoration(text)), info -> info.getElement() == element);
if (!profile.isReplacementTypedVariable(text)) return null;
return ContainerUtil.find(findParameterization(profile.stripReplacementTypedVariableDecorations(text)), info -> info.getElement() == element);
}
@NotNull
public String prepareReplacementPattern() {
final LanguageFileType fileType = options.getMatchOptions().getFileType();
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
assert profile != null;
final StringBuilder buf = new StringBuilder();
final Template template = TemplateManager.getInstance(myProject).createTemplate("", "", options.getReplacement());
final int segmentsCount = template.getSegmentsCount();
final String text = template.getTemplateText();
int prevOffset = 0;
for (int i = 0; i < segmentsCount; i++) {
final int offset = template.getSegmentOffset(i);
final String name = template.getSegmentName(i);
final String compiledName = profile.compileReplacementTypedVariable(name);
buf.append(text, prevOffset, offset).append(compiledName);
prevOffset = offset;
}
buf.append(text.substring(prevOffset));
return buf.toString();
}
}

View File

@@ -55,10 +55,6 @@ public class Replacer {
replacementBuilder = new ReplacementBuilder(this.project, this.options);
}
public static String stripTypedVariableDecoration(final String type) {
return type.substring(1, type.length() - 1);
}
public static int insertSubstitution(StringBuilder result, int offset, final ParameterInfo info, String image) {
if (!image.isEmpty()) {
result.insert(offset + info.getStartIndex(), image);