1 /*
2  * Copyright (C) 2018 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.item
18 
19 import com.android.tools.metalava.model.BaseModifierList
20 import com.android.tools.metalava.model.BoundsTypeItem
21 import com.android.tools.metalava.model.Codebase
22 import com.android.tools.metalava.model.ModifierList
23 import com.android.tools.metalava.model.TypeParameterItem
24 import com.android.tools.metalava.model.VariableTypeItem
25 import com.android.tools.metalava.model.type.DefaultTypeModifiers
26 import com.android.tools.metalava.model.type.DefaultVariableTypeItem
27 
28 /** A [TypeParameterItem] implementation suitable for use by multiple models. */
29 open class DefaultTypeParameterItem(
30     override val codebase: Codebase,
31     modifiers: BaseModifierList,
32     private val name: String,
33     private val isReified: Boolean,
34 ) : TypeParameterItem {
35 
36     final override val modifiers: ModifierList = modifiers.toImmutable()
37 
namenull38     final override fun name() = name
39 
40     /** Must only be used by [type] to cache its result. */
41     private lateinit var variableTypeItem: VariableTypeItem
42 
43     override fun type(): VariableTypeItem {
44         if (!::variableTypeItem.isInitialized) {
45             variableTypeItem = createVariableTypeItem()
46         }
47         return variableTypeItem
48     }
49 
50     /** Create a [VariableTypeItem] for this [TypeParameterItem]. */
createVariableTypeItemnull51     protected open fun createVariableTypeItem(): VariableTypeItem =
52         DefaultVariableTypeItem(DefaultTypeModifiers.emptyUndefinedModifiers, this)
53 
54     lateinit var bounds: List<BoundsTypeItem>
55 
56     final override fun typeBounds(): List<BoundsTypeItem> = bounds
57 
58     final override fun isReified(): Boolean = isReified
59 
60     override fun equals(other: Any?): Boolean {
61         if (this === other) return true
62         if (other !is TypeParameterItem) return false
63 
64         return name() == other.name()
65     }
66 
hashCodenull67     override fun hashCode(): Int {
68         return name().hashCode()
69     }
70 
toStringnull71     override fun toString(): String =
72         if (typeBounds().isEmpty() && !isReified()) name()
73         else
74             buildString {
75                 if (isReified()) append("reified ")
76                 append(name())
77                 if (typeBounds().isNotEmpty()) {
78                     append(" extends ")
79                     typeBounds().joinTo(this, " & ")
80                 }
81             }
82 }
83