Java: create text block from any string concatenation (quick-fix only IDEA-263493)

GitOrigin-RevId: a312536b2e7b42aa2c7cf69beb896dd64b3a037e
This commit is contained in:
Bas Leijdekkers
2023-10-29 14:48:27 +01:00
committed by intellij-monorepo-bot
parent c14512fda7
commit 09d35674b1
6 changed files with 34 additions and 8 deletions

View File

@@ -45,13 +45,11 @@ public class TextBlockMigrationInspection extends AbstractBaseJavaLocalInspectio
if (!ExpressionUtils.hasStringType(expression)) return;
int nNewLines = 0;
TextRange firstNewLineTextRange = null;
boolean hasEscapedQuotes = false;
for (PsiExpression operand : expression.getOperands()) {
PsiLiteralExpression literal = getLiteralExpression(operand);
if (literal == null) return;
if (nNewLines > 1) continue;
String text = literal.getText();
hasEscapedQuotes |= (getQuoteIndex(text) != -1);
int newLineIdx = getNewLineIndex(text, 0);
if (newLineIdx == -1) continue;
if (firstNewLineTextRange == null) {
@@ -65,14 +63,13 @@ public class TextBlockMigrationInspection extends AbstractBaseJavaLocalInspectio
}
boolean hasComments = ContainerUtil.exists(expression.getChildren(), child -> child instanceof PsiComment);
boolean reportWarning = nNewLines > 1 && !hasComments;
boolean reportInfo = isOnTheFly && (hasEscapedQuotes || hasComments);
if (reportWarning) {
boolean quickFixOnly = isOnTheFly && InspectionProjectProfileManager.isInformationLevel(getShortName(), expression);
holder.registerProblem(expression, quickFixOnly ? null : firstNewLineTextRange,
JavaBundle.message("inspection.text.block.migration.concatenation.message"),
new ReplaceWithTextBlockFix());
}
else if (reportInfo) {
else if (isOnTheFly) {
holder.registerProblem(expression,
JavaBundle.message("inspection.text.block.migration.string.message"),
ProblemHighlightType.INFORMATION, new ReplaceWithTextBlockFix());
@@ -151,16 +148,30 @@ public class TextBlockMigrationInspection extends AbstractBaseJavaLocalInspectio
private static String @Nullable [] getContentLines(PsiExpression @NotNull [] operands) {
String[] lines = new String[operands.length];
PsiLiteralExpression previous = null;
for (int i = 0; i < operands.length; i++) {
PsiLiteralExpression literal = getLiteralExpression(operands[i]);
if (literal == null) return null;
String line = getLiteralText(literal);
if (line == null) return null;
if (previous != null && !onSameLine(previous, literal) && !lines[i - 1].endsWith("\\n")) {
lines[i - 1] += "\\\n";
}
previous = literal;
lines[i] = line;
}
return lines;
}
private static boolean onSameLine(@NotNull PsiElement e1, @NotNull PsiElement e2) {
PsiFile containingFile = e1.getContainingFile();
if (containingFile != e2.getContainingFile()) {
throw new IllegalArgumentException();
}
Document document = containingFile.getViewProvider().getDocument();
return document != null && document.getLineNumber(e1.getTextOffset()) == document.getLineNumber(e2.getTextOffset());
}
@Nullable
private static String getLiteralText(@NotNull PsiLiteralExpression literal) {
if (!literal.isTextBlock() && ExpressionUtils.hasStringType(literal)) return PsiLiteralUtil.getStringLiteralContent(literal);

View File

@@ -4,7 +4,8 @@ class TextBlockMigration {
void concatenationWithEscapedQuotesWithoutLineBreaks() {
String div = """
<div lang="{{interpolation?.here}}"></div>""";
<div lang="{{interpolation?.here}}">\
</div>""";
}
}

View File

@@ -6,7 +6,8 @@ class TextBlockMigration {
String string = """
foo
bar
baz \
baz\
\
""";
}

View File

@@ -0,0 +1,11 @@
// "Replace with text block" "INFORMATION-preview"
class TextBlockMigration {
void concatenationWithOneNewLine() {
String code = """
<html>
</html>""";
}
}

View File

@@ -7,7 +7,9 @@ class TextBlockMigration {
this concatenation contains
three quotes
one after another
""\"""";
"\
"\
\"""";
}
}

View File

@@ -1,4 +1,4 @@
// "Fix all 'Text block can be used' problems in file" "false"
// "Replace with text block" "INFORMATION-preview"
class TextBlockMigration {