diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml
index 561811adffff..554753bbaa36 100644
--- a/java/java-impl/src/META-INF/JavaPlugin.xml
+++ b/java/java-impl/src/META-INF/JavaPlugin.xml
@@ -940,6 +940,11 @@
groupKey="group.names.language.level.specific.issues.and.migration.aids12" groupBundle="messages.InspectionsBundle"
enabledByDefault="true" level="INFORMATION"
implementationClass="com.intellij.codeInspection.EnhancedSwitchMigrationInspection" />
+
diff --git a/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockInspection.java b/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockInspection.java
new file mode 100644
index 000000000000..cefb7deb2977
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockInspection.java
@@ -0,0 +1,104 @@
+// Copyright 2000-2018 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.codeInspection.enhancedSwitch;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.openapi.project.Project;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ObjectUtils;
+import com.siyeh.ig.psiutils.CommentTracker;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+import static com.intellij.codeInspection.InspectionsBundle.message;
+
+/**
+ * @author Pavel.Dolgov
+ */
+public class SwitchLabeledRuleCanBeCodeBlockInspection extends LocalInspectionTool {
+ @NotNull
+ @Override
+ public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
+ if (!PsiUtil.getLanguageLevel(holder.getFile()).isAtLeast(LanguageLevel.JDK_12_PREVIEW)) {
+ return PsiElementVisitor.EMPTY_VISITOR;
+ }
+
+ return new JavaElementVisitor() {
+ @Override
+ public void visitSwitchLabeledRuleStatement(PsiSwitchLabeledRuleStatement statement) {
+ super.visitSwitchLabeledRuleStatement(statement);
+
+ PsiSwitchBlock switchBlock = statement.getEnclosingSwitchBlock();
+ PsiStatement body = statement.getBody();
+ if (switchBlock != null && (body instanceof PsiExpressionStatement || body instanceof PsiThrowStatement)) {
+ if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement) {
+ registerProblem(statement, true);
+ }
+ else {
+ registerProblem(statement, false);
+ }
+ }
+ }
+
+ private void registerProblem(PsiSwitchLabeledRuleStatement statement, boolean isExpressionResult) {
+ holder.registerProblem(ObjectUtils.notNull(ObjectUtils.tryCast(statement.getFirstChild(), PsiKeyword.class), statement),
+ message(isExpressionResult ? "inspection.switch.labeled.rule.can.be.code.block.expression.message"
+ : "inspection.switch.labeled.rule.can.be.code.block.statement.message"),
+ new WrapWithCodeBlockFix(isExpressionResult));
+ }
+ };
+ }
+
+ private static class WrapWithCodeBlockFix implements LocalQuickFix {
+ private final String myMessage;
+
+ WrapWithCodeBlockFix(boolean isExpressionResult) {
+ myMessage = message(isExpressionResult ? "inspection.switch.labeled.rule.can.be.code.block.fix.expression.name"
+ : "inspection.switch.labeled.rule.can.be.code.block.fix.statement.name");
+ }
+
+ @Nls(capitalization = Nls.Capitalization.Sentence)
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return myMessage;
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getStartElement();
+ if (element instanceof PsiKeyword) {
+ element = element.getParent();
+ if (element instanceof PsiSwitchLabeledRuleStatement) {
+ PsiSwitchLabeledRuleStatement rule = (PsiSwitchLabeledRuleStatement)element;
+ PsiSwitchBlock switchBlock = rule.getEnclosingSwitchBlock();
+ PsiStatement body = rule.getBody();
+
+ if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement) {
+ wrapExpression((PsiExpressionStatement)body);
+ }
+ else if (body != null) {
+ wrapStatement(body);
+ }
+ }
+ }
+ }
+
+ private static void wrapExpression(PsiExpressionStatement expressionStatement) {
+ PsiExpression expression = expressionStatement.getExpression();
+ CommentTracker tracker = new CommentTracker();
+ tracker.markUnchanged(expression);
+ tracker.replaceAndRestoreComments(expressionStatement, "{ break " + expression.getText() + "; }");
+ }
+
+ private static void wrapStatement(@NotNull PsiStatement statement) {
+ CommentTracker tracker = new CommentTracker();
+ tracker.markUnchanged(statement);
+ tracker.replaceAndRestoreComments(statement, "{ " + statement.getText() + " }");
+ }
+ }
+}
diff --git a/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html b/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html
new file mode 100644
index 000000000000..9bd0b7f192b2
--- /dev/null
+++ b/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html
@@ -0,0 +1,7 @@
+
+
+Reports rules of switch expression or enhanced switch statement which can be converted to a code block.
+
+New in 2019.1
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InExpression.java
new file mode 100644
index 000000000000..4e0262c4ad85
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InExpression.java
@@ -0,0 +1,12 @@
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> Integer.toString(n);
+ case 2 -> { break Integer.toString(n); }
+ case 3 -> throw new RuntimeException();
+ case 4 -> { throw new RuntimeException(); }
+ case 5 -> { break "a";}
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InStatement.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InStatement.java
new file mode 100644
index 000000000000..2d34b1ee6144
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlock/InStatement.java
@@ -0,0 +1,14 @@
+class C {
+ String foo(int n) {
+ String s;
+ switch (n) {
+ case 1 -> s = Integer.toString(n);
+ case 2 -> { s = Integer.toString(n); }
+ case 3 -> throw new RuntimeException();
+ case 4 -> { throw new RuntimeException(); }
+ case 5 -> { s = "a"; }
+ default -> s = "b";
+ };
+ return s;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInExpression.java
new file mode 100644
index 000000000000..91f7eda7843c
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInExpression.java
@@ -0,0 +1,11 @@
+// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/{
+ break Integer.toString(/*2*/n);
+ }/*3*/
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInStatement.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInStatement.java
new file mode 100644
index 000000000000..9c07afc6064a
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterCallInStatement.java
@@ -0,0 +1,13 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ String s;
+ switch (n) {
+ case 1 -> /*1*/{
+ s = Integer.toString(/*2*/n);
+ }/*3*/
+ default -> s = "b";
+ };
+ return s;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterConstInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterConstInExpression.java
new file mode 100644
index 000000000000..466f79f67b45
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterConstInExpression.java
@@ -0,0 +1,11 @@
+// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/ {
+ break "a";
+ } /*2*/
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInExpression.java
new file mode 100644
index 000000000000..6ba89babefcd
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInExpression.java
@@ -0,0 +1,11 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/ {
+ throw new RuntimeException(); /*2*/
+ }
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInStatement.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInStatement.java
new file mode 100644
index 000000000000..dd90c0e9ebb1
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/afterThrowInStatement.java
@@ -0,0 +1,13 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ String s;
+ switch (n) {
+ case 1 -> /*1*/ {
+ throw /*2*/new RuntimeException(); /*3*/
+ }
+ default -> s = "b";
+ };
+ return s;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInExpression.java
new file mode 100644
index 000000000000..fafdc4fe88e5
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInExpression.java
@@ -0,0 +1,9 @@
+// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/Integer.toString(/*2*/n);/*3*/
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInStatement.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInStatement.java
new file mode 100644
index 000000000000..5c9399fb57e7
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeCallInStatement.java
@@ -0,0 +1,11 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ String s;
+ switch (n) {
+ case 1 -> /*1*/s = Integer.toString(/*2*/n);/*3*/
+ default -> s = "b";
+ };
+ return s;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeConstInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeConstInExpression.java
new file mode 100644
index 000000000000..fcdcdc26b08d
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeConstInExpression.java
@@ -0,0 +1,9 @@
+// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/ "a"; /*2*/
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInExpression.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInExpression.java
new file mode 100644
index 000000000000..6ad1d1439fe5
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInExpression.java
@@ -0,0 +1,9 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ return switch (n) {
+ case 1 -> /*1*/ throw new RuntimeException(); /*2*/
+ default -> "b";
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInStatement.java b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInStatement.java
new file mode 100644
index 000000000000..7a1aba992b48
--- /dev/null
+++ b/java/java-tests/testData/inspection/switchLabeledRuleCanBeCodeBlockFix/beforeThrowInStatement.java
@@ -0,0 +1,11 @@
+// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
+class C {
+ String foo(int n) {
+ String s;
+ switch (n) {
+ case 1 -> /*1*/ throw /*2*/new RuntimeException(); /*3*/
+ default -> s = "b";
+ };
+ return s;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockFixTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockFixTest.kt
new file mode 100644
index 000000000000..19bf64a67c23
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockFixTest.kt
@@ -0,0 +1,20 @@
+// Copyright 2000-2018 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.codeInspection.enhancedSwitch
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase
+import com.intellij.codeInspection.LocalInspectionTool
+import com.intellij.codeInspection.enhancedSwitch.SwitchLabeledRuleCanBeCodeBlockInspection
+import com.intellij.testFramework.LightProjectDescriptor
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+
+/**
+ * @author Pavel.Dolgov
+ */
+class SwitchLabeledRuleCanBeCodeBlockFixTest : LightQuickFixParameterizedTestCase() {
+
+ override fun configureLocalInspectionTools(): Array = arrayOf(SwitchLabeledRuleCanBeCodeBlockInspection())
+
+ override fun getProjectDescriptor(): LightProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_12
+
+ override fun getBasePath() = "/inspection/switchLabeledRuleCanBeCodeBlockFix"
+}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockTest.kt
new file mode 100644
index 000000000000..28a0fefb0730
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/enhancedSwitch/SwitchLabeledRuleCanBeCodeBlockTest.kt
@@ -0,0 +1,36 @@
+// Copyright 2000-2018 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.codeInspection.enhancedSwitch
+
+import com.intellij.JavaTestUtil
+import com.intellij.codeHighlighting.HighlightDisplayLevel
+import com.intellij.codeInsight.daemon.HighlightDisplayKey
+import com.intellij.codeInspection.enhancedSwitch.SwitchLabeledRuleCanBeCodeBlockInspection
+import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
+import com.intellij.testFramework.LightProjectDescriptor
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+
+/**
+ * @author Pavel.Dolgov
+ */
+class SwitchLabeledRuleCanBeCodeBlockTest : LightCodeInsightFixtureTestCase() {
+ val inspection = SwitchLabeledRuleCanBeCodeBlockInspection()
+
+ override fun setUp() {
+ super.setUp()
+ myFixture.enableInspections(inspection)
+
+ val currentProfile = ProjectInspectionProfileManager.getInstance(project).currentProfile
+ currentProfile.setErrorLevel(HighlightDisplayKey.find(inspection.shortName), HighlightDisplayLevel.WARNING, project)
+ }
+
+ override fun getProjectDescriptor(): LightProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_12
+
+ override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/switchLabeledRuleCanBeCodeBlock"
+
+ fun testInExpression() = doTest()
+ fun testInStatement() = doTest()
+
+ private fun doTest() {
+ myFixture.testHighlighting("${getTestName(false)}.java")
+ }
+}
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
index 7dcabed928c6..1d883943d6d1 100644
--- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
@@ -1035,4 +1035,10 @@ inspection.replace.with.enhanced.switch.statement.fix.name=Replace with enhanced
inspection.duplicate.branches.in.switch.display.name=Duplicate branches in 'switch' statement
inspection.duplicate.branches.in.switch.message=Duplicate branch in 'switch' statement
inspection.duplicate.branches.in.switch.fix.family.name=Merge duplicate branches of 'switch' statement
-inspection.duplicate.branches.in.switch.fix.name=Merge with ''{0}:''
\ No newline at end of file
+inspection.duplicate.branches.in.switch.fix.name=Merge with ''{0}:''
+
+inspection.switch.labeled.rule.can.be.code.block.display.name=Labeled switch rule can have code block
+inspection.switch.labeled.rule.can.be.code.block.expression.message=Labeled rule's result can be wrapped with code block
+inspection.switch.labeled.rule.can.be.code.block.statement.message=Labeled rule's statement can be wrapped with code block
+inspection.switch.labeled.rule.can.be.code.block.fix.expression.name=Wrap labeled rule's result with code block
+inspection.switch.labeled.rule.can.be.code.block.fix.statement.name=Wrap labeled rule's statement with code block
\ No newline at end of file