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.text 18 19 import com.android.tools.metalava.model.AnnotationItem 20 import com.android.tools.metalava.model.AnnotationRetention 21 import com.android.tools.metalava.model.ClassItem 22 import com.android.tools.metalava.model.ClassKind 23 import com.android.tools.metalava.model.ClassTypeItem 24 import com.android.tools.metalava.model.ConstructorItem 25 import com.android.tools.metalava.model.DefaultModifierList 26 import com.android.tools.metalava.model.FieldItem 27 import com.android.tools.metalava.model.Item 28 import com.android.tools.metalava.model.MethodItem 29 import com.android.tools.metalava.model.PackageItem 30 import com.android.tools.metalava.model.PropertyItem 31 import com.android.tools.metalava.model.TypeItem 32 import com.android.tools.metalava.model.TypeParameterList 33 import com.android.tools.metalava.model.type.DefaultResolvedClassTypeItem 34 import com.android.tools.metalava.reporter.FileLocation 35 import java.util.function.Predicate 36 37 internal open class TextClassItem( 38 override val codebase: TextCodebase, 39 fileLocation: FileLocation = FileLocation.UNKNOWN, 40 modifiers: DefaultModifierList, 41 override val classKind: ClassKind = ClassKind.CLASS, 42 val qualifiedName: String = "", 43 var simpleName: String = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1), 44 val fullName: String = simpleName, 45 override val typeParameterList: TypeParameterList = TypeParameterList.NONE 46 ) : TextItem(codebase = codebase, fileLocation = fileLocation, modifiers = modifiers), ClassItem { 47 48 override var artifact: String? = null 49 equalsnull50 override fun equals(other: Any?): Boolean { 51 if (this === other) return true 52 if (javaClass != other?.javaClass) return false 53 54 other as TextClassItem 55 56 return qualifiedName == other.qualifiedName() 57 } 58 hashCodenull59 override fun hashCode(): Int { 60 return qualifiedName.hashCode() 61 } 62 interfaceTypesnull63 override fun interfaceTypes(): List<ClassTypeItem> = interfaceTypes 64 65 override fun allInterfaces(): Sequence<ClassItem> { 66 return sequenceOf( 67 // Add this if and only if it is an interface. 68 if (classKind == ClassKind.INTERFACE) sequenceOf(this) else emptySequence(), 69 interfaceTypes.asSequence().map { it.asClass() }.filterNotNull(), 70 ) 71 .flatten() 72 } 73 74 private var innerClasses: MutableList<ClassItem> = mutableListOf() 75 76 override var stubConstructor: ConstructorItem? = null 77 78 override var hasPrivateConstructor: Boolean = false 79 innerClassesnull80 override fun innerClasses(): List<ClassItem> = innerClasses 81 82 override fun hasImplicitDefaultConstructor(): Boolean { 83 return false 84 } 85 86 var containingClass: ClassItem? = null 87 containingClassnull88 override fun containingClass(): ClassItem? = containingClass 89 90 private var containingPackage: PackageItem? = null 91 92 fun setContainingPackage(containingPackage: TextPackageItem) { 93 this.containingPackage = containingPackage 94 } 95 containingPackagenull96 override fun containingPackage(): PackageItem = 97 containingClass?.containingPackage() ?: containingPackage ?: error(this) 98 99 override fun hasTypeVariables(): Boolean = typeParameterList.isNotEmpty() 100 101 private var superClassType: ClassTypeItem? = null 102 103 override fun superClass(): ClassItem? = superClassType?.asClass() 104 105 override fun superClassType(): ClassTypeItem? = superClassType 106 107 internal fun setSuperClassType(superClassType: ClassTypeItem?) { 108 this.superClassType = superClassType 109 } 110 setInterfaceTypesnull111 override fun setInterfaceTypes(interfaceTypes: List<ClassTypeItem>) { 112 this.interfaceTypes = interfaceTypes 113 } 114 115 /** Must only be used by [type] to cache its result. */ 116 private lateinit var cachedType: ClassTypeItem 117 typenull118 override fun type(): ClassTypeItem { 119 if (!::cachedType.isInitialized) { 120 cachedType = DefaultResolvedClassTypeItem.createForClass(this) 121 } 122 return cachedType 123 } 124 125 private var interfaceTypes = emptyList<ClassTypeItem>() 126 private val constructors = mutableListOf<ConstructorItem>() 127 private val methods = mutableListOf<MethodItem>() 128 private val fields = mutableListOf<FieldItem>() 129 private val properties = mutableListOf<PropertyItem>() 130 constructorsnull131 override fun constructors(): List<ConstructorItem> = constructors 132 133 override fun methods(): List<MethodItem> = methods 134 135 override fun fields(): List<FieldItem> = fields 136 137 override fun properties(): List<PropertyItem> = properties 138 139 fun addConstructor(constructor: TextConstructorItem) { 140 constructors += constructor 141 } 142 addMethodnull143 fun addMethod(method: TextMethodItem) { 144 methods += method 145 } 146 addFieldnull147 fun addField(field: TextFieldItem) { 148 fields += field 149 } 150 addPropertynull151 fun addProperty(property: TextPropertyItem) { 152 properties += property 153 } 154 addEnumConstantnull155 fun addEnumConstant(field: TextFieldItem) { 156 field.setEnumConstant(true) 157 fields += field 158 } 159 addInnerClassnull160 override fun addInnerClass(cls: ClassItem) { 161 innerClasses.add(cls) 162 } 163 addAnnotationnull164 fun addAnnotation(annotation: AnnotationItem) { 165 modifiers.addAnnotation(annotation) 166 } 167 filteredSuperClassTypenull168 override fun filteredSuperClassType(predicate: Predicate<Item>): TypeItem? { 169 // No filtering in signature files: we assume signature APIs 170 // have already been filtered and all items should match. 171 // This lets us load signature files and rewrite them using updated 172 // output formats etc. 173 return superClassType 174 } 175 176 private var retention: AnnotationRetention? = null 177 getRetentionnull178 override fun getRetention(): AnnotationRetention { 179 retention?.let { 180 return it 181 } 182 183 if (!isAnnotationType()) { 184 error("getRetention() should only be called on annotation classes") 185 } 186 187 retention = ClassItem.findRetention(this) 188 return retention!! 189 } 190 simpleNamenull191 override fun simpleName(): String = simpleName 192 193 override fun fullName(): String = fullName 194 195 override fun qualifiedName(): String = qualifiedName 196 197 override fun createDefaultConstructor(): ConstructorItem { 198 return TextConstructorItem.createDefaultConstructor(codebase, this, fileLocation) 199 } 200 } 201