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