1 /* <lambda>null2 * Copyright (C) 2023 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.turbine 18 19 import com.android.tools.metalava.model.AnnotationRetention 20 import com.android.tools.metalava.model.ClassItem 21 import com.android.tools.metalava.model.ClassKind 22 import com.android.tools.metalava.model.ClassTypeItem 23 import com.android.tools.metalava.model.ConstructorItem 24 import com.android.tools.metalava.model.DefaultModifierList 25 import com.android.tools.metalava.model.FieldItem 26 import com.android.tools.metalava.model.MethodItem 27 import com.android.tools.metalava.model.PackageItem 28 import com.android.tools.metalava.model.PropertyItem 29 import com.android.tools.metalava.model.SourceFile 30 import com.android.tools.metalava.model.TypeParameterList 31 import com.android.tools.metalava.model.VariableTypeItem 32 import com.android.tools.metalava.model.type.DefaultResolvedClassTypeItem 33 import com.android.tools.metalava.model.type.DefaultTypeModifiers 34 import com.android.tools.metalava.model.type.DefaultVariableTypeItem 35 import com.android.tools.metalava.model.updateCopiedMethodState 36 import com.android.tools.metalava.reporter.FileLocation 37 import com.google.turbine.binder.sym.ClassSymbol 38 import com.google.turbine.binder.sym.MethodSymbol 39 40 internal open class TurbineClassItem( 41 codebase: TurbineBasedCodebase, 42 fileLocation: FileLocation, 43 private val name: String, 44 private val fullName: String, 45 private val qualifiedName: String, 46 private val classSymbol: ClassSymbol, 47 modifiers: DefaultModifierList, 48 override val classKind: ClassKind, 49 override val typeParameterList: TypeParameterList, 50 documentation: String, 51 private val source: SourceFile? 52 ) : TurbineItem(codebase, fileLocation, modifiers, documentation), ClassItem { 53 54 override var artifact: String? = null 55 56 override var hasPrivateConstructor: Boolean = false 57 58 override var stubConstructor: ConstructorItem? = null 59 60 internal lateinit var innerClasses: List<TurbineClassItem> 61 62 private var superClassType: ClassTypeItem? = null 63 64 private var allInterfaces: List<ClassItem>? = null 65 66 internal lateinit var containingPackage: TurbinePackageItem 67 68 internal lateinit var fields: List<TurbineFieldItem> 69 70 internal lateinit var methods: MutableList<TurbineMethodItem> 71 72 internal lateinit var constructors: List<TurbineConstructorItem> 73 74 internal var containingClass: TurbineClassItem? = null 75 76 private lateinit var interfaceTypesList: List<ClassTypeItem> 77 78 internal var hasImplicitDefaultConstructor = false 79 80 private var retention: AnnotationRetention? = null 81 82 override fun allInterfaces(): Sequence<ClassItem> { 83 if (allInterfaces == null) { 84 val interfaces = mutableSetOf<ClassItem>() 85 86 // Add self as interface if applicable 87 if (isInterface()) { 88 interfaces.add(this) 89 } 90 91 // Add all the interfaces of super class 92 superClass()?.let { supClass -> 93 supClass.allInterfaces().forEach { interfaces.add(it) } 94 } 95 96 // Add all the interfaces of direct interfaces 97 interfaceTypesList.forEach { interfaceType -> 98 val itf = interfaceType.asClass() 99 itf?.allInterfaces()?.forEach { interfaces.add(it) } 100 } 101 102 allInterfaces = interfaces.toList() 103 } 104 105 return allInterfaces!!.asSequence() 106 } 107 108 override fun constructors(): List<ConstructorItem> = constructors 109 110 override fun containingClass(): TurbineClassItem? = containingClass 111 112 override fun containingPackage(): PackageItem = 113 containingClass?.containingPackage() ?: containingPackage 114 115 override fun fields(): List<FieldItem> = fields 116 117 override fun getRetention(): AnnotationRetention { 118 retention?.let { 119 return it 120 } 121 122 if (!isAnnotationType()) { 123 error("getRetention() should only be called on annotation classes") 124 } 125 126 retention = ClassItem.findRetention(this) 127 return retention!! 128 } 129 130 override fun hasImplicitDefaultConstructor(): Boolean = hasImplicitDefaultConstructor 131 132 override fun createDefaultConstructor(): ConstructorItem { 133 val sym = MethodSymbol(0, classSymbol, name) 134 return TurbineConstructorItem.createDefaultConstructor(codebase, this, sym) 135 } 136 137 override fun hasTypeVariables(): Boolean = typeParameterList.isNotEmpty() 138 139 override fun innerClasses(): List<ClassItem> = innerClasses 140 141 override fun interfaceTypes(): List<ClassTypeItem> = interfaceTypesList 142 143 override fun methods(): List<MethodItem> = methods 144 145 /** 146 * [PropertyItem]s are kotlin specific and it is unlikely that Turbine will ever support Kotlin 147 * so just return an empty list. 148 */ 149 override fun properties(): List<PropertyItem> = emptyList() 150 151 override fun simpleName(): String = name 152 153 override fun qualifiedName(): String = qualifiedName 154 155 override fun fullName(): String = fullName 156 157 override fun setInterfaceTypes(interfaceTypes: List<ClassTypeItem>) { 158 interfaceTypesList = interfaceTypes 159 } 160 161 internal fun setSuperClassType(superClassType: ClassTypeItem?) { 162 this.superClassType = superClassType 163 } 164 165 override fun superClass(): ClassItem? = superClassType?.asClass() 166 167 override fun superClassType(): ClassTypeItem? = superClassType 168 169 /** Must only be used by [type] to cache its result. */ 170 private lateinit var cachedType: ClassTypeItem 171 172 override fun type(): ClassTypeItem { 173 if (!::cachedType.isInitialized) { 174 cachedType = DefaultResolvedClassTypeItem.createForClass(this) 175 } 176 return cachedType 177 } 178 179 private fun createVariableType(typeParam: TurbineTypeParameterItem): VariableTypeItem { 180 val mods = DefaultTypeModifiers.create(typeParam.modifiers.annotations()) 181 return DefaultVariableTypeItem(mods, typeParam) 182 } 183 184 override fun hashCode(): Int = qualifiedName.hashCode() 185 186 override fun equals(other: Any?): Boolean { 187 if (this === other) { 188 return true 189 } 190 return other is ClassItem && qualifiedName() == other.qualifiedName() 191 } 192 193 override fun getSourceFile(): SourceFile? = source 194 195 override fun inheritMethodFromNonApiAncestor(template: MethodItem): MethodItem { 196 val method = template as TurbineMethodItem 197 val replacementMap = mapTypeVariables(method.containingClass()) 198 val retType = method.returnType().convertType(replacementMap) 199 val mods = method.modifiers.duplicate() 200 201 val duplicateMethod = 202 TurbineMethodItem( 203 codebase, 204 FileLocation.UNKNOWN, 205 method.getSymbol(), 206 this, 207 retType, 208 mods, 209 method.typeParameterList, 210 method.documentation, 211 method.defaultValue(), 212 ) 213 214 val params = 215 method.parameters().map { 216 TurbineParameterItem.duplicate(codebase, duplicateMethod, it, replacementMap) 217 } 218 duplicateMethod.parameters = params 219 duplicateMethod.inheritedFrom = method.containingClass() 220 duplicateMethod.throwableTypes = method.throwableTypes 221 222 duplicateMethod.updateCopiedMethodState() 223 224 return duplicateMethod 225 } 226 227 override fun addMethod(method: MethodItem) { 228 methods.add(method as TurbineMethodItem) 229 } 230 } 231