diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt index e7ac8c014b..185df557bf 100644 --- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt +++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/AsyncAndSyncRule.kt @@ -6,12 +6,19 @@ import org.cqfn.diktat.ruleset.constants.Warnings.RUN_BLOCKING_INSIDE_ASYNC import com.pinterest.ktlint.core.Rule import com.pinterest.ktlint.core.ast.ElementType.CALL_EXPRESSION +import com.pinterest.ktlint.core.ast.ElementType.FILE import com.pinterest.ktlint.core.ast.ElementType.FUN +import com.pinterest.ktlint.core.ast.ElementType.LAMBDA_ARGUMENT import com.pinterest.ktlint.core.ast.ElementType.REFERENCE_EXPRESSION import com.pinterest.ktlint.core.ast.parent +import org.cqfn.diktat.ruleset.utils.hasChildOfType +import org.cqfn.diktat.ruleset.utils.prettyPrint import org.jetbrains.kotlin.com.intellij.lang.ASTNode +import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier +import org.jetbrains.kotlin.psi.psiUtil.isLambdaOutsideParentheses /** * This rule finds if using runBlocking in asynchronous code @@ -42,5 +49,5 @@ class AsyncAndSyncRule(private val configRules: List) : Rule("sync- private fun ASTNode.isSuspend() = this.elementType == FUN && (this.psi as KtFunction).modifierList?.hasSuspendModifier() ?: false - private fun ASTNode.isRunBlocking() = this.elementType == REFERENCE_EXPRESSION && this.text == "runBlocking" + private fun ASTNode.isRunBlocking() = this.elementType == REFERENCE_EXPRESSION && this.text == "runBlocking" && this.treeParent.hasChildOfType(LAMBDA_ARGUMENT) } diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt index bb87b857cd..9b45ec8df2 100644 --- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt +++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/AsyncAndSyncRuleTest.kt @@ -45,4 +45,30 @@ class AsyncAndSyncRuleTest : LintTestBase(::AsyncAndSyncRule) { LintError(18, 4, ruleId, "${RUN_BLOCKING_INSIDE_ASYNC.warnText()} runBlocking", false) ) } + + @Test + @Tag(WarningNames.RUN_BLOCKING_INSIDE_ASYNC) + fun `test dot qualified expression case`() { + lintMethod( + """ + |fun foo() { + | GlobalScope.async { + | node.runBlocking() + | runBlocking { + | n++ + | } + | } + |} + | + |fun goo() { + | runBlocking { + | GlobalScope.async { + | n++ + | } + | } + |} + """.trimMargin(), + LintError(4, 8, ruleId, "${RUN_BLOCKING_INSIDE_ASYNC.warnText()} runBlocking", false) + ) + } } diff --git a/info/guide/guide-chapter-5.md b/info/guide/guide-chapter-5.md index b750a8eef0..6eef6ca3a7 100644 --- a/info/guide/guide-chapter-5.md +++ b/info/guide/guide-chapter-5.md @@ -135,7 +135,7 @@ private fun foo() { #### 5.2.4 Synchronizing code inside asynchronous code Try to avoid using runBlocking in asynchronous code -**Example**: +**Invalid example**: ```kotlin GlobalScope.async { runBlocking {