kotlin:S5612 should adjust its behavior for function with @Composable annotations

  • What language is this for?

    • Kotlin for Android, with Jetpack Compose
  • Which rule?

    • kotlin:S5612 Lambdas should not have too many lines
  • Are you using

    • SonarQube Server Developer Edition v2025.3.1 (109879)

    • SonarQube for IDE 10.30.0.82084 in Android Studio Narwhal Feature Drop | 2025.1.2 Patch 2

  • Why do you believe it’s a false-positive/false-negative?

With Jetpack Compose, UI is built by nesting composable functions within trailing lambdas. These lambdas are not for complex logic; they are for declaring a UI hierarchy. It is standard practice for a screen’s content lambda to exceed the default 20-line limit, even for moderately complex views.

  • How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun SettingsScreen() {
    var notificationsEnabled by remember { mutableStateOf(true) }
    var darkModeEnabled by remember { mutableStateOf(false) }
    var dataSaverEnabled by remember { mutableStateOf(false) }
    var autoPlayVideos by remember { mutableStateOf(true) }
    var showProfilePublicly by remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            TopAppBar(title = { Text("App Settings") })
        }
    ) { paddingValues ->
        // This Column's content lambda will trigger the violation.
        // It contains more than 20 lines of declarative UI code.
        Column(
            modifier = Modifier
                .padding(paddingValues)
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            SettingItem(
                title = "Enable Notifications",
                checked = notificationsEnabled,
                onCheckedChange = { notificationsEnabled = it }
            )
            SettingItem(
                title = "Dark Mode",
                checked = darkModeEnabled,
                onCheckedChange = { darkModeEnabled = it }
            )
            SettingItem(
                title = "Data Saver",
                checked = dataSaverEnabled,
                onCheckedChange = { dataSaverEnabled = it }
            )
            SettingItem(
                title = "Auto-play Videos",
                checked = autoPlayVideos,
                onCheckedChange = { autoPlayVideos = it }
            )
            SettingItem(
                title = "Show Profile Publicly",
                checked = showProfilePublicly,
                onCheckedChange = { showProfilePublicly = it }
            )
        }
    }
}

@Composable
private fun SettingItem(
    title: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(text = title)
        Switch(checked = checked, onCheckedChange = onCheckedChange)
    }
}

I believe the behavior of this rule should be quite like for kotlin:s107 where it is considered to add a separate threshold for compose functions.

1 Like

Hello @Qheb ,

First of all - welcome to the community and big thanks for the reporting.
We created a ticket to fix the problem and will work on it in one of the future releases.

Hi Maksim,
That’s great, thank you for the quick response! :slight_smile: