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