1 /*
2  * Copyright (C) 2018 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 class DefaultModifierList(
20     override val codebase: Codebase,
21     private var flags: Int = PACKAGE_PRIVATE,
22     private var annotations: MutableList<AnnotationItem>? = null
23 ) : MutableModifierList {
24     /** Set in [DefaultItem] initialization. */
25     internal lateinit var owner: Item
26 
setnull27     private operator fun set(mask: Int, set: Boolean) {
28         flags =
29             if (set) {
30                 flags or mask
31             } else {
32                 flags and mask.inv()
33             }
34     }
35 
isSetnull36     private fun isSet(mask: Int): Boolean {
37         return flags and mask != 0
38     }
39 
annotationsnull40     override fun annotations(): List<AnnotationItem> {
41         return annotations ?: emptyList()
42     }
43 
ownernull44     override fun owner(): Item {
45         return owner
46     }
47 
getVisibilityLevelnull48     override fun getVisibilityLevel(): VisibilityLevel {
49         val visibilityFlags = flags and VISIBILITY_MASK
50         val levels = VISIBILITY_LEVEL_ENUMS
51         if (visibilityFlags >= levels.size) {
52             throw IllegalStateException(
53                 "Visibility flags are invalid, expected value in range [0, " +
54                     levels.size +
55                     ") got " +
56                     visibilityFlags
57             )
58         }
59         return levels[visibilityFlags]
60     }
61 
isPublicnull62     override fun isPublic(): Boolean {
63         return getVisibilityLevel() == VisibilityLevel.PUBLIC
64     }
65 
isProtectednull66     override fun isProtected(): Boolean {
67         return getVisibilityLevel() == VisibilityLevel.PROTECTED
68     }
69 
isPrivatenull70     override fun isPrivate(): Boolean {
71         return getVisibilityLevel() == VisibilityLevel.PRIVATE
72     }
73 
isStaticnull74     override fun isStatic(): Boolean {
75         return isSet(STATIC)
76     }
77 
isAbstractnull78     override fun isAbstract(): Boolean {
79         return isSet(ABSTRACT)
80     }
81 
isFinalnull82     override fun isFinal(): Boolean {
83         return isSet(FINAL)
84     }
85 
isNativenull86     override fun isNative(): Boolean {
87         return isSet(NATIVE)
88     }
89 
isSynchronizednull90     override fun isSynchronized(): Boolean {
91         return isSet(SYNCHRONIZED)
92     }
93 
isStrictFpnull94     override fun isStrictFp(): Boolean {
95         return isSet(STRICT_FP)
96     }
97 
isTransientnull98     override fun isTransient(): Boolean {
99         return isSet(TRANSIENT)
100     }
101 
isVolatilenull102     override fun isVolatile(): Boolean {
103         return isSet(VOLATILE)
104     }
105 
isDefaultnull106     override fun isDefault(): Boolean {
107         return isSet(DEFAULT)
108     }
109 
isDeprecatednull110     override fun isDeprecated(): Boolean {
111         return isSet(DEPRECATED)
112     }
113 
isVarArgnull114     override fun isVarArg(): Boolean {
115         return isSet(VARARG)
116     }
117 
isSealednull118     override fun isSealed(): Boolean {
119         return isSet(SEALED)
120     }
121 
isFunctionalnull122     override fun isFunctional(): Boolean {
123         return isSet(FUN)
124     }
125 
isInfixnull126     override fun isInfix(): Boolean {
127         return isSet(INFIX)
128     }
129 
isConstnull130     override fun isConst(): Boolean {
131         return isSet(CONST)
132     }
133 
isSuspendnull134     override fun isSuspend(): Boolean {
135         return isSet(SUSPEND)
136     }
137 
isCompanionnull138     override fun isCompanion(): Boolean {
139         return isSet(COMPANION)
140     }
141 
isOperatornull142     override fun isOperator(): Boolean {
143         return isSet(OPERATOR)
144     }
145 
isInlinenull146     override fun isInline(): Boolean {
147         return isSet(INLINE)
148     }
149 
isValuenull150     override fun isValue(): Boolean {
151         return isSet(VALUE)
152     }
153 
isDatanull154     override fun isData(): Boolean {
155         return isSet(DATA)
156     }
157 
isExpectnull158     override fun isExpect(): Boolean {
159         return isSet(EXPECT)
160     }
161 
isActualnull162     override fun isActual(): Boolean {
163         return isSet(ACTUAL)
164     }
165 
setVisibilityLevelnull166     override fun setVisibilityLevel(level: VisibilityLevel) {
167         flags = (flags and VISIBILITY_MASK.inv()) or level.visibilityFlagValue
168     }
169 
setStaticnull170     override fun setStatic(static: Boolean) {
171         set(STATIC, static)
172     }
173 
setAbstractnull174     override fun setAbstract(abstract: Boolean) {
175         set(ABSTRACT, abstract)
176     }
177 
setFinalnull178     override fun setFinal(final: Boolean) {
179         set(FINAL, final)
180     }
181 
setNativenull182     override fun setNative(native: Boolean) {
183         set(NATIVE, native)
184     }
185 
setSynchronizednull186     override fun setSynchronized(synchronized: Boolean) {
187         set(SYNCHRONIZED, synchronized)
188     }
189 
setStrictFpnull190     override fun setStrictFp(strictfp: Boolean) {
191         set(STRICT_FP, strictfp)
192     }
193 
setTransientnull194     override fun setTransient(transient: Boolean) {
195         set(TRANSIENT, transient)
196     }
197 
setVolatilenull198     override fun setVolatile(volatile: Boolean) {
199         set(VOLATILE, volatile)
200     }
201 
setDefaultnull202     override fun setDefault(default: Boolean) {
203         set(DEFAULT, default)
204     }
205 
setSealednull206     override fun setSealed(sealed: Boolean) {
207         set(SEALED, sealed)
208     }
209 
setFunctionalnull210     override fun setFunctional(functional: Boolean) {
211         set(FUN, functional)
212     }
213 
setInfixnull214     override fun setInfix(infix: Boolean) {
215         set(INFIX, infix)
216     }
217 
setOperatornull218     override fun setOperator(operator: Boolean) {
219         set(OPERATOR, operator)
220     }
221 
setInlinenull222     override fun setInline(inline: Boolean) {
223         set(INLINE, inline)
224     }
225 
setValuenull226     override fun setValue(value: Boolean) {
227         set(VALUE, value)
228     }
229 
setDatanull230     override fun setData(data: Boolean) {
231         set(DATA, data)
232     }
233 
234     override fun setVarArg(vararg: Boolean) {
235         set(VARARG, vararg)
236     }
237 
setDeprecatednull238     override fun setDeprecated(deprecated: Boolean) {
239         set(DEPRECATED, deprecated)
240     }
241 
setSuspendnull242     override fun setSuspend(suspend: Boolean) {
243         set(SUSPEND, suspend)
244     }
245 
setCompanionnull246     override fun setCompanion(companion: Boolean) {
247         set(COMPANION, companion)
248     }
249 
setExpectnull250     override fun setExpect(expect: Boolean) {
251         set(EXPECT, expect)
252     }
253 
setActualnull254     override fun setActual(actual: Boolean) {
255         set(ACTUAL, actual)
256     }
257 
addAnnotationnull258     override fun addAnnotation(annotation: AnnotationItem) {
259         if (annotations == null) {
260             annotations = mutableListOf()
261         }
262         annotations?.add(annotation)
263     }
264 
removeAnnotationnull265     override fun removeAnnotation(annotation: AnnotationItem) {
266         annotations?.remove(annotation)
267     }
268 
removeAnnotationsnull269     override fun removeAnnotations(predicate: (AnnotationItem) -> Boolean) {
270         annotations?.removeAll(predicate)
271     }
272 
clearAnnotationsnull273     override fun clearAnnotations(annotation: AnnotationItem) {
274         annotations?.clear()
275     }
276 
isEmptynull277     override fun isEmpty(): Boolean {
278         return flags and DEPRECATED.inv() == 0 // deprecated isn't a real modifier
279     }
280 
isPackagePrivatenull281     override fun isPackagePrivate(): Boolean {
282         return flags and VISIBILITY_MASK == PACKAGE_PRIVATE
283     }
284 
285     /**
286      * Copy this, so it can be used on (and possibly modified by) another [Item] from the same
287      * codebase.
288      */
duplicatenull289     fun duplicate(): DefaultModifierList {
290         val annotations = this.annotations
291         val newAnnotations =
292             if (annotations == null || annotations.isEmpty()) {
293                 null
294             } else {
295                 annotations.toMutableList()
296             }
297         return DefaultModifierList(codebase, flags, newAnnotations)
298     }
299 
300     // Rename? It's not a full equality, it's whether an override's modifier set is significant
equivalentTonull301     override fun equivalentTo(other: ModifierList): Boolean {
302         if (other is DefaultModifierList) {
303             val flags2 = other.flags
304             val mask = EQUIVALENCE_MASK
305 
306             val masked1 = flags and mask
307             val masked2 = flags2 and mask
308             val same = masked1 xor masked2
309             if (same == 0) {
310                 return true
311             } else {
312                 if (
313                     same == FINAL &&
314                         // Only differ in final: not significant if implied by containing class
315                         isFinal() &&
316                         (owner as? MethodItem)?.containingClass()?.modifiers?.isFinal() == true
317                 ) {
318                     return true
319                 } else if (
320                     same == DEPRECATED &&
321                         // Only differ in deprecated: not significant if implied by containing class
322                         isDeprecated() &&
323                         (owner as? MethodItem)?.containingClass()?.effectivelyDeprecated == true
324                 ) {
325                     return true
326                 }
327             }
328         }
329         return false
330     }
331 
equalsnull332     override fun equals(other: Any?): Boolean {
333         if (this === other) return true
334         if (javaClass != other?.javaClass) return false
335 
336         other as DefaultModifierList
337 
338         if (flags != other.flags) return false
339         if (annotations != other.annotations) return false
340 
341         return true
342     }
343 
hashCodenull344     override fun hashCode(): Int {
345         var result = flags
346         result = 31 * result + (annotations?.hashCode() ?: 0)
347         return result
348     }
349 
350     companion object {
351         /**
352          * 'PACKAGE_PRIVATE' is set to 0 to act as the default visibility when no other visibility
353          * flags are explicitly set.
354          */
355         const val PACKAGE_PRIVATE = 0
356         const val PRIVATE = 1
357         const val INTERNAL = 2
358         const val PROTECTED = 3
359         const val PUBLIC = 4
360         const val VISIBILITY_MASK = 0b111
361 
362         /**
363          * An internal copy of VisibilityLevel.values() to avoid paying the cost of duplicating the
364          * array on every call.
365          */
366         private val VISIBILITY_LEVEL_ENUMS = VisibilityLevel.values()
367 
368         // Check that the constants above are consistent with the VisibilityLevel enum, i.e. the
369         // mask is large enough
370         // to include all allowable values and that each visibility level value is the same as the
371         // corresponding enum
372         // constant's ordinal.
<lambda>null373         init {
374             check(PACKAGE_PRIVATE == VisibilityLevel.PACKAGE_PRIVATE.ordinal)
375             check(PRIVATE == VisibilityLevel.PRIVATE.ordinal)
376             check(INTERNAL == VisibilityLevel.INTERNAL.ordinal)
377             check(PROTECTED == VisibilityLevel.PROTECTED.ordinal)
378             check(PUBLIC == VisibilityLevel.PUBLIC.ordinal)
379             // Calculate the mask required to hold as many different values as there are
380             // VisibilityLevel values.
381             // Given N visibility levels, the required mask is constructed by determining the MSB in
382             // the number N - 1
383             // and then setting all bits to the right.
384             // e.g. when N is 5 then N - 1 is 4, the MSB is bit 2, and so the mask is what you get
385             // when you set bits 2,
386             // 1 and 0, i.e. 0b111.
387             val expectedMask =
388                 (1 shl (32 - Integer.numberOfLeadingZeros(VISIBILITY_LEVEL_ENUMS.size - 1))) - 1
389             check(VISIBILITY_MASK == expectedMask)
390         }
391 
392         const val STATIC = 1 shl 3
393         const val ABSTRACT = 1 shl 4
394         const val FINAL = 1 shl 5
395         const val NATIVE = 1 shl 6
396         const val SYNCHRONIZED = 1 shl 7
397         const val STRICT_FP = 1 shl 8
398         const val TRANSIENT = 1 shl 9
399         const val VOLATILE = 1 shl 10
400         const val DEFAULT = 1 shl 11
401         const val DEPRECATED = 1 shl 12
402         const val VARARG = 1 shl 13
403         const val SEALED = 1 shl 14
404         const val FUN = 1 shl 15
405         const val INFIX = 1 shl 16
406         const val OPERATOR = 1 shl 17
407         const val INLINE = 1 shl 18
408         const val SUSPEND = 1 shl 19
409         const val COMPANION = 1 shl 20
410         const val CONST = 1 shl 21
411         const val DATA = 1 shl 22
412         const val VALUE = 1 shl 23
413         const val EXPECT = 1 shl 24
414         const val ACTUAL = 1 shl 25
415 
416         /**
417          * Modifiers considered significant to include signature files (and similarly to consider
418          * whether an override of a method is different from its super implementation)
419          */
420         private const val EQUIVALENCE_MASK =
421             VISIBILITY_MASK or
422                 STATIC or
423                 ABSTRACT or
424                 FINAL or
425                 TRANSIENT or
426                 VOLATILE or
427                 DEPRECATED or
428                 VARARG or
429                 SEALED or
430                 FUN or
431                 INFIX or
432                 OPERATOR or
433                 SUSPEND or
434                 COMPANION
435     }
436 }
437