Migrates ui-lint to use compose:lint:common
Test: lintDebug
Change-Id: Ife406794084eae379b53a3e16e080514f7cd1806
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
index 5ec6d27..4ff61a8 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
@@ -23,11 +23,15 @@
*/
object Names {
object Runtime {
- val packageName = Package("androidx.compose.runtime")
+ val PackageName = Package("androidx.compose.runtime")
- val Composable = Name(packageName, "Composable")
- val CompositionLocal = Name(packageName, "CompositionLocal")
- val Remember = Name(packageName, "remember")
+ val Composable = Name(PackageName, "Composable")
+ val CompositionLocal = Name(PackageName, "CompositionLocal")
+ val Remember = Name(PackageName, "remember")
+ }
+ object Ui {
+ val PackageName = Package("androidx.compose.ui")
+ val Modifier = Name(PackageName, "Modifier")
}
}
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/Stubs.kt b/compose/lint/common/src/main/java/androidx/compose/lint/Stubs.kt
index e2d3c46..66e8fca 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/Stubs.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/Stubs.kt
@@ -45,15 +45,16 @@
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.platform.InspectorValueInfo
+ @Suppress("ModifierFactoryExtensionFunction")
interface Modifier {
- infix fun then(other: Modifier): Modifier =
- if (other === Modifier) this else CombinedModifier(this, other)
+ infix fun then(other: Modifier): Modifier =
+ if (other === Modifier) this else CombinedModifier(this, other)
- interface Element : Modifier
+ interface Element : Modifier
- companion object : Modifier {
- override infix fun then(other: Modifier): Modifier = other
- }
+ companion object : Modifier {
+ override infix fun then(other: Modifier): Modifier = other
+ }
}
class CombinedModifier(
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
index cfe0589..966e6ea 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
@@ -40,7 +40,7 @@
override fun getApplicableMethodNames(): List<String> = listOf(Names.Runtime.Remember.shortName)
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
- if (method.isInPackageName(Names.Runtime.packageName)) {
+ if (method.isInPackageName(Names.Runtime.PackageName)) {
if (node.getExpressionType() == PsiType.VOID) {
context.report(
RememberReturnType,
diff --git a/compose/ui/ui-lint/build.gradle b/compose/ui/ui-lint/build.gradle
index b76c7ac..3a00438 100644
--- a/compose/ui/ui-lint/build.gradle
+++ b/compose/ui/ui-lint/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import androidx.build.BundleInsideHelper
import androidx.build.LibraryGroups
import androidx.build.LibraryType
@@ -24,6 +25,8 @@
id("kotlin")
}
+BundleInsideHelper.forInsideLintJar(project)
+
dependencies {
// compileOnly because we use lintChecks and it doesn't allow other types of deps
// this ugly hack exists because of b/63873667
@@ -34,6 +37,8 @@
}
compileOnly(KOTLIN_STDLIB)
+ bundleInside(project(":compose:lint:common"))
+
testImplementation(KOTLIN_STDLIB)
testImplementation(LINT_CORE)
testImplementation(LINT_TESTS)
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierDeclarationDetector.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierDeclarationDetector.kt
index c75e458..7a8eb63 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierDeclarationDetector.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierDeclarationDetector.kt
@@ -18,6 +18,8 @@
package androidx.compose.ui.lint
+import androidx.compose.lint.Names
+import androidx.compose.lint.isComposable
import androidx.compose.ui.lint.ModifierDeclarationDetector.Companion.ComposableModifierFactory
import androidx.compose.ui.lint.ModifierDeclarationDetector.Companion.ModifierFactoryReturnType
import com.android.tools.lint.client.api.UElementHandler
@@ -64,7 +66,7 @@
val returnType = node.returnType ?: return
// Ignore functions that do not return Modifier or something implementing Modifier
- if (!InheritanceUtil.isInheritor(returnType, ModifierFqn)) return
+ if (!InheritanceUtil.isInheritor(returnType, Names.Ui.Modifier.javaFqn)) return
val source = node.sourcePsi
@@ -207,7 +209,7 @@
.name("Add Modifier receiver")
.range(context.getLocation(source))
.text(name)
- .with("$ModifierShortName.$name")
+ .with("${Names.Ui.Modifier.shortName}.$name")
.autoFix()
.build()
)
@@ -220,10 +222,10 @@
)?.qualifiedName
val hasModifierReceiver = if (receiverFqn != null) {
// If we could resolve the class, match fqn
- receiverFqn == ModifierFqn
+ receiverFqn == Names.Ui.Modifier.javaFqn
} else {
// Otherwise just try and match the short names
- receiverShortName == ModifierShortName
+ receiverShortName == Names.Ui.Modifier.shortName
}
if (!hasModifierReceiver) {
report(
@@ -232,7 +234,7 @@
.name("Change receiver to Modifier")
.range(context.getLocation(source))
.text(receiverShortName)
- .with(ModifierShortName)
+ .with(Names.Ui.Modifier.shortName)
.autoFix()
.build()
)
@@ -254,7 +256,7 @@
)
}
- if (returnType.canonicalText == ModifierFqn) return
+ if (returnType.canonicalText == Names.Ui.Modifier.javaFqn) return
val source = sourcePsi
if (source is KtCallableDeclaration && source.returnTypeString != null) {
@@ -266,7 +268,7 @@
.name("Change return type to Modifier")
.range(context.getLocation(this))
.text(source.returnTypeString)
- .with(ModifierShortName)
+ .with(Names.Ui.Modifier.shortName)
.autoFix()
.build()
)
@@ -284,7 +286,7 @@
.name("Change return type to Modifier")
.range(context.getLocation(this))
.text(getterReturnType)
- .with(ModifierShortName)
+ .with(Names.Ui.Modifier.shortName)
.autoFix()
.build()
)
@@ -301,7 +303,7 @@
.name("Change return type to Modifier")
.range(context.getLocation(source.property))
.text(propertyType)
- .with(ModifierShortName)
+ .with(Names.Ui.Modifier.shortName)
.autoFix()
.build()
)
@@ -318,7 +320,7 @@
.name("Add explicit Modifier return type")
.range(context.getLocation(this))
.pattern("[ \\t\\n]+=")
- .with(": $ModifierShortName =")
+ .with(": ${Names.Ui.Modifier.shortName} =")
.autoFix()
.build()
)
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
index b28a255..a0f2fa1 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
@@ -18,6 +18,9 @@
package androidx.compose.ui.lint
+import androidx.compose.lint.Names
+import androidx.compose.lint.isComposable
+import androidx.compose.lint.returnsUnit
import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
@@ -28,7 +31,6 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.intellij.psi.PsiType
import com.intellij.psi.util.InheritanceUtil
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtParameter
@@ -56,11 +58,11 @@
if (!node.isComposable) return
// Ignore non-unit composable functions
- if (node.returnType != PsiType.VOID) return
+ if (!node.returnsUnit) return
val modifierParameter = node.uastParameters.firstOrNull { parameter ->
parameter.sourcePsi is KtParameter &&
- InheritanceUtil.isInheritor(parameter.type, ModifierFqn)
+ InheritanceUtil.isInheritor(parameter.type, Names.Ui.Modifier.javaFqn)
} ?: return
// Need to strongly type this or else Kotlinc cannot resolve overloads for
@@ -69,12 +71,14 @@
val source = modifierParameter.sourcePsi as KtParameter
+ val modifierName = Names.Ui.Modifier.shortName
+
if (modifierParameter.name != ModifierParameterName) {
context.report(
ModifierParameter,
node,
context.getNameLocation(modifierParameterElement),
- "$ModifierShortName parameter should be named $ModifierParameterName",
+ "$modifierName parameter should be named $ModifierParameterName",
LintFix.create()
.replace()
.name("Change name to $ModifierParameterName")
@@ -85,18 +89,18 @@
)
}
- if (modifierParameter.type.canonicalText != ModifierFqn) {
+ if (modifierParameter.type.canonicalText != Names.Ui.Modifier.javaFqn) {
context.report(
ModifierParameter,
node,
context.getNameLocation(modifierParameterElement),
- "$ModifierShortName parameter should have a type of $ModifierShortName",
+ "$modifierName parameter should have a type of $modifierName",
LintFix.create()
.replace()
.range(context.getLocation(modifierParameterElement))
- .name("Change type to $ModifierShortName")
+ .name("Change type to $modifierName")
.text(source.typeReference!!.text)
- .with(ModifierShortName)
+ .with(modifierName)
.autoFix()
.build()
)
@@ -107,19 +111,19 @@
// If the default value is not a reference expression, then it isn't `Modifier`
// anyway and we can just report an error
val referenceExpression = source.defaultValue as? KtNameReferenceExpression
- if (referenceExpression?.getReferencedName() != ModifierShortName) {
+ if (referenceExpression?.getReferencedName() != modifierName) {
context.report(
ModifierParameter,
node,
context.getNameLocation(modifierParameterElement),
- "Optional $ModifierShortName parameter should have a default value " +
- "of `$ModifierShortName`",
+ "Optional $modifierName parameter should have a default value " +
+ "of `$modifierName`",
LintFix.create()
.replace()
.range(context.getLocation(modifierParameterElement))
- .name("Change default value to $ModifierShortName")
+ .name("Change default value to $modifierName")
.text(defaultValue.text)
- .with(ModifierShortName)
+ .with(modifierName)
.autoFix()
.build()
)
@@ -133,7 +137,7 @@
ModifierParameter,
node,
context.getNameLocation(modifierParameterElement),
- "$ModifierShortName parameter should be the first optional parameter",
+ "$modifierName parameter should be the first optional parameter",
// Hard to make a lint fix for this and keep parameter formatting, so
// ignore it
)
@@ -148,10 +152,11 @@
"Guidelines for Modifier parameters in a Composable function",
"The first (or only) Modifier parameter in a Composable function should follow the " +
"following rules:" +
- "- Be named `$ModifierParameterName`" +
- "- Have a type of `$ModifierShortName`" +
- "- Either have no default value, or have a default value of `$ModifierShortName`" +
- "- If optional, be the first optional parameter in the parameter list",
+ "\n- Be named `$ModifierParameterName`" +
+ "\n- Have a type of `${Names.Ui.Modifier.shortName}`" +
+ "\n- Either have no default value, or have a default value of " +
+ "`${Names.Ui.Modifier.shortName}`" +
+ "\n- If optional, be the first optional parameter in the parameter list",
Category.CORRECTNESS, 3, Severity.WARNING,
Implementation(
ModifierParameterDetector::class.java,
@@ -161,4 +166,4 @@
}
}
-private val ModifierParameterName = ModifierShortName.decapitalize(Locale.ROOT)
+private val ModifierParameterName = Names.Ui.Modifier.shortName.decapitalize(Locale.ROOT)
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/Utils.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/Utils.kt
deleted file mode 100644
index 89e8f8f..0000000
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/Utils.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.ui.lint
-
-import org.jetbrains.uast.UMethod
-
-// TODO: KotlinUMethodWithFakeLightDelegate.hasAnnotation() returns null for some reason, so just
-// look at the annotations directly
-// TODO: annotations is deprecated but the replacement uAnnotations isn't available on the
-// version of lint / uast we compile against
-@Suppress("DEPRECATION")
-val UMethod.isComposable get() = annotations.any { it.qualifiedName == ComposableFqn }
-
-const val ComposableFqn = "androidx.compose.runtime.Composable"
-
-const val ModifierFqn = "androidx.compose.ui.Modifier"
-val ModifierShortName = ModifierFqn.split(".").last()
\ No newline at end of file
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
index e7c2b4b..33aac1f 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierDeclarationDetectorTest.kt
@@ -18,6 +18,7 @@
package androidx.compose.ui.lint
+import androidx.compose.lint.Stubs
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Issue
@@ -57,7 +58,7 @@
}
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -100,7 +101,7 @@
val Modifier.fooModifier3: Modifier.Element get() = TestModifier
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -149,7 +150,7 @@
fun Modifier.fooModifier() = TestModifier
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -184,7 +185,7 @@
val Modifier.fooModifier get() = TestModifier
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -221,7 +222,7 @@
}
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -276,7 +277,7 @@
}
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
@@ -311,7 +312,7 @@
}
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
@@ -343,7 +344,7 @@
val fooModifier3: Modifier get() = TestModifier
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -411,7 +412,7 @@
val TestModifier.fooModifier3: Modifier get() = TestModifier
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -487,8 +488,8 @@
val Modifier.fooModifier4: Modifier get() = TestModifier(someComposableCall(3))
"""
),
- modifierStub,
- composableStub
+ kotlin(Stubs.Modifier),
+ kotlin(Stubs.Composable)
)
.run()
.expect(
@@ -556,7 +557,7 @@
}
"""
),
- modifierStub
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierParameterDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierParameterDetectorTest.kt
index f2e2aec..25b8f24 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierParameterDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/ModifierParameterDetectorTest.kt
@@ -18,6 +18,7 @@
package androidx.compose.ui.lint
+import androidx.compose.lint.Stubs
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Issue
@@ -58,8 +59,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -99,8 +100,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -142,8 +143,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -183,8 +184,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -218,8 +219,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expect(
@@ -273,8 +274,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
@@ -302,8 +303,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
@@ -336,8 +337,8 @@
) {}
"""
),
- composableStub,
- modifierStub
+ kotlin(Stubs.Composable),
+ kotlin(Stubs.Modifier)
)
.run()
.expectClean()
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/Stubs.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/Stubs.kt
deleted file mode 100644
index abe1e46..0000000
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/Stubs.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:Suppress("UnstableApiUsage")
-
-package androidx.compose.ui.lint
-
-import com.android.tools.lint.checks.infrastructure.LintDetectorTest
-
-val modifierStub: LintDetectorTest.TestFile = LintDetectorTest.kotlin(
- """
- package androidx.compose.ui
-
- interface Modifier {
- interface Element : Modifier
- companion object : Modifier
- }
- """
-)
-
-val composableStub: LintDetectorTest.TestFile = LintDetectorTest.kotlin(
- """
- package androidx.compose.runtime
-
- @MustBeDocumented
- @Retention(AnnotationRetention.BINARY)
- @Target(
- AnnotationTarget.FUNCTION,
- AnnotationTarget.TYPE,
- AnnotationTarget.TYPE_PARAMETER,
- AnnotationTarget.PROPERTY
- )
- annotation class Composable
- """
-)