diff --git a/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantExpressionIntention.java b/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantExpressionIntention.java index 4a3f7540..09d36b54 100644 --- a/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantExpressionIntention.java +++ b/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantExpressionIntention.java @@ -25,7 +25,7 @@ import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; import consulo.localize.LocalizeValue; -import consulo.util.lang.StringUtil; +import consulo.util.lang.StringEscapeUtil; import jakarta.annotation.Nonnull; import org.intellij.idea.lang.javascript.intention.JSElementPredicate; import org.intellij.idea.lang.javascript.intention.JSIntention; @@ -40,24 +40,24 @@ fileExtensions = "js" ) public class JSConstantExpressionIntention extends JSIntention { - @Override @Nonnull + @Override public LocalizeValue getText() { return JSIntentionLocalize.constantComputeExpression(); } - @Override @Nonnull + @Override protected JSElementPredicate getElementPredicate() { return new ConstantExpressionPredicate(); } @Override public void processIntention(@Nonnull PsiElement element) throws IncorrectOperationException { - JSExpression expression = (JSExpression)element; + JSExpression expression = (JSExpression) element; Object value = ExpressionUtil.computeConstantExpression(expression); String newExpression = value instanceof String strValue - ? '"' + StringUtil.escapeStringCharacters(strValue) + '"' + ? StringEscapeUtil.quote(strValue, '"') : String.valueOf(value); JSElementFactory.replaceExpression(expression, newExpression); } @@ -65,22 +65,14 @@ public void processIntention(@Nonnull PsiElement element) throws IncorrectOperat private static class ConstantExpressionPredicate implements JSElementPredicate { @Override public boolean satisfiedBy(@Nonnull PsiElement element) { - if (!(element instanceof JSExpression) || ErrorUtil.containsError(element)) { - return false; - } - JSExpression expression = (JSExpression)element; - - if (element instanceof JSLiteralExpression - || (element instanceof JSReferenceExpression referenceExpression && referenceExpression.getQualifier() != null) - || expression instanceof JSCallExpression - || !ExpressionUtil.isConstantExpression(expression) - || ExpressionUtil.computeConstantExpression(expression) == null) { - return false; - } - - PsiElement parent = element.getParent(); - - return !(parent instanceof JSExpression parentExpression && ExpressionUtil.isConstantExpression(parentExpression)); + return element instanceof JSExpression expression + && !ErrorUtil.containsError(element) + && !(element instanceof JSLiteralExpression) + && !(element instanceof JSReferenceExpression refExpr && refExpr.getQualifier() != null) + && !(expression instanceof JSCallExpression) + && ExpressionUtil.isConstantExpression(expression) + && ExpressionUtil.computeConstantExpression(expression) != null + && !(element.getParent() instanceof JSExpression parentExpr && ExpressionUtil.isConstantExpression(parentExpr)); } } } diff --git a/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantSubexpressionIntention.java b/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantSubexpressionIntention.java index c98c59ea..e9372468 100644 --- a/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantSubexpressionIntention.java +++ b/intentions/src/main/java/org/intellij/idea/lang/javascript/intention/constant/JSConstantSubexpressionIntention.java @@ -27,7 +27,7 @@ import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; import consulo.localize.LocalizeValue; -import consulo.util.lang.StringUtil; +import consulo.util.lang.StringEscapeUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import org.intellij.idea.lang.javascript.intention.JSElementPredicate; @@ -44,8 +44,8 @@ fileExtensions = "js" ) public class JSConstantSubexpressionIntention extends JSMutablyNamedIntention { - @Override @Nonnull + @Override protected JSElementPredicate getElementPredicate() { return new ConstantSubexpressionPredicate(); } @@ -60,14 +60,14 @@ protected LocalizeValue getBasicText() { @RequiredReadAction protected LocalizeValue getTextForElement(PsiElement element) { PsiElement parent = element.getParent(); - JSBinaryExpression binaryExpression = (JSBinaryExpression)(parent instanceof JSBinaryExpression ? parent : element); + JSBinaryExpression binaryExpression = (JSBinaryExpression) (parent instanceof JSBinaryExpression ? parent : element); JSExpression lhs = binaryExpression.getLOperand(); JSExpression leftSide = lhs instanceof JSBinaryExpression lhsBinaryExpression ? lhsBinaryExpression.getROperand() : lhs; IElementType operationSign = binaryExpression.getOperationSign(); JSExpression rhs = binaryExpression.getROperand(); - assert (rhs != null); - assert (leftSide != null); + assert rhs != null; + assert leftSide != null; return JSIntentionLocalize.constantComputeSubexpressionMessage( leftSide.getText(), @@ -80,20 +80,17 @@ protected LocalizeValue getTextForElement(PsiElement element) { @RequiredReadAction public void processIntention(@Nonnull PsiElement element) throws IncorrectOperationException { PsiElement parent = element.getParent(); - JSExpression expression = (JSExpression)(parent instanceof JSBinaryExpression ? parent : element); - String newExpression = ""; + JSExpression expression = (JSExpression) (parent instanceof JSBinaryExpression ? parent : element); + StringBuilder newExpression = new StringBuilder(); Object constantValue; - if (expression instanceof JSBinaryExpression) { - JSBinaryExpression binaryExpression = (JSBinaryExpression)expression; - JSExpression lhs = binaryExpression.getLOperand(); - - if (lhs instanceof JSBinaryExpression lhsBinaryExpression) { - JSExpression rightSide = lhsBinaryExpression.getROperand(); + if (expression instanceof JSBinaryExpression binaryExpression) { + if (binaryExpression.getLOperand() instanceof JSBinaryExpression lhsBinaryExpr) { + JSExpression rightSide = lhsBinaryExpr.getROperand(); - newExpression += getLeftSideText(lhsBinaryExpression); + appendLeftSideText(lhsBinaryExpr, newExpression); - assert (rightSide != null); + assert rightSide != null; } constantValue = ExpressionUtil.computeConstantExpression(getSubexpression(binaryExpression)); } @@ -101,20 +98,23 @@ public void processIntention(@Nonnull PsiElement element) throws IncorrectOperat constantValue = ExpressionUtil.computeConstantExpression(expression); } - newExpression += constantValue instanceof String strValue - ? '"' + StringUtil.escapeStringCharacters(strValue) + '"' - : String.valueOf(constantValue); - JSElementFactory.replaceExpression(expression, newExpression); + if (constantValue instanceof String strValue) { + StringEscapeUtil.escape(strValue, '"', newExpression); + } + else { + newExpression.append(constantValue); + } + JSElementFactory.replaceExpression(expression, newExpression.toString()); } @RequiredReadAction - private static String getLeftSideText(JSBinaryExpression binaryExpression) { - return binaryExpression.getLOperand().getText() + - BinaryOperatorUtils.getOperatorText(binaryExpression.getOperationSign()); + private static void appendLeftSideText(JSBinaryExpression binaryExpression, StringBuilder builder) { + builder.append(binaryExpression.getLOperand().getText()) + .append(BinaryOperatorUtils.getOperatorText(binaryExpression.getOperationSign())); } /** - * Returns the smallest subexpression (if precendence allows it). For instance: + * Returns the smallest subexpression (if precedence allows it). For instance: * variable + 2 + 3 normally gets evaluated left to right -> (variable + 2) * + 3 this method returns the right most legal subexpression -> 2 + 3 * @@ -126,7 +126,7 @@ private static String getLeftSideText(JSBinaryExpression binaryExpression) { private static JSBinaryExpression getSubexpression(JSBinaryExpression expression) { JSExpression rhs = expression.getROperand(); IElementType sign = expression.getOperationSign(); - int parentPrecendence = ParenthesesUtils.getPrecendence(expression); + int parentPrecedence = ParenthesesUtils.getPrecendence(expression); if (rhs == null) { return null; @@ -138,17 +138,17 @@ private static JSBinaryExpression getSubexpression(JSBinaryExpression expression return expression; } - JSBinaryExpression lhsBinaryExpression = (JSBinaryExpression)lhs; - int childPrecendence = ParenthesesUtils.getPrecendence(lhsBinaryExpression); + JSBinaryExpression lhsBinaryExpression = (JSBinaryExpression) lhs; + int childPrecedence = ParenthesesUtils.getPrecendence(lhsBinaryExpression); JSExpression leftSide = lhsBinaryExpression.getROperand(); - if (leftSide == null || parentPrecendence > childPrecendence) { + if (leftSide == null || parentPrecedence > childPrecedence) { return null; } try { String subExpressionText = leftSide.getText() + BinaryOperatorUtils.getOperatorText(sign) + rhs.getText(); - return (JSBinaryExpression)JSChangeUtil.createExpressionFromText(expression.getProject(), subExpressionText); + return (JSBinaryExpression) JSChangeUtil.createExpressionFromText(expression.getProject(), subExpressionText); } catch (Throwable ignore) { return null; @@ -174,7 +174,7 @@ public boolean satisfiedBy(@Nonnull PsiElement element) { return false; } } - JSBinaryExpression binaryExpression = (JSBinaryExpression)parent; + JSBinaryExpression binaryExpression = (JSBinaryExpression) parent; JSBinaryExpression subexpression = getSubexpression(binaryExpression); if (subexpression == null) { diff --git a/plugin/src/main/java/com/intellij/javascript/manipulators/JSAbstractElementManipulator.java b/plugin/src/main/java/com/intellij/javascript/manipulators/JSAbstractElementManipulator.java index 551e93c9..f823a0dd 100644 --- a/plugin/src/main/java/com/intellij/javascript/manipulators/JSAbstractElementManipulator.java +++ b/plugin/src/main/java/com/intellij/javascript/manipulators/JSAbstractElementManipulator.java @@ -15,24 +15,30 @@ */ package com.intellij.javascript.manipulators; +import consulo.annotation.access.RequiredWriteAction; import consulo.document.util.TextRange; -import consulo.language.psi.PsiElement; -import consulo.project.Project; import consulo.language.psi.AbstractElementManipulator; +import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; -import consulo.util.lang.StringUtil; +import consulo.project.Project; +import consulo.util.lang.StringEscapeUtil; /** * @author peter */ abstract class JSAbstractElementManipulator extends AbstractElementManipulator { @Override + @RequiredWriteAction + @SuppressWarnings("unchecked") public T handleContentChange(T element, TextRange range, String newContent) throws IncorrectOperationException { String oldText = element.getText(); - newContent = StringUtil.escapeStringCharacters(newContent); - String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset()); + int oldLength = oldText.length(); + StringBuilder newText = new StringBuilder(oldLength); + newText.append(oldText, 0, range.getStartOffset()); + StringEscapeUtil.escape(newContent, '"', newText); + newText.append(oldText, range.getEndOffset(), oldLength); - return (T)element.replace(createTree(newText, element.getProject())); + return (T) element.replace(createTree(newText.toString(), element.getProject())); } protected abstract T createTree(String newText, Project project); diff --git a/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AS3InterfaceDumper.java b/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AS3InterfaceDumper.java index e0d2f1f1..098574c3 100644 --- a/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AS3InterfaceDumper.java +++ b/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AS3InterfaceDumper.java @@ -16,6 +16,7 @@ package com.intellij.lang.javascript.impl.flex.importer; +import consulo.util.lang.StringEscapeUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -86,9 +87,8 @@ protected static String getValueRepr(Object valueObject) { catch (NumberFormatException ignored) { } } - else if (value.length() > 0 && (Character.isDigit( - ch = value.charAt(0)) || (ch == '-' && value.length() > 1 && Character.isDigit(value.charAt(1) - )))) { + else if (value.length() > 0 + && (Character.isDigit(ch = value.charAt(0)) || ch == '-' && value.length() > 1 && Character.isDigit(value.charAt(1)))) { try { Integer.parseInt(value); doQoute = false; @@ -98,17 +98,17 @@ else if (value.length() > 0 && (Character.isDigit( } if (doQoute) { - value = "\"" + quote(value) + "\""; + value = StringEscapeUtil.quote(value, '"'); } } return value; } - private static final Set DO_NOT_NEED_QOTING = + private static final Set DO_NOT_NEED_QUOTING = Set.of("null", "NaN", "undefined", "true", "false", "Infinity", "-Infinity"); private static boolean needsQuoting(String value) { - return !DO_NOT_NEED_QOTING.contains(value); + return !DO_NOT_NEED_QUOTING.contains(value); } @Override diff --git a/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AbstractDumpProcessor.java b/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AbstractDumpProcessor.java index 7eecd220..6a3ccfac 100644 --- a/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AbstractDumpProcessor.java +++ b/plugin/src/main/java/com/intellij/lang/javascript/impl/flex/importer/AbstractDumpProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.lang.javascript.impl.flex.importer; import jakarta.annotation.Nonnull; @@ -237,29 +236,4 @@ protected void dumpInterfacesList(String indent, Traits it, boolean anInterface) append("\n"); } } - - protected static String quote(String s) { - if (s.length() == 0) { - return s; - } - StringBuilder b = new StringBuilder(s.length()); - - for (int i = 0; i < s.length(); ++i) { - char ch = s.charAt(i); - - if (ch == '\\' || ch == '"') { - b.append('\\'); - } - else if (ch == '\n') { - b.append("\\n"); - continue; - } - else if (ch == '\r') { - b.append("\\r"); - continue; - } - b.append(ch); - } - return b.toString(); - } }