1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.compose.lint
18 
19 import kotlin.metadata.ClassName
20 
21 /** Contains common names used for lint checks. */
22 object Names {
23     object Animation {
24         val PackageName = Package("androidx.compose.animation")
25 
26         object Core {
27             val PackageName = Package("androidx.compose.animation.core")
28             val Animatable = Name(PackageName, "Animatable")
29         }
30     }
31 
32     object AnimationCore {
33         val PackageName = Package("androidx.compose.animation.core")
34     }
35 
36     object Runtime {
37         val PackageName = Package("androidx.compose.runtime")
38 
39         val Composable = Name(PackageName, "Composable")
40         val CompositionLocal = Name(PackageName, "CompositionLocal")
41         val DerivedStateOf = Name(PackageName, "derivedStateOf")
42         val State = Name(PackageName, "State")
43         val MutableState = Name(PackageName, "MutableState")
44         val MutableStateOf = Name(PackageName, "mutableStateOf")
45         val MutableIntStateOf = Name(PackageName, "mutableIntStateOf")
46         val MutableLongStateOf = Name(PackageName, "mutableLongStateOf")
47         val MutableFloatStateOf = Name(PackageName, "mutableFloatStateOf")
48         val MutableDoubleStateOf = Name(PackageName, "mutableDoubleStateOf")
49         val MutableStateListOf = Name(PackageName, "mutableStateListOf")
50         val MutableStateMapOf = Name(PackageName, "mutableStateMapOf")
51         val ProduceState = Name(PackageName, "produceState")
52         val Remember = Name(PackageName, "remember")
53         val DisposableEffect = Name(PackageName, "DisposableEffect")
54         val RememberSaveable = Name(PackageName, "rememberSaveable")
55         val LaunchedEffect = Name(PackageName, "LaunchedEffect")
56         val ReusableContent = Name(PackageName, "ReusableContent")
57         val Key = Name(PackageName, "key")
58         val StructuralEqualityPolicy = Name(PackageName, "structuralEqualityPolicy")
59 
60         object Annotation {
61             val PackageName = Package(Runtime.PackageName, "annotation")
62             val FrequentlyChangingValue = Name(PackageName, "FrequentlyChangingValue")
63             val RememberInComposition = Name(PackageName, "RememberInComposition")
64         }
65     }
66 
67     object Ui {
68         val PackageName = Package("androidx.compose.ui")
69         val Composed = Name(PackageName, "composed")
70         val Modifier = Name(PackageName, "Modifier")
71 
72         object Layout {
73             val PackageName = Package("androidx.compose.ui.layout")
74             val ParentDataModifier = Name(PackageName, "ParentDataModifier")
75         }
76 
77         object Platform {
78             val PackageName = Package(Ui.PackageName, "platform")
79             val LocalConfiguration = Name(PackageName, "LocalConfiguration")
80             val LocalResources = Name(PackageName, "LocalResources")
81         }
82 
83         object Pointer {
84             val PackageName = Package(Ui.PackageName, "input.pointer")
85             val PointerInputScope = Name(PackageName, "PointerInputScope")
86             val PointerInputScopeModifier = Name(PackageName, "pointerInput")
87             val AwaitPointerEventScope = Name(PackageName, "awaitPointerEventScope")
88         }
89 
90         object Unit {
91             val PackageName = Package("androidx.compose.ui.unit")
92             val Dp = Name(PackageName, "Dp")
93         }
94 
95         object Node {
96             val PackageName = Package(Ui.PackageName, "node")
97             val ModifierNodeElement = Name(PackageName, "ModifierNodeElement")
98             val CurrentValueOf = Name(PackageName, "currentValueOf")
99         }
100     }
101 
102     object UiGraphics {
103         val PackageName = Package("androidx.compose.ui.graphics")
104         val Color = Name(PackageName, "Color")
105     }
106 }
107 
108 /**
109  * Represents a qualified package
110  *
111  * @property segments the segments representing the package
112  */
113 class PackageName internal constructor(internal val segments: List<String>) {
114     /** The Java-style package name for this [Name], separated with `.` */
115     val javaPackageName: String
116         get() = segments.joinToString(".")
117 }
118 
119 /**
120  * Represents the qualified name for an element
121  *
122  * @property pkg the package for this element
123  * @property nameSegments the segments representing the element - there can be multiple in the case
124  *   of nested classes.
125  */
126 class Name
127 internal constructor(private val pkg: PackageName, private val nameSegments: List<String>) {
128     /** The short name for this [Name] */
129     val shortName: String
130         get() = nameSegments.last()
131 
132     /** The Java-style fully qualified name for this [Name], separated with `.` */
133     val javaFqn: String
134         get() = pkg.segments.joinToString(".", postfix = ".") + nameSegments.joinToString(".")
135 
136     /**
137      * The [ClassName] for use with kotlin.metadata. Note that in kotlin.metadata the actual type
138      * might be different from the underlying JVM type, for example: kotlin/Int -> java/lang/Integer
139      */
140     val kmClassName: ClassName
141         get() = pkg.segments.joinToString("/", postfix = "/") + nameSegments.joinToString(".")
142 
143     /** The [PackageName] of this element. */
144     val packageName: PackageName
145         get() = pkg
146 }
147 
148 /** @return a [PackageName] with a Java-style (separated with `.`) [packageName]. */
Packagenull149 fun Package(packageName: String): PackageName = PackageName(packageName.split("."))
150 
151 /** @return a [PackageName] with a Java-style (separated with `.`) [packageName]. */
152 fun Package(packageName: PackageName, shortName: String): PackageName =
153     PackageName(packageName.segments + shortName.split("."))
154 
155 /** @return a [Name] with the provided [pkg] and Java-style (separated with `.`) [shortName]. */
156 fun Name(pkg: PackageName, shortName: String): Name = Name(pkg, shortName.split("."))
157