From dc8ca06f05acde6ff0dd7d0a63c5517531e34460 Mon Sep 17 00:00:00 2001 From: Mikhail Pyltsin Date: Thu, 5 Jun 2025 11:19:28 +0200 Subject: [PATCH] [java-highlighting] IDEA-374019 Don't show error about 'main' method if there is an error with braces GitOrigin-RevId: 38e303a7ace428d45c6e869fce3acc655dba1a6d --- .../codeserver/highlighting/ClassChecker.java | 19 ++++++++++++++++++- .../BrokenClassToImplicitClass.java | 4 ++-- .../BrokenFileNoHighlighting.java | 8 ++++++++ .../daemon/ImplicitClassHighlightingTest.kt | 6 +++++- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/implicitClass/BrokenFileNoHighlighting.java diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ClassChecker.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ClassChecker.java index f617ec0a4c4c..6293e6db36b5 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ClassChecker.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/ClassChecker.java @@ -15,6 +15,7 @@ import com.intellij.openapi.roots.ModuleFileIndex; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; @@ -402,10 +403,24 @@ final class ClassChecker { PsiMethod[] methods = implicitClass.getMethods(); boolean hasMainMethod = ContainerUtil.exists(methods, method -> "main".equals(method.getName()) && PsiMethodUtil.isMainMethod(method)); if (!hasMainMethod) { + //don't show errors if the file contains broken {} + if(hasErrorElementWithBraces(file)) return; myVisitor.report(JavaErrorKinds.CLASS_IMPLICIT_NO_MAIN_METHOD.create(file, implicitClass)); } } + private static boolean hasErrorElementWithBraces(@NotNull PsiElement parentElement) { + Ref result = new Ref<>(false); + PsiWalkingState.processAll(parentElement, el -> { + if (el instanceof PsiErrorElement element && + (element.getText().contains("}") || element.getText().contains("{"))) { + result.set(true); + return false; + } else return true; + }); + return result.get(); + } + void checkImplicitClassMember(@NotNull PsiMember member) { if (!(member.getContainingClass() instanceof PsiImplicitClass)) return; @@ -448,7 +463,9 @@ final class ClassChecker { } void checkPackageNotAllowedInImplicitClass(@NotNull PsiPackageStatement statement) { - if (myVisitor.isApplicable(JavaFeature.IMPLICIT_CLASSES) && JavaImplicitClassUtil.isFileWithImplicitClass(myVisitor.file())) { + if (myVisitor.isApplicable(JavaFeature.IMPLICIT_CLASSES) && + JavaImplicitClassUtil.isFileWithImplicitClass(myVisitor.file()) && + !hasErrorElementWithBraces(myVisitor.file())) { myVisitor.report(JavaErrorKinds.CLASS_IMPLICIT_PACKAGE.create(statement)); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/BrokenClassToImplicitClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/BrokenClassToImplicitClass.java index 6ce23e6cd7d1..9b6e3daa9d3b 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/BrokenClassToImplicitClass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/BrokenClassToImplicitClass.java @@ -1,4 +1,4 @@ -package p1; +package p1; class Demo{ public static void t1(){} @@ -9,4 +9,4 @@ class Demo{ } public static void t5(){} public static void t6(){} -} \ No newline at end of file +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/implicitClass/BrokenFileNoHighlighting.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/implicitClass/BrokenFileNoHighlighting.java new file mode 100644 index 000000000000..6797823e7aaa --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/implicitClass/BrokenFileNoHighlighting.java @@ -0,0 +1,8 @@ +package com.example; + +public class A { +} + +} + +int a = 1; diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/ImplicitClassHighlightingTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/ImplicitClassHighlightingTest.kt index 49bba34d7f8e..69efd80f2510 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/ImplicitClassHighlightingTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/ImplicitClassHighlightingTest.kt @@ -13,7 +13,7 @@ import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase import org.jetbrains.plugins.groovy.intentions.style.inference.resolve class ImplicitClassHighlightingTest : LightJavaCodeInsightFixtureTestCase() { - override fun getProjectDescriptor() = JAVA_21 + override fun getProjectDescriptor() = JAVA_23 override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/implicitClass" fun testHighlightInsufficientLevel() { @@ -172,6 +172,10 @@ class ImplicitClassHighlightingTest : LightJavaCodeInsightFixtureTestCase() { doTest() } + fun testBrokenFileNoHighlighting() { + doTest() + } + private fun doTest() { myFixture.configureByFile(getTestName(false) + ".java") myFixture.checkHighlighting()