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 isInfixnull122 override fun isInfix(): Boolean { 123 return isSet(INFIX) 124 } 125 isConstnull126 override fun isConst(): Boolean { 127 return isSet(CONST) 128 } 129 isSuspendnull130 override fun isSuspend(): Boolean { 131 return isSet(SUSPEND) 132 } 133 isCompanionnull134 override fun isCompanion(): Boolean { 135 return isSet(COMPANION) 136 } 137 isOperatornull138 override fun isOperator(): Boolean { 139 return isSet(OPERATOR) 140 } 141 isInlinenull142 override fun isInline(): Boolean { 143 return isSet(INLINE) 144 } 145 setVisibilityLevelnull146 override fun setVisibilityLevel(level: VisibilityLevel) { 147 flags = (flags and VISIBILITY_MASK.inv()) or level.visibilityFlagValue 148 } 149 setStaticnull150 override fun setStatic(static: Boolean) { 151 set(STATIC, static) 152 } 153 setAbstractnull154 override fun setAbstract(abstract: Boolean) { 155 set(ABSTRACT, abstract) 156 } 157 setFinalnull158 override fun setFinal(final: Boolean) { 159 set(FINAL, final) 160 } 161 setNativenull162 override fun setNative(native: Boolean) { 163 set(NATIVE, native) 164 } 165 setSynchronizednull166 override fun setSynchronized(synchronized: Boolean) { 167 set(SYNCHRONIZED, synchronized) 168 } 169 setStrictFpnull170 override fun setStrictFp(strictfp: Boolean) { 171 set(STRICT_FP, strictfp) 172 } 173 setTransientnull174 override fun setTransient(transient: Boolean) { 175 set(TRANSIENT, transient) 176 } 177 setVolatilenull178 override fun setVolatile(volatile: Boolean) { 179 set(VOLATILE, volatile) 180 } 181 setDefaultnull182 override fun setDefault(default: Boolean) { 183 set(DEFAULT, default) 184 } 185 setSealednull186 override fun setSealed(sealed: Boolean) { 187 set(SEALED, sealed) 188 } 189 setInfixnull190 override fun setInfix(infix: Boolean) { 191 set(INFIX, infix) 192 } 193 setOperatornull194 override fun setOperator(operator: Boolean) { 195 set(OPERATOR, operator) 196 } 197 setInlinenull198 override fun setInline(inline: Boolean) { 199 set(INLINE, inline) 200 } 201 202 override fun setVarArg(vararg: Boolean) { 203 set(VARARG, vararg) 204 } 205 setDeprecatednull206 fun setDeprecated(deprecated: Boolean) { 207 set(DEPRECATED, deprecated) 208 } 209 setSuspendnull210 fun setSuspend(suspend: Boolean) { 211 set(SUSPEND, suspend) 212 } 213 setCompanionnull214 fun setCompanion(companion: Boolean) { 215 set(COMPANION, companion) 216 } 217 addAnnotationnull218 override fun addAnnotation(annotation: AnnotationItem) { 219 if (annotations == null) { 220 annotations = mutableListOf() 221 } 222 annotations?.add(annotation) 223 } 224 removeAnnotationnull225 override fun removeAnnotation(annotation: AnnotationItem) { 226 annotations?.remove(annotation) 227 } 228 clearAnnotationsnull229 override fun clearAnnotations(annotation: AnnotationItem) { 230 annotations?.clear() 231 } 232 isEmptynull233 override fun isEmpty(): Boolean { 234 return flags and DEPRECATED.inv() == 0 // deprecated isn't a real modifier 235 } 236 isPackagePrivatenull237 override fun isPackagePrivate(): Boolean { 238 return flags and VISIBILITY_MASK == PACKAGE_PRIVATE 239 } 240 241 // Rename? It's not a full equality, it's whether an override's modifier set is significant equivalentTonull242 override fun equivalentTo(other: ModifierList): Boolean { 243 if (other is DefaultModifierList) { 244 val flags2 = other.flags 245 val mask = if (compatibility.includeSynchronized) COMPAT_EQUIVALENCE_MASK else EQUIVALENCE_MASK 246 247 val masked1 = flags and mask 248 val masked2 = flags2 and mask 249 val same = masked1 xor masked2 250 if (same == 0) { 251 return true 252 } else if (compatibility.hideDifferenceImplicit) { 253 if (same == FINAL && 254 // Only differ in final: not significant if implied by containing class 255 isFinal() && (owner as? MethodItem)?.containingClass()?.modifiers?.isFinal() == true) { 256 return true 257 } else if (same == DEPRECATED && 258 // Only differ in deprecated: not significant if implied by containing class 259 isDeprecated() && (owner as? MethodItem)?.containingClass()?.deprecated == true) { 260 return true 261 } 262 } 263 } 264 return false 265 } 266 267 companion object { 268 const val PRIVATE = 0 269 const val INTERNAL = 1 270 const val PACKAGE_PRIVATE = 2 271 const val PROTECTED = 3 272 const val PUBLIC = 4 273 const val VISIBILITY_MASK = 0b111 274 275 /** 276 * An internal copy of VisibilityLevel.values() to avoid paying the cost of duplicating the array on every 277 * call. 278 */ 279 private val VISIBILITY_LEVEL_ENUMS = VisibilityLevel.values() 280 281 // Check that the constants above are consistent with the VisibilityLevel enum, i.e. the mask is large enough 282 // to include all allowable values and that each visibility level value is the same as the corresponding enum 283 // constant's ordinal. <lambda>null284 init { 285 check(PRIVATE == VisibilityLevel.PRIVATE.ordinal) 286 check(INTERNAL == VisibilityLevel.INTERNAL.ordinal) 287 check(PACKAGE_PRIVATE == VisibilityLevel.PACKAGE_PRIVATE.ordinal) 288 check(PROTECTED == VisibilityLevel.PROTECTED.ordinal) 289 check(PUBLIC == VisibilityLevel.PUBLIC.ordinal) 290 // Calculate the mask required to hold as many different values as there are VisibilityLevel values. 291 // Given N visibility levels, the required mask is constructed by determining the MSB in the number N - 1 292 // and then setting all bits to the right. 293 // 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, 294 // 1 and 0, i.e. 0b111. 295 val expectedMask = (1 shl (32 - Integer.numberOfLeadingZeros(VISIBILITY_LEVEL_ENUMS.size - 1))) - 1 296 check(VISIBILITY_MASK == expectedMask) 297 } 298 299 const val STATIC = 1 shl 3 300 const val ABSTRACT = 1 shl 4 301 const val FINAL = 1 shl 5 302 const val NATIVE = 1 shl 6 303 const val SYNCHRONIZED = 1 shl 7 304 const val STRICT_FP = 1 shl 8 305 const val TRANSIENT = 1 shl 9 306 const val VOLATILE = 1 shl 10 307 const val DEFAULT = 1 shl 11 308 const val DEPRECATED = 1 shl 12 309 const val VARARG = 1 shl 13 310 const val SEALED = 1 shl 14 311 // 15 currently unused 312 const val INFIX = 1 shl 16 313 const val OPERATOR = 1 shl 17 314 const val INLINE = 1 shl 18 315 const val SUSPEND = 1 shl 19 316 const val COMPANION = 1 shl 20 317 const val CONST = 1 shl 21 318 319 /** 320 * Modifiers considered significant to include signature files (and similarly 321 * to consider whether an override of a method is different from its super implementation 322 */ 323 private const val EQUIVALENCE_MASK = VISIBILITY_MASK or STATIC or ABSTRACT or 324 FINAL or TRANSIENT or VOLATILE or DEPRECATED or VARARG or 325 SEALED or INFIX or OPERATOR or SUSPEND or COMPANION 326 327 private const val COMPAT_EQUIVALENCE_MASK = EQUIVALENCE_MASK or SYNCHRONIZED 328 } 329 }