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
17package com.android.dx.rop.cst;
18
19/**
20 * Constants of type {@code CONSTANT_*ref_info}.
21 */
22public 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     */
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
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
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
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
90    public final String toString() {
91        return typeName() + '{' + toHuman() + '}';
92    }
93
94    /** {@inheritDoc} */
95    @Override
96    public final boolean isCategory2() {
97        return false;
98    }
99
100    /** {@inheritDoc} */
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     */
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     */
119    public final CstNat getNat() {
120        return nat;
121    }
122}
123