JS/TS: inject jsregexp in RegExp constructor + fix escaping for JS RegExp injection in strings

This commit is contained in:
Anton Lobov
2017-12-19 13:59:56 +01:00
parent 7397deb695
commit 01bf24b384
2 changed files with 21 additions and 2 deletions
@@ -15,7 +15,10 @@
*/
package org.intellij.lang.regexp.inspection;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.ElementManipulator;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlElement;
import com.intellij.xml.util.XmlStringUtil;
@@ -31,7 +34,17 @@ public class RegExpReplacementUtil {
public static String escapeForContext(String text, RegExpElement element) {
final PsiElement context = element.getContainingFile().getContext();
if (RegExpElementImpl.isLiteralExpression(context)) {
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);
String newElementText = newElement.getText();
TextRange newRange = manipulator.getRangeInElement(newElement);
return newElementText.substring(newRange.getStartOffset(), newRange.getEndOffset());
}
else if (RegExpElementImpl.isLiteralExpression(context)) {
// otherwise, just pretend it is a Java-style string
return StringUtil.escapeStringCharacters(text);
}
else if (context instanceof XmlElement) {
@@ -23,6 +23,7 @@ import com.intellij.lang.ParserDefinition;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.IncorrectOperationException;
@@ -85,10 +86,15 @@ public abstract class RegExpElementImpl extends ASTWrapperPsiElement implements
public static boolean isLiteralExpression(@Nullable PsiElement context) {
if (context == null) return false;
final ASTNode astNode = context.getNode();
ASTNode astNode = context.getNode();
if (astNode == null) {
return false;
}
if (astNode instanceof CompositeElement) { // in some languages token nodes are wrapped within a single-child composite
ASTNode[] children = astNode.getChildren(null);
if (children.length != 1) return false;
astNode = children[0];
}
final IElementType elementType = astNode.getElementType();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(context.getLanguage());
return parserDefinition.getStringLiteralElements().contains(elementType);