Home | History | Annotate | Download | only in value
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) 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      */
     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      */
     73     public IntegerValue createIntegerValue()
     74     {
     75         return INTEGER_VALUE;
     76     }
     77 
     78     /**
     79      * Creates a new IntegerValue with a given particular value.
     80      */
     81     public IntegerValue createIntegerValue(int value)
     82     {
     83         return createIntegerValue();
     84     }
     85 
     86 
     87     /**
     88      * Creates a new LongValue with an undefined value.
     89      */
     90     public LongValue createLongValue()
     91     {
     92         return LONG_VALUE;
     93     }
     94 
     95     /**
     96      * Creates a new LongValue with a given particular value.
     97      */
     98     public LongValue createLongValue(long value)
     99     {
    100         return createLongValue();
    101     }
    102 
    103 
    104     /**
    105      * Creates a new FloatValue with an undefined value.
    106      */
    107     public FloatValue createFloatValue()
    108     {
    109         return FLOAT_VALUE;
    110     }
    111 
    112     /**
    113      * Creates a new FloatValue with a given particular value.
    114      */
    115     public FloatValue createFloatValue(float value)
    116     {
    117         return createFloatValue();
    118     }
    119 
    120 
    121     /**
    122      * Creates a new DoubleValue with an undefined value.
    123      */
    124     public DoubleValue createDoubleValue()
    125     {
    126         return DOUBLE_VALUE;
    127     }
    128 
    129     /**
    130      * Creates a new DoubleValue with a given particular value.
    131      */
    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      */
    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      */
    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      */
    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