Skip to content
This repository was archived by the owner on May 7, 2025. It is now read-only.

Commit 104fc5a

Browse files
authored
Merge pull request #542 from kiwicom/task/exception_to_material_textbutton_lint_rule_for_alert_dialogs
Allow usage of material TextButton inside of Material AlertDialog without lint reporting the usage.
2 parents a12b165 + 01c73c5 commit 104fc5a

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

catalog/src/main/java/kiwi/orbit/compose/catalog/screens/DialogsMaterialDialog.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package kiwi.orbit.compose.catalog.screens
22

3-
import android.annotation.SuppressLint
43
import androidx.compose.material3.AlertDialog
54
import androidx.compose.runtime.Composable
65
import androidx.navigation.NavController
@@ -13,7 +12,6 @@ internal fun DialogsMaterialDialog(navController: NavController) {
1312
)
1413
}
1514

16-
@SuppressLint("MaterialDesignInsteadOrbitDesign")
1715
@Composable
1816
private fun DialogsMaterialDialog(
1917
onClose: () -> Unit,

lint/src/main/kotlin/kiwi/orbit/compose/lint/detectors/MaterialDesignInsteadOrbitDesignDetector.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ import com.android.tools.lint.detector.api.Scope
1010
import com.android.tools.lint.detector.api.Severity
1111
import com.intellij.psi.PsiMember
1212
import com.intellij.psi.impl.source.PsiClassReferenceType
13+
import org.jetbrains.kotlin.psi.KtCallExpression
14+
import org.jetbrains.kotlin.psi.psiUtil.parents
1315
import org.jetbrains.uast.UCallExpression
1416
import org.jetbrains.uast.UElement
1517
import org.jetbrains.uast.UQualifiedReferenceExpression
1618
import org.jetbrains.uast.USimpleNameReferenceExpression
19+
import org.jetbrains.uast.getContainingUClass
20+
import org.jetbrains.uast.toUElement
21+
import org.jetbrains.uast.tryResolveNamed
1722

1823
class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanner {
1924
override fun getApplicableUastTypes(): List<Class<out UElement>> {
@@ -29,9 +34,24 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
2934
override fun visitCallExpression(node: UCallExpression) {
3035
val name = node.methodName ?: return
3136
val wrapperName = node.resolve()?.containingClass?.qualifiedName ?: return
32-
val packageName = wrapperName.substring(0, wrapperName.lastIndexOf("."))
37+
val packageName = getPackageName(wrapperName)
3338
val fqn = "$packageName.$name"
3439
val (preferredName) = METHOD_NAMES.entries.firstOrNull { it.value.contains(fqn) } ?: return
40+
41+
// check the potential violation against our allowlist
42+
val allowedEntry = METHOD_ALLOWLIST_IN_PARENT.entries.find { it.key.contains(fqn) }
43+
if (allowedEntry != null) {
44+
val parentExpression = node.sourcePsi?.parents?.find { it is KtCallExpression }
45+
val resolved = parentExpression.toUElement()?.tryResolveNamed()
46+
val parentName = resolved?.name
47+
val parentWrapper = resolved.toUElement()?.getContainingUClass()?.qualifiedName ?: ""
48+
val parentPackage = getPackageName(parentWrapper)
49+
val parentFqn = "$parentPackage.$parentName"
50+
if (allowedEntry.value.find { parentFqn.contains(it) } != null) {
51+
return
52+
}
53+
}
54+
3555
reportIssue(context, node, "$packageName.$name", preferredName)
3656
}
3757

@@ -66,6 +86,17 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
6686
),
6787
)
6888

89+
private val METHOD_ALLOWLIST_IN_PARENT = mapOf(
90+
"androidx.compose.material.TextButton" to setOf(
91+
"androidx.compose.material.AlertDialog",
92+
"androidx.compose.material3.AlertDialog",
93+
),
94+
"androidx.compose.material3.TextButton" to setOf(
95+
"androidx.compose.material.AlertDialog",
96+
"androidx.compose.material3.AlertDialog",
97+
),
98+
)
99+
69100
private val METHOD_NAMES = mapOf(
70101
"kiwi.orbit.compose.ui.controls.ButtonPrimary" to setOf(
71102
"androidx.compose.material.Button",
@@ -191,5 +222,9 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
191222
"Using $name instead of $preferredName",
192223
)
193224
}
225+
226+
private fun getPackageName(fullyQualifiedName: String): String {
227+
return fullyQualifiedName.substring(0, fullyQualifiedName.lastIndexOf("."))
228+
}
194229
}
195230
}

lint/src/test/kotlin/kiwi/orbit/compose/lint/detectors/MaterialDesignInsteadOrbitDesignDetectorTest.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import java.io.File
1414
import org.junit.Assert
1515
import org.junit.Test
1616

17-
@Suppress("UnstableApiUsage")
1817
class MaterialDesignInsteadOrbitDesignDetectorTest {
1918
@Test
2019
fun testDetector() {
@@ -25,9 +24,11 @@ class MaterialDesignInsteadOrbitDesignDetectorTest {
2524
import androidx.compose.material.contentColorFor
2625
import androidx.compose.material.Text
2726
import androidx.compose.material.icons.Icons
27+
import androidx.compose.material3.AlertDialog
2828
import androidx.compose.material3.Card as Card3
2929
import androidx.compose.material3.contentColorFor as contentColorFor3
3030
import androidx.compose.material3.Text as Text3
31+
import androidx.compose.material3.TextButton
3132
import androidx.compose.material3.Divider
3233
import androidx.compose.material3.LocalTextStyle
3334
fun Test() {
@@ -43,7 +44,9 @@ class MaterialDesignInsteadOrbitDesignDetectorTest {
4344
LocalTextStyle.current
4445
LocalTextStyle
4546
LocalTextStyle.provides()
46-
}
47+
AlertDialog(confirmButton = { TextButton("test") })
48+
}
49+
AlertDialog(confirmButton = { TextButton("test") })
4750
}
4851
""".trimIndent(),
4952
)
@@ -52,6 +55,7 @@ class MaterialDesignInsteadOrbitDesignDetectorTest {
5255
package androidx.compose.material
5356
fun Card(content: () -> Unit) {}
5457
fun Text(content: () -> Unit) {}
58+
fun TextButton(content: String) {}
5559
fun contentColorFor(backgroundColor: Color): Color = TODO()
5660
""".trimIndent(),
5761
)
@@ -60,7 +64,12 @@ class MaterialDesignInsteadOrbitDesignDetectorTest {
6064
package androidx.compose.material3
6165
fun Card(content: () -> Unit) {}
6266
fun Text(content: () -> Unit) {}
67+
fun TextButton(content: String) {}
6368
fun Divider() {}
69+
fun AlertDialog(
70+
confirmButton: () -> Unit,
71+
dismissButton: (() -> Unit)? = null,
72+
) {}
6473
fun contentColorFor(backgroundColor: Color): Color = TODO()
6574
@Stable
6675
sealed class CompositionLocal<T> constructor(defaultFactory: () -> T) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy