mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: highlight bad escapes in string template fragments (IDEA-321466)
GitOrigin-RevId: 3d7fb0ab16db230d216bac4eb8b9ac5301232902
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d50045f34f
commit
8354caf1f5
+27
-10
@@ -1400,16 +1400,7 @@ public final class HighlightUtil {
|
||||
}
|
||||
|
||||
if (!StringUtil.startsWithChar(text, '\"')) return null;
|
||||
if (StringUtil.endsWithChar(text, '\"')) {
|
||||
if (text.length() == 1) {
|
||||
String message = JavaErrorBundle.message("illegal.line.end.in.string.literal");
|
||||
if (description != null) {
|
||||
description.set(message);
|
||||
}
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!StringUtil.endsWithChar(text, '\"') || text.length() == 1) {
|
||||
String message = JavaErrorBundle.message("illegal.line.end.in.string.literal");
|
||||
if (description != null) {
|
||||
description.set(message);
|
||||
@@ -1514,6 +1505,32 @@ public final class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HighlightInfo.Builder checkFragmentError(PsiFragment fragment) {
|
||||
String text = fragment.getText();
|
||||
int length = text.length();
|
||||
if (fragment.getTokenType() == JavaTokenType.STRING_TEMPLATE_END) {
|
||||
if (!StringUtil.endsWithChar(text, '\"') || length == 1) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(fragment)
|
||||
.descriptionAndTooltip(JavaErrorBundle.message("illegal.line.end.in.string.literal"));
|
||||
}
|
||||
}
|
||||
if (text.endsWith("\\{")) {
|
||||
text = text.substring(0, length - 2);
|
||||
length -= 2;
|
||||
}
|
||||
StringBuilder chars = new StringBuilder(length);
|
||||
int[] offsets = new int[length + 1];
|
||||
boolean success = CodeInsightUtilCore.parseStringCharacters(text, chars, offsets, fragment.isTextBlock());
|
||||
if (!success) {
|
||||
String message = JavaErrorBundle.message("illegal.escape.character.in.string.literal");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(fragment, calculateErrorRange(text, offsets[chars.length()]))
|
||||
.descriptionAndTooltip(message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static HighlightInfo.@Nullable Builder checkStringTemplateEscapes(@NotNull PsiLiteralExpression expression,
|
||||
@NotNull String text,
|
||||
@NotNull LanguageLevel level,
|
||||
|
||||
+9
-3
@@ -943,9 +943,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
super.visitTemplateExpression(expression);
|
||||
|
||||
add(HighlightUtil.checkTemplateExpression(expression));
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
add(HighlightUtil.checkUnhandledExceptions(expression));
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) add(HighlightUtil.checkUnhandledExceptions(expression));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFragment(@NotNull PsiFragment fragment) {
|
||||
super.visitFragment(fragment);
|
||||
|
||||
HighlightUtil.checkIllegalUnicodeEscapes(fragment, myHolder);
|
||||
if (!myHolder.hasErrorResults()) add(HighlightUtil.checkFragmentError(fragment));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+33
-16
@@ -25,24 +25,12 @@ public class JavaHighlightErrorFilter extends HighlightErrorFilter {
|
||||
}
|
||||
else {
|
||||
// reporting missing semicolons after an unclosed string literal is not useful.
|
||||
PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(element);
|
||||
if (prevLeaf instanceof PsiJavaToken token) {
|
||||
IElementType type = token.getTokenType();
|
||||
if (type == JavaTokenType.STRING_LITERAL) {
|
||||
String text = token.getText();
|
||||
if (text.length() == 1 || !StringUtil.endsWithChar(text, '"')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type == JavaTokenType.CHARACTER_LITERAL) {
|
||||
String text = token.getText();
|
||||
if (text.length() == 1 || !StringUtil.endsWithChar(text, '\'')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isAfterUnclosedStringLiteral(element)) return false;
|
||||
}
|
||||
}
|
||||
else if (description.equals(JavaPsiBundle.message("expected.comma.or.rparen"))) {
|
||||
if (isAfterUnclosedStringLiteral(element)) return false;
|
||||
}
|
||||
else if (description.equals(JavaPsiBundle.message("expected.class.or.interface"))) {
|
||||
String text = element.getText();
|
||||
if ((text.equals(PsiKeyword.SEALED) || text.equals(PsiKeyword.NON_SEALED)) &&
|
||||
@@ -52,4 +40,33 @@ public class JavaHighlightErrorFilter extends HighlightErrorFilter {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAfterUnclosedStringLiteral(@NotNull PsiErrorElement element) {
|
||||
PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(element);
|
||||
if (prevLeaf instanceof PsiJavaToken token) {
|
||||
IElementType type = token.getTokenType();
|
||||
if (type == JavaTokenType.STRING_LITERAL) {
|
||||
String text = token.getText();
|
||||
if (text.length() == 1 || !StringUtil.endsWithChar(text, '"')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type == JavaTokenType.CHARACTER_LITERAL) {
|
||||
String text = token.getText();
|
||||
if (text.length() == 1 || !StringUtil.endsWithChar(text, '\'')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (prevLeaf instanceof PsiFragment fragment) {
|
||||
IElementType type = fragment.getTokenType();
|
||||
if (type == JavaTokenType.STRING_TEMPLATE_END) {
|
||||
String text = fragment.getText();
|
||||
if (text.length() == 1 || !StringUtil.endsWithChar(text, '"')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -40,4 +40,13 @@ class X {
|
||||
void nested() {
|
||||
System.out.println(STR."\{STR."\{STR."\{STR."\{STR."\{STR."\{STR.""}"}"}"}"}"}");
|
||||
}
|
||||
|
||||
String badEscape() {
|
||||
System.out.println(STR."b<error descr="Illegal escape character in string literal">\a</error>d \{} esc<error descr="Illegal escape character in string literal">\a</error>pe 1");
|
||||
System.out.println(STR. """
|
||||
b<error descr="Illegal escape character in string literal">\a</error>d \{} esc<error descr="Illegal escape character in string literal">\a</error>pe 2
|
||||
""");
|
||||
System.out.println(STR."\{<error descr="Illegal line end in string literal">}unclosed);</error>
|
||||
return STR."\{} <error descr="Illegal Unicode escape sequence">\u</error>X";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user