1 /*
2  * Copyright (C) 2017 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 interface MemberItem : Item {
20     /**
21      * The name of this method/field. Constructors have the same name as their containing class'
22      * simple name
23      */
namenull24     fun name(): String
25 
26     /** Returns the internal name of the method, as seen in bytecode */
27     fun internalName(): String = name()
28 
29     /** The containing class */
30     @MetalavaApi override fun containingClass(): ClassItem
31 
32     override fun containingPackage(): PackageItem = containingClass().containingPackage()
33 
34     override fun parent(): ClassItem? = containingClass()
35 
36     override val effectivelyDeprecated: Boolean
37         get() = originallyDeprecated || containingClass().effectivelyDeprecated
38 
39     /**
40      * Returns true if this member is effectively final based on modifiers: it's either final
41      * itself, or implied to be final because its containing class is final or sealed.
42      */
43     fun isEffectivelyFinal(): Boolean {
44         return modifiers.isFinal() ||
45             containingClass().modifiers.isFinal() ||
46             containingClass().modifiers.isSealed()
47     }
48 
49     /**
50      * Returns whether the item can be overridden outside the API surface, which is true is it is
51      * not final and its containing class can be extended.
52      */
canBeExternallyOverriddennull53     fun canBeExternallyOverridden(): Boolean {
54         return !modifiers.isFinal() && containingClass().isExtensible()
55     }
56 
57     /** True if this member was inherited from an ancestor class or interface. */
58     val inheritedFromAncestor
59         get() = inheritedFrom != null
60 
61     /**
62      * If this member is inherited from a super class (typically via [duplicate]) this field points
63      * to the original class it was inherited from
64      */
65     val inheritedFrom: ClassItem?
66 
67     /**
68      * Duplicates this member item.
69      *
70      * This is only used when comparing two [Codebase]s, in which case it is called to inherit a
71      * member from a super class/interface when it exists in the other [Codebase]. The resulting
72      * [MemberItem] is expected to behave as if it was part of the [targetContainingClass] but is
73      * otherwise identical to `this`, e.g. if [targetContainingClass] is [hidden] then so should the
74      * returned [MemberItem].
75      *
76      * The [MemberItem.inheritedFrom] property in the returned [MemberItem] is set to
77      * [containingClass] of this [MemberItem].
78      *
79      * @param targetContainingClass the [ClassItem] that will be used as
80      *   [MemberItem.containingClass]. Note, this may be from a different [Codebase] implementation
81      *   than the [MemberItem] so implementations must be careful to avoid an unconditional
82      *   downcast.
83      */
duplicatenull84     fun duplicate(targetContainingClass: ClassItem): MemberItem
85 }
86