diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index a8197b1c1b23..276c6f51bfd5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -1144,6 +1144,19 @@ public class HighlightUtil extends HighlightUtilBase { } } } + else if (type == JavaTokenType.TEXT_BLOCK_LITERAL) { + if (value == null) { + if (text.charAt(3) != '\n') { + String message = JavaErrorMessages.message("text.block.new.line"); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create(); + } + if (!text.endsWith("\"\"\"")) { + String message = JavaErrorMessages.message("text.block.unclosed"); + int p = expression.getTextRange().getEndOffset(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(p, p).endOfLine().descriptionAndTooltip(message).create(); + } + } + } if (value instanceof Float) { Float number = (Float)value; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java index e84d729e8e8b..a51b2cdb916a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java @@ -64,5 +64,5 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen TokenSet INTEGER_LITERALS = TokenSet.create(INTEGER_LITERAL, LONG_LITERAL); TokenSet REAL_LITERALS = TokenSet.create(FLOAT_LITERAL, DOUBLE_LITERAL); - TokenSet STRING_LITERALS = TokenSet.create(STRING_LITERAL, RAW_STRING_LITERAL); + TokenSet STRING_LITERALS = TokenSet.create(STRING_LITERAL, TEXT_BLOCK_LITERAL, RAW_STRING_LITERAL); } \ No newline at end of file diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 10e396a6ddc3..22c0fe0c203e 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -335,6 +335,8 @@ illegal.escape.character.in.string.literal=Illegal escape character in string li floating.point.number.too.large=Floating point number too large floating.point.number.too.small=Floating point number too small illegal.underscore=Illegal underscore +text.block.new.line=Illegal text block start: missing new line after opening quotes +text.block.unclosed=Unclosed text block import.statement.identifier.or.asterisk.expected.=Identifier or '*' expected diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/TextBlocks.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/TextBlocks.java new file mode 100644 index 000000000000..8e2c6cdf121a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/TextBlocks.java @@ -0,0 +1,7 @@ +class C { + String empty = """ + """; + String invalid1 = """"""; + String invalid2 = """ """; + String invalid3 = """\\n """; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/UnclosedTextBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/UnclosedTextBlock.java new file mode 100644 index 000000000000..c95cff62824c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting13/UnclosedTextBlock.java @@ -0,0 +1,4 @@ +class C { + String unclosed = """ + \"""; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightJava13HighlightingTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightJava13HighlightingTest.kt new file mode 100644 index 000000000000..27a3d2c9b12b --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightJava13HighlightingTest.kt @@ -0,0 +1,18 @@ +// 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.java.codeInsight.daemon + +import com.intellij.JavaTestUtil +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase + +class LightJava13HighlightingTest : LightCodeInsightFixtureTestCase() { + override fun getProjectDescriptor() = JAVA_13 + override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/advHighlighting13" + + fun testTextBlocks() = doTest() + fun testUnclosedTextBlock() = doTest() + + private fun doTest() { + myFixture.configureByFile(getTestName(false) + ".java") + myFixture.checkHighlighting() + } +} \ No newline at end of file diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java index b90fe5c3767e..a5b02309130a 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java @@ -71,6 +71,7 @@ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase { public static final @NotNull LightProjectDescriptor JAVA_10_ANNOTATED = new ProjectDescriptor(LanguageLevel.JDK_10, true); public static final @NotNull LightProjectDescriptor JAVA_11 = new ProjectDescriptor(LanguageLevel.JDK_11); public static final @NotNull LightProjectDescriptor JAVA_12 = new ProjectDescriptor(LanguageLevel.JDK_12_PREVIEW); + public static final @NotNull LightProjectDescriptor JAVA_13 = new ProjectDescriptor(LanguageLevel.JDK_13_PREVIEW); public static final @NotNull LightProjectDescriptor JAVA_X = new ProjectDescriptor(LanguageLevel.JDK_X); public static final @NotNull LightProjectDescriptor JAVA_LATEST = new ProjectDescriptor(LanguageLevel.HIGHEST) {