• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2009 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.optimize.info;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.util.MethodLinker;
25 import proguard.evaluation.value.*;
26 
27 /**
28  * This class stores some optimization information that can be attached to
29  * a field.
30  *
31  * @author Eric Lafortune
32  */
33 public class FieldOptimizationInfo
34 {
35     private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory();
36 
37     private boolean        isWritten;
38     private boolean        isRead;
39     private boolean        canBeMadePrivate = true;
40     private ReferenceValue referencedClass;
41     private Value          value;
42 
43 
FieldOptimizationInfo(Clazz clazz, Field field)44     public FieldOptimizationInfo(Clazz clazz, Field field)
45     {
46         isWritten =
47         isRead    = (field.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0;
48         value     = initialValue(field.getDescriptor(clazz));
49     }
50 
51 
setWritten()52     public void setWritten()
53     {
54         isWritten = true;
55     }
56 
57 
isWritten()58     public boolean isWritten()
59     {
60         return isWritten;
61     }
62 
63 
setRead()64     public void setRead()
65     {
66         isRead = true;
67     }
68 
69 
isRead()70     public boolean isRead()
71     {
72         return isRead;
73     }
74 
75 
setCanNotBeMadePrivate()76     public void setCanNotBeMadePrivate()
77     {
78         canBeMadePrivate = false;
79     }
80 
81 
canBeMadePrivate()82     public boolean canBeMadePrivate()
83     {
84         return canBeMadePrivate;
85     }
86 
87 
generalizeReferencedClass(ReferenceValue referencedClass)88     public void generalizeReferencedClass(ReferenceValue referencedClass)
89     {
90         this.referencedClass = this.referencedClass != null ?
91             this.referencedClass.generalize(referencedClass) :
92             referencedClass;
93     }
94 
95 
getReferencedClass()96     public ReferenceValue getReferencedClass()
97     {
98         return referencedClass;
99     }
100 
101 
generalizeValue(Value value)102     public void generalizeValue(Value value)
103     {
104         this.value = this.value != null ?
105             this.value.generalize(value) :
106             value;
107     }
108 
109 
getValue()110     public Value getValue()
111     {
112         return value;
113     }
114 
115 
116     // Small utility methods.
117 
initialValue(String type)118     private Value initialValue(String type)
119     {
120         switch (type.charAt(0))
121         {
122             case ClassConstants.INTERNAL_TYPE_BOOLEAN:
123             case ClassConstants.INTERNAL_TYPE_BYTE:
124             case ClassConstants.INTERNAL_TYPE_CHAR:
125             case ClassConstants.INTERNAL_TYPE_SHORT:
126             case ClassConstants.INTERNAL_TYPE_INT:
127                 return VALUE_FACTORY.createIntegerValue(0);
128 
129             case ClassConstants.INTERNAL_TYPE_LONG:
130                 return VALUE_FACTORY.createLongValue(0L);
131 
132             case ClassConstants.INTERNAL_TYPE_FLOAT:
133                 return VALUE_FACTORY.createFloatValue(0.0f);
134 
135             case ClassConstants.INTERNAL_TYPE_DOUBLE:
136                 return VALUE_FACTORY.createDoubleValue(0.0);
137 
138             case ClassConstants.INTERNAL_TYPE_CLASS_START:
139             case ClassConstants.INTERNAL_TYPE_ARRAY:
140                 return VALUE_FACTORY.createReferenceValueNull();
141 
142             default:
143                 throw new IllegalArgumentException("Invalid type ["+type+"]");
144         }
145     }
146 
147 
setFieldOptimizationInfo(Clazz clazz, Field field)148     public static void setFieldOptimizationInfo(Clazz clazz, Field field)
149     {
150         MethodLinker.lastMember(field).setVisitorInfo(new FieldOptimizationInfo(clazz, field));
151     }
152 
153 
getFieldOptimizationInfo(Field field)154     public static FieldOptimizationInfo getFieldOptimizationInfo(Field field)
155     {
156         Object visitorInfo = MethodLinker.lastMember(field).getVisitorInfo();
157 
158         return visitorInfo instanceof FieldOptimizationInfo ?
159             (FieldOptimizationInfo)visitorInfo :
160             null;
161     }
162 }
163