From 08e0c753076a5d439eb017cec565395a4bedc372 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 2 Aug 2019 10:20:08 +0300 Subject: [PATCH] text blocks: avoid changing contract of externally used method (IDEA-CR-50967) GitOrigin-RevId: 1d325fd703565bd699ac7dfc4c9711852987f644 --- .../ConcatenationToMessageFormatAction.java | 2 +- .../psi/util/PsiConcatenationUtil.java | 30 ++++++++++++++----- .../ConcatenationToMessageFormatTest.java | 2 +- ...oncatenationWithFormatStringIntention.java | 6 ++-- .../i18n/I18nizeConcatenationQuickFix.java | 2 +- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java index 6e20bff6e4f7..5feccaaf83fd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java @@ -46,7 +46,7 @@ public class ConcatenationToMessageFormatAction implements IntentionAction { PsiPolyadicExpression concatenation = getEnclosingLiteralConcatenation(element); if (concatenation == null) return; List args = new ArrayList<>(); - final String formatString = PsiConcatenationUtil.buildFormatString(concatenation, false, args); + final String formatString = PsiConcatenationUtil.buildUnescapedFormatString(concatenation, false, args); final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); PsiMethodCallExpression call = (PsiMethodCallExpression) diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java index 2128b7d6c118..0f0ddacfb2e0 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.util; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.ObjectUtils; @@ -15,21 +16,36 @@ public class PsiConcatenationUtil { /** * @param formatParameters output parameter, will contain the format parameters found in the concatenation - * @return unescaped (!) format string produced from the concatenation + * @return unescaped format string produced from the concatenation */ - public static String buildFormatString(PsiExpression concatenation, boolean printfFormat, - List formatParameters) { + public static String buildUnescapedFormatString(PsiExpression concatenation, boolean printfFormat, + List formatParameters) { final StringBuilder result = new StringBuilder(); - buildFormatString(concatenation, result, formatParameters, printfFormat); + buildFormatString(concatenation, result, formatParameters, printfFormat, false); return result.toString(); } // externally used + + /** + * @deprecated use {@code buildUnescapedFormatString} instead and use either + * {@code com.intellij.openapi.util.text.StringUtil#escapeStringCharacters(java.lang.String)} + * or + * {@code com.intellij.openapi.util.text.StringUtil#escapeTextBlockCharacters(java.lang.String)} + * to escape the resulting string. + */ + @Deprecated public static void buildFormatString(PsiExpression expression, StringBuilder formatString, List formatParameters, boolean printfFormat) { + buildFormatString(expression, formatString, formatParameters, printfFormat, true); + } + + private static void buildFormatString(PsiExpression expression, StringBuilder formatString, + List formatParameters, boolean printfFormat, boolean escape) { if (expression instanceof PsiLiteralExpression) { final PsiLiteralExpression literalExpression = (PsiLiteralExpression) expression; - final String text = String.valueOf(literalExpression.getValue()); + final String value = String.valueOf(literalExpression.getValue()); + final String text = escape ? StringUtil.escapeStringCharacters(value) : value; String formatText; if (printfFormat) { formatText = text.replace("%", "%%").replace("\\'", "'"); @@ -48,7 +64,7 @@ public class PsiConcatenationUtil { boolean stringStarted = first != null && first.equalsToText(JAVA_LANG_STRING) || second != null && second.equalsToText(JAVA_LANG_STRING); if (stringStarted) { - buildFormatString(operands[0], formatString, formatParameters, printfFormat); + buildFormatString(operands[0], formatString, formatParameters, printfFormat, escape); } for (int i = 1; i < operands.length; i++) { PsiExpression op = operands[i]; @@ -66,7 +82,7 @@ public class PsiConcatenationUtil { } if (stringStarted) { if (optype != null && (optype.equalsToText(JAVA_LANG_STRING) || PsiType.CHAR.equals(optype))) { - buildFormatString(op, formatString, formatParameters, printfFormat); + buildFormatString(op, formatString, formatParameters, printfFormat, escape); } else { addFormatParameter(op, formatString, formatParameters, printfFormat); diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/ConcatenationToMessageFormatTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/ConcatenationToMessageFormatTest.java index 67634a6a21d9..9df131c81e9c 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/ConcatenationToMessageFormatTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/ConcatenationToMessageFormatTest.java @@ -42,7 +42,7 @@ public class ConcatenationToMessageFormatTest extends JavaCodeInsightFixtureTest private void doTest(String expressionText, String messageFormatText, String... foundExpressionTexts) { final PsiExpression expression = getElementFactory().createExpressionFromText(expressionText, null); final ArrayList args = new ArrayList<>(); - final String formatString = PsiConcatenationUtil.buildFormatString(expression, false, args); + final String formatString = PsiConcatenationUtil.buildUnescapedFormatString(expression, false, args); assertEquals(messageFormatText, formatString); assertEquals(foundExpressionTexts.length, args.size()); for (int i = 0; i < foundExpressionTexts.length; i++) { diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java index 92a6eb6f456b..fcc661a74d6d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java @@ -33,7 +33,7 @@ public class ReplaceConcatenationWithFormatStringIntention extends Intention { parent = expression.getParent(); } final List formatParameters = new ArrayList<>(); - final String formatString = PsiConcatenationUtil.buildFormatString(expression, true, formatParameters); + final String formatString = PsiConcatenationUtil.buildUnescapedFormatString(expression, true, formatParameters); if (replaceWithPrintfExpression(expression, formatString, formatParameters)) { return; } @@ -49,7 +49,7 @@ public class ReplaceConcatenationWithFormatStringIntention extends Intention { PsiReplacementUtil.replaceExpression(expression, newExpression.toString(), commentTracker); } - private static boolean replaceWithPrintfExpression(PsiPolyadicExpression expression, CharSequence formatString, + private static boolean replaceWithPrintfExpression(PsiPolyadicExpression expression, String formatString, List formatParameters) { final PsiElement expressionParent = expression.getParent(); if (!(expressionParent instanceof PsiExpressionList)) { @@ -92,7 +92,7 @@ public class ReplaceConcatenationWithFormatStringIntention extends Intention { newExpression.append(commentTracker.text(qualifier)).append('.'); } newExpression.append("printf("); - appendFormatString(expression, formatString.toString(), insertNewline, newExpression); + appendFormatString(expression, formatString, insertNewline, newExpression); for (PsiExpression formatParameter : formatParameters) { newExpression.append(",").append(commentTracker.text(formatParameter)); } diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeConcatenationQuickFix.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeConcatenationQuickFix.java index 05b0a43b384e..4707ac4ab8cb 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeConcatenationQuickFix.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/I18nizeConcatenationQuickFix.java @@ -69,7 +69,7 @@ public class I18nizeConcatenationQuickFix extends I18nizeQuickFix{ String formatString = ""; final List args = new ArrayList<>(); try { - formatString = StringUtil.escapeStringCharacters(PsiConcatenationUtil.buildFormatString(concatenation, false, args)); + formatString = StringUtil.escapeStringCharacters(PsiConcatenationUtil.buildUnescapedFormatString(concatenation, false, args)); } catch (IncorrectOperationException e) { LOG.error(e);