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