1 package spoon.support.reflect.eval; 2 3 import java.lang.annotation.Annotation ; 4 import java.util.ArrayList ; 5 import java.util.Arrays ; 6 import java.util.HashMap ; 7 import java.util.List ; 8 import java.util.Map ; 9 import java.util.Stack ; 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 86 public class VisitorSymbolicEvaluator implements CtVisitor, SymbolicEvaluator { 87 88 List <CtTypeReference> statefullExternals = new ArrayList <CtTypeReference>(); 89 90 public List <CtTypeReference> getStatefullExternals() { 91 return statefullExternals; 92 } 93 94 public VisitorSymbolicEvaluator() { 95 } 96 97 List <SymbolicEvaluationPath> paths = new ArrayList <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 111 public List <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 <SymbolicInstance> args) { 141 Map <CtVariableReference, SymbolicInstance> variables = new HashMap <CtVariableReference, SymbolicInstance>(); 142 CtExecutable<?> e = eref.getDeclaration(); 143 if (e != null) { 144 int i = 0; 146 for (CtVariable<?> v : e.getParameters()) { 147 variables.put(v.getReference(), args.get(i++)); 148 } 149 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 <BranchingPoint> branchingPoints = new Stack <BranchingPoint>(); 166 167 protected SymbolicEvaluationStack stack = new SymbolicEvaluationStack(); 168 169 protected SymbolicHeap heap = new SymbolicHeap(); 170 171 Number convert(CtTypeReference<?> type, Number n) { 172 if (type.getActualClass() == int.class 173 || type.getActualClass() == Integer .class) { 174 return n.intValue(); 175 } 176 if (type.getActualClass() == byte.class 177 || type.getActualClass() == Byte .class) { 178 return n.byteValue(); 179 } 180 if (type.getActualClass() == long.class 181 || type.getActualClass() == Long .class) { 182 return n.longValue(); 183 } 184 if (type.getActualClass() == float.class 185 || type.getActualClass() == Float .class) { 186 return n.floatValue(); 187 } 188 if (type.getActualClass() == short.class 189 || type.getActualClass() == Short .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 <CtElement>(this.branches); 201 } 202 203 public List <CtElement> branches; 204 205 public SymbolicEvaluationStack stack; 206 207 public List <CtElement> uncompletedBranches; 208 209 public List <CtElement> completedBranches = new ArrayList <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 226 public String toString() { 227 return branches.toString(); 228 } 229 } 230 231 private BranchingPoint getBranchingPoint(CtElement... branches) { 232 if (!branchingPoints.isEmpty()) { 233 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 } else { 247 first = false; 248 } 249 } while (!branchingPoints.isEmpty() && first); 250 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 BranchingPoint bp = new BranchingPoint(stack, branches); 261 branchingPoints.push(bp); 262 return bp; 263 } 264 265 @SuppressWarnings ("unchecked") 266 protected SymbolicInstance evaluateBranches(CtElement... branches) { 267 BranchingPoint bp = getBranchingPoint(branches); 269 result = bp.evaluate(this); 271 if (branchingPoints.peek() == bp) { 274 if (bp.uncompletedBranches.size() == 1) { 275 branchingPoints.pop(); 276 } 277 } 278 return result; 279 } 280 281 @SuppressWarnings ("unchecked") 282 public SymbolicInstance evaluate(CtElement element) { 283 if (element == null) 284 return null; 285 element.accept(this); 288 return result; 289 } 290 291 296 @SuppressWarnings ("unchecked") 297 public void invoke(CtExecutable executable, SymbolicInstance... args) { 298 do { 299 resetCurrentEvaluation(); 300 startPath(); 302 List <SymbolicInstance> cargs = new ArrayList <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 } 313 } while (!branchingPoints.isEmpty()); 317 } 319 320 @SuppressWarnings ("unchecked") 321 public void invoke(SymbolicInstance target, CtExecutable executable, 322 List <SymbolicInstance> args) { 323 do { 324 resetCurrentEvaluation(); 325 startPath(); 327 List <SymbolicInstance> cargs = null; 328 if (args != null) { 329 cargs = new ArrayList <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 } 340 } while (!branchingPoints.isEmpty()); 344 } 346 347 350 boolean isGetter(CtExecutableReference e) { 351 return e.getSimpleName().startsWith("get") 352 && e.getParameterTypes().size() == 0; 353 } 354 355 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 ("unchecked") 373 private <T> SymbolicInstance<T> invoke(CtAbstractInvocation<?> caller, 374 CtExecutableReference<T> executable, SymbolicInstance target, 375 List <SymbolicInstance> args) { 376 enterExecutable(caller, executable, target, args); 377 try { 381 CtExecutable<?> decl = executable.getDeclaration(); 382 if (decl != null) { 383 evaluate(decl.getBody()); 384 } else { 385 CtFieldReference fref = null; 388 if (isStateFullExternal(executable.getDeclaringType())) { 389 if (target != null && isGetter(executable)) { 390 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 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 } 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 } finally { 425 exitExecutable(executable); 426 } 427 return result; 428 } 429 430 public <A extends Annotation > void visitCtAnnotation( 431 CtAnnotation<A> annotation) { 432 throw new RuntimeException ("Unknow Element"); 433 } 434 435 public <A extends Annotation > void visitCtAnnotationType( 436 CtAnnotationType<A> annotationType) { 437 throw new RuntimeException ("Unknow Element"); 438 } 439 440 public void visitCtAnonymousExecutable(CtAnonymousExecutable impl) { 441 throw new RuntimeException ("Unknow Element"); 442 } 443 444 public <T, E extends CtExpression<?>> void visitCtArrayAccess( 445 CtArrayAccess<T, E> arrayAccess) { 446 throw new RuntimeException ("Unknow Element"); 447 } 448 449 public <T> void visitCtArrayTypeReference(CtArrayTypeReference<T> reference) { 450 throw new RuntimeException ("Unknow Element"); 451 } 452 453 public void visitCtAssert(CtAssert asserted) { 454 throw new RuntimeException ("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 ("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 > bool = new SymbolicInstance<Boolean >( 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 > number = new SymbolicInstance<Number >( 494 this, operator.getFactory().Type().createReference( 495 Number .class), false); 496 result = number; 497 return; 498 case PLUS: 499 if ((left.getConcreteType().getActualClass() == String .class) 500 || (right.getConcreteType().getActualClass() == String .class)) { 501 SymbolicInstance<String > string = new SymbolicInstance<String >( 502 this, operator.getFactory().Type().createReference( 503 String .class), false); 504 result = string; 505 return; 506 } else { 507 bool = new SymbolicInstance<Boolean >(this, operator 508 .getFactory().Type().createReference(boolean.class), 509 false); 510 result = bool; 511 return; 512 } 513 default: 514 throw new RuntimeException ("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 ("Unknow Element"); 526 } 527 528 public <E> void visitCtCase(CtCase<E> caseStatement) { 529 throw new RuntimeException ("Unknow Element"); 530 } 531 532 public void visitCtCatch(CtCatch catchBlock) { 533 throw new RuntimeException ("Unknow Element"); 534 } 535 536 public <T> void visitCtClass(CtClass<T> ctClass) { 537 throw new RuntimeException ("Unknow Element"); 538 } 539 540 public void visitCtConstructor(CtConstructor c) { 541 throw new RuntimeException ("Unknow Element"); 542 } 543 544 public void visitCtContinue(CtContinue continueStatement) { 545 throw new RuntimeException ("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 > void visitCtEnum(CtEnum<T> ctEnum) { 554 throw new RuntimeException ("Unknow Element"); 555 } 556 557 public <T> void visitCtExecutableReference( 558 CtExecutableReference<T> reference) { 559 throw new RuntimeException ("Unknow Element"); 560 } 561 562 public void visitCtExpression(CtExpression<?> expression) { 563 throw new RuntimeException ("Unknow Element"); 564 } 565 566 public <T> void visitCtField(CtField<T> f) { 567 throw new RuntimeException ("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 SymbolicInstance<T> i = new SymbolicInstance<T>(this, fieldAccess 596 .getType(), false); 597 result = i; 600 } 601 } 602 603 public <T> void visitCtFieldReference(CtFieldReference<T> reference) { 604 throw new RuntimeException ("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 ("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 ("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 <SymbolicInstance> arguments = new ArrayList <SymbolicInstance>(); 642 for (CtExpression expr : invocation.getArguments()) { 643 SymbolicInstance o = evaluate(expr); 644 arguments.add(o); 645 } 646 SymbolicInstance<?> target = evaluate(invocation.getTarget()); 647 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 invoke(invocation, eref, (SymbolicInstance) target, arguments); 665 } 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 ("Unknow Element"); 686 } 687 688 public <T> void visitCtMethod(CtMethod<T> m) { 689 throw new RuntimeException ("Unknow Element"); 690 } 691 692 public <T> void visitCtNewArray(CtNewArray<T> newArray) { 693 throw new RuntimeException ("Unknow Element"); 694 } 695 696 public <T> void visitCtNewClass(CtNewClass<T> newClass) { 697 CtSimpleType<T> c = newClass.getType().getDeclaration(); 698 List <SymbolicInstance> arguments = new ArrayList <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 invoke(newClass, newClass.getExecutable(), i, arguments); 710 } 711 result = i; 713 } 714 715 public <T, A extends T> void visitCtOperatorAssignement( 716 CtOperatorAssignment<T, A> assignment) { 717 throw new RuntimeException ("Unknow Element"); 718 } 719 720 public void visitCtPackage(CtPackage ctPackage) { 721 throw new RuntimeException ("Unknow Element"); 722 } 723 724 public void visitCtPackageReference(CtPackageReference reference) { 725 throw new RuntimeException ("Unknow Element"); 726 } 727 728 public <T> void visitCtParameter(CtParameter<T> parameter) { 729 throw new RuntimeException ("Unknow Element"); 730 } 731 732 public <R> void visitCtStatementList(CtStatementList<R> statements) { 733 throw new RuntimeException ("Unknow Element"); 734 } 735 736 public <T> void visitCtParameterReference(CtParameterReference<T> reference) { 737 throw new RuntimeException ("Unknow Element"); 738 } 739 740 public void visitCtReference(CtReference reference) { 741 throw new RuntimeException ("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 ("Unknow Element"); 751 } 752 753 public void visitCtSynchronized(CtSynchronized synchro) { 754 throw new RuntimeException ("Unknow Element"); 755 } 756 757 public <T, E extends CtExpression<?>> void visitCtTargetedExpression( 758 CtTargetedExpression<T, E> targetedExpression) { 759 throw new RuntimeException ("Unknow Element"); 760 } 761 762 @SuppressWarnings ("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 } 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 throw e; 786 } finally { 787 evaluate(tryBlock.getFinalizer()); 788 } 789 } 790 791 public void visitCtTypeParameter(CtTypeParameter typeParameter) { 792 throw new RuntimeException ("Unknow Element"); 793 } 794 795 public void visitCtTypeParameterReference(CtTypeParameterReference ref) { 796 throw new RuntimeException ("Unknow Element"); 797 } 798 799 public <T> void visitCtTypeReference(CtTypeReference<T> reference) { 800 throw new RuntimeException ("Unknow Element"); 801 } 802 803 public <T> void visitCtUnaryOperator(CtUnaryOperator<T> operator) { 804 evaluate(operator.getOperand()); 805 } 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 ("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 |