RegExp: always use document replacement

because content manipulators ignore text range
This commit is contained in:
Bas Leijdekkers
2018-05-21 16:53:29 +02:00
parent 1e684f04aa
commit 8b6bdb6715
@@ -8,7 +8,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlElement;
import com.intellij.xml.util.XmlStringUtil;
import org.intellij.lang.regexp.psi.RegExpElement;
import org.intellij.lang.regexp.psi.impl.RegExpElementImpl;
import org.jetbrains.annotations.NotNull;
@@ -21,27 +20,36 @@ public class RegExpReplacementUtil {
public static void replaceInContext(@NotNull PsiElement element, @NotNull String text) {
final PsiFile file = element.getContainingFile();
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(element.getProject());
if (injectedLanguageManager.isInjectedFragment(file)) {
final PsiElement context = file.getContext();
ElementManipulator<PsiElement> manipulator = context == null ? null : ElementManipulators.getManipulator(context);
if (manipulator != null) {
// use element manipulator to process escape sequences correctly for all supported languages
final TextRange range = manipulator.getRangeInElement(context);
if (manipulator.handleContentChange(context, range.cutOut(element.getTextRange()), text) != null) {
return;
}
}
if (RegExpElementImpl.isLiteralExpression(context)) {
text = StringUtil.escapeStringCharacters(text);
}
else if (context instanceof XmlElement) {
text = XmlStringUtil.escapeString(text);
}
}
text = escapeForContext(text, file);
final Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(file);
assert document != null;
final TextRange replaceRange = element.getTextRange();
document.replaceString(replaceRange.getStartOffset(), replaceRange.getEndOffset(), text);
}
private static String escapeForContext(String text, PsiFile file) {
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(file.getProject());
if (injectedLanguageManager.isInjectedFragment(file)) {
final PsiElement context = file.getContext();
ElementManipulator<PsiElement> manipulator = context == null ? null : ElementManipulators.getManipulator(context);
if (manipulator != null) {
// use element manipulator to process escape sequences correctly for all supported languages
PsiElement copy = context.copy(); // create a copy to avoid original element modifications
PsiElement newElement = manipulator.handleContentChange(copy, text);
if (newElement != null) {
String newElementText = newElement.getText();
TextRange newRange = manipulator.getRangeInElement(newElement);
return newElementText.substring(newRange.getStartOffset(), newRange.getEndOffset());
}
}
if (RegExpElementImpl.isLiteralExpression(context)) {
// otherwise, just pretend it is a Java-style string
return StringUtil.escapeStringCharacters(text);
}
else if (context instanceof XmlElement) {
return XmlStringUtil.escapeString(text);
}
}
return text;
}
}