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.PsiArrayType 33 import com.intellij.psi.PsiClassType 34 import com.intellij.psi.PsiPrimitiveType 35 import com.intellij.psi.PsiType 36 import com.intellij.psi.PsiWildcardType 37 import com.intellij.psi.util.TypeConversionUtil 38 39 /** Represents a type backed by PSI */ 40 internal sealed class PsiTypeItem( 41 val psiType: PsiType, 42 modifiers: TypeModifiers, 43 ) : DefaultTypeItem(modifiers) { 44 45 /** Returns `true` if `this` type can be assigned from `other` without unboxing the other. */ isAssignableFromWithoutUnboxingnull46 override fun isAssignableFromWithoutUnboxing(other: TypeItem): Boolean { 47 if (other !is PsiTypeItem) return super.isAssignableFromWithoutUnboxing(other) 48 if (this is PrimitiveTypeItem && other !is PrimitiveTypeItem) { 49 return false 50 } 51 return TypeConversionUtil.isAssignable(psiType, other.psiType) 52 } 53 } 54 55 /** A [PsiTypeItem] backed by a [PsiPrimitiveType]. */ 56 internal class PsiPrimitiveTypeItem( 57 psiType: PsiType, 58 override val kind: PrimitiveTypeItem.Primitive, 59 modifiers: TypeModifiers, 60 ) : PrimitiveTypeItem, PsiTypeItem(psiType, modifiers) { duplicatenull61 override fun duplicate(): PsiPrimitiveTypeItem = 62 PsiPrimitiveTypeItem(psiType = psiType, kind = kind, modifiers = modifiers.duplicate()) 63 } 64 65 /** A [PsiTypeItem] backed by a [PsiArrayType]. */ 66 internal class PsiArrayTypeItem( 67 psiType: PsiType, 68 override val componentType: PsiTypeItem, 69 override val isVarargs: Boolean, 70 modifiers: TypeModifiers, 71 ) : ArrayTypeItem, PsiTypeItem(psiType, modifiers) { 72 override fun duplicate(componentType: TypeItem): ArrayTypeItem = 73 PsiArrayTypeItem( 74 psiType = psiType, 75 componentType = componentType as PsiTypeItem, 76 isVarargs = isVarargs, 77 modifiers = modifiers.duplicate() 78 ) 79 } 80 81 /** A [PsiTypeItem] backed by a [PsiClassType] that does not represent a type variable. */ 82 internal open class PsiClassTypeItem( 83 protected val codebase: Codebase, 84 psiType: PsiType, 85 final override val qualifiedName: String, 86 final override val arguments: List<TypeArgumentTypeItem>, 87 final override val outerClassType: PsiClassTypeItem?, 88 final override val className: String, 89 modifiers: TypeModifiers, 90 ) : ClassTypeItem, PsiTypeItem(psiType, modifiers) { 91 92 private val asClassCache by <lambda>null93 lazy(LazyThreadSafetyMode.NONE) { codebase.resolveClass(qualifiedName) } 94 asClassnull95 override fun asClass() = asClassCache 96 97 override fun duplicate( 98 outerClass: ClassTypeItem?, 99 arguments: List<TypeArgumentTypeItem> 100 ): ClassTypeItem = 101 PsiClassTypeItem( 102 codebase = codebase, 103 psiType = psiType, 104 qualifiedName = qualifiedName, 105 arguments = arguments, 106 outerClassType = outerClass as? PsiClassTypeItem, 107 className = className, 108 modifiers = modifiers.duplicate() 109 ) 110 } 111 112 internal class PsiLambdaTypeItem( 113 codebase: Codebase, 114 psiType: PsiType, 115 qualifiedName: String, 116 arguments: List<TypeArgumentTypeItem>, 117 outerClassType: PsiClassTypeItem?, 118 className: String, 119 modifiers: TypeModifiers, 120 override val isSuspend: Boolean, 121 override val receiverType: TypeItem?, 122 override val parameterTypes: List<TypeItem>, 123 override val returnType: TypeItem, 124 ) : 125 PsiClassTypeItem( 126 codebase = codebase, 127 psiType = psiType, 128 qualifiedName = qualifiedName, 129 arguments = arguments, 130 outerClassType = outerClassType, 131 className = className, 132 modifiers = modifiers, 133 ), 134 LambdaTypeItem { 135 136 override fun duplicate( 137 outerClass: ClassTypeItem?, 138 arguments: List<TypeArgumentTypeItem> 139 ): LambdaTypeItem { 140 return PsiLambdaTypeItem( 141 codebase = codebase, 142 psiType = psiType, 143 qualifiedName = qualifiedName, 144 arguments = arguments, 145 outerClassType = outerClass as? PsiClassTypeItem, 146 className = className, 147 modifiers = modifiers.duplicate(), 148 isSuspend = isSuspend, 149 receiverType = receiverType, 150 parameterTypes = parameterTypes, 151 returnType = returnType, 152 ) 153 } 154 } 155 156 /** A [PsiTypeItem] backed by a [PsiClassType] that represents a type variable.e */ 157 internal class PsiVariableTypeItem( 158 psiType: PsiType, 159 modifiers: TypeModifiers, 160 override val asTypeParameter: TypeParameterItem, 161 ) : VariableTypeItem, PsiTypeItem(psiType, modifiers) { 162 163 override val name: String = asTypeParameter.name() 164 duplicatenull165 override fun duplicate(): PsiVariableTypeItem = 166 PsiVariableTypeItem( 167 psiType = psiType, 168 modifiers = modifiers.duplicate(), 169 asTypeParameter = asTypeParameter, 170 ) 171 } 172 173 /** A [PsiTypeItem] backed by a [PsiWildcardType]. */ 174 internal class PsiWildcardTypeItem( 175 psiType: PsiType, 176 override val extendsBound: ReferenceTypeItem?, 177 override val superBound: ReferenceTypeItem?, 178 modifiers: TypeModifiers, 179 ) : WildcardTypeItem, PsiTypeItem(psiType, modifiers) { 180 override fun duplicate( 181 extendsBound: ReferenceTypeItem?, 182 superBound: ReferenceTypeItem? 183 ): WildcardTypeItem = 184 PsiWildcardTypeItem( 185 psiType = psiType, 186 extendsBound = extendsBound, 187 superBound = superBound, 188 modifiers = modifiers.duplicate() 189 ) 190 } 191