1 /*
<lambda>null2  * 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.text
18 
19 import com.android.tools.metalava.model.ArrayTypeItem
20 import com.android.tools.metalava.model.ClassTypeItem
21 import com.android.tools.metalava.model.JAVA_LANG_ANNOTATION
22 import com.android.tools.metalava.model.JAVA_LANG_ENUM
23 import com.android.tools.metalava.model.JAVA_LANG_OBJECT
24 import com.android.tools.metalava.model.TypeItem
25 import com.android.tools.metalava.model.TypeParameterScope
26 import com.android.tools.metalava.model.type.ContextNullability
27 import com.android.tools.metalava.model.type.DefaultTypeItemFactory
28 
29 internal class TextTypeItemFactory(
30     private val codebase: TextCodebase,
31     private val typeParser: TextTypeParser,
32     typeParameterScope: TypeParameterScope = TypeParameterScope.empty,
33 ) : DefaultTypeItemFactory<String, TextTypeItemFactory>(typeParameterScope) {
34 
35     /** A [JAVA_LANG_ANNOTATION] suitable for use as a super type. */
36     val superAnnotationType
37         get() = getInterfaceType(JAVA_LANG_ANNOTATION)
38 
39     /** A [JAVA_LANG_ENUM] suitable for use as a super type. */
40     val superEnumType
41         get() = getSuperClassType(JAVA_LANG_ENUM)
42 
43     /** A [JAVA_LANG_OBJECT] suitable for use as a super type. */
44     val superObjectType
45         get() = getSuperClassType(JAVA_LANG_OBJECT)
46 
47     override fun self() = this
48 
49     override fun createNestedFactory(scope: TypeParameterScope) =
50         TextTypeItemFactory(codebase, typeParser, scope)
51 
52     override fun getType(
53         underlyingType: String,
54         contextNullability: ContextNullability,
55         isVarArg: Boolean
56     ): TypeItem {
57         var typeItem =
58             typeParser.obtainTypeFromString(
59                 underlyingType,
60                 typeParameterScope,
61                 contextNullability,
62             )
63 
64         // Check if the type is an array and its component nullability needs to be updated based on
65         // the context.
66         val forcedComponentNullability = contextNullability.forcedComponentNullability
67         if (
68             typeItem is ArrayTypeItem &&
69                 forcedComponentNullability != null &&
70                 forcedComponentNullability != typeItem.componentType.modifiers.nullability()
71         ) {
72             typeItem =
73                 typeItem.duplicate(typeItem.componentType.duplicate(forcedComponentNullability))
74         }
75 
76         // Check if the type's nullability needs to be updated based on the context.
77         val typeNullability = typeItem.modifiers.nullability()
78         val actualTypeNullability =
79             contextNullability.compute(typeNullability, typeItem.modifiers.annotations())
80         return if (actualTypeNullability != typeNullability) {
81             typeItem.duplicate(actualTypeNullability)
82         } else typeItem
83     }
84 
85     override fun getExceptionType(underlyingType: String) =
86         super.getExceptionType(underlyingType).also { exceptionTypeItem ->
87             if (exceptionTypeItem is ClassTypeItem) {
88                 codebase.requireStubKindFor(exceptionTypeItem, StubKind.THROWABLE)
89             }
90         }
91 
92     override fun getInterfaceType(underlyingType: String) =
93         super.getInterfaceType(underlyingType).also { classTypeItem ->
94             codebase.requireStubKindFor(classTypeItem, StubKind.INTERFACE)
95         }
96 }
97