[java-inspections] IDEA-345407 Some actions inside string template with language annotation lead to exceptions

GitOrigin-RevId: b14296a9785210511c22281a29f177d9d9ff752b
This commit is contained in:
Tagir Valeev
2024-02-23 09:59:04 +01:00
committed by intellij-monorepo-bot
parent 807c36748d
commit 52f3712ce2
5 changed files with 34 additions and 15 deletions

View File

@@ -2126,7 +2126,7 @@ wait.notify.while.not.synchronized.on.problem.descriptor=Call to <code>#ref</cod
call.to.suspicious.string.method.display.name=Call to suspicious 'String' method
call.to.suspicious.string.method.problem.descriptor=<code>String.#ref()</code> called in internationalized context #loc
unnecessary.string.escape.display.name=Unnecessarily escaped character
unnecessary.string.escape.problem.descriptor=<code>#ref</code> is unnecessarily escaped
unnecessary.string.escape.problem.descriptor=<code>{0}</code> is unnecessarily escaped
unnecessary.string.escape.quickfix=Remove unnecessary escaping
redundant.escape.in.regex.replacement.display.name=Redundant escape in regex replacement string

View File

@@ -20,6 +20,7 @@ import com.intellij.codeInspection.dataFlow.fix.RedundantInstanceofFix;
import com.intellij.core.JavaPsiBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.LanguageLevelUtil;
import com.intellij.openapi.module.Module;
@@ -1534,7 +1535,7 @@ public final class HighlightUtil {
}
public static HighlightInfo.Builder checkFragmentError(PsiFragment fragment) {
String text = fragment.getText();
String text = InjectedLanguageManager.getInstance(fragment.getProject()).getUnescapedText(fragment);
if (fragment.getTokenType() == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN) {
final HighlightInfo.Builder info1 = checkTextBlockNewlineAfterOpeningQuotes(fragment, text, null);
if (info1 != null) return info1;

View File

@@ -6,6 +6,7 @@ import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.editor.Document;
@@ -23,7 +24,6 @@ import com.siyeh.ig.PsiReplacementUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
@@ -38,7 +38,7 @@ public final class UnnecessaryStringEscapeInspection extends BaseInspection impl
@NotNull
@Override
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("unnecessary.string.escape.problem.descriptor");
return InspectionGadgetsBundle.message("unnecessary.string.escape.problem.descriptor", infos[1]);
}
@Override
@@ -47,9 +47,8 @@ public final class UnnecessaryStringEscapeInspection extends BaseInspection impl
checkbox("reportChars", InspectionGadgetsBundle.message("inspection.unnecessary.string.escape.report.char.literals.option")));
}
@Nullable
@Override
protected LocalQuickFix buildFix(Object... infos) {
protected @NotNull LocalQuickFix buildFix(Object... infos) {
final String expressionText = (String)infos[0];
return new UnnecessaryStringEscapeFix(expressionText);
}
@@ -219,19 +218,20 @@ public final class UnnecessaryStringEscapeInspection extends BaseInspection impl
return;
}
final String text = fragment.getText();
InjectedLanguageManager manager = InjectedLanguageManager.getInstance(getCurrentFile().getProject());
final String text = manager.getUnescapedText(fragment);
if (fragment.isTextBlock()) {
int end = fragment.getTokenType() == JavaTokenType.TEXT_BLOCK_TEMPLATE_END ? text.length() - 3 : text.length() - 2;
int start = findUnnecessaryTextBlockEscapes(text, 1, end);
while (start >= 0) {
registerErrorAtOffset(fragment, start, 2, text);
registerErrorAtOffset(fragment, start, 2, text, text.substring(start, start + 2));
start = findUnnecessaryTextBlockEscapes(text, start + 2, end);
}
}
else {
int start = findUnnecessaryStringEscapes(text, 1);
while (start >= 0) {
registerErrorAtOffset(fragment, start, 2, text);
registerErrorAtOffset(fragment, start, 2, text, text.substring(start, start + 2));
start = findUnnecessaryStringEscapes(text, start + 2);
}
}
@@ -249,28 +249,29 @@ public final class UnnecessaryStringEscapeInspection extends BaseInspection impl
if (parsingError != null) {
return;
}
InjectedLanguageManager manager = InjectedLanguageManager.getInstance(getCurrentFile().getProject());
if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
final String text = expression.getText();
final String text = manager.getUnescapedText(expression);
if (expression.isTextBlock()) {
int end = text.length() - 3;
int start = findUnnecessaryTextBlockEscapes(text, 4, end);
while (start >= 0) {
registerErrorAtOffset(expression, start, 2, text);
registerErrorAtOffset(expression, start, 2, text, text.substring(start, start + 2));
start = findUnnecessaryTextBlockEscapes(text, start + 2, end);
}
}
else {
int start = findUnnecessaryStringEscapes(text, 1);
while (start >= 0) {
registerErrorAtOffset(expression, start, 2, text);
registerErrorAtOffset(expression, start, 2, text, text.substring(start, start + 2));
start = findUnnecessaryStringEscapes(text, start + 2);
}
}
}
else if (reportChars && PsiTypes.charType().equals(type)) {
final String text = expression.getText();
final String text = manager.getUnescapedText(expression);
if ("'\\\"'".equals(text)) {
registerErrorAtOffset(expression, 1, 2, text);
registerErrorAtOffset(expression, 1, 2, text, text.substring(1, 3));
}
}
}

View File

@@ -0,0 +1,15 @@
import org.intellij.lang.annotations.Language;
public class InInjection {
void test() {
@Language("Java")
String s = STR."""
class NewJavaClass {
void foo(String name) {
// Highlighting is misplaced -- see IDEA-347183
String s = "\\<warning descr="'\'' is unnecessarily escaped">b\</warning>\'\\{}";
}
}
""";
}
}

View File

@@ -23,6 +23,8 @@ public class UnnecessaryStringEscapeInspectionTest extends LightJavaInspectionTe
public void testEscapedNewLineNotUnnecessary() { doTest(); }
public void testBrokenCode() { doTest(); }
public void testInInjection() { doTest(); }
protected void doQuickFixTest() {
myFixture.addClass("""
@@ -55,6 +57,6 @@ public class UnnecessaryStringEscapeInspectionTest extends LightJavaInspectionTe
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
return JAVA_21_ANNOTATED;
}
}