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.Codebase 20 import com.android.tools.metalava.model.FixedDefaultValue 21 import com.android.tools.metalava.model.ParameterItem 22 23 /** 24 * A lamda that given a [ParameterItem] will create a [DefaultValue] for it. 25 * 26 * This is called from within the constructor of the [ParameterItem] and should not access any 27 * properties of [ParameterItem] as they may not have been initialized. This should just store a 28 * reference for later use. 29 */ 30 typealias DefaultValueFactory = (ParameterItem) -> DefaultValue 31 32 /** 33 * Represents a parameter's default value. 34 * 35 * TODO: Investigate this abstraction to see if it matches what we need. It is a little confusing as 36 * [hasDefaultValue] and [isDefaultValueKnown] seem like they should be different but are 37 * implemented in Psi and Turbine to be identical. 38 */ 39 interface DefaultValue { 40 41 /** A [DefaultValue] to use for a parameter that has no default value. */ 42 @Suppress("ConvertObjectToDataObject") // Requires language level 1.9 43 object NONE : DefaultValue { hasDefaultValuenull44 override fun hasDefaultValue() = false 45 46 override fun isDefaultValueKnown() = false 47 48 override fun value() = error("cannot call on NONE DefaultValue") 49 50 /** This is suitable for use by [parameter] as it has no model or codebase dependencies. */ 51 override fun duplicate(parameter: ParameterItem) = this 52 53 /** This is suitable for use in the snapshot as it has no model or codebase dependencies. */ 54 override fun snapshot(parameter: ParameterItem) = this 55 56 override fun toString() = "NONE" 57 } 58 59 /** 60 * A [DefaultValue] to use for a parameter that has a default value but its actual value is not 61 * known. 62 */ 63 @Suppress("ConvertObjectToDataObject") // Requires language level 1.9 64 object UNKNOWN : DefaultValue { 65 override fun hasDefaultValue() = true 66 67 override fun isDefaultValueKnown() = false 68 69 override fun value() = error("cannot call on UNKNOWN DefaultValue") 70 71 /** This is suitable for use by [parameter] as it has no model or codebase dependencies. */ 72 override fun duplicate(parameter: ParameterItem) = this 73 74 /** This is suitable for use in the snapshot as it has no model or codebase dependencies. */ 75 override fun snapshot(parameter: ParameterItem) = this 76 77 override fun toString() = "UNKNOWN" 78 } 79 80 companion object { 81 /** Get a [DefaultValue] wrapper around a fixed [String] value. */ fixedDefaultValuenull82 fun fixedDefaultValue(value: String?): DefaultValue { 83 return FixedDefaultValue(value) 84 } 85 } 86 87 /** 88 * Returns whether this parameter has a default value. In Kotlin, this is supported directly; in 89 * Java, it's supported via a special annotation, {@literal @DefaultValue("source"). This does 90 * not necessarily imply that the default value is accessible, and we know the body of the 91 * default value. 92 * 93 * @see isDefaultValueKnown 94 */ hasDefaultValuenull95 fun hasDefaultValue(): Boolean 96 97 /** 98 * Returns whether this parameter has an accessible default value that we plan to keep. This is 99 * a superset of [hasDefaultValue] - if we are not writing the default values to the signature 100 * file, then the default value might not be available, even though the parameter does have a 101 * default. 102 * 103 * @see hasDefaultValue 104 */ 105 fun isDefaultValueKnown(): Boolean 106 107 /** 108 * Returns the default value. 109 * 110 * **This method should only be called if [isDefaultValueKnown] returned true!** (This is 111 * necessary since the null return value is a valid default value separate from no default value 112 * specified.) 113 * 114 * The default value is the source string literal representation of the value, e.g. strings 115 * would be surrounded by quotes, Booleans are the strings "true" or "false", and so on. 116 */ 117 fun value(): String? 118 119 /** 120 * Return a duplicate of this instance to use by [parameter] which will be in the same type of 121 * [Codebase] as this. 122 */ 123 fun duplicate(parameter: ParameterItem): DefaultValue 124 125 /** 126 * Creates a snapshot of this. 127 * 128 * The default implementation assumes that this is either dependent on a model or the codebase 129 * and so creates a new [DefaultValue] based on the functions above. 130 */ 131 fun snapshot(parameter: ParameterItem) = 132 when { 133 !hasDefaultValue() -> NONE 134 !isDefaultValueKnown() -> UNKNOWN 135 else -> fixedDefaultValue(value()) 136 } 137 } 138