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.code;
18
19import com.android.dx.rop.cst.CstString;
20
21/**
22 * A local variable item: either a name or a signature or both.
23 */
24public class LocalItem implements Comparable<LocalItem> {
25    /** {@code null-ok;} local variable name */
26    private final CstString name;
27
28    /** {@code null-ok;} local variable signature */
29    private final CstString signature;
30
31    /**
32     * Make a new item. If both name and signature are null, null is returned.
33     *
34     * TODO: intern these
35     *
36     * @param name {@code null-ok;} local variable name
37     * @param signature {@code null-ok;} local variable signature
38     * @return {@code non-null;} appropriate instance.
39     */
40    public static LocalItem make(CstString name, CstString signature) {
41        if (name == null && signature == null) {
42            return null;
43        }
44
45        return new LocalItem (name, signature);
46    }
47
48    /**
49     * Constructs instance.
50     *
51     * @param name {@code null-ok;} local variable name
52     * @param signature {@code null-ok;} local variable signature
53     */
54    private LocalItem(CstString name, CstString signature) {
55        this.name = name;
56        this.signature = signature;
57    }
58
59    /** {@inheritDoc} */
60    @Override
61    public boolean equals(Object other) {
62        if (!(other instanceof LocalItem)) {
63            return false;
64        }
65
66        LocalItem local = (LocalItem) other;
67
68        return 0 == compareTo(local);
69    }
70
71    /**
72     * Compares two strings like String.compareTo(), excepts treats a null
73     * as the least-possible string value.
74     *
75     * @return negative integer, zero, or positive integer in accordance
76     * with Comparable.compareTo()
77     */
78    private static int compareHandlesNulls(CstString a, CstString b) {
79        if (a == b) {
80            return 0;
81        } else if (a == null) {
82            return -1;
83        } else if (b == null) {
84            return 1;
85        } else {
86            return a.compareTo(b);
87        }
88    }
89
90    /** {@inheritDoc} */
91    @Override
92    public int compareTo(LocalItem local) {
93        int ret;
94
95        ret = compareHandlesNulls(name, local.name);
96
97        if (ret != 0) {
98            return ret;
99        }
100
101        ret = compareHandlesNulls(signature, local.signature);
102
103        return ret;
104    }
105
106
107    /** {@inheritDoc} */
108    @Override
109    public int hashCode() {
110        return (name == null ? 0 : name.hashCode()) * 31
111                + (signature == null ? 0 : signature.hashCode());
112    }
113
114    /** {@inheritDoc} */
115    @Override
116    public String toString() {
117        if (name != null && signature == null) {
118            return name.toQuoted();
119        } else if (name == null && signature == null) {
120            return "";
121        }
122
123        return "[" + (name == null ? "" : name.toQuoted())
124                + "|" + (signature == null ? "" : signature.toQuoted());
125    }
126
127    /**
128     * Gets name.
129     *
130     * @return {@code null-ok;} name
131     */
132    public CstString getName() {
133        return name;
134    }
135
136    /**
137     * Gets signature.
138     *
139     * @return {@code null-ok;} signature
140     */
141    public CstString getSignature() {
142        return signature;
143    }
144}
145