1 /*
<lambda>null2  * 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
18 
19 interface TypeVisitor {
20     fun visit(primitiveType: PrimitiveTypeItem) = Unit
21 
22     fun visit(arrayType: ArrayTypeItem) = Unit
23 
24     fun visit(classType: ClassTypeItem) = Unit
25 
26     fun visit(variableType: VariableTypeItem) = Unit
27 
28     fun visit(wildcardType: WildcardTypeItem) = Unit
29 }
30 
31 open class BaseTypeVisitor : TypeVisitor {
visitnull32     override fun visit(primitiveType: PrimitiveTypeItem) {
33         visitType(primitiveType)
34         visitPrimitiveType(primitiveType)
35     }
36 
visitnull37     override fun visit(arrayType: ArrayTypeItem) {
38         visitType(arrayType)
39         visitArrayType(arrayType)
40 
41         arrayType.componentType.accept(this)
42     }
43 
visitnull44     override fun visit(classType: ClassTypeItem) {
45         visitType(classType)
46         visitClassType(classType)
47 
48         classType.outerClassType?.accept(this)
49         classType.arguments.forEach { it.accept(this) }
50     }
51 
visitnull52     override fun visit(variableType: VariableTypeItem) {
53         visitType(variableType)
54         visitVariableType(variableType)
55     }
56 
visitnull57     override fun visit(wildcardType: WildcardTypeItem) {
58         visitType(wildcardType)
59         visitWildcardType(wildcardType)
60 
61         wildcardType.extendsBound?.accept(this)
62         wildcardType.superBound?.accept(this)
63     }
64 
visitTypenull65     open fun visitType(type: TypeItem) = Unit
66 
67     open fun visitPrimitiveType(primitiveType: PrimitiveTypeItem) = Unit
68 
69     open fun visitArrayType(arrayType: ArrayTypeItem) = Unit
70 
71     open fun visitClassType(classType: ClassTypeItem) = Unit
72 
73     open fun visitVariableType(variableType: VariableTypeItem) = Unit
74 
75     open fun visitWildcardType(wildcardType: WildcardTypeItem) = Unit
76 }
77 
78 /**
79  * Visitor that recurs through both a main type and a list of other types, assumed to have the same
80  * structure. When visiting an inner type of the main type, it also takes the corresponding inner
81  * type of each of the other types. For instance, when visiting an [ArrayTypeItem], the visitor will
82  * recur to the main type component type along with a list of component types from the other types.
83  * If the types do not have the same structure, the list of other types will shrink when there is no
84  * corresponding inner type relative to the main type.
85  */
86 open class MultipleTypeVisitor {
87     fun visit(primitiveType: PrimitiveTypeItem, other: List<TypeItem>) {
88         visitType(primitiveType, other)
89         visitPrimitiveType(primitiveType, other)
90     }
91 
92     fun visit(arrayType: ArrayTypeItem, other: List<TypeItem>) {
93         visitType(arrayType, other)
94         visitArrayType(arrayType, other)
95 
96         arrayType.componentType.accept(
97             this,
98             other.mapNotNull { (it as? ArrayTypeItem)?.componentType }
99         )
100     }
101 
102     fun visit(classType: ClassTypeItem, other: List<TypeItem>) {
103         visitType(classType, other)
104         visitClassType(classType, other)
105 
106         classType.outerClassType?.accept(
107             this,
108             other.mapNotNull { (it as? ClassTypeItem)?.outerClassType }
109         )
110         classType.arguments.forEachIndexed { index, arg ->
111             arg.accept(
112                 this,
113                 other.mapNotNull { (it as? ClassTypeItem)?.arguments?.getOrNull(index) }
114             )
115         }
116     }
117 
118     fun visit(variableType: VariableTypeItem, other: List<TypeItem>) {
119         visitType(variableType, other)
120         visitVariableType(variableType, other)
121     }
122 
123     fun visit(wildcardType: WildcardTypeItem, other: List<TypeItem>) {
124         visitType(wildcardType, other)
125         visitWildcardType(wildcardType, other)
126 
127         if (wildcardType.superBound != null) {
128             wildcardType.superBound?.accept(
129                 this,
130                 other.mapNotNull { (it as? WildcardTypeItem)?.superBound }
131             )
132         } else {
133             // Only visit the extends bound if the super bound doesn't exist (don't visit implicit
134             // object bounds)
135             wildcardType.extendsBound?.accept(
136                 this,
137                 other.mapNotNull { (it as? WildcardTypeItem)?.extendsBound }
138             )
139         }
140     }
141 
142     open fun visitType(type: TypeItem, other: List<TypeItem>) = Unit
143 
144     open fun visitPrimitiveType(primitiveType: PrimitiveTypeItem, other: List<TypeItem>) = Unit
145 
146     open fun visitArrayType(arrayType: ArrayTypeItem, other: List<TypeItem>) = Unit
147 
148     open fun visitClassType(classType: ClassTypeItem, other: List<TypeItem>) = Unit
149 
150     open fun visitVariableType(variableType: VariableTypeItem, other: List<TypeItem>) = Unit
151 
152     open fun visitWildcardType(wildcardType: WildcardTypeItem, other: List<TypeItem>) = Unit
153 }
154