diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml
index 8c4d61f8bfc..e050b08e874 100644
--- a/idea/resources/META-INF/plugin-common.xml
+++ b/idea/resources/META-INF/plugin-common.xml
@@ -3374,7 +3374,16 @@
level="WEAK WARNING"
language="kotlin"
/>
-
+
+
+
diff --git a/idea/resources/inspectionDescriptions/ControlFlowWithEmptyBody.html b/idea/resources/inspectionDescriptions/ControlFlowWithEmptyBody.html
new file mode 100644
index 00000000000..da05f98b223
--- /dev/null
+++ b/idea/resources/inspectionDescriptions/ControlFlowWithEmptyBody.html
@@ -0,0 +1,5 @@
+
+
+This inspection reports that if, when, for, while and also expressions has empty body.
+
+
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ControlFlowWithEmptyBodyInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ControlFlowWithEmptyBodyInspection.kt
new file mode 100644
index 00000000000..c2f2a1438c6
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ControlFlowWithEmptyBodyInspection.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-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/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.idea.inspections.collections.isCalling
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.allChildren
+import org.jetbrains.kotlin.psi.psiUtil.startOffset
+
+class ControlFlowWithEmptyBodyInspection : AbstractKotlinInspection() {
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = object : KtVisitorVoid() {
+ override fun visitIfExpression(expression: KtIfExpression) {
+ if (expression.then.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, expression.ifKeyword)
+ }
+ val elseKeyword = expression.elseKeyword
+ if (elseKeyword != null && expression.`else`.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, elseKeyword)
+ }
+ }
+
+ override fun visitWhenExpression(expression: KtWhenExpression) {
+ if (expression.entries.isNotEmpty()) return
+ holder.registerProblem(expression, expression.whenKeyword)
+ }
+
+ override fun visitForExpression(expression: KtForExpression) {
+ if (expression.body.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, expression.forKeyword)
+ }
+ }
+
+ override fun visitWhileExpression(expression: KtWhileExpression) {
+ val keyword = expression.allChildren.firstOrNull { it.node.elementType == KtTokens.WHILE_KEYWORD } ?: return
+ if (expression.body.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, keyword)
+ }
+ }
+
+ override fun visitDoWhileExpression(expression: KtDoWhileExpression) {
+ val keyword = expression.allChildren.firstOrNull { it.node.elementType == KtTokens.DO_KEYWORD } ?: return
+ if (expression.body.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, keyword)
+ }
+ }
+
+ override fun visitCallExpression(expression: KtCallExpression) {
+ val callee = expression.calleeExpression ?: return
+ if (!expression.isCalling(controlFlowFunctions)) return
+ val body = when (val argument = expression.valueArguments.singleOrNull()?.getArgumentExpression()) {
+ is KtLambdaExpression -> argument.bodyExpression
+ is KtNamedFunction -> argument.bodyBlockExpression
+ else -> return
+ }
+ if (body.isEmptyBodyOrNull()) {
+ holder.registerProblem(expression, callee)
+ }
+ }
+ }
+
+ private fun KtExpression?.isEmptyBodyOrNull(): Boolean = if (this == null) true else this is KtBlockExpression && statements.isEmpty()
+
+ private fun ProblemsHolder.registerProblem(expression: KtExpression, keyword: PsiElement) {
+ val keywordText = if (expression is KtDoWhileExpression) "do while" else keyword.text
+ registerProblem(
+ expression,
+ keyword.textRange.shiftLeft(expression.startOffset),
+ "'$keywordText' has empty body"
+ )
+ }
+
+ companion object {
+ private val controlFlowFunctions = listOf("kotlin.also").map { FqName(it) }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/.inspection b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/.inspection
new file mode 100644
index 00000000000..99abd6f0ea9
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.ControlFlowWithEmptyBodyInspection
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunction.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunction.kt
new file mode 100644
index 00000000000..d3e979e9921
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunction.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'also' has empty body
+// FIX: none
+// WITH_RUNTIME
+
+fun test() {
+ 42.also(fun(it: Int) {
+ })
+}
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunctionHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunctionHasStatement.kt
new file mode 100644
index 00000000000..92b9c4a4fb2
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunctionHasStatement.kt
@@ -0,0 +1,9 @@
+// PROBLEM: none
+// FIX: none
+// WITH_RUNTIME
+
+fun test() {
+ 42.also(fun(it: Int) {
+ println(it)
+ })
+}
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block.kt
new file mode 100644
index 00000000000..1baf0b4f44b
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'also' has empty body
+// FIX: none
+// WITH_RUNTIME
+
+fun test(i: Int) {
+ i.also {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block2.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block2.kt
new file mode 100644
index 00000000000..7dcb45c7eff
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block2.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'also' has empty body
+// FIX: none
+// WITH_RUNTIME
+
+fun test() {
+ 42.also({ })
+}
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasComment.kt
new file mode 100644
index 00000000000..d8712b94a6f
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasComment.kt
@@ -0,0 +1,9 @@
+// PROBLEM: 'also' has empty body
+// FIX: none
+// WITH_RUNTIME
+
+fun test(i: Int) {
+ i.also {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement.kt
new file mode 100644
index 00000000000..824c4da743a
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement.kt
@@ -0,0 +1,10 @@
+// PROBLEM: none
+// WITH_RUNTIME
+
+fun test(i: Int) {
+ i.also {
+ foo()
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement2.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement2.kt
new file mode 100644
index 00000000000..514745b9543
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement2.kt
@@ -0,0 +1,6 @@
+// PROBLEM: none
+// WITH_RUNTIME
+
+fun test() {
+ 42.also({ println(it) })
+}
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/functionReference.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/functionReference.kt
new file mode 100644
index 00000000000..b9ef433c197
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/functionReference.kt
@@ -0,0 +1,6 @@
+// PROBLEM: none
+// WITH_RUNTIME
+
+fun test() {
+ 42.also(::println)
+}
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/implicitReceiver.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/implicitReceiver.kt
new file mode 100644
index 00000000000..4ab64471666
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/implicitReceiver.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'also' has empty body
+// FIX: none
+// WITH_RUNTIME
+
+fun String.test() {
+ also { }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/block.kt
new file mode 100644
index 00000000000..6319f387a2f
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/block.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'do while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ do {
+ } while (i == 1)
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasComment.kt
new file mode 100644
index 00000000000..1198c8db41e
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasComment.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'do while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ do {
+ // comment
+ } while (i == 1)
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasStatement.kt
new file mode 100644
index 00000000000..d0436159303
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasStatement.kt
@@ -0,0 +1,9 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ do {
+ foo()
+ } while (i == 1)
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/single.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/single.kt
new file mode 100644
index 00000000000..e625c5d1ff1
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/single.kt
@@ -0,0 +1,6 @@
+// PROBLEM: 'do while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ do while (i == 1)
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/singleHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/singleHasStatement.kt
new file mode 100644
index 00000000000..5076599a809
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/singleHasStatement.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ do foo() while (i == 1)
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/block.kt
new file mode 100644
index 00000000000..a00f4c164b2
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/block.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'for' has empty body
+// FIX: none
+
+fun test() {
+ for (i in 1..10) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasComment.kt
new file mode 100644
index 00000000000..35cb8a0d2b8
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasComment.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'for' has empty body
+// FIX: none
+
+fun test() {
+ for (i in 1..10) {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasStatement.kt
new file mode 100644
index 00000000000..64f62a46a09
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasStatement.kt
@@ -0,0 +1,9 @@
+// PROBLEM: none
+
+fun test() {
+ for (i in 1..10) {
+ foo()
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/single.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/single.kt
new file mode 100644
index 00000000000..0b0dd966aca
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/single.kt
@@ -0,0 +1,6 @@
+// PROBLEM: 'for' has empty body
+// FIX: none
+
+fun test() {
+ for (i in 1..10);
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/singleHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/singleHasStatement.kt
new file mode 100644
index 00000000000..1f90b17cc42
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/singleHasStatement.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+fun test() {
+ for (i in 1..10) foo()
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/block.kt
new file mode 100644
index 00000000000..80c7ef707be
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/block.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'if' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasComment.kt
new file mode 100644
index 00000000000..0b10f09ad8b
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasComment.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'if' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasElse.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasElse.kt
new file mode 100644
index 00000000000..485bd4d46b9
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasElse.kt
@@ -0,0 +1,10 @@
+// PROBLEM: 'if' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else if (i == 2) {
+ } else if (i == 3) {
+ } else {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasStatement.kt
new file mode 100644
index 00000000000..68076b90a70
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasStatement.kt
@@ -0,0 +1,9 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ foo()
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/elseIf.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/elseIf.kt
new file mode 100644
index 00000000000..6b18fc77b66
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/elseIf.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'if' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else if (i == 2) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/single.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/single.kt
new file mode 100644
index 00000000000..c40a8bccc5e
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/single.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'if' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) else {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/singleHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/singleHasStatement.kt
new file mode 100644
index 00000000000..07562faa640
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/singleHasStatement.kt
@@ -0,0 +1,8 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ if (i == 1) foo() else {
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/block.kt
new file mode 100644
index 00000000000..1d48399bb99
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/block.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'else' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasComment.kt
new file mode 100644
index 00000000000..aa810bc9b48
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasComment.kt
@@ -0,0 +1,9 @@
+// PROBLEM: 'else' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasStatement.kt
new file mode 100644
index 00000000000..b4e4143c569
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasStatement.kt
@@ -0,0 +1,10 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else {
+ foo()
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/single.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/single.kt
new file mode 100644
index 00000000000..00f4a18cb97
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/single.kt
@@ -0,0 +1,6 @@
+// PROBLEM: 'else' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ if (i == 1) {}else {};
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/singleHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/singleHasStatement.kt
new file mode 100644
index 00000000000..86843c25019
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/singleHasStatement.kt
@@ -0,0 +1,8 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ if (i == 1) {
+ } else foo()
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block.kt
new file mode 100644
index 00000000000..cc86200c98b
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'when' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ when (i) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block2.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block2.kt
new file mode 100644
index 00000000000..40135aec08a
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block2.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'when' has empty body
+// FIX: none
+
+fun test() {
+ when (val i = 1) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasComment.kt
new file mode 100644
index 00000000000..73642bbe817
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasComment.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'when' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ when (i) {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasStatement.kt
new file mode 100644
index 00000000000..95420a5edc3
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasStatement.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ when (i) {
+ else -> {}
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/block.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/block.kt
new file mode 100644
index 00000000000..7e1eecabcf7
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/block.kt
@@ -0,0 +1,7 @@
+// PROBLEM: 'while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ while (i == 1) {
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasComment.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasComment.kt
new file mode 100644
index 00000000000..4f815e1d74e
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasComment.kt
@@ -0,0 +1,8 @@
+// PROBLEM: 'while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ while (i == 1) {
+ // comment
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasStatement.kt
new file mode 100644
index 00000000000..f2f6d1ef193
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasStatement.kt
@@ -0,0 +1,9 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ while (i == 1) {
+ foo()
+ }
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/single.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/single.kt
new file mode 100644
index 00000000000..2633760e781
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/single.kt
@@ -0,0 +1,6 @@
+// PROBLEM: 'while' has empty body
+// FIX: none
+
+fun test(i: Int) {
+ while (i == 1);
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/singleHasStatement.kt b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/singleHasStatement.kt
new file mode 100644
index 00000000000..0b1593bd477
--- /dev/null
+++ b/idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/singleHasStatement.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+fun test(i: Int) {
+ while (i == 1) foo()
+}
+
+fun foo() {}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
index ed4d6a0fe02..1245caacf46 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
@@ -1780,6 +1780,310 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
}
}
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ControlFlowWithEmptyBody extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInControlFlowWithEmptyBody() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Also extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInAlso() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("anonymousFunction.kt")
+ public void testAnonymousFunction() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunction.kt");
+ }
+
+ @TestMetadata("anonymousFunctionHasStatement.kt")
+ public void testAnonymousFunctionHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/anonymousFunctionHasStatement.kt");
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block.kt");
+ }
+
+ @TestMetadata("block2.kt")
+ public void testBlock2() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/block2.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement.kt");
+ }
+
+ @TestMetadata("blockHasStatement2.kt")
+ public void testBlockHasStatement2() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/blockHasStatement2.kt");
+ }
+
+ @TestMetadata("functionReference.kt")
+ public void testFunctionReference() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/functionReference.kt");
+ }
+
+ @TestMetadata("implicitReceiver.kt")
+ public void testImplicitReceiver() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/also/implicitReceiver.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class DoWhile extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInDoWhile() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/block.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/blockHasStatement.kt");
+ }
+
+ @TestMetadata("single.kt")
+ public void testSingle() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/single.kt");
+ }
+
+ @TestMetadata("singleHasStatement.kt")
+ public void testSingleHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/doWhile/singleHasStatement.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class For extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInFor() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/block.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/blockHasStatement.kt");
+ }
+
+ @TestMetadata("single.kt")
+ public void testSingle() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/single.kt");
+ }
+
+ @TestMetadata("singleHasStatement.kt")
+ public void testSingleHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/for/singleHasStatement.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class If extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInIf() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/block.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasElse.kt")
+ public void testBlockHasElse() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasElse.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/blockHasStatement.kt");
+ }
+
+ @TestMetadata("elseIf.kt")
+ public void testElseIf() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/elseIf.kt");
+ }
+
+ @TestMetadata("single.kt")
+ public void testSingle() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/single.kt");
+ }
+
+ @TestMetadata("singleHasStatement.kt")
+ public void testSingleHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/if/singleHasStatement.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class IfElse extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInIfElse() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/block.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/blockHasStatement.kt");
+ }
+
+ @TestMetadata("single.kt")
+ public void testSingle() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/single.kt");
+ }
+
+ @TestMetadata("singleHasStatement.kt")
+ public void testSingleHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/ifElse/singleHasStatement.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class When extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInWhen() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block.kt");
+ }
+
+ @TestMetadata("block2.kt")
+ public void testBlock2() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/block2.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/when/blockHasStatement.kt");
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class While extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInWhile() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/block.kt");
+ }
+
+ @TestMetadata("blockHasComment.kt")
+ public void testBlockHasComment() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasComment.kt");
+ }
+
+ @TestMetadata("blockHasStatement.kt")
+ public void testBlockHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/blockHasStatement.kt");
+ }
+
+ @TestMetadata("single.kt")
+ public void testSingle() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/single.kt");
+ }
+
+ @TestMetadata("singleHasStatement.kt")
+ public void testSingleHasStatement() throws Exception {
+ runTest("idea/testData/inspectionsLocal/controlFlowWithEmptyBody/while/singleHasStatement.kt");
+ }
+ }
+ }
+
@TestMetadata("idea/testData/inspectionsLocal/conventionNameCalls")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)