• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import com.android.tools.metalava.compatibility
20 
21 open class DefaultModifierList(
22     override val codebase: Codebase,
23     protected var flags: Int = PACKAGE_PRIVATE,
24     protected open var annotations: MutableList<AnnotationItem>? = null
25 ) : MutableModifierList {
26     private lateinit var owner: Item
27 
setnull28     private operator fun set(mask: Int, set: Boolean) {
29         flags = 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 
setOwnernull48     fun setOwner(owner: Item) {
49         this.owner = owner
50     }
51 
getVisibilityLevelnull52     override fun getVisibilityLevel(): VisibilityLevel {
53         val visibilityFlags = flags and VISIBILITY_MASK
54         val levels = VISIBILITY_LEVEL_ENUMS
55         if (visibilityFlags >= levels.size) {
56             throw IllegalStateException(
57                 "Visibility flags are invalid, expected value in range [0, " + levels.size + ") got " + visibilityFlags)
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     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 
setVisibilityLevelnull150     override fun setVisibilityLevel(level: VisibilityLevel) {
151         flags = (flags and VISIBILITY_MASK.inv()) or level.visibilityFlagValue
152     }
153 
setStaticnull154     override fun setStatic(static: Boolean) {
155         set(STATIC, static)
156     }
157 
setAbstractnull158     override fun setAbstract(abstract: Boolean) {
159         set(ABSTRACT, abstract)
160     }
161 
setFinalnull162     override fun setFinal(final: Boolean) {
163         set(FINAL, final)
164     }
165 
setNativenull166     override fun setNative(native: Boolean) {
167         set(NATIVE, native)
168     }
169 
setSynchronizednull170     override fun setSynchronized(synchronized: Boolean) {
171         set(SYNCHRONIZED, synchronized)
172     }
173 
setStrictFpnull174     override fun setStrictFp(strictfp: Boolean) {
175         set(STRICT_FP, strictfp)
176     }
177 
setTransientnull178     override fun setTransient(transient: Boolean) {
179         set(TRANSIENT, transient)
180     }
181 
setVolatilenull182     override fun setVolatile(volatile: Boolean) {
183         set(VOLATILE, volatile)
184     }
185 
setDefaultnull186     override fun setDefault(default: Boolean) {
187         set(DEFAULT, default)
188     }
189 
setSealednull190     override fun setSealed(sealed: Boolean) {
191         set(SEALED, sealed)
192     }
193 
setFunctionalnull194     override fun setFunctional(functional: Boolean) {
195         set(FUN, functional)
196     }
197 
setInfixnull198     override fun setInfix(infix: Boolean) {
199         set(INFIX, infix)
200     }
201 
setOperatornull202     override fun setOperator(operator: Boolean) {
203         set(OPERATOR, operator)
204     }
205 
setInlinenull206     override fun setInline(inline: Boolean) {
207         set(INLINE, inline)
208     }
209 
210     override fun setVarArg(vararg: Boolean) {
211         set(VARARG, vararg)
212     }
213 
setDeprecatednull214     fun setDeprecated(deprecated: Boolean) {
215         set(DEPRECATED, deprecated)
216     }
217 
setSuspendnull218     fun setSuspend(suspend: Boolean) {
219         set(SUSPEND, suspend)
220     }
221 
setCompanionnull222     fun setCompanion(companion: Boolean) {
223         set(COMPANION, companion)
224     }
225 
addAnnotationnull226     override fun addAnnotation(annotation: AnnotationItem) {
227         if (annotations == null) {
228             annotations = mutableListOf()
229         }
230         annotations?.add(annotation)
231     }
232 
removeAnnotationnull233     override fun removeAnnotation(annotation: AnnotationItem) {
234         annotations?.remove(annotation)
235     }
236 
clearAnnotationsnull237     override fun clearAnnotations(annotation: AnnotationItem) {
238         annotations?.clear()
239     }
240 
isEmptynull241     override fun isEmpty(): Boolean {
242         return flags and DEPRECATED.inv() == 0 // deprecated isn't a real modifier
243     }
244 
isPackagePrivatenull245     override fun isPackagePrivate(): Boolean {
246         return flags and VISIBILITY_MASK == PACKAGE_PRIVATE
247     }
248 
249     // Rename? It's not a full equality, it's whether an override's modifier set is significant
equivalentTonull250     override fun equivalentTo(other: ModifierList): Boolean {
251         if (other is DefaultModifierList) {
252             val flags2 = other.flags
253             val mask = if (compatibility.includeSynchronized) COMPAT_EQUIVALENCE_MASK else EQUIVALENCE_MASK
254 
255             val masked1 = flags and mask
256             val masked2 = flags2 and mask
257             val same = masked1 xor masked2
258             if (same == 0) {
259                 return true
260             } else if (compatibility.hideDifferenceImplicit) {
261                 if (same == FINAL &&
262                     // Only differ in final: not significant if implied by containing class
263                     isFinal() && (owner as? MethodItem)?.containingClass()?.modifiers?.isFinal() == true) {
264                     return true
265                 } else if (same == DEPRECATED &&
266                     // Only differ in deprecated: not significant if implied by containing class
267                     isDeprecated() && (owner as? MethodItem)?.containingClass()?.deprecated == true) {
268                     return true
269                 }
270             }
271         }
272         return false
273     }
274 
275     companion object {
276         const val PRIVATE = 0
277         const val INTERNAL = 1
278         const val PACKAGE_PRIVATE = 2
279         const val PROTECTED = 3
280         const val PUBLIC = 4
281         const val VISIBILITY_MASK = 0b111
282 
283         /**
284          * An internal copy of VisibilityLevel.values() to avoid paying the cost of duplicating the array on every
285          * call.
286          */
287         private val VISIBILITY_LEVEL_ENUMS = VisibilityLevel.values()
288 
289         // Check that the constants above are consistent with the VisibilityLevel enum, i.e. the mask is large enough
290         // to include all allowable values and that each visibility level value is the same as the corresponding enum
291         // constant's ordinal.
<lambda>null292         init {
293             check(PRIVATE == VisibilityLevel.PRIVATE.ordinal)
294             check(INTERNAL == VisibilityLevel.INTERNAL.ordinal)
295             check(PACKAGE_PRIVATE == VisibilityLevel.PACKAGE_PRIVATE.ordinal)
296             check(PROTECTED == VisibilityLevel.PROTECTED.ordinal)
297             check(PUBLIC == VisibilityLevel.PUBLIC.ordinal)
298             // Calculate the mask required to hold as many different values as there are VisibilityLevel values.
299             // Given N visibility levels, the required mask is constructed by determining the MSB in the number N - 1
300             // and then setting all bits to the right.
301             // e.g. when N is 5 then N - 1 is 4, the MSB is bit 2, and so the mask is what you get when you set bits 2,
302             // 1 and 0, i.e. 0b111.
303             val expectedMask = (1 shl (32 - Integer.numberOfLeadingZeros(VISIBILITY_LEVEL_ENUMS.size - 1))) - 1
304             check(VISIBILITY_MASK == expectedMask)
305         }
306 
307         const val STATIC = 1 shl 3
308         const val ABSTRACT = 1 shl 4
309         const val FINAL = 1 shl 5
310         const val NATIVE = 1 shl 6
311         const val SYNCHRONIZED = 1 shl 7
312         const val STRICT_FP = 1 shl 8
313         const val TRANSIENT = 1 shl 9
314         const val VOLATILE = 1 shl 10
315         const val DEFAULT = 1 shl 11
316         const val DEPRECATED = 1 shl 12
317         const val VARARG = 1 shl 13
318         const val SEALED = 1 shl 14
319         const val FUN = 1 shl 15
320         const val INFIX = 1 shl 16
321         const val OPERATOR = 1 shl 17
322         const val INLINE = 1 shl 18
323         const val SUSPEND = 1 shl 19
324         const val COMPANION = 1 shl 20
325         const val CONST = 1 shl 21
326 
327         /**
328          * Modifiers considered significant to include signature files (and similarly
329          * to consider whether an override of a method is different from its super implementation
330          */
331         private const val EQUIVALENCE_MASK = VISIBILITY_MASK or STATIC or ABSTRACT or
332             FINAL or TRANSIENT or VOLATILE or DEPRECATED or VARARG or
333             SEALED or FUN or INFIX or OPERATOR or SUSPEND or COMPANION
334 
335         private const val COMPAT_EQUIVALENCE_MASK = EQUIVALENCE_MASK or SYNCHRONIZED
336     }
337 }