• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import proguard.classfile.*;
24 import proguard.classfile.util.ClassUtil;
25 
26 /**
27  * This class provides methods to create and reuse Value objects.
28  *
29  * @author Eric Lafortune
30  */
31 public class ValueFactory
32 {
33     // Shared copies of Value objects, to avoid creating a lot of objects.
34     static final IntegerValue INTEGER_VALUE = new UnknownIntegerValue();
35     static final LongValue    LONG_VALUE    = new UnknownLongValue();
36     static final FloatValue   FLOAT_VALUE   = new UnknownFloatValue();
37     static final DoubleValue  DOUBLE_VALUE  = new UnknownDoubleValue();
38 
39     static final ReferenceValue REFERENCE_VALUE_NULL                        = new TypedReferenceValue(null, null, true);
40     static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL = new TypedReferenceValue(ClassConstants.NAME_JAVA_LANG_OBJECT, null, true);
41     static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL   = new TypedReferenceValue(ClassConstants.NAME_JAVA_LANG_OBJECT, null, false);
42 
43 
44     /**
45      * Creates a new Value of the given type.
46      * The type must be a fully specified internal type for primitives, classes,
47      * or arrays.
48      */
createValue(String type, Clazz referencedClass, boolean mayBeNull)49     public Value createValue(String type, Clazz referencedClass, boolean mayBeNull)
50     {
51         switch (type.charAt(0))
52         {
53             case ClassConstants.TYPE_VOID:    return null;
54             case ClassConstants.TYPE_BOOLEAN:
55             case ClassConstants.TYPE_BYTE:
56             case ClassConstants.TYPE_CHAR:
57             case ClassConstants.TYPE_SHORT:
58             case ClassConstants.TYPE_INT:     return createIntegerValue();
59             case ClassConstants.TYPE_LONG:    return createLongValue();
60             case ClassConstants.TYPE_FLOAT:   return createFloatValue();
61             case ClassConstants.TYPE_DOUBLE:  return createDoubleValue();
62             default:                          return createReferenceValue(ClassUtil.isInternalArrayType(type) ?
63                                                                               type :
64                                                                               ClassUtil.internalClassNameFromClassType(type),
65                                                                           referencedClass,
66                                                                           mayBeNull);
67         }
68     }
69 
70     /**
71      * Creates a new IntegerValue with an undefined value.
72      */
createIntegerValue()73     public IntegerValue createIntegerValue()
74     {
75         return INTEGER_VALUE;
76     }
77 
78     /**
79      * Creates a new IntegerValue with a given particular value.
80      */
createIntegerValue(int value)81     public IntegerValue createIntegerValue(int value)
82     {
83         return createIntegerValue();
84     }
85 
86 
87     /**
88      * Creates a new LongValue with an undefined value.
89      */
createLongValue()90     public LongValue createLongValue()
91     {
92         return LONG_VALUE;
93     }
94 
95     /**
96      * Creates a new LongValue with a given particular value.
97      */
createLongValue(long value)98     public LongValue createLongValue(long value)
99     {
100         return createLongValue();
101     }
102 
103 
104     /**
105      * Creates a new FloatValue with an undefined value.
106      */
createFloatValue()107     public FloatValue createFloatValue()
108     {
109         return FLOAT_VALUE;
110     }
111 
112     /**
113      * Creates a new FloatValue with a given particular value.
114      */
createFloatValue(float value)115     public FloatValue createFloatValue(float value)
116     {
117         return createFloatValue();
118     }
119 
120 
121     /**
122      * Creates a new DoubleValue with an undefined value.
123      */
createDoubleValue()124     public DoubleValue createDoubleValue()
125     {
126         return DOUBLE_VALUE;
127     }
128 
129     /**
130      * Creates a new DoubleValue with a given particular value.
131      */
createDoubleValue(double value)132     public DoubleValue createDoubleValue(double value)
133     {
134         return createDoubleValue();
135     }
136 
137 
138     /**
139      * Creates a new ReferenceValue that represents <code>null</code>.
140      */
createReferenceValueNull()141     public ReferenceValue createReferenceValueNull()
142     {
143         return REFERENCE_VALUE_NULL;
144     }
145 
146 
147     /**
148      * Creates a new ReferenceValue of the given type. The type must be an
149      * internal class name or an array type. If the type is <code>null</code>,
150      * the ReferenceValue represents <code>null</code>.
151      */
createReferenceValue(String type, Clazz referencedClass, boolean mayBeNull)152     public ReferenceValue createReferenceValue(String  type,
153                                                Clazz   referencedClass,
154                                                boolean mayBeNull)
155     {
156         return type == null                                       ? REFERENCE_VALUE_NULL                                 :
157                !type.equals(ClassConstants.NAME_JAVA_LANG_OBJECT) ? new TypedReferenceValue(type, referencedClass, mayBeNull) :
158                mayBeNull                                          ? REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL          :
159                                                                     REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL;
160     }
161 
162 
163     /**
164      * Creates a new ReferenceValue for arrays of the given type and length.
165      * The type must be a fully specified internal type for primitives, classes,
166      * or arrays.
167      */
createArrayReferenceValue(String type, Clazz referencedClass, IntegerValue arrayLength)168     public ReferenceValue createArrayReferenceValue(String       type,
169                                                     Clazz        referencedClass,
170                                                     IntegerValue arrayLength)
171     {
172         return createReferenceValue(ClassConstants.TYPE_ARRAY + type,
173                                     referencedClass,
174                                     false);
175     }
176 }
177