• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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