1 package spoon.reflect.eval; 2 3 import java.lang.reflect.Method ; 4 import java.util.Map ; 5 import java.util.TreeMap ; 6 7 import spoon.reflect.declaration.CtField; 8 import spoon.reflect.declaration.CtSimpleType; 9 import spoon.reflect.declaration.ModifierKind; 10 import spoon.reflect.reference.CtFieldReference; 11 import spoon.reflect.reference.CtTypeReference; 12 import spoon.reflect.reference.CtVariableReference; 13 import spoon.support.util.RtHelper; 14 15 19 public class SymbolicInstance<T> { 20 21 static long id = 0; 22 23 26 private static long getNextId() { 27 return id++; 28 } 29 30 33 public static void resetIds() { 34 id = 0; 35 } 36 37 private String symbolName = null; 38 39 48 public static String getSymbolId(CtTypeReference concreteType, String name) { 49 CtTypeReference<?> t = concreteType; 50 if (name != null) { 51 return t.getQualifiedName() + "$" + name; 52 } else { 53 return t.getQualifiedName(); 54 } 55 } 56 57 60 public String getId() { 61 return getSymbolId(concreteType, symbolName); 62 } 63 64 67 @Override 68 public boolean equals(Object obj) { 69 SymbolicInstance i = (SymbolicInstance) obj; 70 boolean b = concreteType.equals(i.concreteType) 71 && fields.equals(i.fields) && isExternal == i.isExternal; 72 return b; 73 } 74 75 85 public SymbolicInstance(SymbolicEvaluator evaluator, 86 CtTypeReference<T> concreteType, boolean isType) { 87 this.concreteType = concreteType; 88 CtSimpleType<T> type = concreteType.getDeclaration(); 89 if (!concreteType.isPrimitif() && type != null) { 90 for (CtField<?> f : type.getFields()) { 91 if (isType && f.hasModifier(ModifierKind.STATIC)) { 92 SymbolicInstance r = evaluator.evaluate(f 93 .getDefaultExpression()); 94 fields.put(f.getReference(), r == null ? null : r.getId()); 95 } 96 if (!isType && !f.hasModifier(ModifierKind.STATIC)) { 97 SymbolicInstance r = evaluator.evaluate(f 98 .getDefaultExpression()); 99 fields.put(f.getReference(), r == null ? null : r.getId()); 100 } 101 } 102 } else { 103 isExternal = true; 104 if (!isType) { 105 for (CtTypeReference<?> t : evaluator.getStatefullExternals()) { 106 if (t.isAssignableFrom(concreteType)) { 107 for (Method m : RtHelper.getAllMethods(concreteType 108 .getActualClass())) { 109 if (m.getName().startsWith("get") 110 && m.getParameterTypes().length == 0) { 111 CtFieldReference f = concreteType 112 .getFactory() 113 .Field() 114 .createReference( 115 concreteType, 116 concreteType 117 .getFactory() 118 .Type() 119 .createReference( 120 m 121 .getReturnType()), 122 m.getName().substring(3)); 123 fields.put(f, null); 124 } 125 } 126 } 127 } 128 } 129 } 130 136 if (isType) { 137 this.symbolName = "type"; 138 } else { 139 this.symbolName = "" + getNextId(); 140 } 141 } 142 143 146 public boolean isStateful() { 147 return !fields.isEmpty(); 148 } 149 150 private boolean isExternal = false; 151 152 private CtTypeReference<T> concreteType; 153 154 private Map <CtVariableReference, String > fields = new TreeMap <CtVariableReference, String >(); 155 156 158 161 public CtTypeReference<T> getConcreteType() { 162 return concreteType; 163 } 164 165 171 public String getFieldValue(CtVariableReference<?> fref) { 172 return fields.get(fref); 173 } 174 175 181 public String getFieldValue(String fname) { 182 for (CtVariableReference v : fields.keySet()) { 183 if (v.getSimpleName().equals(fname)) { 184 return fields.get(v); 185 } 186 } 187 return null; 188 } 189 190 211 215 public void setFieldValue(SymbolicHeap heap, CtVariableReference<?> fref, 216 SymbolicInstance value) { 217 if (fields.containsKey(fref)) { 218 fields.put(fref, value.getId()); 219 heap.store(value); 220 } else { 221 throw new RuntimeException ("unknown field '" + fref 222 + "' for target " + this); 223 } 224 } 225 226 230 public boolean isExternal() { 231 return isExternal; 232 } 233 234 237 @Override 238 public String toString() { 239 return "#" + getId() + fields + "#"; 240 } 241 242 246 public SymbolicInstance<T> getClone() { 247 if (!isStateful()) 248 return this; 249 else 250 return new SymbolicInstance<T>(this); 251 } 252 253 256 public SymbolicInstance(SymbolicInstance<T> i) { 257 concreteType = i.concreteType; 258 isExternal = i.isExternal; 259 symbolName = i.symbolName; 260 fields.putAll(i.fields); 261 } 262 263 266 public String getSymbolName() { 267 return symbolName; 268 } 269 270 273 public Map <CtVariableReference, String > getFields() { 274 return fields; 275 } 276 277 } 278 | Popular Tags |