Skip to content

Commit ca4a1f7

Browse files
author
Alexander Matečný
committed
Utility functions and convenience functions consolidated and placed to LintUtils.kt
1 parent 4c4fd3e commit ca4a1f7

5 files changed

+35
-72
lines changed

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

-27
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,10 @@ import com.android.tools.lint.detector.api.JavaContext
88
import com.android.tools.lint.detector.api.Scope
99
import com.android.tools.lint.detector.api.Severity
1010
import com.android.tools.lint.detector.api.SourceCodeScanner
11-
import com.android.tools.lint.detector.api.computeKotlinArgumentMapping
1211
import com.intellij.psi.PsiElement
13-
import com.intellij.psi.PsiJavaFile
14-
import com.intellij.psi.PsiMember
1512
import com.intellij.psi.PsiMethod
1613
import org.jetbrains.uast.UBlockExpression
1714
import org.jetbrains.uast.UCallExpression
18-
import org.jetbrains.uast.ULambdaExpression
1915
import org.jetbrains.uast.skipParenthesizedExprDown
2016
import org.jetbrains.uast.toUElement
2117
import org.jetbrains.uast.tryResolveNamed
@@ -75,7 +71,6 @@ class DialogButtonsInContentSlotDetector : Detector(), SourceCodeScanner {
7571
)
7672
}
7773
}
78-
7974
}
8075

8176
private fun PsiElement.findAllBlockExpressionsInHierarchy(): List<UBlockExpression> {
@@ -87,26 +82,4 @@ class DialogButtonsInContentSlotDetector : Detector(), SourceCodeScanner {
8782

8883
return expressions
8984
}
90-
91-
private fun PsiMethod.getArgument(
92-
node: UCallExpression,
93-
argumentName: String,
94-
): ULambdaExpression? = computeKotlinArgumentMapping(node, this)
95-
.orEmpty()
96-
.filter { (_, parameter) ->
97-
parameter.name == argumentName
98-
}
99-
.keys
100-
.filterIsInstance<ULambdaExpression>()
101-
.firstOrNull()
102-
103-
private fun PsiMethod.isInPackageName(packageName: String): Boolean {
104-
val actual = (containingFile as? PsiJavaFile)?.packageName
105-
return packageName == actual
106-
}
107-
108-
private fun PsiElement.getPackageName(): String? = when (this) {
109-
is PsiMember -> this.containingClass?.qualifiedName?.let { it.substring(0, it.lastIndexOf(".")) }
110-
else -> null
111-
}
11285
}

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

+31
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,45 @@
1616

1717
package kiwi.orbit.compose.lint.detectors
1818

19+
import com.android.tools.lint.detector.api.computeKotlinArgumentMapping
20+
import com.intellij.psi.PsiElement
21+
import com.intellij.psi.PsiJavaFile
22+
import com.intellij.psi.PsiMember
23+
import com.intellij.psi.PsiMethod
1924
import org.jetbrains.kotlin.psi.KtLambdaExpression
2025
import org.jetbrains.kotlin.psi.KtParameter
2126
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
2227
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
2328
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
29+
import org.jetbrains.uast.UCallExpression
2430
import org.jetbrains.uast.ULambdaExpression
2531
import org.jetbrains.uast.toUElement
2632

