Repository: JetBrains/kotlin
File: plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/k2/ComposableCallChecker.kt (Kotlin)

Code before:
/**
 * Check if `expression` - a call to a composable function or access to a composable property -
 * is allowed in the current context. It is allowed if:
 *
 * - It is executed as part of the body of a composable function.
 * - It is not executed as part of the body of a lambda annotated with `@DisallowComposableCalls`.
 * - It is not inside of a `try` block.
 * - It is not inside of the body of a lambda passed to a `runCatching` call. (As for references to
 *   `@Composable` functions, the type system prevents those from being passed to `runCatching`
 *   calls.)
 * - It is a call to a readonly composable function if it is executed in the body of a function
 *   that is annotated with `@ReadOnlyComposable`.
 *
 * A function is composable if:
 * - It is annotated with `@Composable`.
 * - It is a lambda whose type is inferred to be `ComposableFunction`.
 * - It is an inline lambda whose enclosing function is composable.
 */
private fun checkComposableCall(
    expression: FirQualifiedAccessExpression,
    calleeFunction: FirCallableSymbol<*>,
    context: CheckerContext,
    reporter: DiagnosticReporter,
) {
    if (calleeFunction.callableId == ComposeCallableIds.key) {
        // If key only has the block parameter, report it
        if (expression is FirFunctionCall && expression.arguments.size == 1) {
            reporter.reportOn(
                expression.calleeReference.source,
                ComposeErrors.KEY_CALL_WITH_NO_ARGUMENTS,
                context
            )
        }
    }

    context.visitCurrentScope(
        visitInlineLambdaParameter = { parameter ->
            val containingDeclarationSymbol = parameter.containingDeclarationSymbol
            if (parameter.returnTypeRef.hasDisallowComposableCallsAnnotation(context.session) && containingDeclarationSymbol is FirCallableSymbol) {
                reporter.reportOn(
                    expression.calleeReference.source,
                    ComposeErrors.CAPTURED_COMPOSABLE_INVOCATION,
                    parameter.symbol,
                    containingDeclarationSymbol,
                    context
                )
            }
        },
        visitAnonymousFunction = { function ->
            if (function.typeRef.coneType.functionTypeKind(context.session) === ComposableFunction)
                return

Review comment (suggestion):
Nit:

```suggestion
        // If key call only has the block argument, report it
```

Code after:
/**
 * Check if `expression` - a call to a composable function or access to a composable property -
 * is allowed in the current context. It is allowed if:
 *
 * - It is executed as part of the body of a composable function.
 * - It is not executed as part of the body of a lambda annotated with `@DisallowComposableCalls`.
 * - It is not inside of a `try` block.
 * - It is not inside of the body of a lambda passed to a `runCatching` call. (As for references to
 *   `@Composable` functions, the type system prevents those from being passed to `runCatching`
 *   calls.)
 * - It is a call to a readonly composable function if it is executed in the body of a function
 *   that is annotated with `@ReadOnlyComposable`.
 *
 * A function is composable if:
 * - It is annotated with `@Composable`.
 * - It is a lambda whose type is inferred to be `ComposableFunction`.
 * - It is an inline lambda whose enclosing function is composable.
 */
private fun checkComposableCall(
    expression: FirQualifiedAccessExpression,
    calleeFunction: FirCallableSymbol<*>,
    context: CheckerContext,
    reporter: DiagnosticReporter,
) {
    if (calleeFunction.callableId == ComposeCallableIds.key) {
        // If key call only has the block argument, report it
        if (expression is FirFunctionCall && expression.arguments.size == 1) {
            reporter.reportOn(
                expression.calleeReference.source,
                ComposeErrors.KEY_CALL_WITH_NO_ARGUMENTS,
                context
            )
        }
    }

    context.visitCurrentScope(
        visitInlineLambdaParameter = { parameter ->
            val containingDeclarationSymbol = parameter.containingDeclarationSymbol
            if (parameter.returnTypeRef.hasDisallowComposableCallsAnnotation(context.session) && containingDeclarationSymbol is FirCallableSymbol) {
                reporter.reportOn(
                    expression.calleeReference.source,
                    ComposeErrors.CAPTURED_COMPOSABLE_INVOCATION,
                    parameter.symbol,
                    containingDeclarationSymbol,
                    context
                )
            }
        },
        visitAnonymousFunction = { function ->
            if (function.typeRef.coneType.functionTypeKind(context.session) === ComposableFunction)
                return