• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33     // Signature file parsing
34     val SIGNATURE_FILE_ERROR by Issue(Severity.ERROR)
35     // TODO(b/394789173): Hide until AndroidX has disabled it.
36     val UNQUALIFIED_TYPE_ERROR by Issue(Severity.HIDDEN)
37 
38     // Compatibility issues
39     val ADDED_ANNOTATION by Issue(Severity.ERROR, Category.COMPATIBILITY)
40     val ADDED_PACKAGE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
41     val ADDED_CLASS by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
42     val ADDED_METHOD by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
43     val ADDED_FIELD by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
44     val ADDED_INTERFACE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
45     val REMOVED_ANNOTATION by Issue(Severity.ERROR, Category.COMPATIBILITY)
46     val REMOVED_PACKAGE by Issue(Severity.ERROR, Category.COMPATIBILITY)
47     val REMOVED_CLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
48     val REMOVED_METHOD by Issue(Severity.ERROR, Category.COMPATIBILITY)
49     val REMOVED_FIELD by Issue(Severity.ERROR, Category.COMPATIBILITY)
50     val REMOVED_INTERFACE by Issue(Severity.ERROR, Category.COMPATIBILITY)
51     val CHANGED_STATIC by Issue(Severity.ERROR, Category.COMPATIBILITY)
52     val ADDED_FINAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
53     val CHANGED_VOLATILE by Issue(Severity.ERROR, Category.COMPATIBILITY)
54     val CHANGED_TYPE by Issue(Severity.ERROR, Category.COMPATIBILITY)
55     val CHANGED_VALUE by Issue(Severity.ERROR, Category.COMPATIBILITY)
56     val CHANGED_SUPERCLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
57     val CHANGED_SCOPE by Issue(Severity.ERROR, Category.COMPATIBILITY)
58     val CHANGED_ABSTRACT by Issue(Severity.ERROR, Category.COMPATIBILITY)
59     val CHANGED_DEFAULT by Issue(Severity.ERROR, Category.COMPATIBILITY)
60     val CHANGED_THROWS by Issue(Severity.ERROR, Category.COMPATIBILITY)
61     val CHANGED_NATIVE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
62     val CHANGED_CLASS by Issue(Severity.ERROR, Category.COMPATIBILITY)
63     val CHANGED_DEPRECATED by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
64     val ADDED_FINAL_UNINSTANTIABLE by Issue(Severity.HIDDEN, Category.COMPATIBILITY)
65     val REMOVED_FINAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
66     val REMOVED_FINAL_STRICT by Issue(Severity.ERROR, Category.COMPATIBILITY)
67     val REMOVED_DEPRECATED_CLASS by Issue(REMOVED_CLASS, Category.COMPATIBILITY)
68     val REMOVED_DEPRECATED_METHOD by Issue(REMOVED_METHOD, Category.COMPATIBILITY)
69     val REMOVED_DEPRECATED_FIELD by Issue(REMOVED_FIELD, Category.COMPATIBILITY)
70     val ADDED_ABSTRACT_METHOD by Issue(Severity.ERROR, Category.COMPATIBILITY)
71     val ADDED_REIFIED by Issue(Severity.ERROR, Category.COMPATIBILITY)
72     val REMOVED_JVM_DEFAULT_WITH_COMPATIBILITY by Issue(Severity.ERROR, Category.COMPATIBILITY)
73 
74     // Issues in javadoc generation
75     val UNRESOLVED_LINK by Issue(Severity.ERROR, Category.DOCUMENTATION)
76     val UNAVAILABLE_SYMBOL by Issue(Severity.WARNING, Category.DOCUMENTATION)
77     val HIDDEN_SUPERCLASS by Issue(Severity.WARNING, Category.DOCUMENTATION)
78     val DEPRECATED by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
79     val DEPRECATION_MISMATCH by Issue(Severity.ERROR, Category.DOCUMENTATION)
80     val IO_ERROR by Issue(Severity.ERROR)
81     val HIDDEN_TYPE_PARAMETER by Issue(Severity.WARNING, Category.DOCUMENTATION)
82     val PRIVATE_SUPERCLASS by Issue(Severity.WARNING, Category.DOCUMENTATION)
83     val NULLABLE by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
84     val INT_DEF by Issue(Severity.HIDDEN, Category.DOCUMENTATION)
85     val REQUIRES_PERMISSION by Issue(Severity.ERROR, Category.DOCUMENTATION)
86     val BROADCAST_BEHAVIOR by Issue(Severity.ERROR, Category.DOCUMENTATION)
87     val SDK_CONSTANT by Issue(Severity.ERROR, Category.DOCUMENTATION)
88     val TODO by Issue(Severity.ERROR, Category.DOCUMENTATION)
89 
90     // Metalava warnings (not from doclava)
91 
92     val INVALID_FEATURE_ENFORCEMENT by Issue(Severity.ERROR, Category.DOCUMENTATION)
93 
94     val MISSING_PERMISSION by Issue(Severity.ERROR, Category.DOCUMENTATION)
95     val MULTIPLE_THREAD_ANNOTATIONS by Issue(Severity.ERROR, Category.DOCUMENTATION)
96     val INVALID_NULL_CONVERSION by Issue(Severity.ERROR, Category.COMPATIBILITY)
97     val PARAMETER_NAME_CHANGE by Issue(Severity.ERROR, Category.COMPATIBILITY)
98     val OPERATOR_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
99     val INFIX_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
100     val VARARG_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
101     val ADD_SEALED by Issue(Severity.ERROR, Category.COMPATIBILITY)
102     val FUN_REMOVAL by Issue(Severity.ERROR, Category.COMPATIBILITY)
103     val BECAME_UNCHECKED by Issue(Severity.ERROR, Category.COMPATIBILITY)
104     val ANNOTATION_EXTRACTION by Issue(Severity.ERROR)
105     val SUPERFLUOUS_PREFIX by Issue(Severity.WARNING)
106     val HIDDEN_TYPEDEF_CONSTANT by Issue(Severity.ERROR)
107     val INTERNAL_ERROR by Issue(Severity.ERROR)
108     val RETURNING_UNEXPECTED_CONSTANT 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, Category.API_LINT)
111     val INCONSISTENT_MERGE_ANNOTATION by Issue(Severity.WARNING_ERROR_WHEN_NEW, Category.API_LINT)
112     // The plan is for this to be set as an error once (1) existing code is marked as @deprecated
113     // and (2) the principle is adopted by the API council
114     val REFERENCES_DEPRECATED by Issue(Severity.HIDDEN, Category.API_LINT)
115     val UNHIDDEN_SYSTEM_API by Issue(Severity.ERROR, Category.API_LINT)
116     val SHOWING_MEMBER_IN_HIDDEN_CLASS by Issue(Severity.ERROR, Category.API_LINT)
117     val INVALID_NULLABILITY_ANNOTATION by Issue(Severity.ERROR)
118     val REFERENCES_HIDDEN by Issue(Severity.ERROR, Category.API_LINT)
119     val IGNORING_SYMLINK by Issue(Severity.INFO)
120     val INVALID_NULLABILITY_ANNOTATION_WARNING by Issue(Severity.WARNING)
121     // The plan is for this to be set as an error once (1) existing code is marked as @deprecated
122     // and (2) the principle is adopted by the API council
123     val EXTENDS_DEPRECATED by Issue(Severity.HIDDEN, Category.API_LINT)
124     val FORBIDDEN_TAG by Issue(Severity.ERROR, Category.DOCUMENTATION)
125     val MISSING_COLUMN by Issue(Severity.WARNING, Category.DOCUMENTATION)
126     val INVALID_SYNTAX by Issue(Severity.ERROR)
127     val INVALID_PACKAGE by Issue(Severity.ERROR)
128     val UNRESOLVED_IMPORT by Issue(Severity.INFO)
129     val HIDDEN_ABSTRACT_METHOD by Issue(Severity.ERROR, Category.API_LINT)
130 
131     // API lint
132     val START_WITH_LOWER by Issue(Severity.ERROR, Category.API_LINT)
133     val START_WITH_UPPER by Issue(Severity.ERROR, Category.API_LINT)
134     val ALL_UPPER by Issue(Severity.ERROR, Category.API_LINT)
135     val ACRONYM_NAME by Issue(Severity.WARNING, Category.API_LINT)
136     val ENUM by Issue(Severity.ERROR, Category.API_LINT)
137     val ENDS_WITH_IMPL by Issue(Severity.ERROR, Category.API_LINT)
138     val MIN_MAX_CONSTANT by Issue(Severity.WARNING, Category.API_LINT)
139     val COMPILE_TIME_CONSTANT by Issue(Severity.ERROR, Category.API_LINT)
140     val SINGULAR_CALLBACK by Issue(Severity.ERROR, Category.API_LINT)
141     val CALLBACK_NAME by Issue(Severity.WARNING, Category.API_LINT)
142     // Obsolete per https://s.android.com/api-guidelines.
143     val CALLBACK_INTERFACE by Issue(Severity.HIDDEN, Category.API_LINT)
144     val CALLBACK_METHOD_NAME by Issue(Severity.ERROR, Category.API_LINT)
145     val LISTENER_INTERFACE by Issue(Severity.ERROR, Category.API_LINT)
146     val SINGLE_METHOD_INTERFACE by Issue(Severity.ERROR, Category.API_LINT)
147     val INTENT_NAME by Issue(Severity.ERROR, Category.API_LINT)
148     val ACTION_VALUE by Issue(Severity.ERROR, Category.API_LINT)
149     val EQUALS_AND_HASH_CODE by Issue(Severity.ERROR, Category.API_LINT)
150     val PARCEL_CREATOR by Issue(Severity.ERROR, Category.API_LINT)
151     val PARCEL_NOT_FINAL by Issue(Severity.ERROR, Category.API_LINT)
152     val PARCEL_CONSTRUCTOR by Issue(Severity.ERROR, Category.API_LINT)
153     val PROTECTED_MEMBER by Issue(Severity.ERROR, Category.API_LINT)
154     val PAIRED_REGISTRATION by Issue(Severity.ERROR, Category.API_LINT)
155     val VISIBLY_SYNCHRONIZED by Issue(Severity.ERROR, Category.API_LINT)
156     val INTENT_BUILDER_NAME by Issue(Severity.WARNING, Category.API_LINT)
157     val CONTEXT_NAME_SUFFIX by Issue(Severity.ERROR, Category.API_LINT)
158     val INTERFACE_CONSTANT by Issue(Severity.ERROR, Category.API_LINT)
159     val ON_NAME_EXPECTED by Issue(Severity.WARNING, Category.API_LINT)
160     val TOP_LEVEL_BUILDER by Issue(Severity.WARNING, Category.API_LINT)
161     val MISSING_BUILD_METHOD by Issue(Severity.WARNING, Category.API_LINT)
162     val BUILDER_SET_STYLE by Issue(Severity.WARNING, Category.API_LINT)
163     val SETTER_RETURNS_THIS by Issue(Severity.WARNING, Category.API_LINT)
164     val RAW_AIDL by Issue(Severity.ERROR, Category.API_LINT)
165     val INTERNAL_CLASSES by Issue(Severity.ERROR, Category.API_LINT)
166     val PACKAGE_LAYERING by Issue(Severity.WARNING, Category.API_LINT)
167     val GETTER_SETTER_NAMES by Issue(Severity.ERROR, Category.API_LINT)
168     val CONCRETE_COLLECTION by Issue(Severity.ERROR, Category.API_LINT)
169     val OVERLAPPING_CONSTANTS by Issue(Severity.WARNING, Category.API_LINT)
170     val GENERIC_EXCEPTION by Issue(Severity.ERROR, 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.COMPATIBILITY)
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     val CONDITIONAL_REQUIRES_PERMISSION_NOT_EXPLAINED by Issue(Severity.HIDDEN, Category.API_LINT)
236     val VALUE_CLASS_DEFINITION by Issue(Severity.ERROR, Category.API_LINT)
237     val INVALID_ENVIRONMENT_IN_RESTRICTED_FOR_ENVIRONMENT by
238         Issue(Severity.ERROR, Category.API_LINT)
239     val MISSING_FROM_VALUE by Issue(Severity.ERROR, Category.API_LINT)
240     val INHERIT_CHANGES_SIGNATURE by Issue(Severity.WARNING_ERROR_WHEN_NEW)
241     val DATA_CLASS_DEFINITION by Issue(Severity.HIDDEN, Category.API_LINT)
242 
findIssueByIdnull243     fun findIssueById(id: String?): Issue? {
244         return nameToIssue[id]
245     }
246 
findCategoryByIdnull247     fun findCategoryById(id: String?): Category =
248         Category.entries.find { it.id == id }
249             ?: error(
<lambda>null250                 "Unknown category: '$id', expected one of ${Category.entries.joinToString { it.id }}"
251             )
252 
253     fun findIssuesByCategory(category: Category?): List<Issue> =
254         allIssues.filter { it.category == category }
255 
256     class Issue
257     private constructor(
258         val defaultLevel: Severity,
259         /**
260          * When `level` is set to [Severity.INHERIT], this is the parent from which the issue will
261          * inherit its level.
262          */
263         val parent: Issue?,
264         /** Applicable category */
265         val category: Category,
266     ) : ReadOnlyProperty<Issues, Issue> {
267         /** The name of this issue */
268         lateinit var name: String
269             internal set
270 
271         internal constructor(
272             defaultLevel: Severity,
273             category: Category = Category.UNKNOWN
274         ) : this(defaultLevel, null, category)
275 
276         internal constructor(
277             parent: Issue,
278             category: Category
279         ) : this(Severity.INHERIT, parent, category)
280 
281         /**
282          * Called to get the value of the delegating property; as this is the value just return it.
283          */
getValuenull284         override fun getValue(thisRef: Issues, property: KProperty<*>): Issue {
285             return this
286         }
287 
288         /**
289          * Called once on creation to retrieve the property delegate.
290          *
291          * Initializes the name and adds a mapping from the name to this and then just returns this
292          * as the delegate.
293          */
provideDelegatenull294         operator fun provideDelegate(thisRef: Issues, property: KProperty<*>): Issue {
295             // Initialize issue names based on the property names.
296             name = enumConstantToCamelCase(property.name)
297             nameToIssue[name] = this
298             return this
299         }
300 
toStringnull301         override fun toString(): String {
302             return "Issue $name"
303         }
304 
305         init {
306             allIssues.add(this)
307         }
308     }
309 
310     enum class Category(val description: String) {
311         COMPATIBILITY("Compatibility"),
312         DOCUMENTATION("Documentation"),
313         API_LINT("API Lint"),
314         UNKNOWN("Default");
315 
316         /** Identifier for use in command-line arguments and reporting. */
317         val id: String = enumConstantToCamelCase(name)
318     }
319 
320     init {
321         // Make sure that every Issue was created as a property delegate using `by` and not just
322         // assigned to the field using `=`.
323         for (issue in allIssues) {
324             check(issue.name != "")
325         }
326     }
327 }
328 
329 /**
330  * Convert enum constant name to camel case starting with an upper case letter.
331  *
332  * e.g. `ALPHA_BETA` becomes `AlphaBeta`.
333  */
enumConstantToCamelCasenull334 private fun enumConstantToCamelCase(name: String): String {
335     return name
336         .splitToSequence("_")
337         .map { "${it[0]}${it.substring(1).lowercase(Locale.US)}" }
338         .joinToString("")
339 }
340