1 /*
2 * Copyright (C) 2023 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.reporter
17
18 import java.util.Locale
19 import kotlin.properties.ReadOnlyProperty
20 import kotlin.reflect.KProperty
21
22 object Issues {
23 private val allIssues: MutableList<Issue> = ArrayList(300)
24
25 /** A list of all the issues. */
26 val all: List<Issue> by this::allIssues
27
28 private val nameToIssue: MutableMap<String, Issue> = HashMap(300)
29
30 val PARSE_ERROR by Issue(Severity.ERROR)
31 val DUPLICATE_SOURCE_CLASS by Issue(Severity.WARNING)
32 // Compatibility issues
33 val ADDED_PACKAGE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
34 val ADDED_CLASS by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
35 val ADDED_METHOD by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
36 val ADDED_FIELD by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
37 val ADDED_INTERFACE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
38 val REMOVED_PACKAGE by Issue(Severity.ERROR, Category.COMPATIBILITY)
39 val REMOVED_CLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
40 val REMOVED_METHOD by Issue(Severity.ERROR, Category.COMPATIBILITY)
41 val REMOVED_FIELD by Issue(Severity.ERROR, Category.COMPATIBILITY)
42 val REMOVED_INTERFACE by Issue(Severity.ERROR, Category.COMPATIBILITY)
43 val CHANGED_STATIC by Issue(Severity.ERROR, Category.COMPATIBILITY)
44 val ADDED_FINAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
45 val CHANGED_TRANSIENT by Issue(Severity.ERROR, Category.COMPATIBILITY)
46 val CHANGED_VOLATILE by Issue(Severity.ERROR, Category.COMPATIBILITY)
47 val CHANGED_TYPE by Issue(Severity.ERROR, Category.COMPATIBILITY)
48 val CHANGED_VALUE by Issue(Severity.ERROR, Category.COMPATIBILITY)
49 val CHANGED_SUPERCLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
50 val CHANGED_SCOPE by Issue(Severity.ERROR, Category.COMPATIBILITY)
51 val CHANGED_ABSTRACT by Issue(Severity.ERROR, Category.COMPATIBILITY)
52 val CHANGED_DEFAULT by Issue(Severity.ERROR, Category.COMPATIBILITY)
53 val CHANGED_THROWS by Issue(Severity.ERROR, Category.COMPATIBILITY)
54 val CHANGED_NATIVE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
55 val CHANGED_CLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
56 val CHANGED_DEPRECATED by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
57 val CHANGED_SYNCHRONIZED by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
58 val CONFLICTING_SHOW_ANNOTATIONS by Issue(Severity.ERROR, Category.UNKNOWN)
59 val ADDED_FINAL_UNINSTANTIABLE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
60 val REMOVED_FINAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
61 val REMOVED_FINAL_STRICT by Issue(Severity.ERROR, Category.COMPATIBILITY)
62 val REMOVED_DEPRECATED_CLASS by Issue(REMOVED_CLASS, Category.COMPATIBILITY)
63 val REMOVED_DEPRECATED_METHOD by Issue(REMOVED_METHOD, Category.COMPATIBILITY)
64 val REMOVED_DEPRECATED_FIELD by Issue(REMOVED_FIELD, Category.COMPATIBILITY)
65 val ADDED_ABSTRACT_METHOD by Issue(Severity.ERROR, Category.COMPATIBILITY)
66 val ADDED_REIFIED by Issue(Severity.ERROR, Category.COMPATIBILITY)
67 val REMOVED_JVM_DEFAULT_WITH_COMPATIBILITY by Issue(Severity.ERROR, Category.COMPATIBILITY)
68
69 // Issues in javadoc generation
70 val UNRESOLVED_LINK by Issue(Severity.ERROR, Category.DOCUMENTATION)
71 val UNAVAILABLE_SYMBOL by Issue(Severity.WARNING, Category.DOCUMENTATION)
72 val HIDDEN_SUPERCLASS by Issue(Severity.WARNING, Category.DOCUMENTATION)
73 val DEPRECATED by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
74 val DEPRECATION_MISMATCH by Issue(Severity.ERROR, Category.DOCUMENTATION)
75 val IO_ERROR by Issue(Severity.ERROR)
76 val HIDDEN_TYPE_PARAMETER by Issue(Severity.WARNING, Category.DOCUMENTATION)
77 val PRIVATE_SUPERCLASS by Issue(Severity.WARNING, Category.DOCUMENTATION)
78 val NULLABLE by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
79 val INT_DEF by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
80 val REQUIRES_PERMISSION by Issue(Severity.ERROR, Category.DOCUMENTATION)
81 val BROADCAST_BEHAVIOR by Issue(Severity.ERROR, Category.DOCUMENTATION)
82 val SDK_CONSTANT by Issue(Severity.ERROR, Category.DOCUMENTATION)
83 val TODO by Issue(Severity.ERROR, Category.DOCUMENTATION)
84 val NO_ARTIFACT_DATA by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
85 val BROKEN_ARTIFACT_FILE by Issue(Severity.ERROR, Category.DOCUMENTATION)
86
87 // Metalava warnings (not from doclava)
88
89 val INVALID_FEATURE_ENFORCEMENT by Issue(Severity.ERROR, Category.DOCUMENTATION)
90
91 val MISSING_PERMISSION by Issue(Severity.ERROR, Category.DOCUMENTATION)
92 val MULTIPLE_THREAD_ANNOTATIONS by Issue(Severity.ERROR, Category.DOCUMENTATION)
93 val UNRESOLVED_CLASS by Issue(Severity.ERROR, Category.DOCUMENTATION)
94 val INVALID_NULL_CONVERSION by Issue(Severity.ERROR, Category.COMPATIBILITY)
95 val PARAMETER_NAME_CHANGE by Issue(Severity.ERROR, Category.COMPATIBILITY)
96 val OPERATOR_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
97 val INFIX_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
98 val VARARG_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
99 val ADD_SEALED by Issue(Severity.ERROR, Category.COMPATIBILITY)
100 val FUN_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
101 val BECAME_UNCHECKED by Issue(Severity.ERROR, Category.COMPATIBILITY)
102 val ANNOTATION_EXTRACTION by Issue(Severity.ERROR)
103 val SUPERFLUOUS_PREFIX by Issue(Severity.WARNING)
104 val HIDDEN_TYPEDEF_CONSTANT by Issue(Severity.ERROR)
105 val EXPECTED_PLATFORM_TYPE by Issue(Severity.HIDDEN)
106 val INTERNAL_ERROR by Issue(Severity.ERROR)
107 val RETURNING_UNEXPECTED_CONSTANT by Issue(Severity.WARNING)
108 val DEPRECATED_OPTION by Issue(Severity.WARNING)
109 val BOTH_PACKAGE_INFO_AND_HTML by Issue(Severity.WARNING, Category.DOCUMENTATION)
110 val UNMATCHED_MERGE_ANNOTATION by Issue(Severity.ERROR)
111 // The plan is for this to be set as an error once (1) existing code is marked as @deprecated
112 // and (2) the principle is adopted by the API council
113 val REFERENCES_DEPRECATED by Issue(Severity.HIDDEN)
114 val UNHIDDEN_SYSTEM_API by Issue(Severity.ERROR)
115 val SHOWING_MEMBER_IN_HIDDEN_CLASS by Issue(Severity.ERROR)
116 val INVALID_NULLABILITY_ANNOTATION by Issue(Severity.ERROR)
117 val REFERENCES_HIDDEN by Issue(Severity.ERROR)
118 val IGNORING_SYMLINK by Issue(Severity.INFO)
119 val INVALID_NULLABILITY_ANNOTATION_WARNING by Issue(Severity.WARNING)
120 // The plan is for this to be set as an error once (1) existing code is marked as @deprecated
121 // and (2) the principle is adopted by the API council
122 val EXTENDS_DEPRECATED by Issue(Severity.HIDDEN)
123 val FORBIDDEN_TAG by Issue(Severity.ERROR)
124 val MISSING_COLUMN by Issue(Severity.WARNING, Category.DOCUMENTATION)
125 val INVALID_SYNTAX by Issue(Severity.ERROR)
126 val UNRESOLVED_IMPORT by Issue(Severity.INFO)
127 val HIDDEN_ABSTRACT_METHOD by Issue(Severity.ERROR)
128
129 // API lint
130 val START_WITH_LOWER by Issue(Severity.ERROR, Category.API_LINT)
131 val START_WITH_UPPER by Issue(Severity.ERROR, Category.API_LINT)
132 val ALL_UPPER by Issue(Severity.ERROR, Category.API_LINT)
133 val ACRONYM_NAME by Issue(Severity.WARNING, Category.API_LINT)
134 val ENUM by Issue(Severity.ERROR, Category.API_LINT)
135 val ENDS_WITH_IMPL by Issue(Severity.ERROR, Category.API_LINT)
136 val MIN_MAX_CONSTANT by Issue(Severity.WARNING, Category.API_LINT)
137 val COMPILE_TIME_CONSTANT by Issue(Severity.ERROR, Category.API_LINT)
138 val SINGULAR_CALLBACK by Issue(Severity.ERROR, Category.API_LINT)
139 val CALLBACK_NAME by Issue(Severity.WARNING, Category.API_LINT)
140 // Obsolete per https://s.android.com/api-guidelines.
141 val CALLBACK_INTERFACE by Issue(Severity.HIDDEN, Category.API_LINT)
142 val CALLBACK_METHOD_NAME by Issue(Severity.ERROR, Category.API_LINT)
143 val LISTENER_INTERFACE by Issue(Severity.ERROR, Category.API_LINT)
144 val SINGLE_METHOD_INTERFACE by Issue(Severity.ERROR, Category.API_LINT)
145 val INTENT_NAME by Issue(Severity.ERROR, Category.API_LINT)
146 val ACTION_VALUE by Issue(Severity.ERROR, Category.API_LINT)
147 val EQUALS_AND_HASH_CODE by Issue(Severity.ERROR, Category.API_LINT)
148 val PARCEL_CREATOR by Issue(Severity.ERROR, Category.API_LINT)
149 val PARCEL_NOT_FINAL by Issue(Severity.ERROR, Category.API_LINT)
150 val PARCEL_CONSTRUCTOR by Issue(Severity.ERROR, Category.API_LINT)
151 val PROTECTED_MEMBER by Issue(Severity.ERROR, Category.API_LINT)
152 val PAIRED_REGISTRATION by Issue(Severity.ERROR, Category.API_LINT)
153 val REGISTRATION_NAME by Issue(Severity.ERROR, Category.API_LINT)
154 val VISIBLY_SYNCHRONIZED by Issue(Severity.ERROR, Category.API_LINT)
155 val INTENT_BUILDER_NAME by Issue(Severity.WARNING, Category.API_LINT)
156 val CONTEXT_NAME_SUFFIX by Issue(Severity.ERROR, Category.API_LINT)
157 val INTERFACE_CONSTANT by Issue(Severity.ERROR, Category.API_LINT)
158 val ON_NAME_EXPECTED by Issue(Severity.WARNING, Category.API_LINT)
159 val TOP_LEVEL_BUILDER by Issue(Severity.WARNING, Category.API_LINT)
160 val MISSING_BUILD_METHOD by Issue(Severity.WARNING, Category.API_LINT)
161 val BUILDER_SET_STYLE by Issue(Severity.WARNING, Category.API_LINT)
162 val SETTER_RETURNS_THIS by Issue(Severity.WARNING, Category.API_LINT)
163 val RAW_AIDL by Issue(Severity.ERROR, Category.API_LINT)
164 val INTERNAL_CLASSES by Issue(Severity.ERROR, Category.API_LINT)
165 val PACKAGE_LAYERING by Issue(Severity.WARNING, Category.API_LINT)
166 val GETTER_SETTER_NAMES by Issue(Severity.ERROR, Category.API_LINT)
167 val CONCRETE_COLLECTION by Issue(Severity.ERROR, Category.API_LINT)
168 val OVERLAPPING_CONSTANTS by Issue(Severity.WARNING, Category.API_LINT)
169 val GENERIC_EXCEPTION by Issue(Severity.ERROR, Category.API_LINT)
170 val ILLEGAL_STATE_EXCEPTION by Issue(Severity.WARNING, Category.API_LINT)
171 val RETHROW_REMOTE_EXCEPTION by Issue(Severity.ERROR, Category.API_LINT)
172 val MENTIONS_GOOGLE by Issue(Severity.ERROR, Category.API_LINT)
173 val HEAVY_BIT_SET by Issue(Severity.ERROR, Category.API_LINT)
174 val MANAGER_CONSTRUCTOR by Issue(Severity.ERROR, Category.API_LINT)
175 val MANAGER_LOOKUP by Issue(Severity.ERROR, Category.API_LINT)
176 val AUTO_BOXING by Issue(Severity.ERROR, Category.API_LINT)
177 val STATIC_UTILS by Issue(Severity.ERROR, Category.API_LINT)
178 val CONTEXT_FIRST by Issue(Severity.ERROR, Category.API_LINT)
179 val LISTENER_LAST by Issue(Severity.WARNING, Category.API_LINT)
180 val EXECUTOR_REGISTRATION by Issue(Severity.WARNING, Category.API_LINT)
181 val CONFIG_FIELD_NAME by Issue(Severity.ERROR, Category.API_LINT)
182 val RESOURCE_FIELD_NAME by Issue(Severity.ERROR, Category.API_LINT)
183 val RESOURCE_VALUE_FIELD_NAME by Issue(Severity.ERROR, Category.API_LINT)
184 val RESOURCE_STYLE_FIELD_NAME by Issue(Severity.ERROR, Category.API_LINT)
185 val STREAM_FILES by Issue(Severity.WARNING, Category.API_LINT)
186 val PARCELABLE_LIST by Issue(Severity.WARNING, Category.API_LINT)
187 val ABSTRACT_INNER by Issue(Severity.WARNING, Category.API_LINT)
188 val BANNED_THROW by Issue(Severity.ERROR, Category.API_LINT)
189 val EXTENDS_ERROR by Issue(Severity.ERROR, Category.API_LINT)
190 val EXCEPTION_NAME by Issue(Severity.ERROR, Category.API_LINT)
191 val METHOD_NAME_UNITS by Issue(Severity.ERROR, Category.API_LINT)
192 val FRACTION_FLOAT by Issue(Severity.ERROR, Category.API_LINT)
193 val PERCENTAGE_INT by Issue(Severity.ERROR, Category.API_LINT)
194 val NOT_CLOSEABLE by Issue(Severity.WARNING, Category.API_LINT)
195 val KOTLIN_OPERATOR by Issue(Severity.INFO, Category.API_LINT)
196 val ARRAY_RETURN by Issue(Severity.WARNING, Category.API_LINT)
197 val USER_HANDLE by Issue(Severity.WARNING, Category.API_LINT)
198 val USER_HANDLE_NAME by Issue(Severity.WARNING, Category.API_LINT)
199 val SERVICE_NAME by Issue(Severity.ERROR, Category.API_LINT)
200 val METHOD_NAME_TENSE by Issue(Severity.WARNING, Category.API_LINT)
201 val NO_CLONE by Issue(Severity.ERROR, Category.API_LINT)
202 val USE_ICU by Issue(Severity.WARNING, Category.API_LINT)
203 val USE_PARCEL_FILE_DESCRIPTOR by Issue(Severity.ERROR, Category.API_LINT)
204 val NO_BYTE_OR_SHORT by Issue(Severity.WARNING, Category.API_LINT)
205 val SINGLETON_CONSTRUCTOR by Issue(Severity.ERROR, Category.API_LINT)
206 val KOTLIN_KEYWORD by Issue(Severity.ERROR, Category.API_LINT)
207 val UNIQUE_KOTLIN_OPERATOR by Issue(Severity.ERROR, Category.API_LINT)
208 val SAM_SHOULD_BE_LAST by Issue(Severity.WARNING, Category.API_LINT)
209 val MISSING_JVMSTATIC by Issue(Severity.WARNING, Category.API_LINT)
210 val DEFAULT_VALUE_CHANGE by Issue(Severity.ERROR, Category.API_LINT)
211 val DOCUMENT_EXCEPTIONS by Issue(Severity.ERROR, Category.API_LINT)
212 val FORBIDDEN_SUPER_CLASS by Issue(Severity.ERROR, Category.API_LINT)
213 val MISSING_NULLABILITY by Issue(Severity.ERROR, Category.API_LINT)
214 // This issue must be manually enabled
215 val MISSING_INNER_NULLABILITY by Issue(Severity.HIDDEN, Category.API_LINT)
216 val INVALID_NULLABILITY_OVERRIDE by Issue(Severity.ERROR, Category.API_LINT)
217 val MUTABLE_BARE_FIELD by Issue(Severity.ERROR, Category.API_LINT)
218 val INTERNAL_FIELD by Issue(Severity.ERROR, Category.API_LINT)
219 val PUBLIC_TYPEDEF by Issue(Severity.ERROR, Category.API_LINT)
220 val ANDROID_URI by Issue(Severity.ERROR, Category.API_LINT)
221 val BAD_FUTURE by Issue(Severity.ERROR, Category.API_LINT)
222 val STATIC_FINAL_BUILDER by Issue(Severity.WARNING, Category.API_LINT)
223 val GETTER_ON_BUILDER by Issue(Severity.WARNING, Category.API_LINT)
224 val MISSING_GETTER_MATCHING_BUILDER by Issue(Severity.WARNING, Category.API_LINT)
225 val OPTIONAL_BUILDER_CONSTRUCTOR_ARGUMENT by Issue(Severity.WARNING, Category.API_LINT)
226 val NO_SETTINGS_PROVIDER by Issue(Severity.HIDDEN, Category.API_LINT)
227 val NULLABLE_COLLECTION by Issue(Severity.WARNING, Category.API_LINT)
228 val NULLABLE_COLLECTION_ELEMENT by Issue(Severity.WARNING, Category.API_LINT)
229 val ASYNC_SUFFIX_FUTURE by Issue(Severity.ERROR, Category.API_LINT)
230 val GENERIC_CALLBACKS by Issue(Severity.ERROR, Category.API_LINT)
231 val KOTLIN_DEFAULT_PARAMETER_ORDER by Issue(Severity.ERROR, Category.API_LINT)
232 val UNFLAGGED_API by Issue(Severity.HIDDEN, Category.API_LINT)
233 val FLAGGED_API_LITERAL by Issue(Severity.WARNING_ERROR_WHEN_NEW, Category.API_LINT)
234 val GETTER_SETTER_NULLABILITY by Issue(Severity.WARNING_ERROR_WHEN_NEW, Category.API_LINT)
235
findIssueByIdnull236 fun findIssueById(id: String?): Issue? {
237 return nameToIssue[id]
238 }
239
findIssueByIdIgnoringCasenull240 fun findIssueByIdIgnoringCase(id: String): Issue? {
241 for (e in allIssues) {
242 if (id.equals(e.name, ignoreCase = true)) {
243 return e
244 }
245 }
246 return null
247 }
248
<lambda>null249 fun findCategoryById(id: String?): Category? = Category.values().find { it.id == id }
250
findIssuesByCategorynull251 fun findIssuesByCategory(category: Category?): List<Issue> =
252 allIssues.filter { it.category == category }
253
254 class Issue
255 private constructor(
256 val defaultLevel: Severity,
257 /**
258 * When `level` is set to [Severity.INHERIT], this is the parent from which the issue will
259 * inherit its level.
260 */
261 val parent: Issue?,
262 /** Applicable category */
263 val category: Category,
264 ) : ReadOnlyProperty<Issues, Issue> {
265 /** The name of this issue */
266 lateinit var name: String
267 internal set
268
269 internal constructor(
270 defaultLevel: Severity,
271 category: Category = Category.UNKNOWN
272 ) : this(defaultLevel, null, category)
273
274 internal constructor(
275 parent: Issue,
276 category: Category
277 ) : this(Severity.INHERIT, parent, category)
278
279 /**
280 * Called to get the value of the delegating property; as this is the value just return it.
281 */
getValuenull282 override fun getValue(thisRef: Issues, property: KProperty<*>): Issue {
283 return this
284 }
285
286 /**
287 * Called once on creation to retrieve the property delegate.
288 *
289 * Initializes the name and adds a mapping from the name to this and then just returns this
290 * as the delegate.
291 */
provideDelegatenull292 operator fun provideDelegate(thisRef: Issues, property: KProperty<*>): Issue {
293 // Initialize issue names based on the property names.
294 name = enumConstantToCamelCase(property.name)
295 nameToIssue[name] = this
296 return this
297 }
298
toStringnull299 override fun toString(): String {
300 return "Issue $name"
301 }
302
303 init {
304 allIssues.add(this)
305 }
306 }
307
308 enum class Category(val description: String) {
309 COMPATIBILITY("Compatibility"),
310 DOCUMENTATION("Documentation"),
311 API_LINT("API Lint"),
312 UNKNOWN("Default");
313
314 /** Identifier for use in command-line arguments and reporting. */
315 val id: String = enumConstantToCamelCase(name)
316 }
317
318 init {
319 // Make sure that every Issue was created as a property delegate using `by` and not just
320 // assigned to the field using `=`.
321 for (issue in allIssues) {
322 check(issue.name != "")
323 }
324 }
325 }
326
327 /**
328 * Convert enum constant name to camel case starting with an upper case letter.
329 *
330 * e.g. `ALPHA_BETA` becomes `AlphaBeta`.
331 */
enumConstantToCamelCasenull332 private fun enumConstantToCamelCase(name: String): String {
333 return name
334 .splitToSequence("_")
335 .map { "${it[0]}${it.substring(1).lowercase(Locale.US)}" }
336 .joinToString("")
337 }
338