1 /*
2  * Copyright (C) 2007 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.dexgen.rop.cst;
18 
19 /**
20  * Constants of type {@code CONSTANT_*ref_info}.
21  */
22 public abstract class CstMemberRef extends TypedConstant {
23     /** {@code non-null;} the type of the defining class */
24     private final CstType definingClass;
25 
26     /** {@code non-null;} the name-and-type */
27     private final CstNat nat;
28 
29     /**
30      * Constructs an instance.
31      *
32      * @param definingClass {@code non-null;} the type of the defining class
33      * @param nat {@code non-null;} the name-and-type
34      */
CstMemberRef(CstType definingClass, CstNat nat)35     /*package*/ CstMemberRef(CstType definingClass, CstNat nat) {
36         if (definingClass == null) {
37             throw new NullPointerException("definingClass == null");
38         }
39 
40         if (nat == null) {
41             throw new NullPointerException("nat == null");
42         }
43 
44         this.definingClass = definingClass;
45         this.nat = nat;
46     }
47 
48     /** {@inheritDoc} */
49     @Override
equals(Object other)50     public final boolean equals(Object other) {
51         if ((other == null) || (getClass() != other.getClass())) {
52             return false;
53         }
54 
55         CstMemberRef otherRef = (CstMemberRef) other;
56         return definingClass.equals(otherRef.definingClass) &&
57             nat.equals(otherRef.nat);
58     }
59 
60     /** {@inheritDoc} */
61     @Override
hashCode()62     public final int hashCode() {
63         return (definingClass.hashCode() * 31) ^ nat.hashCode();
64     }
65 
66     /**
67      * {@inheritDoc}
68      *
69      * <p><b>Note:</b> This implementation just compares the defining
70      * class and name, and it is up to subclasses to compare the rest
71      * after calling {@code super.compareTo0()}.</p>
72      */
73     @Override
compareTo0(Constant other)74     protected int compareTo0(Constant other) {
75         CstMemberRef otherMember = (CstMemberRef) other;
76         int cmp = definingClass.compareTo(otherMember.definingClass);
77 
78         if (cmp != 0) {
79             return cmp;
80         }
81 
82         CstUtf8 thisName = nat.getName();
83         CstUtf8 otherName = otherMember.nat.getName();
84 
85         return thisName.compareTo(otherName);
86     }
87 
88     /** {@inheritDoc} */
89     @Override
toString()90     public final String toString() {
91         return typeName() + '{' + toHuman() + '}';
92     }
93 
94     /** {@inheritDoc} */
95     @Override
isCategory2()96     public final boolean isCategory2() {
97         return false;
98     }
99 
100     /** {@inheritDoc} */
toHuman()101     public final String toHuman() {
102         return definingClass.toHuman() + '.' + nat.toHuman();
103     }
104 
105     /**
106      * Gets the type of the defining class.
107      *
108      * @return {@code non-null;} the type of defining class
109      */
getDefiningClass()110     public final CstType getDefiningClass() {
111         return definingClass;
112     }
113 
114     /**
115      * Gets the defining name-and-type.
116      *
117      * @return {@code non-null;} the name-and-type
118      */
getNat()119     public final CstNat getNat() {
120         return nat;
121     }
122 }
123