KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > reflect > eval > SymbolicInstance


1 package spoon.reflect.eval;
2
3 import java.lang.reflect.Method JavaDoc;
4 import java.util.Map JavaDoc;
5 import java.util.TreeMap JavaDoc;
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 /**
16  * This class represents symbolic values that can be used by
17  * {@link spoon.reflect.eval.SymbolicEvaluator}.
18  */

19 public class SymbolicInstance<T> {
20
21     static long id = 0;
22
23     /**
24      * Gets the next id to be attributed to the created instance.
25      */

26     private static long getNextId() {
27         return id++;
28     }
29
30     /**
31      * Resets the id counter.
32      */

33     public static void resetIds() {
34         id = 0;
35     }
36
37     private String JavaDoc symbolName = null;
38
39     /**
40      * Helper method to get the symbol's unique Id from its type and its name.
41      *
42      * @param concreteType
43      * the type
44      * @param name
45      * the name (can be null)
46      * @return a unique Id or the type id if name is null
47      */

48     public static String JavaDoc getSymbolId(CtTypeReference concreteType, String JavaDoc name) {
49         CtTypeReference<?> t = concreteType;
50         if (name != null) {
51             return t.getQualifiedName() + "$" + name;
52         } else {
53             return t.getQualifiedName();
54         }
55     }
56
57     /**
58      * Gets the unique Id of this abstract instance.
59      */

60     public String JavaDoc getId() {
61         return getSymbolId(concreteType, symbolName);
62     }
63
64     /**
65      * Tests the equality.
66      */

67     @Override JavaDoc
68     public boolean equals(Object JavaDoc 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     /**
76      * Creates a new abstract instance (logical value).
77      *
78      * @param evaluator
79      * the evaluator
80      * @param concreteType
81      * the type of the instance
82      * @param isType
83      * tells if it is a type instance or a regular instance
84      */

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 JavaDoc 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         // evaluator.getHeap().get(
131
// evaluator,
132
// concreteType.getFactory().Type()
133
// .createReference(
134
// m.getReturnType()));
135

136         if (isType) {
137             this.symbolName = "type";
138         } else {
139             this.symbolName = "" + getNextId();
140         }
141     }
142
143     /**
144      * Tells if this logical value is stateful or not.
145      */

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 JavaDoc<CtVariableReference, String JavaDoc> fields = new TreeMap JavaDoc<CtVariableReference, String JavaDoc>();
155
156     // private Map<String, AbstractInstance> properties;
157

158     /**
159      * Gets the type of the abstract instance.
160      */

161     public CtTypeReference<T> getConcreteType() {
162         return concreteType;
163     }
164
165     /**
166      * Gets the value of a field belonging to this instance, as an abstract
167      * instance id.
168      *
169      * @return null if non-existing field
170      */

171     public String JavaDoc getFieldValue(CtVariableReference<?> fref) {
172         return fields.get(fref);
173     }
174
175     /**
176      * Gets the value of a field belonging to this instance and identified by
177      * its name, as an abstract instance id.
178      *
179      * @return null if non-existing field
180      */

181     public String JavaDoc getFieldValue(String JavaDoc 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     // /**
191
// * Sets the value of an assumed property belonging to this instance.
192
// */
193
// public void setPropertyValue(String propertyName, AbstractInstance value)
194
// {
195
// if (value == null)
196
// return;
197
// if (properties == null)
198
// properties = new HashMap<String, AbstractInstance>();
199
// properties.put(propertyName, value);
200
// }
201
//
202
// /**
203
// * Gets the value of an assumed property belonging to this instance.
204
// */
205
// public AbstractInstance getPropertyValue(String propertyName) {
206
// if (properties == null)
207
// return null;
208
// return properties.get(propertyName);
209
// }
210

211     /**
212      * Sets the value of a field belonging to this instance, and stores the
213      * instance on the heap.
214      */

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 JavaDoc("unknown field '" + fref
222                     + "' for target " + this);
223         }
224     }
225
226     /**
227      * Tells if this instance is a wrapper for an instance external from the
228      * evaluator (regular Java object).
229      */

230     public boolean isExternal() {
231         return isExternal;
232     }
233
234     /**
235      * A string representation.
236      */

237     @Override JavaDoc
238     public String JavaDoc toString() {
239         return "#" + getId() + fields + "#";
240     }
241
242     /**
243      * Gets a copy of this instance (if the instance is stateless, returns
244      * this).
245      */

246     public SymbolicInstance<T> getClone() {
247         if (!isStateful())
248             return this;
249         else
250             return new SymbolicInstance<T>(this);
251     }
252
253     /**
254      * Creates a copy of the given instance.
255      */

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     /**
264      * Gets the name of this symbolic instance.
265      */

266     public String JavaDoc getSymbolName() {
267         return symbolName;
268     }
269
270     /**
271      * Gets the fields for this instance.
272      */

273     public Map JavaDoc<CtVariableReference, String JavaDoc> getFields() {
274         return fields;
275     }
276
277 }
278
Popular Tags