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 */ 21package proguard.optimize.info; 22 23import proguard.classfile.*; 24import proguard.classfile.util.MethodLinker; 25import 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 */ 33public 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 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 52 public void setWritten() 53 { 54 isWritten = true; 55 } 56 57 58 public boolean isWritten() 59 { 60 return isWritten; 61 } 62 63 64 public void setRead() 65 { 66 isRead = true; 67 } 68 69 70 public boolean isRead() 71 { 72 return isRead; 73 } 74 75 76 public void setCanNotBeMadePrivate() 77 { 78 canBeMadePrivate = false; 79 } 80 81 82 public boolean canBeMadePrivate() 83 { 84 return canBeMadePrivate; 85 } 86 87 88 public void generalizeReferencedClass(ReferenceValue referencedClass) 89 { 90 this.referencedClass = this.referencedClass != null ? 91 this.referencedClass.generalize(referencedClass) : 92 referencedClass; 93 } 94 95 96 public ReferenceValue getReferencedClass() 97 { 98 return referencedClass; 99 } 100 101 102 public void generalizeValue(Value value) 103 { 104 this.value = this.value != null ? 105 this.value.generalize(value) : 106 value; 107 } 108 109 110 public Value getValue() 111 { 112 return value; 113 } 114 115 116 // Small utility methods. 117 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 148 public static void setFieldOptimizationInfo(Clazz clazz, Field field) 149 { 150 MethodLinker.lastMember(field).setVisitorInfo(new FieldOptimizationInfo(clazz, field)); 151 } 152 153 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