1 /* 2 * 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 import com.android.tools.metalava.model.item.DefaultValue 20 21 @MetalavaApi 22 interface ParameterItem : ClassContentItem, Item { 23 /** The name of this field */ namenull24 fun name(): String 25 26 /** The type of this field */ 27 @MetalavaApi override fun type(): TypeItem 28 29 override fun findCorrespondingItemIn( 30 codebase: Codebase, 31 superMethods: Boolean, 32 duplicate: Boolean, 33 ) = 34 containingCallable() 35 .findCorrespondingItemIn(codebase, superMethods = superMethods, duplicate = duplicate) 36 ?.parameters() 37 ?.getOrNull(parameterIndex) 38 39 /** The containing callable. */ 40 fun containingCallable(): CallableItem 41 42 /** The possible containing method, returns null if this is a constructor parameter. */ 43 fun possibleContainingMethod(): MethodItem? = containingCallable().let { it as? MethodItem } 44 45 /** Index of this parameter in the parameter list (0-based) */ 46 val parameterIndex: Int 47 48 /** 49 * The public name of this parameter. In Kotlin, names are part of the public API; in Java they 50 * are not. In Java, you can annotate a parameter with {@literal @ParameterName("foo")} to name 51 * the parameter something (potentially different from the actual code parameter name). 52 */ publicNamenull53 fun publicName(): String? 54 55 /** 56 * Returns whether this parameter has a default value. In Kotlin, this is supported directly; in 57 * Java, it's supported via a special annotation, {@literal @DefaultValue("source"). This does 58 * not necessarily imply that the default value is accessible, and we know the body of the 59 * default value. 60 * 61 * @see isDefaultValueKnown 62 */ 63 fun hasDefaultValue(): Boolean 64 65 /** 66 * Returns whether this parameter has an accessible default value that we plan to keep. This is 67 * a superset of [hasDefaultValue] - if we are not writing the default values to the signature 68 * file, then the default value might not be available, even though the parameter does have a 69 * default. 70 * 71 * @see hasDefaultValue 72 */ 73 fun isDefaultValueKnown(): Boolean 74 75 /** 76 * Returns the default value. 77 * 78 * **This method should only be called if [isDefaultValueKnown] returned true!** (This is 79 * necessary since the null return value is a valid default value separate from no default value 80 * specified.) 81 * 82 * The default value is the source string literal representation of the value, e.g. strings 83 * would be surrounded by quotes, Booleans are the strings "true" or "false", and so on. 84 */ 85 fun defaultValueAsString(): String? 86 87 /** The default value of this [ParameterItem]. */ 88 val defaultValue: DefaultValue 89 90 /** Whether this is a varargs parameter */ 91 fun isVarArgs(): Boolean = modifiers.isVarArg() 92 93 /** The property declared by this parameter; inverse of [PropertyItem.constructorParameter] */ 94 val property: PropertyItem? 95 get() = null 96 97 override fun parent(): CallableItem? = containingCallable() 98 99 override val effectivelyDeprecated: Boolean 100 get() = originallyDeprecated || containingCallable().effectivelyDeprecated 101 102 override fun baselineElementId() = 103 containingCallable().baselineElementId() + " parameter #" + parameterIndex 104 105 override fun accept(visitor: ItemVisitor) { 106 visitor.visit(this) 107 } 108 109 /** 110 * Returns whether this parameter is SAM convertible or a Kotlin lambda. If this parameter is 111 * the last parameter, it also means that it could be called in Kotlin using the trailing lambda 112 * syntax. 113 * 114 * Specifically this will attempt to handle the follow cases: 115 * - Java SAM interface = true 116 * - Kotlin SAM interface = false // Kotlin (non-fun) interfaces are not SAM convertible 117 * - Kotlin fun interface = true 118 * - Kotlin lambda = true 119 * - Any other type = false 120 */ isSamCompatibleOrKotlinLambdanull121 fun isSamCompatibleOrKotlinLambda(): Boolean = 122 // TODO(b/354889186): Implement correctly 123 false 124 125 /** 126 * Create a duplicate of this for [containingCallable]. 127 * 128 * The duplicate's [type] must have applied the [typeVariableMap] substitutions by using 129 * [TypeItem.convertType]. 130 * 131 * This is called from within the constructor of the [containingCallable] so must only access 132 * its `name` and its reference. In particularly it must not access its 133 * [CallableItem.parameters] property as this is called during its initialization. 134 */ 135 fun duplicate( 136 containingCallable: CallableItem, 137 typeVariableMap: TypeParameterBindings, 138 ): ParameterItem 139 140 override fun equalsToItem(other: Any?): Boolean { 141 if (this === other) return true 142 if (other !is ParameterItem) return false 143 144 return parameterIndex == other.parameterIndex && 145 containingCallable() == other.containingCallable() 146 } 147 hashCodeForItemnull148 override fun hashCodeForItem(): Int { 149 return name().hashCode() 150 } 151 toStringForItemnull152 override fun toStringForItem() = "parameter ${name()}" 153 154 override fun containingClass(): ClassItem = containingCallable().containingClass() 155 156 override fun containingPackage(): PackageItem? = containingCallable().containingPackage() 157 158 // TODO: modifier list 159 } 160