1 /*
2  * Copyright (C) 2024 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.ApiVariantSelectorsFactory
20 import com.android.tools.metalava.model.BaseModifierList
21 import com.android.tools.metalava.model.CallableBody
22 import com.android.tools.metalava.model.CallableBodyFactory
23 import com.android.tools.metalava.model.CallableItem
24 import com.android.tools.metalava.model.ClassItem
25 import com.android.tools.metalava.model.ClassKind
26 import com.android.tools.metalava.model.ClassOrigin
27 import com.android.tools.metalava.model.ClassTypeItem
28 import com.android.tools.metalava.model.ConstructorItem
29 import com.android.tools.metalava.model.ExceptionTypeItem
30 import com.android.tools.metalava.model.FieldItem
31 import com.android.tools.metalava.model.Item
32 import com.android.tools.metalava.model.ItemDocumentation
33 import com.android.tools.metalava.model.ItemDocumentationFactory
34 import com.android.tools.metalava.model.ItemLanguage
35 import com.android.tools.metalava.model.MethodItem
36 import com.android.tools.metalava.model.PackageItem
37 import com.android.tools.metalava.model.ParameterItem
38 import com.android.tools.metalava.model.PropertyItem
39 import com.android.tools.metalava.model.SourceFile
40 import com.android.tools.metalava.model.TypeItem
41 import com.android.tools.metalava.model.TypeParameterList
42 import com.android.tools.metalava.reporter.FileLocation
43 
44 /**
45  * A lambda that when passed the [Item] will return the public name, or null if there is not one.
46  */
47 typealias PublicNameProvider = (Item) -> String?
48 
49 /** A factory for creating [Item] instances suitable for use by many models. */
50 class DefaultItemFactory(
51     /** The [DefaultCodebase] to which returned [Item]s will belong. */
52     private val codebase: DefaultCodebase,
53 
54     /** The default language for [Item]s created by this. */
55     private val defaultItemLanguage: ItemLanguage,
56 
57     /** The default [ApiVariantSelectorsFactory] for [Item]s created by this. */
58     private val defaultVariantSelectorsFactory: ApiVariantSelectorsFactory,
59 ) {
60     /** Create a [PackageItem]. */
createPackageItemnull61     fun createPackageItem(
62         fileLocation: FileLocation,
63         modifiers: BaseModifierList,
64         documentationFactory: ItemDocumentationFactory,
65         qualifiedName: String,
66         containingPackage: PackageItem?,
67         overviewDocumentation: ResourceFile?,
68     ): DefaultPackageItem {
69         return DefaultPackageItem(
70             codebase,
71             fileLocation,
72             defaultItemLanguage,
73             modifiers,
74             documentationFactory,
75             defaultVariantSelectorsFactory,
76             qualifiedName,
77             containingPackage,
78             overviewDocumentation,
79         )
80     }
81 
82     /** Create a [ConstructorItem]. */
createClassItemnull83     fun createClassItem(
84         fileLocation: FileLocation,
85         itemLanguage: ItemLanguage = defaultItemLanguage,
86         modifiers: BaseModifierList,
87         documentationFactory: ItemDocumentationFactory = ItemDocumentation.NONE_FACTORY,
88         source: SourceFile? = null,
89         classKind: ClassKind,
90         containingClass: ClassItem?,
91         containingPackage: PackageItem,
92         qualifiedName: String = "",
93         typeParameterList: TypeParameterList,
94         origin: ClassOrigin,
95         superClassType: ClassTypeItem?,
96         interfaceTypes: List<ClassTypeItem>,
97     ) =
98         DefaultClassItem(
99             codebase,
100             fileLocation,
101             itemLanguage,
102             modifiers,
103             documentationFactory,
104             defaultVariantSelectorsFactory,
105             source,
106             classKind,
107             containingClass,
108             containingPackage,
109             qualifiedName,
110             typeParameterList,
111             origin,
112             superClassType,
113             interfaceTypes,
114         )
115 
116     /** Create a [ConstructorItem]. */
117     fun createConstructorItem(
118         fileLocation: FileLocation,
119         itemLanguage: ItemLanguage = defaultItemLanguage,
120         modifiers: BaseModifierList,
121         documentationFactory: ItemDocumentationFactory,
122         name: String,
123         containingClass: ClassItem,
124         typeParameterList: TypeParameterList,
125         returnType: ClassTypeItem,
126         parameterItemsFactory: ParameterItemsFactory,
127         throwsTypes: List<ExceptionTypeItem>,
128         callableBodyFactory: CallableBodyFactory = CallableBody.UNAVAILABLE_FACTORY,
129         implicitConstructor: Boolean,
130         isPrimary: Boolean = false,
131     ): ConstructorItem =
132         DefaultConstructorItem(
133             codebase,
134             fileLocation,
135             itemLanguage,
136             modifiers,
137             documentationFactory,
138             defaultVariantSelectorsFactory,
139             name,
140             containingClass,
141             typeParameterList,
142             returnType,
143             parameterItemsFactory,
144             throwsTypes,
145             callableBodyFactory,
146             implicitConstructor,
147             isPrimary,
148         )
149 
150     /** Create a [FieldItem]. */
151     fun createFieldItem(
152         fileLocation: FileLocation,
153         itemLanguage: ItemLanguage = defaultItemLanguage,
154         modifiers: BaseModifierList,
155         documentationFactory: ItemDocumentationFactory,
156         name: String,
157         containingClass: ClassItem,
158         type: TypeItem,
159         isEnumConstant: Boolean,
160         fieldValue: FieldValue?,
161     ): FieldItem =
162         DefaultFieldItem(
163             codebase,
164             fileLocation,
165             itemLanguage,
166             defaultVariantSelectorsFactory,
167             modifiers,
168             documentationFactory,
169             name,
170             containingClass,
171             type,
172             isEnumConstant,
173             fieldValue,
174         )
175 
176     /** Create a [MethodItem]. */
177     fun createMethodItem(
178         fileLocation: FileLocation,
179         itemLanguage: ItemLanguage = defaultItemLanguage,
180         modifiers: BaseModifierList,
181         documentationFactory: ItemDocumentationFactory,
182         name: String,
183         containingClass: ClassItem,
184         typeParameterList: TypeParameterList,
185         returnType: TypeItem,
186         parameterItemsFactory: ParameterItemsFactory,
187         throwsTypes: List<ExceptionTypeItem>,
188         callableBodyFactory: CallableBodyFactory = CallableBody.UNAVAILABLE_FACTORY,
189         annotationDefault: String,
190     ): MethodItem =
191         DefaultMethodItem(
192             codebase,
193             fileLocation,
194             itemLanguage,
195             modifiers,
196             documentationFactory,
197             defaultVariantSelectorsFactory,
198             name,
199             containingClass,
200             typeParameterList,
201             returnType,
202             parameterItemsFactory,
203             throwsTypes,
204             callableBodyFactory,
205             annotationDefault,
206         )
207 
208     /** Create a [ParameterItem]. */
209     fun createParameterItem(
210         fileLocation: FileLocation,
211         itemLanguage: ItemLanguage = defaultItemLanguage,
212         modifiers: BaseModifierList,
213         name: String,
214         publicNameProvider: PublicNameProvider,
215         containingCallable: CallableItem,
216         parameterIndex: Int,
217         type: TypeItem,
218         defaultValueFactory: DefaultValueFactory,
219     ): ParameterItem =
220         DefaultParameterItem(
221             codebase,
222             fileLocation,
223             itemLanguage,
224             modifiers,
225             name,
226             publicNameProvider,
227             containingCallable,
228             parameterIndex,
229             type,
230             defaultValueFactory,
231         )
232 
233     /** Create a [PropertyItem]. */
234     fun createPropertyItem(
235         fileLocation: FileLocation,
236         itemLanguage: ItemLanguage = defaultItemLanguage,
237         documentationFactory: ItemDocumentationFactory = ItemDocumentation.NONE_FACTORY,
238         modifiers: BaseModifierList,
239         name: String,
240         containingClass: ClassItem,
241         type: TypeItem,
242         getter: MethodItem? = null,
243         setter: MethodItem? = null,
244         constructorParameter: ParameterItem? = null,
245         backingField: FieldItem? = null,
246     ): PropertyItem =
247         DefaultPropertyItem(
248             codebase,
249             fileLocation,
250             itemLanguage,
251             documentationFactory,
252             defaultVariantSelectorsFactory,
253             modifiers,
254             name,
255             containingClass,
256             type,
257             getter,
258             setter,
259             constructorParameter,
260             backingField,
261         )
262 
263     /**
264      * Create a [DefaultTypeParameterItem].
265      *
266      * This returns [DefaultTypeParameterItem] because access is needed to its
267      * [DefaultTypeParameterItem.bounds] after creation as full creation is a two stage process due
268      * to cyclical dependencies between [DefaultTypeParameterItem] in a type parameters list.
269      *
270      * TODO(b/351410134): Provide support in this factory for two stage initialization.
271      */
272     fun createTypeParameterItem(
273         modifiers: BaseModifierList,
274         name: String,
275         isReified: Boolean,
276     ) =
277         DefaultTypeParameterItem(
278             codebase,
279             modifiers,
280             name,
281             isReified,
282         )
283 }
284