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.ClassItem 20 import com.android.tools.metalava.model.Item 21 import com.android.tools.metalava.model.MethodItem 22 import com.android.tools.metalava.model.ParameterItem 23 import com.android.tools.metalava.model.TypeItem 24 import com.android.tools.metalava.model.TypeParameterItem 25 import com.android.tools.metalava.model.TypeParameterList 26 import com.android.tools.metalava.model.TypeParameterListOwner 27 import java.util.function.Predicate 28 29 open class TextMethodItem( 30 codebase: TextCodebase, 31 name: String, 32 containingClass: TextClassItem, 33 modifiers: TextModifiers, 34 private val returnType: TextTypeItem?, 35 position: SourcePositionInfo 36 ) : TextMemberItem( 37 codebase, name, containingClass, position, 38 modifiers = modifiers 39 ), 40 MethodItem, 41 TypeParameterListOwner { 42 init { 43 @Suppress("LeakingThis") 44 modifiers.setOwner(this) 45 } 46 equalsnull47 override fun equals(other: Any?): Boolean { 48 if (this === other) return true 49 if (other !is MethodItem) return false 50 51 if (name() != other.name()) { 52 return false 53 } 54 55 if (containingClass() != other.containingClass()) { 56 return false 57 } 58 59 val parameters1 = parameters() 60 val parameters2 = other.parameters() 61 62 if (parameters1.size != parameters2.size) { 63 return false 64 } 65 66 for (i in parameters1.indices) { 67 val parameter1 = parameters1[i] 68 val parameter2 = parameters2[i] 69 if (parameter1.type() != parameter2.type()) { 70 return false 71 } 72 } 73 return true 74 } 75 hashCodenull76 override fun hashCode(): Int { 77 return name().hashCode() 78 } 79 isConstructornull80 override fun isConstructor(): Boolean = false 81 82 override fun returnType(): TypeItem? = returnType 83 84 override fun superMethods(): List<MethodItem> { 85 if (isConstructor()) { 86 return emptyList() 87 } 88 89 val list = mutableListOf<MethodItem>() 90 91 var curr = containingClass().superClass() 92 while (curr != null) { 93 val superMethod = curr.findMethod(this) 94 if (superMethod != null) { 95 list.add(superMethod) 96 break 97 } 98 curr = curr.superClass() 99 } 100 101 // Interfaces 102 for (itf in containingClass().allInterfaces()) { 103 val interfaceMethod = itf.findMethod(this) 104 if (interfaceMethod != null) { 105 list.add(interfaceMethod) 106 } 107 } 108 109 return list 110 } 111 findMainDocumentationnull112 override fun findMainDocumentation(): String = documentation 113 114 override fun findPredicateSuperMethod(predicate: Predicate<Item>): MethodItem? = null 115 116 private var typeParameterList: TypeParameterList = TypeParameterList.NONE 117 118 fun setTypeParameterList(typeParameterList: TypeParameterList) { 119 this.typeParameterList = typeParameterList 120 } 121 typeParameterListnull122 override fun typeParameterList(): TypeParameterList = typeParameterList 123 124 override fun typeParameterListOwnerParent(): TypeParameterListOwner? { 125 return containingClass() as TextClassItem? 126 } 127 resolveParameternull128 override fun resolveParameter(variable: String): TypeParameterItem? { 129 for (t in typeParameterList.typeParameters()) { 130 if (t.simpleName() == variable) { 131 return t 132 } 133 } 134 135 return (containingClass() as TextClassItem).resolveParameter(variable) 136 } 137 duplicatenull138 override fun duplicate(targetContainingClass: ClassItem): MethodItem { 139 val duplicated = TextMethodItem( 140 codebase, name(), targetContainingClass as TextClassItem, 141 modifiers.duplicate(), returnType, position 142 ) 143 duplicated.inheritedFrom = containingClass() 144 145 // Preserve flags that may have been inherited (propagated) from surrounding packages 146 if (targetContainingClass.hidden) { 147 duplicated.hidden = true 148 } 149 if (targetContainingClass.removed) { 150 duplicated.removed = true 151 } 152 if (targetContainingClass.docOnly) { 153 duplicated.docOnly = true 154 } 155 if (targetContainingClass.deprecated) { 156 duplicated.deprecated = true 157 } 158 159 duplicated.varargs = varargs 160 duplicated.deprecated = deprecated 161 duplicated.annotationDefault = annotationDefault 162 duplicated.throwsTypes.addAll(throwsTypes) 163 duplicated.throwsClasses = throwsClasses 164 duplicated.typeParameterList = typeParameterList 165 // Consider cloning these: they have back references to the parent method (though it's 166 // unlikely anyone will care about the difference in parent methods) 167 duplicated.parameters.addAll(parameters) 168 169 return duplicated 170 } 171 172 override val synthetic: Boolean get() = isEnumSyntheticMethod() 173 174 private val throwsTypes = mutableListOf<String>() 175 private val parameters = mutableListOf<TextParameterItem>() 176 private var throwsClasses: List<ClassItem>? = null 177 throwsTypeNamesnull178 fun throwsTypeNames(): List<String> { 179 return throwsTypes 180 } 181 throwsTypesnull182 override fun throwsTypes(): List<ClassItem> = if (throwsClasses == null) emptyList() else throwsClasses!! 183 184 fun setThrowsList(throwsClasses: List<TextClassItem>) { 185 this.throwsClasses = throwsClasses 186 } 187 parametersnull188 override fun parameters(): List<ParameterItem> = parameters 189 190 fun addException(throwsType: String) { 191 throwsTypes += throwsType 192 } 193 addParameternull194 fun addParameter(parameter: TextParameterItem) { 195 parameters += parameter 196 } 197 198 private var varargs: Boolean = false 199 setVarargsnull200 fun setVarargs(varargs: Boolean) { 201 this.varargs = varargs 202 } 203 isVarArgnull204 fun isVarArg(): Boolean = varargs 205 206 override fun isExtensionMethod(): Boolean = codebase.unsupported() 207 208 override var inheritedMethod: Boolean = false 209 override var inheritedFrom: ClassItem? = null 210 211 override fun toString(): String = 212 "${if (isConstructor()) "constructor" else "method"} ${containingClass().qualifiedName()}.${name()}(${parameters().joinToString { 213 it.type().toSimpleType() 214 }})" 215 216 private var annotationDefault = "" 217 218 fun setAnnotationDefault(default: String) { 219 annotationDefault = default 220 } 221 defaultValuenull222 override fun defaultValue(): String { 223 return annotationDefault 224 } 225 } 226