1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2013 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
23/**
24 * This IntegerValue represents a particular integer value.
25 *
26 * @author Eric Lafortune
27 */
28final class ParticularIntegerValue extends SpecificIntegerValue
29{
30    private final int value;
31
32
33    /**
34     * Creates a new particular integer value.
35     */
36    public ParticularIntegerValue(int value)
37    {
38        this.value = value;
39    }
40
41
42    // Implementations for IntegerValue.
43
44    public int value()
45    {
46        return value;
47    }
48
49
50    // Implementations of unary methods of IntegerValue.
51
52    public IntegerValue negate()
53    {
54        return new ParticularIntegerValue(-value);
55    }
56
57    public IntegerValue convertToByte()
58    {
59        int byteValue = (byte)value;
60
61        return byteValue == value ?
62            this :
63            new ParticularIntegerValue(byteValue);
64    }
65
66    public IntegerValue convertToCharacter()
67    {
68        int charValue = (char)value;
69
70        return charValue == value ?
71            this :
72            new ParticularIntegerValue(charValue);
73    }
74
75    public IntegerValue convertToShort()
76    {
77        int shortValue = (short)value;
78
79        return shortValue == value ?
80            this :
81            new ParticularIntegerValue(shortValue);
82    }
83
84    public LongValue convertToLong()
85    {
86        return new ParticularLongValue((long)value);
87    }
88
89    public FloatValue convertToFloat()
90    {
91        return new ParticularFloatValue((float)value);
92    }
93
94    public DoubleValue convertToDouble()
95    {
96        return new ParticularDoubleValue((double)value);
97    }
98
99
100    // Implementations of binary methods of IntegerValue.
101
102    public IntegerValue generalize(IntegerValue other)
103    {
104        return other.generalize(this);
105    }
106
107    public IntegerValue add(IntegerValue other)
108    {
109        return other.add(this);
110    }
111
112    public IntegerValue subtract(IntegerValue other)
113    {
114        return other.subtractFrom(this);
115    }
116
117    public IntegerValue subtractFrom(IntegerValue other)
118    {
119        return other.subtract(this);
120    }
121
122    public IntegerValue multiply(IntegerValue other)
123    {
124        return other.multiply(this);
125    }
126
127    public IntegerValue divide(IntegerValue other)
128    throws ArithmeticException
129    {
130        return other.divideOf(this);
131    }
132
133    public IntegerValue divideOf(IntegerValue other)
134    throws ArithmeticException
135    {
136        return other.divide(this);
137    }
138
139    public IntegerValue remainder(IntegerValue other)
140    throws ArithmeticException
141    {
142        return other.remainderOf(this);
143    }
144
145    public IntegerValue remainderOf(IntegerValue other)
146    throws ArithmeticException
147    {
148        return other.remainder(this);
149    }
150
151    public IntegerValue shiftLeft(IntegerValue other)
152    {
153        return other.shiftLeftOf(this);
154    }
155
156    public IntegerValue shiftLeftOf(IntegerValue other)
157    {
158        return other.shiftLeft(this);
159    }
160
161    public IntegerValue shiftRight(IntegerValue other)
162    {
163        return other.shiftRightOf(this);
164    }
165
166    public IntegerValue shiftRightOf(IntegerValue other)
167    {
168        return other.shiftRight(this);
169    }
170
171    public IntegerValue unsignedShiftRight(IntegerValue other)
172    {
173        return other.unsignedShiftRightOf(this);
174    }
175
176    public IntegerValue unsignedShiftRightOf(IntegerValue other)
177    {
178        return other.unsignedShiftRight(this);
179    }
180
181    public LongValue shiftLeftOf(LongValue other)
182    {
183        return other.shiftLeft(this);
184    }
185
186    public LongValue shiftRightOf(LongValue other)
187    {
188        return other.shiftRight(this);
189    }
190
191    public LongValue unsignedShiftRightOf(LongValue other)
192    {
193        return other.unsignedShiftRight(this);
194    }
195
196    public IntegerValue and(IntegerValue other)
197    {
198        return other.and(this);
199    }
200
201    public IntegerValue or(IntegerValue other)
202    {
203        return other.or(this);
204    }
205
206    public IntegerValue xor(IntegerValue other)
207    {
208        return other.xor(this);
209    }
210
211    public int equal(IntegerValue other)
212    {
213        return other.equal(this);
214    }
215
216    public int lessThan(IntegerValue other)
217    {
218        return other.greaterThan(this);
219    }
220
221    public int lessThanOrEqual(IntegerValue other)
222    {
223        return other.greaterThanOrEqual(this);
224    }
225
226
227    // Implementations of binary IntegerValue methods with ParticularIntegerValue
228    // arguments.
229
230    public IntegerValue generalize(ParticularIntegerValue other)
231    {
232        return generalize((SpecificIntegerValue)other);
233    }
234
235    public IntegerValue add(ParticularIntegerValue other)
236    {
237        return new ParticularIntegerValue(this.value + other.value);
238    }
239
240    public IntegerValue subtract(ParticularIntegerValue other)
241    {
242        return new ParticularIntegerValue(this.value - other.value);
243    }
244
245    public IntegerValue subtractFrom(ParticularIntegerValue other)
246    {
247        return new ParticularIntegerValue(other.value - this.value);
248    }
249
250    public IntegerValue multiply(ParticularIntegerValue other)
251    {
252        return new ParticularIntegerValue(this.value * other.value);
253    }
254
255    public IntegerValue divide(ParticularIntegerValue other)
256    throws ArithmeticException
257    {
258        return new ParticularIntegerValue(this.value / other.value);
259    }
260
261    public IntegerValue divideOf(ParticularIntegerValue other)
262    throws ArithmeticException
263    {
264        return new ParticularIntegerValue(other.value / this.value);
265    }
266
267    public IntegerValue remainder(ParticularIntegerValue other)
268    throws ArithmeticException
269    {
270        return new ParticularIntegerValue(this.value % other.value);
271    }
272
273    public IntegerValue remainderOf(ParticularIntegerValue other)
274    throws ArithmeticException
275    {
276        return new ParticularIntegerValue(other.value % this.value);
277    }
278
279    public IntegerValue shiftLeft(ParticularIntegerValue other)
280    {
281        return new ParticularIntegerValue(this.value << other.value);
282    }
283
284    public IntegerValue shiftRight(ParticularIntegerValue other)
285    {
286        return new ParticularIntegerValue(this.value >> other.value);
287    }
288
289    public IntegerValue unsignedShiftRight(ParticularIntegerValue other)
290    {
291        return new ParticularIntegerValue(this.value >>> other.value);
292    }
293
294    public IntegerValue shiftLeftOf(ParticularIntegerValue other)
295    {
296        return new ParticularIntegerValue(other.value << this.value);
297    }
298
299    public IntegerValue shiftRightOf(ParticularIntegerValue other)
300    {
301        return new ParticularIntegerValue(other.value >> this.value);
302    }
303
304    public IntegerValue unsignedShiftRightOf(ParticularIntegerValue other)
305    {
306        return new ParticularIntegerValue(other.value >>> this.value);
307    }
308
309    public LongValue shiftLeftOf(ParticularLongValue other)
310    {
311        return new ParticularLongValue(other.value() << this.value);
312    }
313
314    public LongValue shiftRightOf(ParticularLongValue other)
315    {
316        return new ParticularLongValue(other.value() >> this.value);
317    }
318
319    public LongValue unsignedShiftRightOf(ParticularLongValue other)
320    {
321        return new ParticularLongValue(other.value() >>> this.value);
322    }
323
324    public IntegerValue and(ParticularIntegerValue other)
325    {
326        return new ParticularIntegerValue(this.value & other.value);
327    }
328
329    public IntegerValue or(ParticularIntegerValue other)
330    {
331        return new ParticularIntegerValue(this.value | other.value);
332    }
333
334    public IntegerValue xor(ParticularIntegerValue other)
335    {
336        return new ParticularIntegerValue(this.value ^ other.value);
337    }
338
339    public int equal(ParticularIntegerValue other)
340    {
341        return this.value == other.value ? ALWAYS : NEVER;
342    }
343
344    public int lessThan(ParticularIntegerValue other)
345    {
346        return this.value <  other.value ? ALWAYS : NEVER;
347    }
348
349    public int lessThanOrEqual(ParticularIntegerValue other)
350    {
351        return this.value <= other.value ? ALWAYS : NEVER;
352    }
353
354
355    // Implementations for Value.
356
357    public boolean isParticular()
358    {
359        return true;
360    }
361
362
363    // Implementations for Object.
364
365    public boolean equals(Object object)
366    {
367        return super.equals(object) &&
368               this.value == ((ParticularIntegerValue)object).value;
369    }
370
371
372    public int hashCode()
373    {
374        return this.getClass().hashCode() ^
375               value;
376    }
377
378
379    public String toString()
380    {
381        return Integer.toString(value);
382    }
383}