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 }