33+
internal fun PsiMethod.isInPackageName(packageName: String): Boolean {
34+
val actual = (containingFile as? PsiJavaFile)?.packageName
35+
return packageName == actual
36+
}
37+
38+
internal fun PsiElement.getPackageName(): String? = when (this) {
39+
is PsiMember -> this.containingClass?.qualifiedName?.let { it.substring(0, it.lastIndexOf(".")) }
40+
else -> null
41+
}
42+
43+
/**
44+
* Get arguments of a method. Useful for retrieving Compose Lambda expression used as arguments.
45+
*/
46+
internal fun PsiMethod.getArgument(
47+
node: UCallExpression,
48+
argumentName: String,
49+
): ULambdaExpression? = computeKotlinArgumentMapping(node, this)
50+
.orEmpty()
51+
.filter { (_, parameter) ->
52+
parameter.name == argumentName
53+
}
54+
.keys
55+
.filterIsInstance<ULambdaExpression>()
56+
.firstOrNull()
57+
2758
/**
2859
* Returns a list of unreferenced parameters in [this]. If no parameters have been specified, but
2960
* there is an implicit `it` parameter, this will return a list containing an

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

+2-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import org.jetbrains.uast.UCallExpression
1616
import org.jetbrains.uast.UElement
1717
import org.jetbrains.uast.UQualifiedReferenceExpression
1818
import org.jetbrains.uast.USimpleNameReferenceExpression
19-
import org.jetbrains.uast.getContainingUClass
2019
import org.jetbrains.uast.toUElement
2120
import org.jetbrains.uast.tryResolveNamed
2221

@@ -33,8 +32,7 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
3332
return object : UElementHandler() {
3433
override fun visitCallExpression(node: UCallExpression) {
3534
val name = node.methodName ?: return
36-
val wrapperName = node.resolve()?.containingClass?.qualifiedName ?: return
37-
val packageName = getPackageName(wrapperName)
35+
val packageName = node.resolve()?.getPackageName()?: return
3836
val fqn = "$packageName.$name"
3937
val (preferredName) = METHOD_NAMES.entries.firstOrNull { it.value.contains(fqn) } ?: return
4038

@@ -44,8 +42,7 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
4442
val parentExpression = node.sourcePsi?.parents?.find { it is KtCallExpression }
4543
val resolved = parentExpression.toUElement()?.tryResolveNamed()
4644
val parentName = resolved?.name
47-
val parentWrapper = resolved.toUElement()?.getContainingUClass()?.qualifiedName ?: ""
48-
val parentPackage = getPackageName(parentWrapper)
45+
val parentPackage = resolved?.getPackageName() ?: ""
4946
val parentFqn = "$parentPackage.$parentName"
5047
if (allowedEntry.value.find { parentFqn.contains(it) } != null) {
5148
return
@@ -222,9 +219,5 @@ class MaterialDesignInsteadOrbitDesignDetector : Detector(), Detector.UastScanne
222219
"Using $name instead of $preferredName",
223220
)
224221
}
225-
226-
private fun getPackageName(fullyQualifiedName: String): String {
227-
return fullyQualifiedName.substring(0, fullyQualifiedName.lastIndexOf("."))
228-
}
229222
}
230223
}

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

+2-30
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,10 @@ import com.android.tools.lint.detector.api.JavaContext
88
import com.android.tools.lint.detector.api.Scope
99
import com.android.tools.lint.detector.api.Severity
1010
import com.android.tools.lint.detector.api.SourceCodeScanner
11-
import com.android.tools.lint.detector.api.computeKotlinArgumentMapping
12-
import com.intellij.psi.PsiElement
13-
import com.intellij.psi.PsiJavaFile
14-
import com.intellij.psi.PsiMember
1511
import com.intellij.psi.PsiMethod
1612
import com.intellij.psi.PsiNamedElement
1713
import org.jetbrains.uast.UBlockExpression
1814
import org.jetbrains.uast.UCallExpression
19-
import org.jetbrains.uast.ULambdaExpression
2015
import org.jetbrains.uast.skipParenthesizedExprDown
2116
import org.jetbrains.uast.tryResolveNamed
2217

@@ -51,7 +46,7 @@ class MaterialDialogWithOrbitButtonsDetector : Detector(), SourceCodeScanner {
5146

5247
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
5348
if (method.isInPackageName(PACKAGE_MATERIAL_ALERT)) {
54-
val confirmButtonArgument = getArgument(node, method, MATERIAL_ALERT_CONFIRM_BUTTON_PARAM)
49+
val confirmButtonArgument = method.getArgument(node, MATERIAL_ALERT_CONFIRM_BUTTON_PARAM)
5550

5651
(confirmButtonArgument?.body as? UBlockExpression)?.let { body ->
5752
val resolvedBodyExpression = body.resolveFirstBodyExpression() ?: return@let
@@ -77,7 +72,7 @@ class MaterialDialogWithOrbitButtonsDetector : Detector(), SourceCodeScanner {
7772
}
7873
}
7974

80-
val dismissButtonArgument = getArgument(node, method, MATERIAL_ALERT_DISMISS_BUTTON_PARAM)
75+
val dismissButtonArgument = method.getArgument(node, MATERIAL_ALERT_DISMISS_BUTTON_PARAM)
8176

8277
(dismissButtonArgument?.body as? UBlockExpression)?.let { body ->
8378
val resolvedBodyExpression = body.resolveFirstBodyExpression() ?: return@let
@@ -105,29 +100,6 @@ class MaterialDialogWithOrbitButtonsDetector : Detector(), SourceCodeScanner {
105100
}
106101
}
107102

108-
private fun getArgument(
109-
node: UCallExpression,
110-
method: PsiMethod,
111-
argumentName: String,
112-
): ULambdaExpression? = computeKotlinArgumentMapping(node, method)
113-
.orEmpty()
114-
.filter { (_, parameter) ->
115-
parameter.name == argumentName
116-
}
117-
.keys
118-
.filterIsInstance<ULambdaExpression>()
119-
.firstOrNull()
120-
121-
private fun PsiMethod.isInPackageName(packageName: String): Boolean {
122-
val actual = (containingFile as? PsiJavaFile)?.packageName
123-
return packageName == actual
124-
}
125-
126-
private fun PsiElement.getPackageName(): String? = when (this) {
127-
is PsiMember -> this.containingClass?.qualifiedName?.let { it.substring(0, it.lastIndexOf(".")) }
128-
else -> null
129-
}
130-
131103
private fun UBlockExpression.resolveFirstBodyExpression(): PsiNamedElement? {
132104
return expressions.firstOrNull()?.skipParenthesizedExprDown()?.tryResolveNamed()
133105
}

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

-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import com.android.tools.lint.detector.api.Scope
2525
import com.android.tools.lint.detector.api.Severity
2626
import com.android.tools.lint.detector.api.SourceCodeScanner
2727
import com.android.tools.lint.detector.api.computeKotlinArgumentMapping
28-
import com.intellij.psi.PsiJavaFile
2928
import com.intellij.psi.PsiMethod
3029
import java.util.EnumSet
3130
import org.jetbrains.uast.UCallExpression
@@ -86,9 +85,4 @@ class ScaffoldContentPaddingDetector :
8685
}
8786
}
8887
}
89-
90-
private fun PsiMethod.isInPackageName(packageName: String): Boolean {
91-
val actual = (containingFile as? PsiJavaFile)?.packageName
92-
return packageName == actual
93-
}
9488
}

0 commit comments

Comments
 (0)