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 29c30724b4f9..3d8956f4dd92 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
@@ -1,4 +1,4 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.CodeInsightUtilCore;
@@ -2444,6 +2444,30 @@ public final class HighlightUtil {
return null;
}
+ static HighlightInfo.Builder checkLocalClassReferencedFromAnotherSwitchBranch(@NotNull PsiJavaCodeReferenceElement ref,
+ @NotNull PsiClass aClass) {
+ if (!(aClass.getParent() instanceof PsiDeclarationStatement declarationStatement) ||
+ !(declarationStatement.getParent() instanceof PsiCodeBlock codeBlock) ||
+ !(codeBlock.getParent() instanceof PsiSwitchBlock)) {
+ return null;
+ }
+ boolean classSeen = false;
+ for (PsiStatement statement : codeBlock.getStatements()) {
+ if (classSeen) {
+ if (PsiTreeUtil.isAncestor(statement, ref, true)) break;
+ if (statement instanceof PsiSwitchLabelStatement) {
+ String description =
+ JavaErrorBundle.message("local.class.referenced.from.other.switch.branch", HighlightUtil.formatClass(aClass));
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).descriptionAndTooltip(description);
+ }
+ }
+ else if (statement == declarationStatement) {
+ classSeen = true;
+ }
+ }
+ return null;
+ }
+
static void checkSwitchExpressionHasResult(@NotNull PsiSwitchExpression switchExpression,
@NotNull Consumer super HighlightInfo.Builder> errorSink) {
PsiCodeBlock switchBody = switchExpression.getBody();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index c798fb3ba634..bbc164f48015 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeHighlighting.Pass;
@@ -1204,6 +1204,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (result != null) {
PsiElement resolved = result.getElement();
if (!hasErrorResults()) add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolved));
+ if (!hasErrorResults() && resolved instanceof PsiClass aClass) {
+ add(HighlightUtil.checkLocalClassReferencedFromAnotherSwitchBranch(ref, aClass));
+ }
if (!hasErrorResults() && resolved instanceof PsiModifierListOwner) {
HighlightingFeature.checkPreviewFeature(ref, myPreviewFeatureVisitor);
}
diff --git a/java/java-psi-impl/src/messages/JavaErrorBundle.properties b/java/java-psi-impl/src/messages/JavaErrorBundle.properties
index aaab7531d70e..26173337ddf5 100644
--- a/java/java-psi-impl/src/messages/JavaErrorBundle.properties
+++ b/java/java-psi-impl/src/messages/JavaErrorBundle.properties
@@ -124,6 +124,7 @@ invalid.qualified.new=Invalid qualified new
class.name.expected=Class name expected
no.enclosing.instance.in.scope=No enclosing instance of type ''{0}'' is in scope
is.not.an.enclosing.class=''{0}'' is not an enclosing class
+local.class.referenced.from.other.switch.branch=Local class ''{0}'' cannot be referenced from another switch branch
cannot.be.referenced.from.static.context=''{0}'' cannot be referenced from a static context
no.default.constructor.available=There is no parameterless constructor available in ''{0}''
missing.return.statement=Missing return statement
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/SwitchStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/SwitchStatement.java
index ad4521c687fa..b7a2bba5713c 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/SwitchStatement.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/SwitchStatement.java
@@ -21,5 +21,12 @@ class SwitchStatement {
switch (0) {
return;
}
+
+ switch (0) {
+ case 0:
+ class Local {}
+ case 1:
+ Local x = new Local();
+ }
}
}
\ No newline at end of file