1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.evaluation.value;
22
23import proguard.classfile.Clazz;
24
25/**
26 * This class represents a partially evaluated reference value.
27 *
28 * @author Eric Lafortune
29 */
30public abstract class ReferenceValue extends Category1Value
31{
32    /**
33     * Returns the type.
34     */
35    public abstract String getType();
36;
37
38    /**
39     * Returns the class that is referenced by the type.
40     */
41    public abstract Clazz getReferencedClass();
42
43
44    // Basic unary methods.
45
46    /**
47     * Returns whether the type is <code>null</code>.
48     */
49    public abstract int isNull();
50
51
52    /**
53     * Returns whether the type is an instance of the given type.
54     */
55    public abstract int instanceOf(String otherType, Clazz otherReferencedClass);
56
57
58    /**
59     * Returns a generalization of this ReferenceValue that may be null,
60     * depending on the flag.
61     */
62    public abstract ReferenceValue generalizeMayBeNull(boolean mayBeNull);
63
64
65    /**
66     * Returns the length of the array, assuming this type is an array.
67     */
68    public IntegerValue arrayLength(ValueFactory valueFactory)
69    {
70        return valueFactory.createIntegerValue();
71    }
72
73
74    /**
75     * Returns the value of the array at the given index, assuming this type
76     * is an integer array.
77     */
78    public IntegerValue integerArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
79    {
80        return valueFactory.createIntegerValue();
81    }
82
83
84    /**
85     * Returns the value of the array at the given index, assuming this type
86     * is an long array.
87     */
88    public LongValue longArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
89    {
90        return valueFactory.createLongValue();
91    }
92
93
94    /**
95     * Returns the value of the array at the given index, assuming this type
96     * is an float array.
97     */
98    public FloatValue floatArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
99    {
100        return valueFactory.createFloatValue();
101    }
102
103
104    /**
105     * Returns the value of the array at the given index, assuming this type
106     * is an double array.
107     */
108    public DoubleValue doubleArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
109    {
110        return valueFactory.createDoubleValue();
111    }
112
113
114    /**
115     * Returns the value of the array at the given index, assuming this type
116     * is a reference array.
117     */
118    public abstract ReferenceValue referenceArrayLoad(IntegerValue indexValue, ValueFactory valueFactory);
119
120
121    /**
122     * Stores the given value at the given index in the given array, assuming
123     * this type is an array.
124     */
125    public void arrayStore(IntegerValue indexValue, Value value)
126    {
127    }
128
129
130    // Basic binary methods.
131
132    /**
133     * Returns the generalization of this ReferenceValue and the given other
134     * ReferenceValue.
135     */
136    public abstract ReferenceValue generalize(ReferenceValue other);
137
138
139    /**
140     * Returns whether this ReferenceValue is equal to the given other
141     * ReferenceValue.
142     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
143     */
144    public abstract int equal(ReferenceValue other);
145
146
147    // Derived unary methods.
148
149    /**
150     * Returns whether this ReferenceValue is not <code>null</code>.
151     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
152     */
153    public final int isNotNull()
154    {
155        return -isNull();
156    }
157
158
159    // Derived binary methods.
160
161    /**
162     * Returns whether this ReferenceValue and the given ReferenceValue are different.
163     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
164     */
165    public final int notEqual(ReferenceValue other)
166    {
167        return -equal(other);
168    }
169
170
171    // Similar binary methods, but this time with typed reference arguments.
172
173    /**
174     * Returns the generalization of this ReferenceValue and the given other
175     * TypedReferenceValue.
176     */
177    public ReferenceValue generalize(TypedReferenceValue other)
178    {
179        return generalize((ReferenceValue)other);
180    }
181
182
183    /**
184     * Returns whether this ReferenceValue is equal to the given other
185     * TypedReferenceValue.
186     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
187     */
188    public int equal(TypedReferenceValue other)
189    {
190        return equal((ReferenceValue)other);
191    }
192
193
194    // Similar binary methods, but this time with identified reference
195    // arguments.
196
197    /**
198     * Returns the generalization of this ReferenceValue and the given other
199     * IdentifiedReferenceValue.
200     */
201    public ReferenceValue generalize(IdentifiedReferenceValue other)
202    {
203        return generalize((TypedReferenceValue)other);
204    }
205
206
207    /**
208     * Returns whether this ReferenceValue is equal to the given other
209     * IdentifiedReferenceValue.
210     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
211     */
212    public int equal(IdentifiedReferenceValue other)
213    {
214        return equal((TypedReferenceValue)other);
215    }
216
217
218    // Similar binary methods, but this time with array reference arguments.
219
220    /**
221     * Returns the generalization of this ReferenceValue and the given other
222     * ArrayReferenceValue.
223     */
224    public ReferenceValue generalize(ArrayReferenceValue other)
225    {
226        return generalize((TypedReferenceValue)other);
227    }
228
229
230    /**
231     * Returns whether this ReferenceValue is equal to the given other
232     * ArrayReferenceValue.
233     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
234     */
235    public int equal(ArrayReferenceValue other)
236    {
237        return equal((TypedReferenceValue)other);
238    }
239
240
241    // Similar binary methods, but this time with identified array reference
242    // arguments.
243
244    /**
245     * Returns the generalization of this ReferenceValue and the given other
246     * IdentifiedArrayReferenceValue.
247     */
248    public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
249    {
250        return generalize((ArrayReferenceValue)other);
251    }
252
253
254    /**
255     * Returns whether this ReferenceValue is equal to the given other
256     * IdentifiedArrayReferenceValue.
257     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
258     */
259    public int equal(IdentifiedArrayReferenceValue other)
260    {
261        return equal((ArrayReferenceValue)other);
262    }
263
264
265    // Similar binary methods, but this time with detailed array reference
266    // arguments.
267
268    /**
269     * Returns the generalization of this ReferenceValue and the given other
270     * DetailedArrayReferenceValue.
271     */
272    public ReferenceValue generalize(DetailedArrayReferenceValue other)
273    {
274        return generalize((IdentifiedArrayReferenceValue)other);
275    }
276
277
278    /**
279     * Returns whether this ReferenceValue is equal to the given other
280     * DetailedArrayReferenceValue.
281     * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
282     */
283    public int equal(DetailedArrayReferenceValue other)
284    {
285        return equal((IdentifiedArrayReferenceValue)other);
286    }
287
288
289    // Implementations for Value.
290
291    public final ReferenceValue referenceValue()
292    {
293        return this;
294    }
295
296    public final Value generalize(Value other)
297    {
298        return this.generalize(other.referenceValue());
299    }
300
301    public final int computationalType()
302    {
303        return TYPE_REFERENCE;
304    }
305}
306