Skip to content

Commit

Permalink
Prepare release 1.2.1.
Browse files Browse the repository at this point in the history
Fixup MissingModifierDefaultValue

Exclude composable functions in abstract classes and interfaces: Compose
compiler does not permit default values there

Closes #11
  • Loading branch information
dimsuz committed Aug 14, 2022
1 parent 2138b13 commit d58a855
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.2.1 - 2022-08-14

* Ignore composable functions in interfaces/abstract classes for `MissingModifierDefaultValue` (#11)

## 1.2.0 - 2022-08-14

* New rule: `TopLevelComposableFunctions` ensures that all composable functions are top-level functions (disabled by default)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Detekt rules for Jetpack Compose

[![MavenCentral](https://img.shields.io/maven-central/v/ru.kode/detekt-rules-compose?versionPrefix=1.2.0)](https://search.maven.org/artifact/ru.kode/detekt-rules-compose)
[![MavenCentral](https://img.shields.io/maven-central/v/ru.kode/detekt-rules-compose?versionPrefix=1.2.1)](https://search.maven.org/artifact/ru.kode/detekt-rules-compose)

A set of [Detekt](https://detekt.dev) rules to help prevent common errors in projects using Jetpack Compose.

Expand Down Expand Up @@ -39,7 +39,7 @@ More detailed rule descriptions with code snippets can be found in the [Wiki](ht
Add detekt rules plugin in your `build.gradle` (or use any other [supported method](https://detekt.dev/docs/introduction/extensions#let-detekt-know-about-your-extensions)):
```
dependencies {
detektPlugins("ru.kode:detekt-rules-compose:1.2.0")
detektPlugins("ru.kode:detekt-rules-compose:1.2.1")
}
```
and then add this configuration section to your `detekt-config.yml` to activate the rules:
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ org.gradle.jvmargs=-XX:MaxMetaspaceSize=1g

kotlin.code.style=official

versionName=1.2.0
versionName=1.2.1
pomGroupId=ru.kode
pomDescription=Detekt rules for Jetpack Compose
pomUrl=https://github.com/appKODE/detekt-rules-compose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.rules.hasAnnotation
import io.gitlab.arturbosch.detekt.rules.isAbstract
import io.gitlab.arturbosch.detekt.rules.isOpen
import io.gitlab.arturbosch.detekt.rules.isOverride
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.psiUtil.containingClass
import ru.kode.detekt.rule.compose.node.isModifier

/**
Expand Down Expand Up @@ -43,6 +46,13 @@ class MissingModifierDefaultValue(config: Config = Config.empty) : Rule(config)
override fun visitNamedFunction(function: KtNamedFunction) {
if (function.hasAnnotation("Composable")) {
val modifierParameter = function.valueParameters.find { it.isModifier() }
// abstract functions and interface functions cannot have default parameters
// (Compose compiler plugin restriction).
// Open methods do not have those restrictions, but it feels logical to exclude them too
// in a similar manner
if (function.isAbstract() || function.isOpen() || function.containingClass()?.isInterface() == true) {
return
}
if (!function.isOverride() && modifierParameter?.hasDefaultValue() == false) {
reportError(modifierParameter)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,48 @@ class MissingModifierDefaultValueTest : ShouldSpec(
findings.shouldBeEmpty()
}

should("not report an interface function") {
// language=kotlin
val code = """
interface Screen {
@Composable
fun Content(modifier: Modifier)
}
""".trimIndent()

val findings = MissingModifierDefaultValue().lint(code)

findings.shouldBeEmpty()
}

should("not report an abstract function") {
// language=kotlin
val code = """
abstract class Screen {
@Composable
abstract fun Content(modifier: Modifier)
}
""".trimIndent()

val findings = MissingModifierDefaultValue().lint(code)

findings.shouldBeEmpty()
}

should("not report an open function") {
// language=kotlin
val code = """
open class Screen {
@Composable
open fun Content(modifier: Modifier) {}
}
""".trimIndent()

val findings = MissingModifierDefaultValue().lint(code)

findings.shouldBeEmpty()
}

should("not report overriding function when inheriting an open class") {
// language=kotlin
val code = """
Expand Down Expand Up @@ -83,7 +125,7 @@ class MissingModifierDefaultValueTest : ShouldSpec(
val code = """
abstract class Screen {
@Composable
abstract fun Content(modifier: Modifier = Modifier)
abstract fun Content(modifier: Modifier)
}
class ScreenImpl : Screen() {
Expand All @@ -103,7 +145,7 @@ class MissingModifierDefaultValueTest : ShouldSpec(
val code = """
interface Screen {
@Composable
fun Content(modifier: Modifier = Modifier)
fun Content(modifier: Modifier)
}
class ScreenImpl : Screen {
Expand Down

0 comments on commit d58a855

Please sign in to comment.