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.ClassConstants;
24
25/**
26 * This class represents a partially evaluated long value.
27 *
28 * @author Eric Lafortune
29 */
30public abstract class LongValue extends Category2Value
31{
32    /**
33     * Returns the specific long value, if applicable.
34     */
35    public long value()
36    {
37        return 0;
38    }
39
40
41    // Basic unary methods.
42
43    /**
44     * Returns the negated value of this LongValue.
45     */
46    public abstract LongValue negate();
47
48
49    /**
50     * Converts this LongValue to an IntegerValue.
51     */
52    public abstract IntegerValue convertToInteger();
53
54    /**
55     * Converts this LongValue to a FloatValue.
56     */
57    public abstract FloatValue convertToFloat();
58
59    /**
60     * Converts this LongValue to a DoubleValue.
61     */
62    public abstract DoubleValue convertToDouble();
63
64
65    // Basic binary methods.
66
67    /**
68     * Returns the generalization of this LongValue and the given other
69     * LongValue.
70     */
71    public LongValue generalize(LongValue other)
72    {
73        return other.generalize(this);
74    }
75
76    /**
77     * Returns the sum of this LongValue and the given LongValue.
78     */
79    public LongValue add(LongValue other)
80    {
81        return other.add(this);
82    }
83
84    /**
85     * Returns the difference of this LongValue and the given LongValue.
86     */
87    public LongValue subtract(LongValue other)
88    {
89        return other.subtractFrom(this);
90    }
91
92    /**
93     * Returns the difference of the given LongValue and this LongValue.
94     */
95    public LongValue subtractFrom(LongValue other)
96    {
97        return other.subtract(this);
98    }
99
100    /**
101     * Returns the product of this LongValue and the given LongValue.
102     */
103    public LongValue multiply(LongValue other)
104    throws ArithmeticException
105    {
106        return other.multiply(this);
107    }
108
109    /**
110     * Returns the quotient of this LongValue and the given LongValue.
111     */
112    public LongValue divide(LongValue other)
113    throws ArithmeticException
114    {
115        return other.divideOf(this);
116    }
117
118    /**
119     * Returns the quotient of the given LongValue and this LongValue.
120     */
121    public LongValue divideOf(LongValue other)
122    throws ArithmeticException
123    {
124        return other.divide(this);
125    }
126
127    /**
128     * Returns the remainder of this LongValue divided by the given
129     * LongValue.
130     */
131    public LongValue remainder(LongValue other)
132    throws ArithmeticException
133    {
134        return other.remainderOf(this);
135    }
136
137    /**
138     * Returns the remainder of the given LongValue divided by this
139     * LongValue.
140     */
141    public LongValue remainderOf(LongValue other)
142    throws ArithmeticException
143    {
144        return other.remainder(this);
145    }
146
147    /**
148     * Returns this LongValue, shifted left by the given IntegerValue.
149     */
150    public LongValue shiftLeft(IntegerValue other)
151    {
152        return other.shiftLeftOf(this);
153    }
154
155    /**
156     * Returns this LongValue, shifted right by the given IntegerValue.
157     */
158    public LongValue shiftRight(IntegerValue other)
159    {
160        return other.shiftRightOf(this);
161    }
162
163    /**
164     * Returns this unsigned LongValue, shifted left by the given
165     * IntegerValue.
166     */
167    public LongValue unsignedShiftRight(IntegerValue other)
168    {
169        return other.unsignedShiftRightOf(this);
170    }
171
172    /**
173     * Returns the logical <i>and</i> of this LongValue and the given
174     * LongValue.
175     */
176    public LongValue and(LongValue other)
177    {
178        return other.and(this);
179    }
180
181    /**
182     * Returns the logical <i>or</i> of this LongValue and the given
183     * LongValue.
184     */
185    public LongValue or(LongValue other)
186    {
187        return other.or(this);
188    }
189
190    /**
191     * Returns the logical <i>xor</i> of this LongValue and the given
192     * LongValue.
193     */
194    public LongValue xor(LongValue other)
195    {
196        return other.xor(this);
197    }
198
199    /**
200     * Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
201     * less than, equal to, or greater than the given LongValue, respectively.
202     */
203    public IntegerValue compare(LongValue other)
204    {
205        return other.compareReverse(this);
206    }
207
208
209    // Derived binary methods.
210
211    /**
212     * Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
213     * less than, equal to, or greater than the given LongValue, respectively.
214     */
215    public final IntegerValue compareReverse(LongValue other)
216    {
217        return compare(other).negate();
218    }
219
220
221    // Similar binary methods, but this time with more specific arguments.
222
223    /**
224     * Returns the generalization of this LongValue and the given other
225     * SpecificLongValue.
226     */
227    public LongValue generalize(SpecificLongValue other)
228    {
229        return this;
230    }
231
232
233    /**
234     * Returns the sum of this LongValue and the given SpecificLongValue.
235     */
236    public LongValue add(SpecificLongValue other)
237    {
238        return this;
239    }
240
241    /**
242     * Returns the difference of this LongValue and the given SpecificLongValue.
243     */
244    public LongValue subtract(SpecificLongValue other)
245    {
246        return this;
247    }
248
249    /**
250     * Returns the difference of the given SpecificLongValue and this LongValue.
251     */
252    public LongValue subtractFrom(SpecificLongValue other)
253    {
254        return this;
255    }
256
257    /**
258     * Returns the product of this LongValue and the given SpecificLongValue.
259     */
260    public LongValue multiply(SpecificLongValue other)
261    {
262        return this;
263    }
264
265    /**
266     * Returns the quotient of this LongValue and the given
267     * SpecificLongValue.
268     */
269    public LongValue divide(SpecificLongValue other)
270    {
271        return this;
272    }
273
274    /**
275     * Returns the quotient of the given SpecificLongValue and this
276     * LongValue.
277     */
278    public LongValue divideOf(SpecificLongValue other)
279    {
280        return this;
281    }
282
283    /**
284     * Returns the remainder of this LongValue divided by the given
285     * SpecificLongValue.
286     */
287    public LongValue remainder(SpecificLongValue other)
288    {
289        return this;
290    }
291
292    /**
293     * Returns the remainder of the given SpecificLongValue divided by this
294     * LongValue.
295     */
296    public LongValue remainderOf(SpecificLongValue other)
297    {
298        return this;
299    }
300
301    /**
302     * Returns this LongValue, shifted left by the given SpecificLongValue.
303     */
304    public LongValue shiftLeft(SpecificLongValue other)
305    {
306        return this;
307    }
308
309    /**
310     * Returns this LongValue, shifted right by the given SpecificLongValue.
311     */
312    public LongValue shiftRight(SpecificLongValue other)
313    {
314        return this;
315    }
316
317    /**
318     * Returns this unsigned LongValue, shifted right by the given
319     * SpecificLongValue.
320     */
321    public LongValue unsignedShiftRight(SpecificLongValue other)
322    {
323        return this;
324    }
325
326    /**
327     * Returns the logical <i>and</i> of this LongValue and the given
328     * SpecificLongValue.
329     */
330    public LongValue and(SpecificLongValue other)
331    {
332        return this;
333    }
334
335    /**
336     * Returns the logical <i>or</i> of this LongValue and the given
337     * SpecificLongValue.
338     */
339    public LongValue or(SpecificLongValue other)
340    {
341        return this;
342    }
343
344    /**
345     * Returns the logical <i>xor</i> of this LongValue and the given
346     * SpecificLongValue.
347     */
348    public LongValue xor(SpecificLongValue other)
349    {
350        return this;
351    }
352
353    /**
354     * Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
355     * less than, equal to, or greater than the given SpecificLongValue,
356     * respectively.
357     */
358    public IntegerValue compare(SpecificLongValue other)
359    {
360        return new ComparisonValue(this, other);
361    }
362
363
364    // Derived binary methods.
365
366    /**
367     * Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
368     * less than, equal to, or greater than the given SpecificLongValue,
369     * respectively.
370     */
371    public final IntegerValue compareReverse(SpecificLongValue other)
372    {
373        return compare(other).negate();
374    }
375
376
377    // Similar binary methods, but this time with particular arguments.
378
379    /**
380     * Returns the generalization of this LongValue and the given other
381     * ParticularLongValue.
382     */
383    public LongValue generalize(ParticularLongValue other)
384    {
385        return generalize((SpecificLongValue)other);
386    }
387
388
389    /**
390     * Returns the sum of this LongValue and the given ParticularLongValue.
391     */
392    public LongValue add(ParticularLongValue other)
393    {
394        return add((SpecificLongValue)other);
395    }
396
397    /**
398     * Returns the difference of this LongValue and the given ParticularLongValue.
399     */
400    public LongValue subtract(ParticularLongValue other)
401    {
402        return subtract((SpecificLongValue)other);
403    }
404
405    /**
406     * Returns the difference of the given ParticularLongValue and this LongValue.
407     */
408    public LongValue subtractFrom(ParticularLongValue other)
409    {
410        return subtractFrom((SpecificLongValue)other);
411    }
412
413    /**
414     * Returns the product of this LongValue and the given ParticularLongValue.
415     */
416    public LongValue multiply(ParticularLongValue other)
417    {
418        return multiply((SpecificLongValue)other);
419    }
420
421    /**
422     * Returns the quotient of this LongValue and the given
423     * ParticularLongValue.
424     */
425    public LongValue divide(ParticularLongValue other)
426    {
427        return divide((SpecificLongValue)other);
428    }
429
430    /**
431     * Returns the quotient of the given ParticularLongValue and this
432     * LongValue.
433     */
434    public LongValue divideOf(ParticularLongValue other)
435    {
436        return divideOf((SpecificLongValue)other);
437    }
438
439    /**
440     * Returns the remainder of this LongValue divided by the given
441     * ParticularLongValue.
442     */
443    public LongValue remainder(ParticularLongValue other)
444    {
445        return remainder((SpecificLongValue)other);
446    }
447
448    /**
449     * Returns the remainder of the given ParticularLongValue divided by this
450     * LongValue.
451     */
452    public LongValue remainderOf(ParticularLongValue other)
453    {
454        return remainderOf((SpecificLongValue)other);
455    }
456
457    /**
458     * Returns this LongValue, shifted left by the given ParticularIntegerValue.
459     */
460    public LongValue shiftLeft(ParticularIntegerValue other)
461    {
462        return shiftLeft((SpecificIntegerValue)other);
463    }
464
465    /**
466     * Returns this LongValue, shifted right by the given ParticularIntegerValue.
467     */
468    public LongValue shiftRight(ParticularIntegerValue other)
469    {
470        return shiftRight((SpecificIntegerValue)other);
471    }
472
473    /**
474     * Returns this unsigned LongValue, shifted right by the given
475     * ParticularIntegerValue.
476     */
477    public LongValue unsignedShiftRight(ParticularIntegerValue other)
478    {
479        return unsignedShiftRight((SpecificIntegerValue)other);
480    }
481
482    /**
483     * Returns the logical <i>and</i> of this LongValue and the given
484     * ParticularLongValue.
485     */
486    public LongValue and(ParticularLongValue other)
487    {
488        return and((SpecificLongValue)other);
489    }
490
491    /**
492     * Returns the logical <i>or</i> of this LongValue and the given
493     * ParticularLongValue.
494     */
495    public LongValue or(ParticularLongValue other)
496    {
497        return or((SpecificLongValue)other);
498    }
499
500    /**
501     * Returns the logical <i>xor</i> of this LongValue and the given
502     * ParticularLongValue.
503     */
504    public LongValue xor(ParticularLongValue other)
505    {
506        return xor((SpecificLongValue)other);
507    }
508
509    /**
510     * Returns an IntegerValue with value -1, 0, or 1, if this LongValue is
511     * less than, equal to, or greater than the given ParticularLongValue,
512     * respectively.
513     */
514    public IntegerValue compare(ParticularLongValue other)
515    {
516        return compare((SpecificLongValue)other);
517    }
518
519
520    // Derived binary methods.
521
522    /**
523     * Returns an IntegerValue with value 1, 0, or -1, if this LongValue is
524     * less than, equal to, or greater than the given ParticularLongValue,
525     * respectively.
526     */
527    public final IntegerValue compareReverse(ParticularLongValue other)
528    {
529        return compare(other).negate();
530    }
531
532
533    // Implementations for Value.
534
535    public final LongValue longValue()
536    {
537        return this;
538    }
539
540    public final Value generalize(Value other)
541    {
542        return this.generalize(other.longValue());
543    }
544
545    public final int computationalType()
546    {
547        return TYPE_LONG;
548    }
549
550    public final String internalType()
551    {
552        return String.valueOf(ClassConstants.TYPE_INT);
553    }
554}
555