From e4150e0d4e05e4aac5c0465bc8068270ae901ef4 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 19 Dec 2025 12:16:31 +0100 Subject: [PATCH] IDEA-383426 [java]: normalize strings with leading newlines when replacing with text block GitOrigin-RevId: a31195746d6d797f217d13c7351179fa12adb6ae --- .../TextBlockMigrationInspection.java | 22 +++++++++++-------- .../afterLeadingNewlines.java | 12 ++++++++++ .../beforeLeadingNewlines.java | 10 +++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/inspection/textBlockMigration/afterLeadingNewlines.java create mode 100644 java/java-tests/testData/inspection/textBlockMigration/beforeLeadingNewlines.java diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/TextBlockMigrationInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/TextBlockMigrationInspection.java index 6f1dec1564f1..70d1220405c6 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/TextBlockMigrationInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/TextBlockMigrationInspection.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInspection; import com.intellij.codeInspection.options.OptPane; @@ -115,17 +115,15 @@ public final class TextBlockMigrationInspection extends AbstractBaseJavaLocalIns if (expression == null) return; Document document = expression.getContainingFile().getViewProvider().getDocument(); if (document == null) return; - PsiLiteralExpression literalExpression = tryCast(expression, PsiLiteralExpression.class); - if (literalExpression != null) { - replaceWithTextBlock(new PsiExpression[]{literalExpression}, literalExpression); - return; + if (expression instanceof PsiLiteralExpression literalExpression) { + replaceWithTextBlock(literalExpression, new PsiExpression[]{literalExpression}); + } + else if (expression instanceof PsiPolyadicExpression polyadicExpression && ExpressionUtils.hasStringType(polyadicExpression)) { + replaceWithTextBlock(polyadicExpression, polyadicExpression.getOperands()); } - PsiPolyadicExpression polyadicExpression = tryCast(expression, PsiPolyadicExpression.class); - if (polyadicExpression == null || !ExpressionUtils.hasStringType(polyadicExpression)) return; - replaceWithTextBlock(polyadicExpression.getOperands(), polyadicExpression); } - private static void replaceWithTextBlock(PsiExpression @NotNull [] operands, @NotNull PsiExpression toReplace) { + private static void replaceWithTextBlock(@NotNull PsiExpression toReplace, PsiExpression @NotNull [] operands) { String[] lines = getContentLines(operands); if (lines == null) return; CommentTracker tracker = new CommentTracker(); @@ -139,6 +137,12 @@ public final class TextBlockMigrationInspection extends AbstractBaseJavaLocalIns // append \ + newline at the end of the last line, so we can use closing """ to indent lines[lines.length - 1] += "\\\n"; } + for (int i = 0; i < lines.length - 1; i++) { + String line = lines[i]; + if (line.endsWith("\\\n") && lines[i + 1].equals("\n")) { + lines[i] = line.substring(0, line.length() - 2); // normalize strings with leading newlines + } + } String content = StringUtil.join(lines); if (content.endsWith(" ")) { content = content.substring(0, content.length() - 1) + "\\s"; diff --git a/java/java-tests/testData/inspection/textBlockMigration/afterLeadingNewlines.java b/java/java-tests/testData/inspection/textBlockMigration/afterLeadingNewlines.java new file mode 100644 index 000000000000..88bd461722e1 --- /dev/null +++ b/java/java-tests/testData/inspection/textBlockMigration/afterLeadingNewlines.java @@ -0,0 +1,12 @@ +// "Replace with text block" "true-preview" + +class LeadingNewlines { + + public static void main(String[] args) { + String text = """ + + +---------------------------- ------------------------------------------------------------+ + | Unable to authenticate the microservice. Administrative functions will not be available | + +-----------------------------------------------------------------------------------------+"""; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/textBlockMigration/beforeLeadingNewlines.java b/java/java-tests/testData/inspection/textBlockMigration/beforeLeadingNewlines.java new file mode 100644 index 000000000000..20a0fcd0d697 --- /dev/null +++ b/java/java-tests/testData/inspection/textBlockMigration/beforeLeadingNewlines.java @@ -0,0 +1,10 @@ +// "Replace with text block" "true-preview" + +class LeadingNewlines { + + public static void main(String[] args) { + String text = "\n+---------------------------- ------------------------------------------------------------+" + + "\n| Unable to authenticate the microservice. Administrative functions will not be available |" + + "\n+-----------------------------------------------------------------------------------------+"; + } +} \ No newline at end of file