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 open class DefaultModifierList( 20 override val codebase: Codebase, 21 protected var flags: Int = PACKAGE_PRIVATE, 22 protected open var annotations: MutableList<AnnotationItem>? = null 23 ) : MutableModifierList { 24 private lateinit var owner: Item 25 setnull26 private operator fun set(mask: Int, set: Boolean) { 27 flags = if (set) { 28 flags or mask 29 } else { 30 flags and mask.inv() 31 } 32 } 33 isSetnull34 private fun isSet(mask: Int): Boolean { 35 return flags and mask != 0 36 } 37 annotationsnull38 override fun annotations(): List<AnnotationItem> { 39 return annotations ?: emptyList() 40 } 41 ownernull42 override fun owner(): Item { 43 return owner 44 } 45 setOwnernull46 fun setOwner(owner: Item) { 47 this.owner = owner 48 } 49 getVisibilityLevelnull50 override fun getVisibilityLevel(): VisibilityLevel { 51 val visibilityFlags = flags and VISIBILITY_MASK 52 val levels = VISIBILITY_LEVEL_ENUMS 53 if (visibilityFlags >= levels.size) { 54 throw IllegalStateException( 55 "Visibility flags are invalid, expected value in range [0, " + levels.size + ") got " + visibilityFlags 56 ) 57 } 58 return levels[visibilityFlags] 59 } 60 isPublicnull61 override fun isPublic(): Boolean { 62 return getVisibilityLevel() == VisibilityLevel.PUBLIC 63 } 64 isProtectednull65 override fun isProtected(): Boolean { 66 return getVisibilityLevel() == VisibilityLevel.PROTECTED 67 } 68 isPrivatenull69 override fun isPrivate(): Boolean { 70 return getVisibilityLevel() == VisibilityLevel.PRIVATE 71 } 72 isStaticnull73 override fun isStatic(): Boolean { 74 return isSet(STATIC) 75 } 76 isAbstractnull77 override fun isAbstract(): Boolean { 78 return isSet(ABSTRACT) 79 } 80 isFinalnull81 override fun isFinal(): Boolean { 82 return isSet(FINAL) 83 } 84 isNativenull85 override fun isNative(): Boolean { 86 return isSet(NATIVE) 87 } 88 isSynchronizednull89 override fun isSynchronized(): Boolean { 90 return isSet(SYNCHRONIZED) 91 } 92 isStrictFpnull93 override fun isStrictFp(): Boolean { 94 return isSet(STRICT_FP) 95 } 96 isTransientnull97 override fun isTransient(): Boolean { 98 return isSet(TRANSIENT) 99 } 100 isVolatilenull101 override fun isVolatile(): Boolean { 102 return isSet(VOLATILE) 103 } 104 isDefaultnull105 override fun isDefault(): Boolean { 106 return isSet(DEFAULT) 107 } 108 isDeprecatednull109 fun isDeprecated(): Boolean { 110 return isSet(DEPRECATED) 111 } 112 isVarArgnull113 override fun isVarArg(): Boolean { 114 return isSet(VARARG) 115 } 116 isSealednull117 override fun isSealed(): Boolean { 118 return isSet(SEALED) 119 } 120 isFunctionalnull121 override fun isFunctional(): Boolean { 122 return isSet(FUN) 123 } 124 isInfixnull125 override fun isInfix(): Boolean { 126 return isSet(INFIX) 127 } 128 isConstnull129 override fun isConst(): Boolean { 130 return isSet(CONST) 131 } 132 isSuspendnull133 override fun isSuspend(): Boolean { 134 return isSet(SUSPEND) 135 } 136 isCompanionnull137 override fun isCompanion(): Boolean { 138 return isSet(COMPANION) 139 } 140 isOperatornull141 override fun isOperator(): Boolean { 142 return isSet(OPERATOR) 143 } 144 isInlinenull145 override fun isInline(): Boolean { 146 return isSet(INLINE) 147 } 148 isValuenull149 override fun isValue(): Boolean { 150 return isSet(VALUE) 151 } 152 isDatanull153 override fun isData(): Boolean { 154 return isSet(DATA) 155 } 156 setVisibilityLevelnull157 override fun setVisibilityLevel(level: VisibilityLevel) { 158 flags = (flags and VISIBILITY_MASK.inv()) or level.visibilityFlagValue 159 } 160 setStaticnull161 override fun setStatic(static: Boolean) { 162 set(STATIC, static) 163 } 164 setAbstractnull165 override fun setAbstract(abstract: Boolean) { 166 set(ABSTRACT, abstract) 167 } 168 setFinalnull169 override fun setFinal(final: Boolean) { 170 set(FINAL, final) 171 } 172 setNativenull173 override fun setNative(native: Boolean) { 174 set(NATIVE, native) 175 } 176 setSynchronizednull177 override fun setSynchronized(synchronized: Boolean) { 178 set(SYNCHRONIZED, synchronized) 179 } 180 setStrictFpnull181 override fun setStrictFp(strictfp: Boolean) { 182 set(STRICT_FP, strictfp) 183 } 184 setTransientnull185 override fun setTransient(transient: Boolean) { 186 set(TRANSIENT, transient) 187 } 188 setVolatilenull189 override fun setVolatile(volatile: Boolean) { 190 set(VOLATILE, volatile) 191 } 192 setDefaultnull193 override fun setDefault(default: Boolean) { 194 set(DEFAULT, default) 195 } 196 setSealednull197 override fun setSealed(sealed: Boolean) { 198 set(SEALED, sealed) 199 } 200 setFunctionalnull201 override fun setFunctional(functional: Boolean) { 202 set(FUN, functional) 203 } 204 setInfixnull205 override fun setInfix(infix: Boolean) { 206 set(INFIX, infix) 207 } 208 setOperatornull209 override fun setOperator(operator: Boolean) { 210 set(OPERATOR, operator) 211 } 212 setInlinenull213 override fun setInline(inline: Boolean) { 214 set(INLINE, inline) 215 } 216 setValuenull217 override fun setValue(value: Boolean) { 218 set(VALUE, value) 219 } 220 setDatanull221 override fun setData(data: Boolean) { 222 set(DATA, data) 223 } 224 225 override fun setVarArg(vararg: Boolean) { 226 set(VARARG, vararg) 227 } 228 setDeprecatednull229 fun setDeprecated(deprecated: Boolean) { 230 set(DEPRECATED, deprecated) 231 } 232 setSuspendnull233 fun setSuspend(suspend: Boolean) { 234 set(SUSPEND, suspend) 235 } 236 setCompanionnull237 fun setCompanion(companion: Boolean) { 238 set(COMPANION, companion) 239 } 240 addAnnotationnull241 override fun addAnnotation(annotation: AnnotationItem) { 242 if (annotations == null) { 243 annotations = mutableListOf() 244 } 245 annotations?.add(annotation) 246 } 247 removeAnnotationnull248 override fun removeAnnotation(annotation: AnnotationItem) { 249 annotations?.remove(annotation) 250 } 251 clearAnnotationsnull252 override fun clearAnnotations(annotation: AnnotationItem) { 253 annotations?.clear() 254 } 255 isEmptynull256 override fun isEmpty(): Boolean { 257 return flags and DEPRECATED.inv() == 0 // deprecated isn't a real modifier 258 } 259 isPackagePrivatenull260 override fun isPackagePrivate(): Boolean { 261 return flags and VISIBILITY_MASK == PACKAGE_PRIVATE 262 } 263 264 // Rename? It's not a full equality, it's whether an override's modifier set is significant equivalentTonull265 override fun equivalentTo(other: ModifierList): Boolean { 266 if (other is DefaultModifierList) { 267 val flags2 = other.flags 268 val mask = EQUIVALENCE_MASK 269 270 val masked1 = flags and mask 271 val masked2 = flags2 and mask 272 val same = masked1 xor masked2 273 if (same == 0) { 274 return true 275 } else { 276 if (same == FINAL && 277 // Only differ in final: not significant if implied by containing class 278 isFinal() && (owner as? MethodItem)?.containingClass()?.modifiers?.isFinal() == true 279 ) { 280 return true 281 } else if (same == DEPRECATED && 282 // Only differ in deprecated: not significant if implied by containing class 283 isDeprecated() && (owner as? MethodItem)?.containingClass()?.deprecated == true 284 ) { 285 return true 286 } 287 } 288 } 289 return false 290 } 291 292 companion object { 293 const val PRIVATE = 0 294 const val INTERNAL = 1 295 const val PACKAGE_PRIVATE = 2 296 const val PROTECTED = 3 297 const val PUBLIC = 4 298 const val VISIBILITY_MASK = 0b111 299 300 /** 301 * An internal copy of VisibilityLevel.values() to avoid paying the cost of duplicating the array on every 302 * call. 303 */ 304 private val VISIBILITY_LEVEL_ENUMS = VisibilityLevel.values() 305 306 // Check that the constants above are consistent with the VisibilityLevel enum, i.e. the mask is large enough 307 // to include all allowable values and that each visibility level value is the same as the corresponding enum 308 // constant's ordinal. <lambda>null309 init { 310 check(PRIVATE == VisibilityLevel.PRIVATE.ordinal) 311 check(INTERNAL == VisibilityLevel.INTERNAL.ordinal) 312 check(PACKAGE_PRIVATE == VisibilityLevel.PACKAGE_PRIVATE.ordinal) 313 check(PROTECTED == VisibilityLevel.PROTECTED.ordinal) 314 check(PUBLIC == VisibilityLevel.PUBLIC.ordinal) 315 // Calculate the mask required to hold as many different values as there are VisibilityLevel values. 316 // Given N visibility levels, the required mask is constructed by determining the MSB in the number N - 1 317 // and then setting all bits to the right. 318 // 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, 319 // 1 and 0, i.e. 0b111. 320 val expectedMask = (1 shl (32 - Integer.numberOfLeadingZeros(VISIBILITY_LEVEL_ENUMS.size - 1))) - 1 321 check(VISIBILITY_MASK == expectedMask) 322 } 323 324 const val STATIC = 1 shl 3 325 const val ABSTRACT = 1 shl 4 326 const val FINAL = 1 shl 5 327 const val NATIVE = 1 shl 6 328 const val SYNCHRONIZED = 1 shl 7 329 const val STRICT_FP = 1 shl 8 330 const val TRANSIENT = 1 shl 9 331 const val VOLATILE = 1 shl 10 332 const val DEFAULT = 1 shl 11 333 const val DEPRECATED = 1 shl 12 334 const val VARARG = 1 shl 13 335 const val SEALED = 1 shl 14 336 const val FUN = 1 shl 15 337 const val INFIX = 1 shl 16 338 const val OPERATOR = 1 shl 17 339 const val INLINE = 1 shl 18 340 const val SUSPEND = 1 shl 19 341 const val COMPANION = 1 shl 20 342 const val CONST = 1 shl 21 343 const val DATA = 1 shl 22 344 const val VALUE = 1 shl 23 345 346 /** 347 * Modifiers considered significant to include signature files (and similarly 348 * to consider whether an override of a method is different from its super implementation 349 */ 350 private const val EQUIVALENCE_MASK = VISIBILITY_MASK or STATIC or ABSTRACT or 351 FINAL or TRANSIENT or VOLATILE or DEPRECATED or VARARG or 352 SEALED or FUN or INFIX or OPERATOR or SUSPEND or COMPANION 353 } 354 } 355