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 package com.android.tools.metalava.apilevels
17
18 /** Represents a parent of [ApiElement]. */
19 interface ParentApiElement {
20 /** The API version this API was first introduced in. */
21 val since: ApiVersion
22
23 /**
24 * The version in which this API last appeared, if this is not the latest API then it will be
25 * treated as having been removed in the next API version, i.e. [lastPresentIn] + 1.
26 */
27 val lastPresentIn: ApiVersion
28
29 /**
30 * The SDKs and their versions this API was first introduced in.
31 *
32 * The value is a comma-separated list of <int>:<int> values, where the first
33 * <int> is the integer ID of an SDK, and the second <int> the version of that SDK,
34 * in which this API first appeared.
35 *
36 * This field is a super-set of mSince, and if non-null/non-empty, should be preferred.
37 */
38 val sdks: String?
39
40 /** The optional API level this element was deprecated in. */
41 val deprecatedIn: ApiVersion?
42 }
43
44 /**
45 * Represents an API element, e.g. class, method or field.
46 *
47 * @param name the name of the API element
48 */
49 open class ApiElement(val name: String) : ParentApiElement, Comparable<ApiElement> {
50
51 /**
52 * The Android API level of this ApiElement. i.e. The Android platform SDK version this API was
53 * first introduced in.
54 */
55 final override lateinit var since: ApiVersion
56 private set
57
58 /**
59 * The extension version of this ApiElement. i.e. The Android extension SDK version this API was
60 * first introduced in.
61 */
62 var sinceExtension: ExtVersion? = null
63 private set
64
65 final override var sdks: String? = null
66 private set
67
68 var mainlineModule: String? = null
69 private set
70
71 /** The optional API level this element was deprecated in. */
72 final override var deprecatedIn: ApiVersion? = null
73 private set
74
75 final override lateinit var lastPresentIn: ApiVersion
76 private set
77
toStringnull78 override fun toString(): String {
79 return name
80 }
81
82 /**
83 * Checks if this API element was introduced not later than another API element.
84 *
85 * @param other the API element to compare to
86 * @return true if this API element was introduced not later than `other`
87 */
introducedNotLaterThannull88 fun introducedNotLaterThan(other: ApiElement?): Boolean {
89 return since <= other!!.since
90 }
91
92 /**
93 * Updates the API element with information for a specific API version.
94 *
95 * @param apiVersion an API version for which the API element existed
96 * @param deprecated whether the API element was deprecated in the API version in question
97 */
updatenull98 fun update(apiVersion: ApiVersion, deprecated: Boolean = deprecatedIn != null) {
99 assert(apiVersion.isValid)
100 if (!::since.isInitialized || since > apiVersion) {
101 since = apiVersion
102 }
103 if (!::lastPresentIn.isInitialized || lastPresentIn < apiVersion) {
104 lastPresentIn = apiVersion
105 }
106 val deprecatedVersion = deprecatedIn
107 if (deprecated) {
108 // If it was not previously deprecated or was deprecated in a later version than this
109 // one then deprecate it in this version.
110 if (deprecatedVersion == null || deprecatedVersion > apiVersion) {
111 deprecatedIn = apiVersion
112 }
113 } else {
114 // If it was previously deprecated and was deprecated in an earlier version than this
115 // one then treat it as being undeprecated.
116 if (deprecatedVersion != null && deprecatedVersion < apiVersion) {
117 deprecatedIn = null
118 }
119 }
120 }
121
122 /**
123 * Analogous to update(), but for extensions sdk versions.
124 *
125 * @param extVersion an extension SDK version for which the API element existed
126 */
updateExtensionnull127 fun updateExtension(extVersion: ExtVersion) {
128 assert(extVersion.isValid)
129 // Record the earliest extension in which this appeared.
130 if (sinceExtension == null || sinceExtension!! > extVersion) {
131 sinceExtension = extVersion
132 }
133 }
134
135 /**
136 * Clears the sdk extension information from this [ApiElement].
137 *
138 * This is only intended for use by [Api.patchSdkExtensionsHistory].
139 */
clearSdkExtensionInfonull140 fun clearSdkExtensionInfo() {
141 this.sinceExtension = null
142 this.sdks = null
143 }
144
updateSdksnull145 fun updateSdks(sdks: String?) {
146 this.sdks = sdks
147 }
148
updateMainlineModulenull149 fun updateMainlineModule(module: String?) {
150 mainlineModule = module
151 }
152
compareTonull153 override fun compareTo(other: ApiElement): Int {
154 return name.compareTo(other.name)
155 }
156 }
157
compareTonull158 operator fun ApiVersion?.compareTo(other: ApiVersion?): Int =
159 if (this == null) {
160 if (other == null) 0 else -1
161 } else if (other == null) +1 else this.compareTo(other)
162