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