xref: /aosp_15_r20/tools/metalava/metalava-model/src/main/java/com/android/tools/metalava/model/TypeParameterItem.kt (revision 115816f9299ab6ddd6b9673b81f34e707f6bacab)
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
18 
19 @MetalavaApi
20 interface TypeParameterItem {
21     val codebase: Codebase
22 
23     /** Return the modifiers of this class */
24     @MetalavaApi val modifiers: ModifierList
25 
26     /** The name of the type parameter. */
namenull27     fun name(): String
28 
29     /** The [VariableTypeItem] representing the type of this type parameter. */
30     fun type(): VariableTypeItem
31 
32     fun typeBounds(): List<BoundsTypeItem>
33 
34     /**
35      * Get the erased type of this, i.e. the type that would be used at runtime to represent
36      * something of this type. That is either the first bound (the super class) or
37      * `java.lang.Object` if there are no bounds.
38      */
39     fun asErasedType(): BoundsTypeItem? =
40         typeBounds().firstOrNull() ?: codebase.resolveClass(JAVA_LANG_OBJECT)?.type()
41 
42     fun isReified(): Boolean
43 
44     fun toSource(): String {
45         return buildString {
46             if (isReified()) {
47                 append("reified ")
48             }
49             append(name())
50             // If the only bound is Object, omit it because it is implied.
51             if (
52                 typeBounds().isNotEmpty() && typeBounds().singleOrNull()?.isJavaLangObject() != true
53             ) {
54                 append(" extends ")
55                 var first = true
56                 for (bound in typeBounds()) {
57                     if (!first) {
58                         append(" ")
59                         append("&")
60                         append(" ")
61                     }
62                     first = false
63                     append(bound.toTypeString(SOURCE_TYPE_STRING_CONFIGURATION))
64                 }
65             }
66         }
67     }
68 
69     companion object {
70         /** [TypeStringConfiguration] for use by [toSource]. */
71         private val SOURCE_TYPE_STRING_CONFIGURATION =
72             TypeStringConfiguration(spaceBetweenParameters = true)
73     }
74 }
75