Source Code Cross Referenced for VisitorSymbolicEvaluator.java in  » Code-Analyzer » Spoon » spoon » support » reflect » eval » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » Spoon » spoon.support.reflect.eval 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* 
0002:         * Spoon - http://spoon.gforge.inria.fr/
0003:         * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
0004:         * 
0005:         * This software is governed by the CeCILL-C License under French law and
0006:         * abiding by the rules of distribution of free software. You can use, modify 
0007:         * and/or redistribute the software under the terms of the CeCILL-C license as 
0008:         * circulated by CEA, CNRS and INRIA at http://www.cecill.info. 
0009:         * 
0010:         * This program is distributed in the hope that it will be useful, but WITHOUT 
0011:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
0012:         * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
0013:         *  
0014:         * The fact that you are presently reading this means that you have had
0015:         * knowledge of the CeCILL-C license and that you accept its terms.
0016:         */
0017:
0018:        package spoon.support.reflect.eval;
0019:
0020:        import java.lang.annotation.Annotation;
0021:        import java.util.ArrayList;
0022:        import java.util.Arrays;
0023:        import java.util.HashMap;
0024:        import java.util.List;
0025:        import java.util.Map;
0026:        import java.util.Stack;
0027:
0028:        import spoon.processing.Severity;
0029:        import spoon.reflect.Factory;
0030:        import spoon.reflect.code.CtAbstractInvocation;
0031:        import spoon.reflect.code.CtArrayAccess;
0032:        import spoon.reflect.code.CtAssert;
0033:        import spoon.reflect.code.CtAssignment;
0034:        import spoon.reflect.code.CtBinaryOperator;
0035:        import spoon.reflect.code.CtBlock;
0036:        import spoon.reflect.code.CtBreak;
0037:        import spoon.reflect.code.CtCase;
0038:        import spoon.reflect.code.CtCatch;
0039:        import spoon.reflect.code.CtCodeSnippetExpression;
0040:        import spoon.reflect.code.CtCodeSnippetStatement;
0041:        import spoon.reflect.code.CtConditional;
0042:        import spoon.reflect.code.CtContinue;
0043:        import spoon.reflect.code.CtDo;
0044:        import spoon.reflect.code.CtExpression;
0045:        import spoon.reflect.code.CtFieldAccess;
0046:        import spoon.reflect.code.CtFor;
0047:        import spoon.reflect.code.CtForEach;
0048:        import spoon.reflect.code.CtIf;
0049:        import spoon.reflect.code.CtInvocation;
0050:        import spoon.reflect.code.CtLiteral;
0051:        import spoon.reflect.code.CtLocalVariable;
0052:        import spoon.reflect.code.CtNewArray;
0053:        import spoon.reflect.code.CtNewClass;
0054:        import spoon.reflect.code.CtOperatorAssignment;
0055:        import spoon.reflect.code.CtReturn;
0056:        import spoon.reflect.code.CtStatement;
0057:        import spoon.reflect.code.CtStatementList;
0058:        import spoon.reflect.code.CtSwitch;
0059:        import spoon.reflect.code.CtSynchronized;
0060:        import spoon.reflect.code.CtThrow;
0061:        import spoon.reflect.code.CtTry;
0062:        import spoon.reflect.code.CtUnaryOperator;
0063:        import spoon.reflect.code.CtVariableAccess;
0064:        import spoon.reflect.code.CtWhile;
0065:        import spoon.reflect.declaration.CtAnnotation;
0066:        import spoon.reflect.declaration.CtAnnotationType;
0067:        import spoon.reflect.declaration.CtAnonymousExecutable;
0068:        import spoon.reflect.declaration.CtClass;
0069:        import spoon.reflect.declaration.CtConstructor;
0070:        import spoon.reflect.declaration.CtElement;
0071:        import spoon.reflect.declaration.CtEnum;
0072:        import spoon.reflect.declaration.CtExecutable;
0073:        import spoon.reflect.declaration.CtField;
0074:        import spoon.reflect.declaration.CtInterface;
0075:        import spoon.reflect.declaration.CtMethod;
0076:        import spoon.reflect.declaration.CtPackage;
0077:        import spoon.reflect.declaration.CtParameter;
0078:        import spoon.reflect.declaration.CtType;
0079:        import spoon.reflect.declaration.CtTypeParameter;
0080:        import spoon.reflect.declaration.CtVariable;
0081:        import spoon.reflect.declaration.ModifierKind;
0082:        import spoon.reflect.eval.StepKind;
0083:        import spoon.reflect.eval.SymbolicEvaluationStack;
0084:        import spoon.reflect.eval.SymbolicEvaluationStep;
0085:        import spoon.reflect.eval.SymbolicEvaluator;
0086:        import spoon.reflect.eval.SymbolicEvaluatorObserver;
0087:        import spoon.reflect.eval.SymbolicHeap;
0088:        import spoon.reflect.eval.SymbolicInstance;
0089:        import spoon.reflect.eval.SymbolicStackFrame;
0090:        import spoon.reflect.reference.CtArrayTypeReference;
0091:        import spoon.reflect.reference.CtExecutableReference;
0092:        import spoon.reflect.reference.CtFieldReference;
0093:        import spoon.reflect.reference.CtLocalVariableReference;
0094:        import spoon.reflect.reference.CtPackageReference;
0095:        import spoon.reflect.reference.CtParameterReference;
0096:        import spoon.reflect.reference.CtTypeParameterReference;
0097:        import spoon.reflect.reference.CtTypeReference;
0098:        import spoon.reflect.reference.CtVariableReference;
0099:        import spoon.reflect.visitor.CtVisitor;
0100:        import spoon.reflect.visitor.Query;
0101:        import spoon.reflect.visitor.filter.TypeFilter;
0102:
0103:        /**
0104:         * This visitor implements an abstract evaluator for the program compile-time
0105:         * metamodel.
0106:         */
0107:        public class VisitorSymbolicEvaluator implements  CtVisitor,
0108:                SymbolicEvaluator {
0109:
0110:            List<CtTypeReference<?>> statefullExternals = new ArrayList<CtTypeReference<?>>();
0111:
0112:            public List<CtTypeReference<?>> getStatefullExternals() {
0113:                return statefullExternals;
0114:            }
0115:
0116:            /**
0117:             * The default constructor.
0118:             *
0119:             * @param observers
0120:             *            observers to be notified of the progress of the evaluation
0121:             */
0122:            public VisitorSymbolicEvaluator(
0123:                    SymbolicEvaluatorObserver[] observers) {
0124:                for (SymbolicEvaluatorObserver observer : observers) {
0125:                    addObserver(observer);
0126:                }
0127:            }
0128:
0129:            // List<SymbolicEvaluationPath> paths = new
0130:            // ArrayList<SymbolicEvaluationPath>();
0131:
0132:            private void startPath() {
0133:                // paths.add(new SymbolicEvaluationPath());
0134:                notifyStartPath();
0135:            }
0136:
0137:            // public SymbolicEvaluationPath getCurrentPath() {
0138:            // return paths.get(paths.size() - 1);
0139:            // }
0140:
0141:            // private void addToPath(AbstractStackFrame frame) {
0142:            // paths.get(paths.size() - 1).add(frame);
0143:            // }
0144:
0145:            // public List<SymbolicEvaluationPath> getPaths() {
0146:            // return paths;
0147:            // }
0148:            //
0149:            // public void dumpPaths() {
0150:            // int i = 1;
0151:            // for (SymbolicEvaluationPath p : paths) {
0152:            // System.out.println("-- path " + (i++));
0153:            // p.dump();
0154:            // }
0155:            // }
0156:
0157:            private void resetCurrentEvaluation() {
0158:                stack = new SymbolicEvaluationStack();
0159:                heap.clear();
0160:                SymbolicInstance.resetIds();
0161:                result = null;
0162:            }
0163:
0164:            public void reset() {
0165:                resetCurrentEvaluation();
0166:                branchingPoints.clear();
0167:                // paths.clear();
0168:            }
0169:
0170:            private SymbolicInstance<?> result = null;
0171:
0172:            void enterExecutable(CtAbstractInvocation<?> caller,
0173:                    CtExecutableReference<?> eref, SymbolicInstance<?> target,
0174:                    List<SymbolicInstance<?>> args) {
0175:                Map<CtVariableReference<?>, SymbolicInstance<?>> variables = new HashMap<CtVariableReference<?>, SymbolicInstance<?>>();
0176:                CtExecutable<?> e = eref.getDeclaration();
0177:                if (e != null) {
0178:                    // initialize arguments
0179:                    int i = 0;
0180:                    for (CtVariable<?> v : e.getParameters()) {
0181:                        variables.put(v.getReference(), args.get(i++));
0182:                    }
0183:                    // initialize local variables
0184:                    for (CtVariable<?> v : Query.getElements(e.getBody(),
0185:                            new TypeFilter<CtVariable<?>>(CtVariable.class))) {
0186:                        variables.put(v.getReference(), null);
0187:                    }
0188:                }
0189:                stack.enterFrame(caller, target, eref, args, variables);
0190:                notifyEnterStep(new SymbolicEvaluationStep(StepKind.ENTER,
0191:                        new SymbolicStackFrame(getStack().getFrameStack()
0192:                                .peek()), new SymbolicHeap(getHeap())));
0193:            }
0194:
0195:            void exitExecutable(CtExecutableReference<?> eref) {
0196:                stack.setResult(result);
0197:                notifyExitStep(new SymbolicEvaluationStep(StepKind.EXIT,
0198:                        new SymbolicStackFrame(getStack().getFrameStack()
0199:                                .peek()), new SymbolicHeap(getHeap())));
0200:                stack.exitFrame();
0201:            }
0202:
0203:            protected Stack<BranchingPoint> branchingPoints = new Stack<BranchingPoint>();
0204:
0205:            protected SymbolicEvaluationStack stack = new SymbolicEvaluationStack();
0206:
0207:            protected SymbolicHeap heap = new SymbolicHeap();
0208:
0209:            private List<SymbolicEvaluatorObserver> observers = new ArrayList<SymbolicEvaluatorObserver>();
0210:
0211:            Number convert(CtTypeReference<?> type, Number n) {
0212:                if ((type.getActualClass() == int.class)
0213:                        || (type.getActualClass() == Integer.class)) {
0214:                    return n.intValue();
0215:                }
0216:                if ((type.getActualClass() == byte.class)
0217:                        || (type.getActualClass() == Byte.class)) {
0218:                    return n.byteValue();
0219:                }
0220:                if ((type.getActualClass() == long.class)
0221:                        || (type.getActualClass() == Long.class)) {
0222:                    return n.longValue();
0223:                }
0224:                if ((type.getActualClass() == float.class)
0225:                        || (type.getActualClass() == Float.class)) {
0226:                    return n.floatValue();
0227:                }
0228:                if ((type.getActualClass() == short.class)
0229:                        || (type.getActualClass() == Short.class)) {
0230:                    return n.shortValue();
0231:                }
0232:                return n;
0233:            }
0234:
0235:            class BranchingPoint {
0236:                public BranchingPoint(SymbolicEvaluationStack stack,
0237:                        CtElement... branches) {
0238:                    this .stack = new SymbolicEvaluationStack(stack);
0239:                    this .branches = Arrays.asList(branches);
0240:                    uncompletedBranches = new ArrayList<CtElement>(
0241:                            this .branches);
0242:                }
0243:
0244:                public List<CtElement> branches;
0245:
0246:                public SymbolicEvaluationStack stack;
0247:
0248:                public List<CtElement> uncompletedBranches;
0249:
0250:                public List<CtElement> completedBranches = new ArrayList<CtElement>();
0251:
0252:                public SymbolicInstance<?> evaluate(
0253:                        VisitorSymbolicEvaluator evaluator) {
0254:                    return evaluator.evaluate(uncompletedBranches.get(0));
0255:                }
0256:
0257:                public boolean nextBranch() {
0258:                    completedBranches.add(uncompletedBranches.get(0));
0259:                    uncompletedBranches.remove(0);
0260:                    if (uncompletedBranches.isEmpty()) {
0261:                        return false;
0262:                    }
0263:                    return true;
0264:                }
0265:
0266:                @Override
0267:                public String toString() {
0268:                    return branches.toString();
0269:                }
0270:            }
0271:
0272:            private BranchingPoint getBranchingPoint(CtElement... branches) {
0273:                if (!branchingPoints.isEmpty()) {
0274:                    // look for the first uncompleted bp at the top of the stack
0275:                    boolean first = true;
0276:                    do {
0277:                        BranchingPoint bp = branchingPoints.peek();
0278:                        if (bp.stack.equals(stack)
0279:                                && bp.branches.equals(Arrays.asList(branches))) {
0280:                            bp.nextBranch();
0281:                            return bp;
0282:                            // if (!bp.nextBranch()) {
0283:                            // branchingPoints.pop();
0284:                            // } else {
0285:                            // return bp;
0286:                            // }
0287:                        }
0288:                        first = false;
0289:                    } while (!branchingPoints.isEmpty() && first);
0290:                    // look for any bp in the stack
0291:                    for (int i = branchingPoints.size() - 2; i >= 0; i--) {
0292:                        BranchingPoint bp = branchingPoints.get(i);
0293:                        if (bp.stack.equals(stack)
0294:                                && bp.branches.equals(Arrays.asList(branches))) {
0295:                            return bp;
0296:                        }
0297:                    }
0298:                }
0299:                // create a new branch
0300:                BranchingPoint bp = new BranchingPoint(stack, branches);
0301:                branchingPoints.push(bp);
0302:                return bp;
0303:            }
0304:
0305:            @SuppressWarnings("unchecked")
0306:            protected SymbolicInstance evaluateBranches(CtElement... branches) {
0307:                // System.out.println("branches: "+Arrays.asList(branches));
0308:                BranchingPoint bp = getBranchingPoint(branches);
0309:                // System.out.println("bp: "+bp);
0310:                result = bp.evaluate(this );
0311:                // System.out.println("result: "+result);
0312:                // remove completed bp
0313:                if (branchingPoints.peek() == bp) {
0314:                    if (bp.uncompletedBranches.size() == 1) {
0315:                        branchingPoints.pop();
0316:                    }
0317:                }
0318:                return result;
0319:            }
0320:
0321:            public SymbolicInstance<?> evaluate(CtElement element) {
0322:                if (element == null) {
0323:                    return null;
0324:                }
0325:                // System.out.println("[evaluating
0326:                // "+element.getClass().getSimpleName()+"]");
0327:                element.accept(this );
0328:                if (result == null) {
0329:                    result = SymbolicInstance.NULL;
0330:                }
0331:                return result;
0332:            }
0333:
0334:            @SuppressWarnings("unchecked")
0335:            public <T> SymbolicInstance<T> evaluate(CtExpression<T> expression) {
0336:                if (expression == null) {
0337:                    return null;
0338:                }
0339:                // System.out.println("[evaluating
0340:                // "+element.getClass().getSimpleName()+"]");
0341:                expression.accept(this );
0342:                if (result == null) {
0343:                    result = SymbolicInstance.NULL;
0344:                }
0345:                return (SymbolicInstance<T>) result;
0346:            }
0347:
0348:            // private boolean evaluationCompleted() {
0349:            // return branchingPoints.size() == 1
0350:            // && branchingPoints.peek().uncompletedBranches.size() == 1;
0351:            // }
0352:
0353:            public void invoke(CtExecutable<?> executable,
0354:                    SymbolicInstance<?>... args) {
0355:                do {
0356:                    resetCurrentEvaluation();
0357:                    startPath();
0358:                    List<SymbolicInstance<?>> cargs = new ArrayList<SymbolicInstance<?>>();
0359:                    for (SymbolicInstance<?> i : args) {
0360:                        cargs.add(i == null ? null : i.getClone());
0361:                    }
0362:                    SymbolicInstance<?> target = heap.getType(this , executable
0363:                            .getDeclaringType().getReference());
0364:                    try {
0365:                        invoke(null, executable.getReference(), target, cargs);
0366:                    } catch (SymbolicWrappedException e) {
0367:                        // swallow it
0368:                    }
0369:                    notifyEndPath();
0370:                } while (!branchingPoints.isEmpty());
0371:            }
0372:
0373:            public void invoke(SymbolicInstance<?> target,
0374:                    CtExecutable<?> executable, List<SymbolicInstance<?>> args) {
0375:                do {
0376:                    resetCurrentEvaluation();
0377:                    // AbstractInstance.dumpHeap();
0378:                    startPath();
0379:                    List<SymbolicInstance<?>> cargs = null;
0380:                    if (args != null) {
0381:                        cargs = new ArrayList<SymbolicInstance<?>>();
0382:                        for (SymbolicInstance<?> i : args) {
0383:                            cargs.add(i == null ? null : i.getClone());
0384:                        }
0385:                    }
0386:                    try {
0387:                        invoke(null, executable.getReference(), target, cargs);
0388:                    } catch (SymbolicWrappedException e) {
0389:                        e.printStackTrace();
0390:                        // swallow it
0391:                    }
0392:                    notifyEndPath();
0393:                    // System.out.println("END");
0394:                    // dumpPaths();
0395:                    // heap.dump();
0396:                } while (!branchingPoints.isEmpty());
0397:                // dumpPaths();
0398:
0399:            }
0400:
0401:            /**
0402:             * Tell if the given method follows the getter naming conventions.
0403:             */
0404:            boolean isGetter(CtExecutableReference<?> e) {
0405:                return e.getSimpleName().startsWith("get")
0406:                        && (e.getParameterTypes().size() == 0);
0407:            }
0408:
0409:            /**
0410:             * Tell if the given method follows the setter naming conventions.
0411:             */
0412:            boolean isSetter(CtExecutableReference<?> e) {
0413:                return e.getSimpleName().startsWith("set")
0414:                        && (e.getParameterTypes().size() == 1);
0415:            }
0416:
0417:            boolean isStateFullExternal(CtTypeReference<?> type) {
0418:                for (CtTypeReference<?> t : getStatefullExternals()) {
0419:                    if (t.isAssignableFrom(type)) {
0420:                        return true;
0421:                    }
0422:                }
0423:                return false;
0424:            }
0425:
0426:            @SuppressWarnings("unchecked")
0427:            private <T> SymbolicInstance<T> invoke(
0428:                    CtAbstractInvocation<?> caller,
0429:                    CtExecutableReference<T> executable,
0430:                    SymbolicInstance<?> target, List<SymbolicInstance<?>> args) {
0431:                enterExecutable(caller, executable, target, args);
0432:                // System.out.println("[invoking " + caller + "]");
0433:                // stack.dump();
0434:                // heap.dump();
0435:                try {
0436:                    CtExecutable<?> decl = executable.getDeclaration();
0437:                    if (decl != null) {
0438:                        if (decl.getBody() != null) {
0439:                            evaluate(decl.getBody());
0440:                            if (executable.isConstructor()) {
0441:                                result = target;
0442:                            } else {
0443:                                result = null;
0444:                            }
0445:                        } else {
0446:                            result = new SymbolicInstance(this , executable
0447:                                    .getType(), false);
0448:                        }
0449:                    } else {
0450:                        // not accessible (set the result to the return type or to the
0451:                        // field value if a getter)
0452:                        CtFieldReference fref = null;
0453:                        if (isStateFullExternal(executable.getDeclaringType())) {
0454:                            if ((target != null) && isGetter(executable)) {
0455:                                // System.out.println(m);
0456:                                SymbolicInstance r = null;
0457:                                fref = executable.getFactory().Field()
0458:                                        .createReference(
0459:                                                target.getConcreteType(),
0460:                                                executable.getType(),
0461:                                                executable.getSimpleName()
0462:                                                        .substring(3));
0463:                                r = heap.get(target.getFieldValue(fref));
0464:                                if (r != null) {
0465:                                    result = r;
0466:                                } else {
0467:                                    result = new SymbolicInstance(this ,
0468:                                            executable.getType(), false);
0469:                                }
0470:                            } else if ((target != null) && isSetter(executable)) {
0471:                                // System.out.println(m.toString()+"
0472:                                // "+caller.getPosition());
0473:                                fref = executable.getFactory().Field()
0474:                                        .createReference(
0475:                                                target.getConcreteType(),
0476:                                                executable.getType(),
0477:                                                executable.getSimpleName()
0478:                                                        .substring(3));
0479:                                target.setFieldValue(heap, fref, args.get(0));
0480:                                result = new SymbolicInstance(this , executable
0481:                                        .getType(), false);
0482:                                // heap.dump();
0483:                                // stack.dump();
0484:                            } else {
0485:                                result = new SymbolicInstance(this , executable
0486:                                        .getType(), false);
0487:                            }
0488:                        } else {
0489:                            if (!executable.isConstructor()) {
0490:                                result = new SymbolicInstance(this , executable
0491:                                        .getType(), false);
0492:                            } else {
0493:                                // TODO: JJ - verify this
0494:                                result = target;
0495:                            }
0496:                        }
0497:                    }
0498:                } catch (ReturnException e) {
0499:                    // normal return
0500:                } finally {
0501:                    exitExecutable(executable);
0502:                }
0503:                return (SymbolicInstance<T>) result;
0504:            }
0505:
0506:            private void skip(CtElement e) {
0507:                e.getFactory().getEnvironment().report(null, Severity.WARNING,
0508:                        e, "symbolic evaluator: ignoring unsupported element");
0509:            }
0510:
0511:            public <A extends Annotation> void visitCtAnnotation(
0512:                    CtAnnotation<A> annotation) {
0513:                skip(annotation);
0514:            }
0515:
0516:            public <A extends Annotation> void visitCtAnnotationType(
0517:                    CtAnnotationType<A> annotationType) {
0518:                throw new RuntimeException("Not evaluable");
0519:            }
0520:
0521:            public void visitCtAnonymousExecutable(CtAnonymousExecutable impl) {
0522:                throw new RuntimeException("Not evaluable");
0523:            }
0524:
0525:            public <T, E extends CtExpression<?>> void visitCtArrayAccess(
0526:                    CtArrayAccess<T, E> arrayAccess) {
0527:                skip(arrayAccess);
0528:            }
0529:
0530:            public <T> void visitCtArrayTypeReference(
0531:                    CtArrayTypeReference<T> reference) {
0532:                throw new RuntimeException("Not evaluable");
0533:            }
0534:
0535:            public <T> void visitCtCodeSnippetExpression(
0536:                    CtCodeSnippetExpression<T> expression) {
0537:                skip(expression);
0538:            }
0539:
0540:            public void visitCtCodeSnippetStatement(
0541:                    CtCodeSnippetStatement statement) {
0542:                skip(statement);
0543:            }
0544:
0545:            public <T> void visitCtAssert(CtAssert<T> asserted) {
0546:                skip(asserted);
0547:            }
0548:
0549:            public <T, A extends T> void visitCtAssignment(
0550:                    CtAssignment<T, A> assignment) {
0551:
0552:                if (assignment.getAssigned() instanceof  CtVariableAccess) {
0553:                    CtVariableReference<T> vref = ((CtVariableAccess<T>) assignment
0554:                            .getAssigned()).getVariable();
0555:                    SymbolicInstance<?> res = evaluate(assignment
0556:                            .getAssignment());
0557:                    if (vref instanceof  CtFieldReference) {
0558:                        CtExpression<?> target = ((CtFieldAccess<?>) assignment
0559:                                .getAssigned()).getTarget();
0560:                        if (target == null) {
0561:                            stack.getThis().setFieldValue(heap, vref, res);
0562:                        } else {
0563:                            ((SymbolicInstance<?>) evaluate(target))
0564:                                    .setFieldValue(heap, vref, res);
0565:                        }
0566:                    } else {
0567:                        stack.setVariableValue(vref, res);
0568:                    }
0569:                    result = res;
0570:                }
0571:            }
0572:
0573:            @SuppressWarnings("unchecked")
0574:            public <T> void visitCtBinaryOperator(CtBinaryOperator<T> operator) {
0575:                SymbolicInstance left = evaluate(operator.getLeftHandOperand());
0576:                SymbolicInstance right = evaluate(operator
0577:                        .getRightHandOperand());
0578:                switch (operator.getKind()) {
0579:                case AND:
0580:                case OR:
0581:                case EQ:
0582:                    if (left.equalsRef(right)) {
0583:                        result = SymbolicInstance.TRUE;
0584:                    } else {
0585:                        result = SymbolicInstance.FALSE;
0586:                    }
0587:                    return;
0588:                case NE:
0589:                    if (!left.equalsRef(right)) {
0590:                        result = SymbolicInstance.TRUE;
0591:                    } else {
0592:                        result = SymbolicInstance.FALSE;
0593:                    }
0594:                    return;
0595:                case GE:
0596:                case LE:
0597:                case GT:
0598:                case LT:
0599:                case INSTANCEOF:
0600:                    SymbolicInstance<Boolean> bool = new SymbolicInstance<Boolean>(
0601:                            this , operator.getFactory().Type().createReference(
0602:                                    boolean.class), false);
0603:                    result = bool;
0604:                    return;
0605:                case MINUS:
0606:                case MUL:
0607:                case DIV:
0608:                    SymbolicInstance<Number> number = new SymbolicInstance<Number>(
0609:                            this , operator.getFactory().Type().createReference(
0610:                                    Number.class), false);
0611:                    result = number;
0612:                    return;
0613:                case PLUS:
0614:                    if ((left.getConcreteType() != null)
0615:                            && ((left.getConcreteType().getActualClass() == String.class) || (right
0616:                                    .getConcreteType().getActualClass() == String.class))) {
0617:                        SymbolicInstance<String> string = new SymbolicInstance<String>(
0618:                                this , operator.getFactory().Type()
0619:                                        .createReference(String.class), false);
0620:                        result = string;
0621:                        return;
0622:                    }
0623:                    bool = new SymbolicInstance<Boolean>(this ,
0624:                            operator.getFactory().Type().createReference(
0625:                                    boolean.class), false);
0626:                    result = bool;
0627:                    return;
0628:                default:
0629:                    throw new RuntimeException("unsupported operator");
0630:                }
0631:            }
0632:
0633:            public <R> void visitCtBlock(CtBlock<R> block) {
0634:                for (CtStatement s : block.getStatements()) {
0635:                    evaluate(s);
0636:                }
0637:            }
0638:
0639:            public void visitCtBreak(CtBreak breakStatement) {
0640:                skip(breakStatement);
0641:            }
0642:
0643:            public <E> void visitCtCase(CtCase<E> caseStatement) {
0644:                skip(caseStatement);
0645:            }
0646:
0647:            public void visitCtCatch(CtCatch catchBlock) {
0648:                skip(catchBlock);
0649:            }
0650:
0651:            public <T> void visitCtClass(CtClass<T> ctClass) {
0652:                throw new RuntimeException("Not evaluable");
0653:            }
0654:
0655:            public <T> void visitCtConstructor(CtConstructor<T> c) {
0656:                throw new RuntimeException("Not evaluable");
0657:            }
0658:
0659:            public void visitCtContinue(CtContinue continueStatement) {
0660:                skip(continueStatement);
0661:            }
0662:
0663:            public void visitCtDo(CtDo doLoop) {
0664:                evaluate(doLoop.getBody());
0665:                evaluate(doLoop.getLoopingExpression());
0666:            }
0667:
0668:            public <T extends Enum<?>> void visitCtEnum(CtEnum<T> ctEnum) {
0669:                throw new RuntimeException("Not evaluable");
0670:            }
0671:
0672:            public <T> void visitCtExecutableReference(
0673:                    CtExecutableReference<T> reference) {
0674:                throw new RuntimeException("Not evaluable");
0675:            }
0676:
0677:            public <T> void visitCtField(CtField<T> f) {
0678:                skip(f);
0679:            }
0680:
0681:            boolean isAccessible(CtFieldReference<?> field) {
0682:                return field.getDeclaringType().isAssignableFrom(
0683:                        stack.getThis().getConcreteType());
0684:            }
0685:
0686:            public <T> void visitCtFieldAccess(CtFieldAccess<T> fieldAccess) {
0687:                if (fieldAccess.getVariable().getSimpleName().equals("this")) {
0688:                    result = stack.getThis();
0689:                    return;
0690:                }
0691:                if (fieldAccess.getVariable().getSimpleName().equals("class")) {
0692:                    SymbolicInstance<?> type = heap.getType(this , fieldAccess
0693:                            .getType());
0694:                    result = type;
0695:                    return;
0696:                }
0697:                SymbolicInstance<?> target = evaluate(fieldAccess.getTarget());
0698:                if (target == null) {
0699:                    if (isAccessible(fieldAccess.getVariable())) {
0700:                        target = stack.getThis();
0701:                    }
0702:                }
0703:                if ((target != null) && !target.isExternal()) {
0704:                    result = heap.get(target.getFieldValue(fieldAccess
0705:                            .getVariable()));
0706:                } else {
0707:                    // set the type to the declared one
0708:                    SymbolicInstance<T> i = new SymbolicInstance<T>(this ,
0709:                            fieldAccess.getType(), false);
0710:                    // this instance is not put on the heap because it will be put if
0711:                    // assigned to an object's field
0712:                    result = i;
0713:                }
0714:            }
0715:
0716:            public <T> void visitCtFieldReference(CtFieldReference<T> reference) {
0717:                throw new RuntimeException("Not evaluable");
0718:            }
0719:
0720:            public void visitCtFor(CtFor forLoop) {
0721:                for (CtStatement s : forLoop.getForInit()) {
0722:                    evaluate(s);
0723:                }
0724:                evaluate(forLoop.getExpression());
0725:                evaluate(forLoop.getBody());
0726:                for (CtStatement s : forLoop.getForUpdate()) {
0727:                    evaluate(s);
0728:                }
0729:            }
0730:
0731:            public void visitCtForEach(CtForEach foreach) {
0732:                evaluate(foreach.getBody());
0733:            }
0734:
0735:            public void visitCtIf(CtIf ifElement) {
0736:                SymbolicInstance<?> result = evaluate(ifElement.getCondition());
0737:                if (result == SymbolicInstance.TRUE) {
0738:                    evaluate(ifElement.getThenStatement());
0739:                    return;
0740:                }
0741:                if (result == SymbolicInstance.FALSE) {
0742:                    evaluate(ifElement.getElseStatement());
0743:                    return;
0744:                }
0745:                evaluateBranches(ifElement.getThenStatement(), ifElement
0746:                        .getElseStatement());
0747:            }
0748:
0749:            public <T> void visitCtInterface(CtInterface<T> intrface) {
0750:                throw new RuntimeException("Not evaluable");
0751:            }
0752:
0753:            public <T> void visitCtInvocation(CtInvocation<T> invocation) {
0754:                CtExecutableReference<T> eref = invocation.getExecutable();
0755:                // if (eref.getSimpleName().equals("<init>"))
0756:                // return;
0757:                List<SymbolicInstance<?>> arguments = new ArrayList<SymbolicInstance<?>>();
0758:                for (CtExpression<?> expr : invocation.getArguments()) {
0759:                    SymbolicInstance<?> o = evaluate(expr);
0760:                    arguments.add(o);
0761:                }
0762:                SymbolicInstance<?> target = evaluate(invocation.getTarget());
0763:                // redirect ref to the overloading method if any
0764:                if (target != null) {
0765:                    CtExecutableReference<T> override = eref
0766:                            .getOverridingExecutable(target.getConcreteType());
0767:                    if (override != null) {
0768:                        eref = override;
0769:                    }
0770:                }
0771:                if (target == null) {
0772:                    if (eref.isStatic()) {
0773:                        target = heap.getType(this , eref.getDeclaringType());
0774:                    } else {
0775:                        target = stack.getThis();
0776:                    }
0777:                }
0778:                // CtExecutable<T> e = eref.getDeclaration();
0779:                // if (e != null) {
0780:                invoke(invocation, eref, target, arguments);
0781:                // } else {
0782:                // // method is not accessible
0783:                // // set the result to the declared type
0784:                // Method m = invocation.getExecutable().getActualMethod();
0785:                // stack.setResult(heap.get(this, invocation.getFactory().Type()
0786:                // .createReference(m.getReturnType())));
0787:                // }
0788:            }
0789:
0790:            public <T> void visitCtLiteral(CtLiteral<T> literal) {
0791:                if (literal.getValue() == null) {
0792:                    result = SymbolicInstance.NULL;
0793:                } else if (literal.getValue().equals(true)) {
0794:                    result = SymbolicInstance.TRUE;
0795:                } else if (literal.getValue().equals(false)) {
0796:                    result = SymbolicInstance.FALSE;
0797:                } else if ((literal.getValue() instanceof  Number)) {
0798:                    if (((Number) literal.getValue()).intValue() == 0) {
0799:                        result = SymbolicInstance.ZERO;
0800:                    }
0801:                } else {
0802:                    result = new SymbolicInstance<T>(this , literal.getType(),
0803:                            false);
0804:                }
0805:            }
0806:
0807:            public <T> void visitCtLocalVariable(
0808:                    final CtLocalVariable<T> localVariable) {
0809:                stack.setVariableValue(localVariable.getReference(),
0810:                        evaluate(localVariable.getDefaultExpression()));
0811:            }
0812:
0813:            public <T> void visitCtLocalVariableReference(
0814:                    CtLocalVariableReference<T> reference) {
0815:                throw new RuntimeException("Not evaluable");
0816:            }
0817:
0818:            public <T> void visitCtMethod(CtMethod<T> m) {
0819:                throw new RuntimeException("Not evaluable");
0820:            }
0821:
0822:            public <T> void visitCtNewArray(CtNewArray<T> newArray) {
0823:                skip(newArray);
0824:            }
0825:
0826:            public <T> void visitCtNewClass(CtNewClass<T> newClass) {
0827:                // CtExecutable<T> e = eref.getDeclaration();
0828:                List<SymbolicInstance<?>> arguments = new ArrayList<SymbolicInstance<?>>();
0829:                for (CtExpression<?> expr : newClass.getArguments()) {
0830:                    SymbolicInstance<?> o = evaluate(expr);
0831:                    arguments.add(o);
0832:                }
0833:                SymbolicInstance<T> i = new SymbolicInstance<T>(this , newClass
0834:                        .getType(), false);
0835:                heap.store(i);
0836:                // evaluate the constructor
0837:                invoke(newClass, newClass.getExecutable(), i, arguments);
0838:                // TODO: something better for externals
0839:                result = i;
0840:            }
0841:
0842:            public <T, A extends T> void visitCtOperatorAssignement(
0843:                    CtOperatorAssignment<T, A> assignment) {
0844:                skip(assignment);
0845:            }
0846:
0847:            public void visitCtPackage(CtPackage ctPackage) {
0848:                throw new RuntimeException("Not evaluable");
0849:            }
0850:
0851:            public void visitCtPackageReference(CtPackageReference reference) {
0852:                throw new RuntimeException("Not evaluable");
0853:            }
0854:
0855:            public <T> void visitCtParameter(CtParameter<T> parameter) {
0856:                throw new RuntimeException("Not evaluable");
0857:            }
0858:
0859:            public <R> void visitCtStatementList(CtStatementList<R> statements) {
0860:                skip(statements);
0861:            }
0862:
0863:            public <T> void visitCtParameterReference(
0864:                    CtParameterReference<T> reference) {
0865:                throw new RuntimeException("Not evaluable");
0866:            }
0867:
0868:            public <R> void visitCtReturn(CtReturn<R> returnStatement) {
0869:                result = evaluate(returnStatement.getReturnedExpression());
0870:                throw new ReturnException(returnStatement);
0871:            }
0872:
0873:            public <E> void visitCtSwitch(CtSwitch<E> switchStatement) {
0874:                skip(switchStatement);
0875:            }
0876:
0877:            public void visitCtSynchronized(CtSynchronized synchro) {
0878:                skip(synchro);
0879:            }
0880:
0881:            @SuppressWarnings("unchecked")
0882:            public void visitCtThrow(CtThrow throwStatement) {
0883:                throw new SymbolicWrappedException(evaluate(throwStatement
0884:                        .getThrownExpression()), throwStatement, getStack());
0885:            }
0886:
0887:            public void visitCtTry(CtTry tryBlock) {
0888:                try {
0889:                    evaluate(tryBlock.getBody());
0890:                } catch (ReturnException r) {
0891:                    // normal return
0892:                } catch (SymbolicWrappedException e) {
0893:                    for (CtCatch c : tryBlock.getCatchers()) {
0894:                        if (c.getParameter().getType().isAssignableFrom(
0895:                                e.getAbstractCause().getConcreteType())) {
0896:                            getStack().setVariableValue(
0897:                                    c.getParameter().getReference(),
0898:                                    e.getAbstractCause());
0899:                            evaluate(c.getBody());
0900:                            return;
0901:                        }
0902:                    }
0903:                    // re-throw unhandled exception
0904:                    throw e;
0905:                } finally {
0906:                    evaluate(tryBlock.getFinalizer());
0907:                }
0908:            }
0909:
0910:            public void visitCtTypeParameter(CtTypeParameter typeParameter) {
0911:                throw new RuntimeException("Not evaluable");
0912:            }
0913:
0914:            public void visitCtTypeParameterReference(
0915:                    CtTypeParameterReference ref) {
0916:                throw new RuntimeException("Not evaluable");
0917:            }
0918:
0919:            public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
0920:                throw new RuntimeException("Not evaluable");
0921:            }
0922:
0923:            public <T> void visitCtUnaryOperator(CtUnaryOperator<T> operator) {
0924:                evaluate(operator.getOperand());
0925:                // switch (operator.getKind()) {
0926:                // case POSTINC:
0927:                // case POSTDEC:
0928:                // case PREINC:
0929:                // case PREDEC:
0930:                // case NEG:
0931:                // AbstractInstance<Number>
0932:                // number=AbstractInstance.get(this,operator.getFactory().Type().createReference(Number.class));
0933:                // setResult(number);
0934:                // return;
0935:                // case NOT:
0936:                // AbstractInstance<Boolean>
0937:                // bool=AbstractInstance.get(this,operator.getFactory().Type().createReference(Boolean.class));
0938:                // setResult(bool);
0939:                // return;
0940:                // default:
0941:                // throw new RuntimeException("unsupported operator");
0942:                // }
0943:            }
0944:
0945:            public <T> void visitCtVariableAccess(
0946:                    CtVariableAccess<T> variableAccess) {
0947:                CtVariableReference<?> vref = variableAccess.getVariable();
0948:                result = stack.getVariableValue(vref);
0949:            }
0950:
0951:            public void visitCtWhile(CtWhile whileLoop) {
0952:                evaluate(whileLoop.getLoopingExpression());
0953:                evaluate(whileLoop.getBody());
0954:            }
0955:
0956:            public <T> void visitCtConditional(CtConditional<T> conditional) {
0957:                evaluate(conditional.getCondition());
0958:                evaluate(conditional.getThenExpression());
0959:                evaluate(conditional.getElseExpression());
0960:            }
0961:
0962:            public SymbolicHeap getHeap() {
0963:                return heap;
0964:            }
0965:
0966:            public SymbolicEvaluationStack getStack() {
0967:                return stack;
0968:            }
0969:
0970:            protected void notifyExitStep(SymbolicEvaluationStep step) {
0971:                for (SymbolicEvaluatorObserver o : observers) {
0972:                    o.onExitStep(this , step);
0973:                }
0974:
0975:            }
0976:
0977:            protected void notifyEnterStep(SymbolicEvaluationStep step) {
0978:                for (SymbolicEvaluatorObserver o : observers) {
0979:                    o.onEnterStep(this , step);
0980:                }
0981:            }
0982:
0983:            protected void notifyStartPath() {
0984:                for (SymbolicEvaluatorObserver o : observers) {
0985:                    o.onStartPath(this );
0986:                }
0987:            }
0988:
0989:            protected void notifyEndPath() {
0990:                for (SymbolicEvaluatorObserver o : observers) {
0991:                    o.onEndPath(this );
0992:                }
0993:            }
0994:
0995:            public void addObserver(SymbolicEvaluatorObserver observer) {
0996:                observers.add(observer);
0997:            }
0998:
0999:            public void addObservers(
1000:                    List<SymbolicEvaluatorObserver> evaluatorObservers) {
1001:                observers.addAll(evaluatorObservers);
1002:            }
1003:
1004:            public void invoke(CtExecutable<?> executable) {
1005:                Factory f = executable.getFactory();
1006:                List<SymbolicInstance<?>> args = new ArrayList<SymbolicInstance<?>>();
1007:                for (CtParameter<?> p : executable.getParameters()) {
1008:                    SymbolicInstance<?> arg = f.Eval().createSymbolicInstance(
1009:                            this , p.getType(), false);
1010:                    getHeap().store(arg);
1011:                    args.add(arg);
1012:                }
1013:                // Create target(this) for the invocation
1014:                SymbolicInstance<?> target = f.Eval()
1015:                        .createSymbolicInstance(
1016:                                this ,
1017:                                executable.getDeclaringType().getReference(),
1018:                                executable.getModifiers().contains(
1019:                                        ModifierKind.STATIC));
1020:                // Seed the fields of the class
1021:                CtType<?> targetType = executable.getDeclaringType();
1022:                for (CtField<?> field : targetType.getFields()) {
1023:                    if (!field.getModifiers().contains(ModifierKind.STATIC)
1024:                            && executable.getModifiers().contains(
1025:                                    ModifierKind.STATIC)) {
1026:                        continue;
1027:                    }
1028:
1029:                    CtVariableReference<?> fref = field.getReference();
1030:                    SymbolicInstance<?> si = f.Eval().createSymbolicInstance(
1031:                            this , fref.getType(), false);
1032:                    target.setFieldValue(getHeap(), fref, si);
1033:                }
1034:
1035:                getHeap().store(target);
1036:                invoke(target, executable, args);
1037:
1038:            }
1039:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.