• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 com.android.tools.metalava.model.psi
18 
19 import com.android.tools.metalava.model.ArrayTypeItem
20 import com.android.tools.metalava.model.ClassTypeItem
21 import com.android.tools.metalava.model.Codebase
22 import com.android.tools.metalava.model.DefaultTypeItem
23 import com.android.tools.metalava.model.LambdaTypeItem
24 import com.android.tools.metalava.model.PrimitiveTypeItem
25 import com.android.tools.metalava.model.ReferenceTypeItem
26 import com.android.tools.metalava.model.TypeArgumentTypeItem
27 import com.android.tools.metalava.model.TypeItem
28 import com.android.tools.metalava.model.TypeModifiers
29 import com.android.tools.metalava.model.TypeParameterItem
30 import com.android.tools.metalava.model.VariableTypeItem
31 import com.android.tools.metalava.model.WildcardTypeItem
32 import com.intellij.psi.LambdaUtil
33 import com.intellij.psi.PsiArrayType
34 import com.intellij.psi.PsiClassType
35 import com.intellij.psi.PsiPrimitiveType
36 import com.intellij.psi.PsiType
37 import com.intellij.psi.PsiWildcardType
38 import com.intellij.psi.util.TypeConversionUtil
39 
40 /** Represents a type backed by PSI */
41 internal sealed class PsiTypeItem(
42     val psiType: PsiType,
43     modifiers: TypeModifiers,
44     val kotlinTypeInfo: KotlinTypeInfo?,
45 ) : DefaultTypeItem(modifiers) {
46     /** Whether the [psiType] is originally a value class type. */
isValueClassTypenull47     override fun isValueClassType(): Boolean = kotlinTypeInfo?.isValueClassType() ?: false
48 
49     /** Returns `true` if `this` type can be assigned from `other` without unboxing the other. */
50     override fun isAssignableFromWithoutUnboxing(other: TypeItem): Boolean {
51         if (other !is PsiTypeItem) return super.isAssignableFromWithoutUnboxing(other)
52         if (this is PrimitiveTypeItem && other !is PrimitiveTypeItem) {
53             return false
54         }
55         return TypeConversionUtil.isAssignable(psiType, other.psiType)
56     }
57 }
58 
59 /** A [PsiTypeItem] backed by a [PsiPrimitiveType]. */
60 internal class PsiPrimitiveTypeItem(
61     psiType: PsiType,
62     override val kind: PrimitiveTypeItem.Primitive,
63     modifiers: TypeModifiers,
64     kotlinTypeInfo: KotlinTypeInfo?,
65 ) : PrimitiveTypeItem, PsiTypeItem(psiType, modifiers, kotlinTypeInfo) {
66     @Deprecated(
67         "implementation detail of this class",
68         replaceWith = ReplaceWith("substitute(modifiers)"),
69     )
duplicatenull70     override fun duplicate(modifiers: TypeModifiers): PsiPrimitiveTypeItem =
71         PsiPrimitiveTypeItem(
72             psiType = psiType,
73             kind = kind,
74             modifiers = modifiers,
75             kotlinTypeInfo = kotlinTypeInfo,
76         )
77 }
78 
79 /** A [PsiTypeItem] backed by a [PsiArrayType]. */
80 internal class PsiArrayTypeItem(
81     psiType: PsiType,
82     override val componentType: TypeItem,
83     override val isVarargs: Boolean,
84     modifiers: TypeModifiers,
85     kotlinTypeInfo: KotlinTypeInfo?,
86 ) : ArrayTypeItem, PsiTypeItem(psiType, modifiers, kotlinTypeInfo) {
87     @Deprecated(
88         "implementation detail of this class",
89         replaceWith = ReplaceWith("substitute(modifiers, componentType)"),
90     )
91     override fun duplicate(modifiers: TypeModifiers, componentType: TypeItem): ArrayTypeItem =
92         PsiArrayTypeItem(
93             psiType = psiType,
94             componentType = componentType,
95             isVarargs = isVarargs,
96             modifiers = modifiers,
97             kotlinTypeInfo = kotlinTypeInfo,
98         )
99 }
100 
101 /** A [PsiTypeItem] backed by a [PsiClassType] that does not represent a type variable. */
102 internal open class PsiClassTypeItem(
103     protected val codebase: Codebase,
104     psiType: PsiType,
105     final override val qualifiedName: String,
106     final override val arguments: List<TypeArgumentTypeItem>,
107     final override val outerClassType: ClassTypeItem?,
108     modifiers: TypeModifiers,
109     kotlinTypeInfo: KotlinTypeInfo?,
110 ) : ClassTypeItem, PsiTypeItem(psiType, modifiers, kotlinTypeInfo) {
111     override val className: String = ClassTypeItem.computeClassName(qualifiedName)
112 
113     private val asClassCache by
<lambda>null114         lazy(LazyThreadSafetyMode.NONE) { codebase.resolveClass(qualifiedName) }
115 
asClassnull116     override fun asClass() = asClassCache
117 
118     override fun isFunctionalType(): Boolean {
119         return LambdaUtil.isFunctionalType(psiType)
120     }
121 
122     @Deprecated(
123         "implementation detail of this class",
124         replaceWith = ReplaceWith("substitute(modifiers, outerClassType, arguments)"),
125     )
duplicatenull126     override fun duplicate(
127         modifiers: TypeModifiers,
128         outerClassType: ClassTypeItem?,
129         arguments: List<TypeArgumentTypeItem>
130     ): ClassTypeItem =
131         PsiClassTypeItem(
132             codebase = codebase,
133             psiType = psiType,
134             qualifiedName = qualifiedName,
135             arguments = arguments,
136             outerClassType = outerClassType,
137             modifiers = modifiers,
138             kotlinTypeInfo = kotlinTypeInfo,
139         )
140 }
141 
142 internal class PsiLambdaTypeItem(
143     codebase: Codebase,
144     psiType: PsiType,
145     qualifiedName: String,
146     arguments: List<TypeArgumentTypeItem>,
147     outerClassType: ClassTypeItem?,
148     modifiers: TypeModifiers,
149     override val isSuspend: Boolean,
150     override val receiverType: TypeItem?,
151     override val parameterTypes: List<TypeItem>,
152     override val returnType: TypeItem,
153     kotlinTypeInfo: KotlinTypeInfo?,
154 ) :
155     PsiClassTypeItem(
156         codebase = codebase,
157         psiType = psiType,
158         qualifiedName = qualifiedName,
159         arguments = arguments,
160         outerClassType = outerClassType,
161         modifiers = modifiers,
162         kotlinTypeInfo = kotlinTypeInfo,
163     ),
164     LambdaTypeItem {
165 
166     @Deprecated(
167         "implementation detail of this class",
168         replaceWith = ReplaceWith("substitute(modifiers, outerClassType, arguments)"),
169     )
170     override fun duplicate(
171         modifiers: TypeModifiers,
172         outerClassType: ClassTypeItem?,
173         arguments: List<TypeArgumentTypeItem>
174     ): LambdaTypeItem {
175         return PsiLambdaTypeItem(
176             codebase = codebase,
177             psiType = psiType,
178             qualifiedName = qualifiedName,
179             arguments = arguments,
180             outerClassType = outerClassType,
181             modifiers = modifiers,
182             isSuspend = isSuspend,
183             receiverType = receiverType,
184             parameterTypes = parameterTypes,
185             returnType = returnType,
186             kotlinTypeInfo = kotlinTypeInfo,
187         )
188     }
189 }
190 
191 /** A [PsiTypeItem] backed by a [PsiClassType] that represents a type variable.e */
192 internal class PsiVariableTypeItem(
193     psiType: PsiType,
194     modifiers: TypeModifiers,
195     override val asTypeParameter: TypeParameterItem,
196     kotlinTypeInfo: KotlinTypeInfo?,
197 ) : VariableTypeItem, PsiTypeItem(psiType, modifiers, kotlinTypeInfo) {
198 
199     override val name: String = asTypeParameter.name()
200 
201     @Deprecated(
202         "implementation detail of this class",
203         replaceWith = ReplaceWith("substitute(modifiers)"),
204     )
duplicatenull205     override fun duplicate(modifiers: TypeModifiers): PsiVariableTypeItem =
206         PsiVariableTypeItem(
207             psiType = psiType,
208             modifiers = modifiers,
209             asTypeParameter = asTypeParameter,
210             kotlinTypeInfo = kotlinTypeInfo,
211         )
212 }
213 
214 /** A [PsiTypeItem] backed by a [PsiWildcardType]. */
215 internal class PsiWildcardTypeItem(
216     psiType: PsiType,
217     override val extendsBound: ReferenceTypeItem?,
218     override val superBound: ReferenceTypeItem?,
219     modifiers: TypeModifiers,
220     kotlinTypeInfo: KotlinTypeInfo?,
221 ) : WildcardTypeItem, PsiTypeItem(psiType, modifiers, kotlinTypeInfo) {
222     @Deprecated(
223         "implementation detail of this class",
224         replaceWith = ReplaceWith("substitute(modifiers, extendsBound, superBound)")
225     )
226     override fun duplicate(
227         modifiers: TypeModifiers,
228         extendsBound: ReferenceTypeItem?,
229         superBound: ReferenceTypeItem?
230     ): WildcardTypeItem =
231         PsiWildcardTypeItem(
232             psiType = psiType,
233             extendsBound = extendsBound,
234             superBound = superBound,
235             modifiers = modifiers,
236             kotlinTypeInfo = kotlinTypeInfo,
237         )
238 }
239