KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > spoon > support > reflect > eval > VisitorSymbolicEvaluator


1 package spoon.support.reflect.eval;
2
3 import java.lang.annotation.Annotation JavaDoc;
4 import java.util.ArrayList JavaDoc;
5 import java.util.Arrays JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.List JavaDoc;
8 import java.util.Map JavaDoc;
9 import java.util.Stack JavaDoc;
10
11 import spoon.reflect.code.CtAbstractInvocation;
12 import spoon.reflect.code.CtArrayAccess;
13 import spoon.reflect.code.CtAssert;
14 import spoon.reflect.code.CtAssignment;
15 import spoon.reflect.code.CtBinaryOperator;
16 import spoon.reflect.code.CtBlock;
17 import spoon.reflect.code.CtBreak;
18 import spoon.reflect.code.CtCase;
19 import spoon.reflect.code.CtCatch;
20 import spoon.reflect.code.CtConditional;
21 import spoon.reflect.code.CtContinue;
22 import spoon.reflect.code.CtDo;
23 import spoon.reflect.code.CtExpression;
24 import spoon.reflect.code.CtFieldAccess;
25 import spoon.reflect.code.CtFor;
26 import spoon.reflect.code.CtForEach;
27 import spoon.reflect.code.CtIf;
28 import spoon.reflect.code.CtInvocation;
29 import spoon.reflect.code.CtLiteral;
30 import spoon.reflect.code.CtLocalVariable;
31 import spoon.reflect.code.CtNewArray;
32 import spoon.reflect.code.CtNewClass;
33 import spoon.reflect.code.CtOperatorAssignment;
34 import spoon.reflect.code.CtReturn;
35 import spoon.reflect.code.CtStatement;
36 import spoon.reflect.code.CtStatementList;
37 import spoon.reflect.code.CtSwitch;
38 import spoon.reflect.code.CtSynchronized;
39 import spoon.reflect.code.CtTargetedExpression;
40 import spoon.reflect.code.CtThrow;
41 import spoon.reflect.code.CtTry;
42 import spoon.reflect.code.CtUnaryOperator;
43 import spoon.reflect.code.CtVariableAccess;
44 import spoon.reflect.code.CtWhile;
45 import spoon.reflect.declaration.CtAnnotation;
46 import spoon.reflect.declaration.CtAnnotationType;
47 import spoon.reflect.declaration.CtAnonymousExecutable;
48 import spoon.reflect.declaration.CtClass;
49 import spoon.reflect.declaration.CtConstructor;
50 import spoon.reflect.declaration.CtElement;
51 import spoon.reflect.declaration.CtEnum;
52 import spoon.reflect.declaration.CtExecutable;
53 import spoon.reflect.declaration.CtField;
54 import spoon.reflect.declaration.CtInterface;
55 import spoon.reflect.declaration.CtMethod;
56 import spoon.reflect.declaration.CtPackage;
57 import spoon.reflect.declaration.CtParameter;
58 import spoon.reflect.declaration.CtSimpleType;
59 import spoon.reflect.declaration.CtTypeParameter;
60 import spoon.reflect.declaration.CtVariable;
61 import spoon.reflect.eval.StepKind;
62 import spoon.reflect.eval.SymbolicEvaluationPath;
63 import spoon.reflect.eval.SymbolicEvaluationStack;
64 import spoon.reflect.eval.SymbolicEvaluator;
65 import spoon.reflect.eval.SymbolicHeap;
66 import spoon.reflect.eval.SymbolicInstance;
67 import spoon.reflect.reference.CtArrayTypeReference;
68 import spoon.reflect.reference.CtExecutableReference;
69 import spoon.reflect.reference.CtFieldReference;
70 import spoon.reflect.reference.CtGenericElementReference;
71 import spoon.reflect.reference.CtLocalVariableReference;
72 import spoon.reflect.reference.CtPackageReference;
73 import spoon.reflect.reference.CtParameterReference;
74 import spoon.reflect.reference.CtReference;
75 import spoon.reflect.reference.CtTypeParameterReference;
76 import spoon.reflect.reference.CtTypeReference;
77 import spoon.reflect.reference.CtVariableReference;
78 import spoon.reflect.visitor.CtVisitor;
79 import spoon.reflect.visitor.Query;
80 import spoon.support.query.TypeFilter;
81
82 /**
83  * This visitor implements an abstract evaluator for the program compile-time
84  * metamodel.
85  */

