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