86 public class VisitorSymbolicEvaluator implements CtVisitor, SymbolicEvaluator {
87
88     List JavaDoc<CtTypeReference> statefullExternals = new ArrayList JavaDoc<CtTypeReference>();
89
90     public List JavaDoc<CtTypeReference> getStatefullExternals() {
91         return statefullExternals;
92     }
93
94     public VisitorSymbolicEvaluator() {
95     }
96
97     List JavaDoc<SymbolicEvaluationPath> paths = new ArrayList JavaDoc<SymbolicEvaluationPath>();
98
99     private void startPath() {
100         paths.add(new SymbolicEvaluationPath());
101     }
102
103     private SymbolicEvaluationPath getCurrentPath() {
104         return paths.get(paths.size() - 1);
105     }
106
107     // private void addToPath(AbstractStackFrame frame) {
108
// paths.get(paths.size() - 1).add(frame);
109
// }
110

111     public List JavaDoc<SymbolicEvaluationPath> getPaths() {
112         return paths;
113     }
114
115     public void dumpPaths() {
116         int i = 1;
117         for (SymbolicEvaluationPath p : paths) {
118             System.out.println("-- path " + (i++));
119             p.dump();
120         }
121     }
122
123     private void resetCurrentEvaluation() {
124         stack = new SymbolicEvaluationStack();
125         heap.clear();
126         SymbolicInstance.resetIds();
127         result = null;
128     }
129
130     public void reset() {
131         resetCurrentEvaluation();
132         branchingPoints.clear();
133         paths.clear();
134     }
135
136     private SymbolicInstance result = null;
137
138     void enterExecutable(CtAbstractInvocation<?> caller,
139             CtExecutableReference<?> eref, SymbolicInstance target,
140             List JavaDoc<SymbolicInstance> args) {
141         Map JavaDoc<CtVariableReference, SymbolicInstance> variables = new HashMap JavaDoc<CtVariableReference, SymbolicInstance>();
142         CtExecutable<?> e = eref.getDeclaration();
143         if (e != null) {
144             // initialize arguments
145
int i = 0;
146             for (CtVariable<?> v : e.getParameters()) {
147                 variables.put(v.getReference(), args.get(i++));
148             }
149             // initialize local variables
150
for (CtVariable<?> v : Query.getElements(e.getBody(),
151                     new TypeFilter<CtVariable>(CtVariable.class))) {
152                 variables.put(v.getReference(), null);
153             }
154         }
155         stack.enterFrame(caller, target, eref, args, variables);
156         getCurrentPath().addStep(StepKind.ENTER, this);
157     }
158
159     void exitExecutable(CtExecutableReference<?> eref) {
160         stack.setResult(result);
161         getCurrentPath().addStep(StepKind.EXIT, this);
162         stack.exitFrame();
163     }
164
165     protected Stack JavaDoc<BranchingPoint> branchingPoints = new Stack JavaDoc<BranchingPoint>();
166
167     protected SymbolicEvaluationStack stack = new SymbolicEvaluationStack();
168
169     protected SymbolicHeap heap = new SymbolicHeap();
170
171     Number JavaDoc convert(CtTypeReference<?> type, Number JavaDoc n) {
172         if (type.getActualClass() == int.class
173                 || type.getActualClass() == Integer JavaDoc.class) {
174             return n.intValue();
175         }
176         if (type.getActualClass() == byte.class
177                 || type.getActualClass() == Byte JavaDoc.class) {
178             return n.byteValue();
179         }
180         if (type.getActualClass() == long.class
181                 || type.getActualClass() == Long JavaDoc.class) {
182             return n.longValue();
183         }
184         if (type.getActualClass() == float.class
185                 || type.getActualClass() == Float JavaDoc.class) {
186             return n.floatValue();
187         }
188         if (type.getActualClass() == short.class
189                 || type.getActualClass() == Short JavaDoc.class) {
190             return n.shortValue();
191         }
192         return n;
193     }
194
195     class BranchingPoint {
196         public BranchingPoint(SymbolicEvaluationStack stack,
197                 CtElement... branches) {
198             this.stack = new SymbolicEvaluationStack(stack);
199             this.branches = Arrays.asList(branches);
200             this.uncompletedBranches = new ArrayList JavaDoc<CtElement>(this.branches);
201         }
202
203         public List JavaDoc<CtElement> branches;
204
205         public SymbolicEvaluationStack stack;
206
207         public List JavaDoc<CtElement> uncompletedBranches;
208
209         public List JavaDoc<CtElement> completedBranches = new ArrayList JavaDoc<CtElement>();
210
211         public SymbolicInstance evaluate(VisitorSymbolicEvaluator evaluator) {
212             return evaluator.evaluate(uncompletedBranches.get(0));
213         }
214
215         public boolean nextBranch() {
216             completedBranches.add(uncompletedBranches.get(0));
217             uncompletedBranches.remove(0);
218             if (uncompletedBranches.isEmpty()) {
219                 return false;
220             } else {
221                 return true;
222             }
223         }
224
225         @Override JavaDoc
226         public String JavaDoc toString() {
227             return branches.toString();
228         }
229     }
230
231     private BranchingPoint getBranchingPoint(CtElement... branches) {
232         if (!branchingPoints.isEmpty()) {
233             // look for the first uncompleted bp at the top of the stack
234
boolean first = true;
235             do {
236                 BranchingPoint bp = branchingPoints.peek();
237                 if (bp.stack.equals(stack)
238                         && bp.branches.equals(Arrays.asList(branches))) {
239                     bp.nextBranch();
240                     return bp;
241                     // if (!bp.nextBranch()) {
242
// branchingPoints.pop();
243
// } else {
244
// return bp;
245
// }
246
} else {
247                     first = false;
248                 }
249             } while (!branchingPoints.isEmpty() && first);
250             // look for any bp in the stack
251
for (int i = branchingPoints.size() - 2; i >= 0; i--) {
252                 BranchingPoint bp = branchingPoints.get(i);
253                 if (bp.stack.equals(stack)
254                         && bp.branches.equals(Arrays.asList(branches))) {
255                     return bp;
256                 }
257             }
258         }
259         // create a new branch
260
BranchingPoint bp = new BranchingPoint(stack, branches);
261         branchingPoints.push(bp);
262         return bp;
263     }
264
265     @SuppressWarnings JavaDoc("unchecked")
266     protected SymbolicInstance evaluateBranches(CtElement... branches) {
267         // System.out.println("branches: "+Arrays.asList(branches));
268
BranchingPoint bp = getBranchingPoint(branches);
269         // System.out.println("bp: "+bp);
270
result = bp.evaluate(this);
271         // System.out.println("result: "+result);
272
// remove completed bp
273
if (branchingPoints.peek() == bp) {
274             if (bp.uncompletedBranches.size() == 1) {
275                 branchingPoints.pop();
276             }
277         }
278         return result;
279     }
280
281     @SuppressWarnings JavaDoc("unchecked")
282     public SymbolicInstance evaluate(CtElement element) {
283         if (element == null)
284             return null;
285         // System.out.println("[evaluating
286
// "+element.getClass().getSimpleName()+"]");
287
element.accept(this);
288         return result;
289     }
290
291     // private boolean evaluationCompleted() {
292
// return branchingPoints.size() == 1
293
// && branchingPoints.peek().uncompletedBranches.size() == 1;
294
// }
295

296     @SuppressWarnings JavaDoc("unchecked")
297     public void invoke(CtExecutable executable, SymbolicInstance... args) {
298         do {
299             resetCurrentEvaluation();
300             // AbstractInstance.dumpHeap();
301
startPath();
302             List JavaDoc<SymbolicInstance> cargs = new ArrayList JavaDoc<SymbolicInstance>();
303             for (SymbolicInstance i : args) {
304                 cargs.add(i == null ? null : i.getClone());
305             }
306             SymbolicInstance target = heap.getType(this, executable
307                     .getDeclaringType().getReference());
308             try {
309                 invoke(null, executable.getReference(), target, cargs);
310             } catch (SymbolicWrappedException e) {
311                 // swallow it
312
}
313             // System.out.println("END");
314
// stack.dumpFrameStack();
315
// heap.dump();
316
} while (!branchingPoints.isEmpty());
317         // dumpPaths();
318
}
319
320     @SuppressWarnings JavaDoc("unchecked")
321     public void invoke(SymbolicInstance target, CtExecutable executable,
322             List JavaDoc<SymbolicInstance> args) {
323         do {
324             resetCurrentEvaluation();
325             // AbstractInstance.dumpHeap();
326
startPath();
327             List JavaDoc<SymbolicInstance> cargs = null;
328             if (args != null) {
329                 cargs = new ArrayList JavaDoc<SymbolicInstance>();
330                 for (SymbolicInstance i : args) {
331                     cargs.add(i == null ? null : i.getClone());
332                 }
333             }
334             try {
335                 invoke(null, executable.getReference(), target, cargs);
336             } catch (SymbolicWrappedException e) {
337                 e.printStackTrace();
338                 // swallow it
339
}
340             // System.out.println("END");
341
// stack.dumpFrameStack();
342
// heap.dump();
343
} while (!branchingPoints.isEmpty());
344         // dumpPaths();
345
}
346
347     /**
348      * Tell if the given method follows the getter naming conventions.
349      */

350     boolean isGetter(CtExecutableReference e) {
351         return e.getSimpleName().startsWith("get")
352                 && e.getParameterTypes().size() == 0;
353     }
354
355     /**
356      * Tell if the given method follows the setter naming conventions.
357      */

358     boolean isSetter(CtExecutableReference e) {
359         return e.getSimpleName().startsWith("set")
360                 && e.getParameterTypes().size() == 1;
361     }
362
363     boolean isStateFullExternal(CtTypeReference type) {
364         for (CtTypeReference<?> t : getStatefullExternals()) {
365             if (t.isAssignableFrom(type)) {
366                 return true;
367             }
368         }
369         return false;
370     }
371
372     @SuppressWarnings JavaDoc("unchecked")
373     private <T> SymbolicInstance<T> invoke(CtAbstractInvocation<?> caller,
374             CtExecutableReference<T> executable, SymbolicInstance target,
375             List JavaDoc<SymbolicInstance> args) {
376         enterExecutable(caller, executable, target, args);
377         // System.out.println("[invoking " + caller + "]");
378
// stack.dump();
379
// heap.dump();
380
try {
381             CtExecutable<?> decl = executable.getDeclaration();
382             if (decl != null) {
383                 evaluate(decl.getBody());
384             } else {
385                 // not accessible (set the result to the return type or to the
386
// field value if a getter)
387
CtFieldReference fref = null;
388                 if (isStateFullExternal(executable.getDeclaringType())) {
389                     if (target != null && isGetter(executable)) {
390                         // System.out.println(m);
391
SymbolicInstance r = null;
392                         fref = executable.getFactory().Field().createReference(
393                                 target.getConcreteType(), executable.getType(),
394                                 executable.getSimpleName().substring(3));
395                         r = heap.get(target.getFieldValue(fref));
396                         if (r != null) {
397                             result = r;
398                         } else {
399                             result = new SymbolicInstance(this, executable
400                                     .getType(), false);
401                         }
402                     } else if (target != null && isSetter(executable)) {
403                         // System.out.println(m.toString()+"
404
// "+caller.getPosition());
405
fref = executable.getFactory().Field().createReference(
406                                 target.getConcreteType(), executable.getType(),
407                                 executable.getSimpleName().substring(3));
408                         target.setFieldValue(heap, fref, args.get(0));
409                         result = new SymbolicInstance(this, executable
410                                 .getType(), false);
411                         // heap.dump();
412
// stack.dump();
413
} else {
414                         result = new SymbolicInstance(this, executable
415                                 .getType(), false);
416                     }
417                 } else {
418                     result = new SymbolicInstance(this, executable.getType(),
419                             false);
420                 }
421             }
422         } catch (ReturnException e) {
423             // normal return
424
} finally {
425             exitExecutable(executable);
426         }
427         return result;
428     }
429
430     public <A extends Annotation JavaDoc> void visitCtAnnotation(
431             CtAnnotation<A> annotation) {
432         throw new RuntimeException JavaDoc("Unknow Element");
433     }
434
435     public <A extends Annotation JavaDoc> void visitCtAnnotationType(
436             CtAnnotationType<A> annotationType) {
437         throw new RuntimeException JavaDoc("Unknow Element");
438     }
439
440     public void visitCtAnonymousExecutable(CtAnonymousExecutable impl) {
441         throw new RuntimeException JavaDoc("Unknow Element");
442     }
443
444     public <T, E extends CtExpression<?>> void visitCtArrayAccess(
445             CtArrayAccess<T, E> arrayAccess) {
446         throw new RuntimeException JavaDoc("Unknow Element");
447     }
448
449     public <T> void visitCtArrayTypeReference(CtArrayTypeReference<T> reference) {
450         throw new RuntimeException JavaDoc("Unknow Element");
451     }
452
453     public void visitCtAssert(CtAssert asserted) {
454         throw new RuntimeException JavaDoc("Unknow Element");
455     }
456
457     public <T, A extends T> void visitCtAssignment(CtAssignment<T, A> assignment) {
458         if (assignment.getAssigned() instanceof CtVariableAccess) {
459             CtVariableReference<T> vref = ((CtVariableAccess<T>) assignment
460                     .getAssigned()).getVariable();
461             SymbolicInstance res = evaluate(assignment.getAssignment());
462             if (vref instanceof CtFieldReference) {
463                 stack.getThis().setFieldValue(heap, vref, res);
464             } else {
465                 stack.setVariableValue(vref, res);
466             }
467             result = res;
468         }
469     }
470
471     @SuppressWarnings JavaDoc("unchecked")
472     public <T> void visitCtBinaryOperator(CtBinaryOperator<T> operator) {
473         SymbolicInstance left = evaluate(operator.getLeftHandOperand());
474         SymbolicInstance right = evaluate(operator.getRightHandOperand());
475         switch (operator.getKind()) {
476         case AND:
477         case OR:
478         case EQ:
479         case NE:
480         case GE:
481         case LE:
482         case GT:
483         case LT:
484         case INSTANCEOF:
485             SymbolicInstance<Boolean JavaDoc> bool = new SymbolicInstance<Boolean JavaDoc>(
486                     this, operator.getFactory().Type().createReference(
487                             boolean.class), false);
488             result = bool;
489             return;
490         case MINUS:
491         case MUL:
492         case DIV:
493             SymbolicInstance<Number JavaDoc> number = new SymbolicInstance<Number JavaDoc>(
494                     this, operator.getFactory().Type().createReference(
495                             Number JavaDoc.class), false);
496             result = number;
497             return;
498         case PLUS:
499             if ((left.getConcreteType().getActualClass() == String JavaDoc.class)
500                     || (right.getConcreteType().getActualClass() == String JavaDoc.class)) {
501                 SymbolicInstance<String JavaDoc> string = new SymbolicInstance<String JavaDoc>(
502                         this, operator.getFactory().Type().createReference(
503                                 String JavaDoc.class), false);
504                 result = string;
505                 return;
506             } else {
507                 bool = new SymbolicInstance<Boolean JavaDoc>(this, operator
508                         .getFactory().Type().createReference(boolean.class),
509                         false);
510                 result = bool;
511                 return;
512             }
513         default:
514             throw new RuntimeException JavaDoc("unsupported operator");
515         }
516     }
517
518     public <R> void visitCtBlock(CtBlock<R> block) {
519         for (CtStatement s : block.getStatements()) {
520             evaluate(s);
521         }
522     }
523
524     public void visitCtBreak(CtBreak breakStatement) {
525         throw new RuntimeException JavaDoc("Unknow Element");
526     }
527
528     public <E> void visitCtCase(CtCase<E> caseStatement) {
529         throw new RuntimeException JavaDoc("Unknow Element");
530     }
531
532     public void visitCtCatch(CtCatch catchBlock) {
533         throw new RuntimeException JavaDoc("Unknow Element");
534     }
535
536     public <T> void visitCtClass(CtClass<T> ctClass) {
537         throw new RuntimeException JavaDoc("Unknow Element");
538     }
539
540     public void visitCtConstructor(CtConstructor c) {
541         throw new RuntimeException JavaDoc("Unknow Element");
542     }
543
544     public void visitCtContinue(CtContinue continueStatement) {
545         throw new RuntimeException JavaDoc("Unknow Element");
546     }
547
548     public void visitCtDo(CtDo doLoop) {
549         evaluate(doLoop.getBody());
550         evaluate(doLoop.getLoopingExpression());
551     }
552
553     public <T extends Enum JavaDoc> void visitCtEnum(CtEnum<T> ctEnum) {
554         throw new RuntimeException JavaDoc("Unknow Element");
555     }
556
557     public <T> void visitCtExecutableReference(
558             CtExecutableReference<T> reference) {
559         throw new RuntimeException JavaDoc("Unknow Element");
560     }
561
562     public void visitCtExpression(CtExpression<?> expression) {
563         throw new RuntimeException JavaDoc("Unknow Element");
564     }
565
566     public <T> void visitCtField(CtField<T> f) {
567         throw new RuntimeException JavaDoc("Unknow Element");
568     }
569
570     boolean isAccessible(CtFieldReference<?> field) {
571         return field.getDeclaringType().isAssignableFrom(
572                 stack.getThis().getConcreteType());
573     }
574
575     public <T> void visitCtFieldAccess(CtFieldAccess<T> fieldAccess) {
576         if (fieldAccess.getVariable().getSimpleName().equals("this")) {
577             result = stack.getThis();
578             return;
579         }
580         if (fieldAccess.getVariable().getSimpleName().equals("class")) {
581             SymbolicInstance type = heap.getType(this, fieldAccess.getType());
582             result = type;
583             return;
584         }
585         SymbolicInstance<?> target = evaluate(fieldAccess.getTarget());
586         if (target == null) {
587             if (isAccessible(fieldAccess.getVariable())) {
588                 target = stack.getThis();
589             }
590         }
591         if (target != null && !target.isExternal()) {
592             result = heap.get(target.getFieldValue(fieldAccess.getVariable()));
593         } else {
594             // set the type to the declared one
595
SymbolicInstance<T> i = new SymbolicInstance<T>(this, fieldAccess
596                     .getType(), false);
597             // this instance is not put on the heap because it will be put if
598
// assigned to an object's field
599
result = i;
600         }
601     }
602
603     public <T> void visitCtFieldReference(CtFieldReference<T> reference) {
604         throw new RuntimeException JavaDoc("Unknow Element");
605     }
606
607     public void visitCtFor(CtFor forLoop) {
608         for (CtStatement s : forLoop.getForInit()) {
609             evaluate(s);
610         }
611         evaluate(forLoop.getExpression());
612         evaluate(forLoop.getBody());
613         for (CtStatement s : forLoop.getForUpdate()) {
614             evaluate(s);
615         }
616     }
617
618     public void visitCtForEach(CtForEach foreach) {
619         evaluate(foreach.getBody());
620     }
621
622     public void visitCtGenericElementReference(
623             CtGenericElementReference reference) {
624         throw new RuntimeException JavaDoc("Unknow Element");
625     }
626
627     public void visitCtIf(CtIf ifElement) {
628         evaluate(ifElement.getCondition());
629         evaluateBranches(ifElement.getThenStatement(), ifElement
630                 .getElseStatement());
631     }
632
633     public <T> void visitCtInterface(CtInterface<T> intrface) {
634         throw new RuntimeException JavaDoc("Unknow Element");
635     }
636
637     public <T> void visitCtInvocation(CtInvocation<T> invocation) {
638         CtExecutableReference<T> eref = invocation.getExecutable();
639         if (eref.getSimpleName().equals("<init>"))
640             return;
641         List JavaDoc<SymbolicInstance> arguments = new ArrayList JavaDoc<SymbolicInstance>();
642         for (CtExpression expr : invocation.getArguments()) {
643             SymbolicInstance o = evaluate(expr);
644             arguments.add(o);
645         }
646         SymbolicInstance<?> target = evaluate(invocation.getTarget());
647         // redirect ref to the overloading method if any
648
if (target != null) {
649             CtExecutableReference<T> overload = eref
650                     .getOverloadingExecutable(target.getConcreteType());
651             if (overload != null) {
652                 eref = overload;
653             }
654         }
655         if (target == null) {
656             if (eref.isStatic()) {
657                     target = heap.getType(this, eref.getDeclaringType());
658             } else {
659                 target = stack.getThis();
660             }
661         }
662         // CtExecutable<T> e = eref.getDeclaration();
663
// if (e != null) {
664
invoke(invocation, eref, (SymbolicInstance) target, arguments);
665         // } else {
666
// // method is not accessible
667
// // set the result to the declared type
668
// Method m = invocation.getExecutable().getActualMethod();
669
// stack.setResult(heap.get(this, invocation.getFactory().Type()
670
// .createReference(m.getReturnType())));
671
// }
672
}
673
674     public <T> void visitCtLiteral(CtLiteral<T> literal) {
675         result = new SymbolicInstance<T>(this, literal.getType(), false);
676     }
677
678     public <T> void visitCtLocalVariable(final CtLocalVariable<T> localVariable) {
679         stack.setVariableValue(localVariable.getReference(),
680                 evaluate(localVariable.getDefaultExpression()));
681     }
682
683     public <T> void visitCtLocalVariableReference(
684             CtLocalVariableReference<T> reference) {
685         throw new RuntimeException JavaDoc("Unknow Element");
686     }
687
688     public <T> void visitCtMethod(CtMethod<T> m) {
689         throw new RuntimeException JavaDoc("Unknow Element");
690     }
691
692     public <T> void visitCtNewArray(CtNewArray<T> newArray) {
693         throw new RuntimeException JavaDoc("Unknow Element");
694     }
695
696     public <T> void visitCtNewClass(CtNewClass<T> newClass) {
697         CtSimpleType<T> c = newClass.getType().getDeclaration();
698         // CtExecutable<T> e = eref.getDeclaration();
699
List JavaDoc<SymbolicInstance> arguments = new ArrayList JavaDoc<SymbolicInstance>();
700         for (CtExpression expr : newClass.getArguments()) {
701             SymbolicInstance o = evaluate(expr);
702             arguments.add(o);
703         }
704         SymbolicInstance<T> i = new SymbolicInstance<T>(this, newClass
705                 .getType(), false);
706         heap.store(i);
707         if (c != null) {
708             // evaluate the constructor
709
invoke(newClass, newClass.getExecutable(), i, arguments);
710         }
711         // TODO: something better for externals
712
result = i;
713     }
714
715     public <T, A extends T> void visitCtOperatorAssignement(
716             CtOperatorAssignment<T, A> assignment) {
717         throw new RuntimeException JavaDoc("Unknow Element");
718     }
719
720     public void visitCtPackage(CtPackage ctPackage) {
721         throw new RuntimeException JavaDoc("Unknow Element");
722     }
723
724     public void visitCtPackageReference(CtPackageReference reference) {
725         throw new RuntimeException JavaDoc("Unknow Element");
726     }
727
728     public <T> void visitCtParameter(CtParameter<T> parameter) {
729         throw new RuntimeException JavaDoc("Unknow Element");
730     }
731
732     public <R> void visitCtStatementList(CtStatementList<R> statements) {
733         throw new RuntimeException JavaDoc("Unknow Element");
734     }
735
736     public <T> void visitCtParameterReference(CtParameterReference<T> reference) {
737         throw new RuntimeException JavaDoc("Unknow Element");
738     }
739
740     public void visitCtReference(CtReference reference) {
741         throw new RuntimeException JavaDoc("Unknow Element");
742     }
743
744     public <R> void visitCtReturn(CtReturn<R> returnStatement) {
745         result = evaluate(returnStatement.getReturnedExpression());
746         throw new ReturnException(returnStatement);
747     }
748
749     public <E> void visitCtSwitch(CtSwitch<E> switchStatement) {
750         throw new RuntimeException JavaDoc("Unknow Element");
751     }
752
753     public void visitCtSynchronized(CtSynchronized synchro) {
754         throw new RuntimeException JavaDoc("Unknow Element");
755     }
756
757     public <T, E extends CtExpression<?>> void visitCtTargetedExpression(
758             CtTargetedExpression<T, E> targetedExpression) {
759         throw new RuntimeException JavaDoc("Unknow Element");
760     }
761
762     @SuppressWarnings JavaDoc("unchecked")
763     public void visitCtThrow(CtThrow throwStatement) {
764         throw new SymbolicWrappedException(evaluate(throwStatement
765                 .getThrownExpression()), throwStatement, getStack());
766     }
767
768     public void visitCtTry(CtTry tryBlock) {
769         try {
770             evaluate(tryBlock.getBody());
771         } catch (ReturnException r) {
772             // normal return
773
} catch (SymbolicWrappedException e) {
774             for (CtCatch c : tryBlock.getCatchers()) {
775                 if (c.getParameter().getType().isAssignableFrom(
776                         e.getAbstractCause().getConcreteType())) {
777                     getStack().setVariableValue(
778                             c.getParameter().getReference(),
779                             e.getAbstractCause());
780                     evaluate(c.getBody());
781                     return;
782                 }
783             }
784             // re-throw unhandled exception
785
throw e;
786         } finally {
787             evaluate(tryBlock.getFinalizer());
788         }
789     }
790
791     public void visitCtTypeParameter(CtTypeParameter typeParameter) {
792         throw new RuntimeException JavaDoc("Unknow Element");
793     }
794
795     public void visitCtTypeParameterReference(CtTypeParameterReference ref) {
796         throw new RuntimeException JavaDoc("Unknow Element");
797     }
798
799     public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
800         throw new RuntimeException JavaDoc("Unknow Element");
801     }
802
803     public <T> void visitCtUnaryOperator(CtUnaryOperator<T> operator) {
804         evaluate(operator.getOperand());
805         // switch (operator.getKind()) {
806
// case POSTINC:
807
// case POSTDEC:
808
// case PREINC:
809
// case PREDEC:
810
// case NEG:
811
// AbstractInstance<Number>
812
// number=AbstractInstance.get(this,operator.getFactory().Type().createReference(Number.class));
813
// setResult(number);
814
// return;
815
// case NOT:
816
// AbstractInstance<Boolean>
817
// bool=AbstractInstance.get(this,operator.getFactory().Type().createReference(Boolean.class));
818
// setResult(bool);
819
// return;
820
// default:
821
// throw new RuntimeException("unsupported operator");
822
// }
823
}
824
825     public <T> void visitCtVariableAccess(CtVariableAccess<T> variableAccess) {
826         CtVariableReference<?> vref = variableAccess.getVariable();
827         result = stack.getVariableValue(vref);
828     }
829
830     public void visitCtVariableReference(CtVariableReference reference) {
831         throw new RuntimeException JavaDoc("Unknow Element");
832     }
833
834     public void visitCtWhile(CtWhile whileLoop) {
835         evaluate(whileLoop.getLoopingExpression());
836         evaluate(whileLoop.getBody());
837     }
838
839     public <T> void visitCtConditional(CtConditional<T> conditional) {
840         evaluate(conditional.getCondition());
841         evaluate(conditional.getThenExpression());
842         evaluate(conditional.getElseExpression());
843     }
844
845     public SymbolicHeap getHeap() {
846         return heap;
847     }
848
849     public SymbolicEvaluationStack getStack() {
850         return stack;
851     }
852
853 }
854
Popular Tags