Source Code Cross Referenced for AspectTransformer.java in  » Parser » Rats-Parser-Generators » xtc » lang » c4 » 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 » Parser » Rats Parser Generators » xtc.lang.c4 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * xtc - The eXTensible Compiler
0003:         * Copyright (C) 2005-2006 Princeton University
0004:         *
0005:         * This program is free software; you can redistribute it and/or
0006:         * modify it under the terms of the GNU General Public License
0007:         * version 2 as published by the Free Software Foundation.
0008:         *
0009:         * This program is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012:         * GNU General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU General Public License
0015:         * along with this program; if not, write to the Free Software
0016:         * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
0017:         * USA.
0018:         */
0019:        package xtc.lang.c4;
0020:
0021:        import xtc.tree.GNode;
0022:
0023:        import java.util.ArrayList;
0024:        import java.util.HashMap;
0025:        import java.util.Iterator;
0026:        import java.util.List;
0027:
0028:        import xtc.xform.Query;
0029:        import xtc.xform.Engine;
0030:
0031:        import java.lang.reflect.InvocationTargetException;
0032:        import java.lang.reflect.Method;
0033:
0034:        /**
0035:         * Transforms Aspect constructs to pure C code.
0036:         *
0037:         * @author Marco Yuen
0038:         */
0039:        public class AspectTransformer {
0040:            /** The root of the AST to be transformed. */
0041:            private GNode root = null;
0042:
0043:            /** A list of names of the aspect nodes */
0044:            private ArrayList aspectList = null;
0045:
0046:            /** A XForm engine */
0047:            private Engine engine = null;
0048:
0049:            /** A bindings of names and mangled names */
0050:            private HashMap bindings = null;
0051:
0052:            /** 
0053:             * Global variable that indicates the name of the 
0054:             * aspect that's being transformed.
0055:             */
0056:            private String curAspectName = null;
0057:
0058:            /** The counter for creating unique label statements. */
0059:            private static int uniqueLabelCounter = 0;
0060:
0061:            /**
0062:             * Creates an AspectTransformer.
0063:             * 
0064:             * @param r The root node
0065:             */
0066:            public AspectTransformer(GNode r) {
0067:                this .root = r;
0068:                this .engine = new Engine();
0069:                bindings = new HashMap();
0070:
0071:                // Create a list of node names that need to be transformed.
0072:                this .aspectList = new ArrayList();
0073:                this .aspectList.add("AspectDefinition");
0074:                this .aspectList.add("AspectStructureDeclaration");
0075:                this .aspectList.add("AspectFunctionDefinition");
0076:            };
0077:
0078:            /**
0079:             * A dispatcher.
0080:             * @param name The name of the method.
0081:             * @param args Arguments for the method.
0082:             * @param argValues Values of the arguments.
0083:             */
0084:            public Object process(String name, Class[] args, Object[] argValues) {
0085:                try {
0086:                    Method m = getClass().getMethod(name, args);
0087:                    return m.invoke(this , argValues);
0088:                } catch (SecurityException e) {
0089:                    e.printStackTrace();
0090:                } catch (NoSuchMethodException e) {
0091:                    e.printStackTrace();
0092:                } catch (IllegalArgumentException e) {
0093:                    e.printStackTrace();
0094:                } catch (IllegalAccessException e) {
0095:                    e.printStackTrace();
0096:                } catch (InvocationTargetException e) {
0097:                    e.printStackTrace();
0098:                }
0099:                return null;
0100:            }
0101:
0102:            /** 
0103:             * Based on the current GNode name, and dispatch the correct 
0104:             * method to perform a tranfomation on the GNode.
0105:             */
0106:            public void transform() {
0107:                List result = null;
0108:                Query query = null;
0109:                for (Iterator i = aspectList.iterator(); i.hasNext();) {
0110:                    String aspectNodeName = (String) i.next();
0111:                    if (!aspectNodeName.equals("AspectStructureDeclaration"))
0112:                        query = new Query("//" + aspectNodeName);
0113:                    else
0114:                        query = new Query("//" + aspectNodeName
0115:                                + "/../../../../..");
0116:                    result = engine.run(query, root);
0117:
0118:                    // Invoke the method with name "process"+aspectNodeName.
0119:                    if (!result.isEmpty()) {
0120:                        process("process" + aspectNodeName,
0121:                                new Class[] { List.class },
0122:                                new Object[] { result });
0123:                    }
0124:                }
0125:            }
0126:
0127:            // -------------------------------------------------------------------------
0128:            // Utility Functions
0129:            // -------------------------------------------------------------------------
0130:
0131:            /**
0132:             * Return the declarator of a node.
0133:             *
0134:             * @param n The node.
0135:             */
0136:            private String getSimpleDeclarator(GNode n) {
0137:                if (null == n)
0138:                    return null;
0139:                Query simpleDeclarator = new Query("//SimpleDeclarator");
0140:                List result = engine.run(simpleDeclarator, n);
0141:                if (result.size() <= 0)
0142:                    return null;
0143:                else
0144:                    return ((GNode) result.get(0)).getString(0);
0145:            }
0146:
0147:            /**
0148:             * Mangle the names in declarations.
0149:             *
0150:             * @param n The node to be mangled.
0151:             * @param prefix The string that prepend to the name.
0152:             */
0153:            private void changeDeclarator(GNode n, String prefix) {
0154:                boolean structUnion = false;
0155:                Query simpleQuery = new Query("//SimpleDeclarator");
0156:                Query structQuery = new Query(
0157:                        "/DeclarationSpecifiers/StructureTypeDefinition/../..");
0158:                Query unionQuery = new Query(
0159:                        "/DeclarationSpecifiers/UnionTypeDefinition/../..");
0160:
0161:                List result = engine.run(structQuery, n);
0162:                if (result.size() > 0)
0163:                    structUnion = true;
0164:                else {
0165:                    result = engine.run(unionQuery, n);
0166:                    if (result.size() > 0)
0167:                        structUnion = true;
0168:                }
0169:
0170:                if (structUnion) {
0171:                    GNode decl = (GNode) result.get(0);
0172:                    GNode structTypeDef = decl.getGeneric(1).getGeneric(0);
0173:                    String structTag = structTypeDef.getString(1);
0174:                    if (null != structTag) {
0175:                        structTypeDef.set(1, prefix + structTag);
0176:                        ((HashMap) bindings.get(curAspectName)).put("struct "
0177:                                + structTag, prefix + structTag);
0178:                    }
0179:
0180:                    GNode initDeclaratorList = decl.getGeneric(2);
0181:                    if (initDeclaratorList != null) {
0182:                        result = engine.run(simpleQuery, initDeclaratorList);
0183:                        GNode simpleDecl = (GNode) result.get(0);
0184:                        ((HashMap) bindings.get(curAspectName))
0185:                                .put(simpleDecl.getString(0), prefix
0186:                                        + simpleDecl.getString(0));
0187:                        simpleDecl.set(0, prefix + simpleDecl.getString(0));
0188:                    }
0189:                    return;
0190:                }
0191:
0192:                result = engine.run(simpleQuery, n);
0193:                GNode simpleDecl = (GNode) result.get(0);
0194:                ((HashMap) bindings.get(curAspectName)).put(simpleDecl
0195:                        .getString(0), prefix + simpleDecl.getString(0));
0196:                simpleDecl.set(0, prefix + simpleDecl.getString(0));
0197:            }
0198:
0199:            /**
0200:             * Determine if a function has a void return type or not.
0201:             *
0202:             * @param declSpec The DeclarationSpecifier of FunctionDefinition.
0203:             */
0204:            private boolean isReturnVoid(GNode declSpec) {
0205:                if (null != declSpec) {
0206:                    Query q = new Query("//VoidTypeSpecifier");
0207:                    List result = engine.run(q, declSpec);
0208:                    if (result.isEmpty())
0209:                        return false;
0210:                    else
0211:                        return true;
0212:                }
0213:                return false;
0214:            }
0215:
0216:            /**
0217:             * This function manages the mangling of names for aspect introduction.
0218:             *
0219:             * @param n The node that contains a primary identifier.
0220:             */
0221:            private void replacePriID(GNode n) {
0222:                HashMap symbols = (HashMap) bindings.get(curAspectName);
0223:                ArrayList structSyms = (ArrayList) bindings.get("struct"
0224:                        + curAspectName);
0225:                List results = null;
0226:                Iterator reIt = null;
0227:
0228:                Query priIDQuery = new Query("//PrimaryIdentifier");
0229:                Query structTypeRef = new Query(
0230:                        "/DeclarationSpecifiers/StructureTypeReference/../..");
0231:                Query typeDefName = new Query("//TypedefName");
0232:                Query directCompSel = new Query("//DirectComponentSelection");
0233:                Query indirectCompSel = new Query(
0234:                        "//IndirectComponentSelection");
0235:
0236:                results = engine.run(structTypeRef, n);
0237:                if (results.size() > 0) {
0238:                    GNode declaration = (GNode) results.get(0);
0239:                    GNode structDecl = declaration.getGeneric(1).getGeneric(0);
0240:                    GNode initDeclList = declaration.getGeneric(2);
0241:                    /*System.out.println("-------> " + structDecl.getName());*/
0242:                    if (symbols
0243:                            .containsKey("struct " + structDecl.getString(1))) {
0244:                        structDecl.set(1, symbols.get("struct "
0245:                                + structDecl.getString(1)));
0246:                    }
0247:                    // if key is in symbol table -> this struct has an advice in it.
0248:                    if (symbols.containsKey("field_struct_tag "
0249:                            + structDecl.getString(1))) {
0250:                        if (null == initDeclList) {
0251:                            System.err.println("initDeclList is null!?");
0252:                            System.exit(1);
0253:                        }
0254:                        String decltor = getSimpleDeclarator(initDeclList);
0255:                        Object val = symbols.get("field_struct_tag "
0256:                                + structDecl.getString(1));
0257:                        symbols.put("field_struct " + decltor, val);
0258:                    }
0259:
0260:                    //System.out.println("------- Symbol Table -------\n" + bindings + "\n------- Symbol Table -------");
0261:                }
0262:
0263:                results = engine.run(priIDQuery, n);
0264:                for (reIt = results.iterator(); reIt.hasNext();) {
0265:                    GNode priID = (GNode) reIt.next();
0266:                    //System.out.println("priID: " + priID.getString(0));
0267:                    if (null != symbols
0268:                            && symbols.containsKey(priID.getString(0))) {
0269:                        //System.out.println("-------> Find a match in symbols table." + priID.getString(0));
0270:                        priID.set(0, symbols.get(priID.getString(0)));
0271:                    }
0272:                }
0273:
0274:                results = engine.run(typeDefName, n);
0275:                for (reIt = results.iterator(); reIt.hasNext();) {
0276:                    GNode typedefName = (GNode) reIt.next();
0277:                    if (symbols.containsKey(typedefName.getString(0))) {
0278:                        typedefName.set(0, symbols
0279:                                .get(typedefName.getString(0)));
0280:                    }
0281:                }
0282:
0283:                results = engine.run(directCompSel, n);
0284:                if (results.size() > 0) {
0285:                    GNode leftMost = (GNode) results.get(results.size() - 1);
0286:                    String structName = leftMost.getGeneric(0).getString(0);
0287:                    if (symbols.containsKey("field_struct " + structName)) {
0288:                        ArrayList fields = (ArrayList) symbols
0289:                                .get("field_struct " + structName);
0290:                        if (fields.contains(leftMost.getString(1))) {
0291:                            leftMost.set(0, makeDirectComponentSel(leftMost
0292:                                    .getGeneric(0), curAspectName));
0293:                        }
0294:                    }
0295:                }
0296:
0297:                results = engine.run(indirectCompSel, n);
0298:                if (results.size() > 0) {
0299:                    GNode leftMost = (GNode) results.get(results.size() - 1);
0300:                    String structName = leftMost.getGeneric(0).getString(0);
0301:                    if (symbols.containsKey("field_struct " + structName)) {
0302:                        ArrayList fields = (ArrayList) symbols
0303:                                .get("field_struct " + structName);
0304:                        if (fields.contains(leftMost.getString(1))) {
0305:                            leftMost.set(0, makeIndirectComponentSel(leftMost
0306:                                    .getGeneric(0), curAspectName));
0307:                        }
0308:                    }
0309:                }
0310:            }
0311:
0312:            // -------------------------------------------------------------------------
0313:            // Nodes
0314:            // -------------------------------------------------------------------------
0315:
0316:            /**
0317:             * Create a structure field access statement. (eg. sturctname.field)
0318:             *
0319:             * @param PriID The struct name.
0320:             * @param fieldName The field name.
0321:             */
0322:            public GNode makeDirectComponentSel(GNode PriID, String fieldName) {
0323:                return GNode.create("DirectComponentSelection", PriID,
0324:                        fieldName);
0325:            }
0326:
0327:            /**
0328:             * Create a structure field access with a pointer. (eg. structname->field)
0329:             *
0330:             * @param PriID The struct name.
0331:             * @param fieldName The field name.
0332:             */
0333:            public GNode makeIndirectComponentSel(GNode PriID, String fieldName) {
0334:                return GNode.create("IndirectComponentSelection", PriID,
0335:                        fieldName);
0336:            }
0337:
0338:            /**
0339:             * Create a assignment.
0340:             * 
0341:             * @param id The left hand value.
0342:             * @param val The right hand value.
0343:             */
0344:            public GNode makeAssignment(String id, GNode val) {
0345:                return GNode.create("AssignmentExpression", GNode.create(
0346:                        "PrimaryIdentifier", id), "=", val);
0347:            }
0348:
0349:            /**
0350:             * Create a goto statement.
0351:             *
0352:             * @param label The label to jump to.
0353:             */
0354:            public GNode makeGoto(String label) {
0355:                return GNode.create("GotoStatement", label);
0356:            }
0357:
0358:            /**
0359:             * Create a goto statement. However, instead of using a label 
0360:             * as the arugment, it uses a variable (eg. goto *var). 
0361:             * This is a GCC extension.
0362:             *
0363:             * @param label The name of the label variable.
0364:             * @return A goto statement.
0365:             */
0366:            public GNode makeGotoWithAddress(String label) {
0367:                return GNode.create("GotoStatement", GNode.create(
0368:                        "PrimaryIdentifier", label));
0369:            }
0370:
0371:            /**
0372:             * Create a label.
0373:             *
0374:             * @param label The label name.
0375:             * @param stmt Statements associate with that label.
0376:             * @return A label in C.
0377:             */
0378:            public GNode makeLabel(String label, GNode stmt) {
0379:                return GNode.create("LabeledStatement", GNode.create(
0380:                        "NamedLabel", label, null), stmt);
0381:            }
0382:
0383:            /**
0384:             * Create a do-while loop.
0385:             *
0386:             * @param stmts The statemenst inside the do-while loop.
0387:             * @param condition The invariant for the do-while loop.
0388:             * @return A do-while loop construct.
0389:             */
0390:            public GNode makeDoStmt(GNode stmts, GNode condition) {
0391:                if (null == stmts)
0392:                    stmts = GNode.create("CompoundStatement", null);
0393:                return GNode.create("DoStatement", stmts, condition);
0394:            }
0395:
0396:            /**
0397:             * Create a return statement.
0398:             *
0399:             * @param val The return value.
0400:             * @return A return statement with the specified value.
0401:             */
0402:            public GNode makeReturn(GNode val) {
0403:                return GNode.create("ReturnStatement", val);
0404:            }
0405:
0406:            /**
0407:             * Create a structure declaration.
0408:             *
0409:             * @param type The Qualifier for the structure.
0410:             * @param decl The name of the structure.
0411:             * @return A sturct declaration with all the fields declared.
0412:             */
0413:            public GNode makeStructureDeclaration(GNode type, String decl) {
0414:                GNode structDecl = GNode.create("StructureDeclaration");
0415:                GNode specQualList = GNode.create("SpecifierQualifierList");
0416:                GNode declarator = GNode.create("StructureDeclarationList");
0417:                GNode attrDecl = GNode.create("AttributedDeclarator");
0418:
0419:                attrDecl.add(null);
0420:                attrDecl.add(GNode.create("SimpleDeclarator").add(decl));
0421:                attrDecl.add(null);
0422:                declarator.add(attrDecl);
0423:
0424:                specQualList.add(type);
0425:
0426:                structDecl.add(null);
0427:                structDecl.add(specQualList);
0428:                structDecl.add(declarator);
0429:
0430:                return structDecl;
0431:            }
0432:
0433:            /**
0434:             * Create a declaration.
0435:             *
0436:             * @param declSpecifier The type and qualifier for the declaration.
0437:             * @param declarator The declarator for the declaration.
0438:             * @return A declaration with the specificed type and name.
0439:             */
0440:            public GNode makeDeclaration(GNode declSpecifier, String declarator) {
0441:                GNode initDeclList = GNode.create("InitializedDeclaratorList");
0442:                GNode initDecl = GNode.create("InitializedDeclarator");
0443:                GNode simpleDecl = GNode.create("SimpleDeclarator", declarator);
0444:
0445:                // Create the InitializedDeclarator
0446:                initDecl.add(null);
0447:                initDecl.add(simpleDecl);
0448:                initDecl.add(null);
0449:                initDecl.add(null);
0450:                initDecl.add(null);
0451:
0452:                // Add it to InitializedDeclaratorList
0453:                initDeclList.add(initDecl);
0454:
0455:                GNode decl = GNode.create("Declaration");
0456:                decl.add(null); // No __extension__
0457:                decl.add(declSpecifier); // Type
0458:                decl.add(initDeclList); // Declarator
0459:
0460:                return decl;
0461:            }
0462:
0463:            /**
0464:             * Create a declataion with initializer.
0465:             *
0466:             * @param declSpecifier The type.
0467:             * @param initDeclarator The initialzier.
0468:             * @return A declaration.
0469:             */
0470:            public GNode makeDeclaration(GNode declSpecifier,
0471:                    GNode initDeclarator) {
0472:                GNode decl = GNode.create("Declaration");
0473:                GNode initDeclList = GNode.create("InitializedDeclaratorList");
0474:
0475:                initDeclList.add(initDeclarator);
0476:
0477:                decl.add(null);
0478:                decl.add(declSpecifier);
0479:                decl.add(initDeclList);
0480:                return decl;
0481:            }
0482:
0483:            /**
0484:             * Create a structure definition.
0485:             *
0486:             * @param structTag The struct tag. Optional.
0487:             * @param beforeAttrs The attributes. Optional.
0488:             * @param declList The fields declaration.
0489:             * @param afterAttrs The attributes. Optional.
0490:             * @return A complete structure.
0491:             */
0492:            public GNode makeStructure(String structTag, GNode beforeAttrs,
0493:                    GNode declList, GNode afterAttrs) {
0494:                GNode structure = GNode.create("StructureTypeDefinition");
0495:                // Attributes
0496:                if (null == beforeAttrs)
0497:                    structure.add(null);
0498:                else
0499:                    structure.add(beforeAttrs);
0500:
0501:                // Structure tag
0502:                if (null == structTag)
0503:                    structure.add(null);
0504:                else
0505:                    structure.add(structTag);
0506:
0507:                // StructureDeclarationList
0508:                GNode structDecl = null;
0509:                structure.add(declList);
0510:
0511:                // Attributes
0512:                if (null == afterAttrs)
0513:                    structure.add(null);
0514:                else
0515:                    structure.add(afterAttrs);
0516:
0517:                return structure;
0518:            }
0519:
0520:            /**
0521:             * Create a LabelAddressExpression.
0522:             *
0523:             * @param label The label.
0524:             * @return A GNode LabelAddressExpression.
0525:             */
0526:            public GNode makeLabelAddressExpression(String label) {
0527:                return GNode.create("LabelAddressExpression", label);
0528:            }
0529:
0530:            /**
0531:             * Create a identifier with pointers.
0532:             * 
0533:             * @param numPointer
0534:             * @param declarator
0535:             * @return A GNode for pointer.
0536:             */
0537:            public GNode makePointerDeclarator(int numPointer, String declarator) {
0538:                GNode pointerDecl = GNode.create("PointerDeclarator");
0539:                GNode pointer = (GNode) GNode.create("Pointer").add(
0540:                        GNode.create("TypeQualifierList")).add(null);
0541:                GNode tmpPointer = pointer, newPointer = null;
0542:
0543:                for (int i = 1; i < numPointer; ++i) {
0544:                    newPointer = (GNode) GNode.create("Pointer").add(
0545:                            GNode.create("TypeQualifierList")).add(null);
0546:                    tmpPointer.set(1, newPointer);
0547:                    tmpPointer = newPointer;
0548:                }
0549:
0550:                pointerDecl.add(pointer);
0551:                pointerDecl.add(GNode.create("SimpleDeclarator")
0552:                        .add(declarator));
0553:
0554:                return pointerDecl;
0555:            }
0556:
0557:            // -------------------------------------------------------------------------
0558:            // Aspect Nodes Transformation
0559:            // -------------------------------------------------------------------------
0560:
0561:            /**
0562:             * Transform a global advice to C code.
0563:             *
0564:             * @param nodes The list of AspectDefinition nodes.
0565:             */
0566:            public void processAspectDefinition(List nodes) {
0567:                String prefix = null;
0568:                int cnt = 0;
0569:                ArrayList declList = null;
0570:
0571:                for (int i = 0; i < root.size(); ++i) {
0572:                    GNode n = root.getGeneric(i);
0573:                    declList = new ArrayList();
0574:                    if (null != n && n.hasName("AspectDefinition")) {
0575:                        curAspectName = n.getString(1);
0576:                        // Create a binding table for this aspect.
0577:                        if (!bindings.containsKey(curAspectName)) {
0578:                            bindings.put(curAspectName, new HashMap());
0579:                        }
0580:                        prefix = "__aspect__" + curAspectName + "__";
0581:                        GNode declFuncDef = n.getGeneric(2);
0582:                        // Process the declarations and function definitions
0583:                        for (int j = 2; j < n.size(); ++j) {
0584:                            GNode decl = (GNode) n.get(j);
0585:                            changeDeclarator(decl, prefix);
0586:                            declList.add(decl);
0587:                        }
0588:
0589:                        root.remove(i);
0590:                        root.addAll(i, declList);
0591:                        ++cnt;
0592:                    }
0593:                }
0594:
0595:                if (cnt != nodes.size()) {
0596:                    System.err.println("cnt != nodes.size()");
0597:                    System.exit(1);
0598:                }
0599:            }
0600:
0601:            /**
0602:             * Transfrom struct or union introduction into C code.
0603:             *
0604:             * @param nodes The list of introduction nodes.
0605:             */
0606:            public void processAspectStructureDeclaration(List nodes) {
0607:                //System.out.println("-------> Process AspectStructSpecifier");
0608:                Query q = null;
0609:                Query simpleDeclQuery = new Query("//SimpleDeclarator");
0610:                List result = null;
0611:                ArrayList fieldsVec = new ArrayList();
0612:                for (Iterator i = nodes.iterator(); i.hasNext();) {
0613:                    GNode declaration = (GNode) i.next();
0614:                    //System.out.println("-------> " + declaration.getName());
0615:                    GNode structTypeDef = declaration.getGeneric(1).getGeneric(
0616:                            0);
0617:                    String structTag = structTypeDef.getString(1);
0618:                    //System.out.println("-------> " + structTypeDef.getName());
0619:                    //System.out.println("\t\tStructure's Tag: " + structTag);
0620:                    GNode structDeclList = structTypeDef.getGeneric(2); // StructureDeclarationList
0621:                    GNode structDeclaration = null;
0622:                    GNode initDeclList = declaration.getGeneric(2);
0623:
0624:                    for (int j = 0; j < structDeclList.size(); ++j) {
0625:                        GNode structDecl = (GNode) structDeclList.get(j);
0626:                        if (null != structDecl) {
0627:                            //System.out.println("\t\t" + structDecl.getName());
0628:                            GNode declSpec = structDecl.getGeneric(1);
0629:                            //System.out.println("\t\t" + declSpec.getName());
0630:                            if (declSpec.hasName("AspectStructureDeclaration")) {
0631:                                curAspectName = declSpec.getString(1);
0632:                                if (!bindings.containsKey(curAspectName)) {
0633:                                    bindings.put(curAspectName, new HashMap());
0634:                                }
0635:                                GNode A_StructDeclList = declSpec.getGeneric(2); // StructureDeclarationList
0636:                                //System.out.println("-------> " + A_StructDeclList.getName());
0637:                                result = engine.run(simpleDeclQuery,
0638:                                        A_StructDeclList);
0639:                                for (Iterator simpleDecl = result.iterator(); simpleDecl
0640:                                        .hasNext();) {
0641:                                    GNode simDeclNode = (GNode) simpleDecl
0642:                                            .next();
0643:                                    fieldsVec.add(simDeclNode.getString(0));
0644:                                    //((ArrayList)bindings.get(curAspectName)).add("field:" + simDeclNode.getString(0));
0645:                                }
0646:                                structDeclaration = makeStructureDeclaration(
0647:                                        makeStructure(null, null,
0648:                                                A_StructDeclList, null),
0649:                                        declSpec.getString(1));
0650:                                structDeclList.set(j, structDeclaration);
0651:                            }
0652:                        }
0653:                    }
0654:
0655:                    ((HashMap) bindings.get(curAspectName)).put(
0656:                            "field_struct_tag " + structTag, fieldsVec);
0657:                    if (null != initDeclList) {
0658:                        for (Iterator it = initDeclList.iterator(); it
0659:                                .hasNext();) {
0660:                            GNode initDecl = (GNode) it.next();
0661:                            ((HashMap) bindings.get(curAspectName)).put(
0662:                                    "field_struct "
0663:                                            + getSimpleDeclarator(initDecl),
0664:                                    fieldsVec);
0665:                        }
0666:                    }
0667:                }
0668:            }
0669:
0670:            /**
0671:             * Transform AspectFunctionDefinition to C code.
0672:             *
0673:             * @param nodes
0674:             */
0675:            public void processAspectFunctionDefinition(List nodes) {
0676:                AspectFunctionAnalyzer funcAnalyzer = new AspectFunctionAnalyzer(
0677:                        (GNode) nodes.get(0));
0678:                funcAnalyzer.analyze();
0679:
0680:                boolean isAround = false, returnVoid = false, printReturn = false, hasAround = false, bodyBegin = false;
0681:                ArrayList aroundList = new ArrayList();
0682:                Query proceedCheck = new Query(
0683:                        "//FunctionCall/PrimaryIdentifier/\"proceed\"");
0684:                Query simpleDecl = new Query("//SimpleDeclarator");
0685:                List result = null;
0686:                String functionName = "", nodeName = "";
0687:                hasAround = funcAnalyzer.hasAround();
0688:                //System.out.println("AspectFunctionDefinition ------->");
0689:
0690:                /*
0691:                 * XXX: To make this more clean. I will probably need to change the grammar and use 
0692:                 * the inside-out operator from XForm.
0693:                 * Search for AspectFunctionDefinition in the root level.
0694:                 * If found, do the transfromation. Then, replace AspectFunctionDefinition
0695:                 * with FunctionDefinition.
0696:                 */
0697:                for (int nodeInx = 0; nodeInx < root.size(); ++nodeInx) {
0698:                    boolean gotReturn = false, gotProceed = false;
0699:
0700:                    GNode node = root.getGeneric(nodeInx);
0701:                    if (null == node
0702:                            || !node.hasName("AspectFunctionDefinition"))
0703:                        continue;
0704:
0705:                    GNode returnType = node.getGeneric(1);
0706:                    //System.out.println("Return Type:" + returnType.getName());
0707:                    returnVoid = isReturnVoid(returnType);
0708:
0709:                    GNode paramList = node.getGeneric(2).getGeneric(1);
0710:                    //System.out.println("Parameter List: " + paramList.getName());
0711:
0712:                    GNode aspectCompound = (GNode) node.get(4);
0713:                    //System.out.println("Compound: " + aspectCompound.getName());
0714:
0715:                    // The node that will eventually replace AspectCompoundStatement.
0716:                    GNode replacementNode = GNode.create("CompoundStatement");
0717:
0718:                    GNode beforeAReturnVal = null;
0719:
0720:                    // >>>> ----------------------- Declaring __returned__
0721:                    // Declare __returned__ if the return type is non-void.
0722:                    if (!(returnVoid)) {
0723:                        // System.out.println("-------> Non-void return type.");
0724:                        // proxyNode = GNode.create("CompoundStatement");
0725:                        replacementNode.add(makeDeclaration(returnType,
0726:                                "__returned__"));
0727:                    }
0728:                    // <<<< ----------------------- Declaring __returned__ END
0729:
0730:                    // >>>> ----------------------- Declaring void *gotoDest
0731:                    if (hasAround) {
0732:                        GNode initDecl = GNode.create("InitializedDeclarator");
0733:                        for (int i = 0; i < 5; ++i) {
0734:                            initDecl.add(null);
0735:                        }
0736:                        initDecl.set(1, makePointerDeclarator(1, "gotoDest"));
0737:                        replacementNode.add(makeDeclaration(GNode.create(
0738:                                "VoidTypeSpecifier", false), initDecl));
0739:                    }
0740:                    // <<<< ----------------------- Declaring void *gotoDest END
0741:
0742:                    // >>>> ----------------------- Transforming Before Advice
0743:                    if (funcAnalyzer.hasBefore()) {
0744:                        GNode aspectStmtList = funcAnalyzer.getBefore();
0745:
0746:                        // Convert AspectStatement in AspectStmtList to CompoundStatement's.
0747:                        for (Iterator aclIt = aspectStmtList.iterator(); aclIt
0748:                                .hasNext();) {
0749:                            GNode tmpCompound = GNode
0750:                                    .create("CompoundStatement");
0751:                            GNode aspectStmt = (GNode) aclIt.next();
0752:                            curAspectName = aspectStmt.getString(1);
0753:                            //result = engine.run(proceedCheck, aspectStmt);
0754:                            if (funcAnalyzer.isAround(curAspectName)) {
0755:                                isAround = true;
0756:                                aroundList.add(curAspectName);
0757:                            }
0758:
0759:                            // System.out.println("-------> Processing (Before)" + aspectStmt.getString(1));
0760:
0761:                            // Skip the Keyword and aspect name, and copy all the declarations or 
0762:                            // expressions over to tmpCompound.
0763:
0764:                            for (int i = 2; i < aspectStmt.size(); ++i) {
0765:                                GNode tmp = (GNode) aspectStmt.get(i);
0766:                                //System.out.println("-------> Adding " + tmp.getName());
0767:
0768:                                // Set a label. Perseve advice order.
0769:                                if (bodyBegin) {
0770:                                    bodyBegin = false;
0771:                                    tmpCompound.add(makeLabel("__body_begin",
0772:                                            null));
0773:                                }
0774:
0775:                                // XXX I need to revamp this sometime in the future. Suggestions on improvements are VERY welcome :)
0776:                                result = engine
0777:                                        .run(
0778:                                                new Query(
0779:                                                        "//FunctionCall/PrimaryIdentifier/\"proceed\"/../../.."),
0780:                                                tmp);
0781:                                //System.out.println("Result: " + result.size());
0782:                                //if(tmp.hasName("ExpressionStatement") && tmp.getGeneric(0).hasName("FunctionCall")
0783:                                //                && tmp.getGeneric(0).getGeneric(0).getString(0).equals("proceed") && isAround) {
0784:                                if (isAround && result.size() > 0) {
0785:                                    for (Iterator it = result.iterator(); it
0786:                                            .hasNext();) {
0787:                                        GNode expStmt = (GNode) it.next();
0788:                                        //System.out.println("expStmt: " + expStmt.getName());
0789:                                        //System.out.println("tmp: " + tmp.getName());
0790:
0791:                                        gotProceed = true;
0792:                                        if (tmp.hasName("ExpressionStatement")) {
0793:                                            GNode expressionList = tmp
0794:                                                    .getGeneric(0)
0795:                                                    .getGeneric(1);
0796:                                            List simResult = engine.run(
0797:                                                    simpleDecl, paramList);
0798:                                            for (int paramInx = 0; paramInx < simResult
0799:                                                    .size(); ++paramInx) {
0800:                                                GNode simpleDeclarator = (GNode) simResult
0801:                                                        .get(paramInx);
0802:                                                tmpCompound
0803:                                                        .add(makeAssignment(
0804:                                                                simpleDeclarator
0805:                                                                        .getString(0),
0806:                                                                expressionList
0807:                                                                        .getGeneric(paramInx)));
0808:                                            }
0809:
0810:                                            tmpCompound
0811:                                                    .add(makeAssignment(
0812:                                                            "gotoDest",
0813:                                                            makeLabelAddressExpression("__"
0814:                                                                    + curAspectName
0815:                                                                    + "__return_point"
0816:                                                                    + uniqueLabelCounter)));
0817:
0818:                                            //Goto main body
0819:                                            tmpCompound
0820:                                                    .add(makeGoto("__body_begin"));
0821:
0822:                                            // Declare label
0823:                                            tmpCompound.add(makeLabel("__"
0824:                                                    + curAspectName
0825:                                                    + "__return_point"
0826:                                                    + uniqueLabelCounter++,
0827:                                                    null));
0828:                                        } else {
0829:                                            List parResults = engine
0830:                                                    .run(
0831:                                                            new Query(
0832:                                                                    "//FunctionCall/PrimaryIdentifier/\"proceed\"/../../../.."),
0833:                                                            tmp);
0834:                                            //System.out.println("parResults size: " + parResults.size());
0835:                                            for (Iterator pit = parResults
0836:                                                    .iterator(); pit.hasNext();) {
0837:                                                ArrayList statements = new ArrayList();
0838:                                                GNode parent = (GNode) pit
0839:                                                        .next();
0840:                                                //System.out.println("parent: " + parent.getName());
0841:                                                for (int j = 0; j < parent
0842:                                                        .size(); ++j) {
0843:                                                    GNode child = parent
0844:                                                            .getGeneric(j);
0845:                                                    //if(null != child && child.equals(expStmt)) {
0846:                                                    if (null != child
0847:                                                            && result
0848:                                                                    .contains(child)) {
0849:                                                        GNode expressionList = child
0850:                                                                .getGeneric(0)
0851:                                                                .getGeneric(1);
0852:                                                        List simResult = engine
0853:                                                                .run(
0854:                                                                        simpleDecl,
0855:                                                                        paramList);
0856:                                                        for (int paramInx = 0; paramInx < simResult
0857:                                                                .size(); ++paramInx) {
0858:                                                            GNode simpleDeclarator = (GNode) simResult
0859:                                                                    .get(paramInx);
0860:                                                            statements
0861:                                                                    .add(makeAssignment(
0862:                                                                            simpleDeclarator
0863:                                                                                    .getString(0),
0864:                                                                            expressionList
0865:                                                                                    .getGeneric(paramInx)));
0866:                                                        }
0867:
0868:                                                        statements
0869:                                                                .add(makeAssignment(
0870:                                                                        "gotoDest",
0871:                                                                        makeLabelAddressExpression("__"
0872:                                                                                + curAspectName
0873:                                                                                + "__return_point"
0874:                                                                                + uniqueLabelCounter)));
0875:                                                        statements
0876:                                                                .add(makeGoto("__body_begin"));
0877:                                                        statements
0878:                                                                .add(makeLabel(
0879:                                                                        "__"
0880:                                                                                + curAspectName
0881:                                                                                + "__return_point"
0882:                                                                                + uniqueLabelCounter++,
0883:                                                                        null));
0884:                                                        parent.remove(j);
0885:                                                        parent.addAll(j,
0886:                                                                statements);
0887:                                                    }
0888:                                                }
0889:                                            }
0890:
0891:                                        }
0892:                                    }
0893:                                    if (!tmp.hasName("ExpressionStatement"))
0894:                                        tmpCompound.add(tmp);
0895:                                } else if (tmp.hasName("ReturnStatement")
0896:                                        && isAround) {
0897:                                    gotReturn = true;
0898:                                    if (!gotProceed) {
0899:                                        tmpCompound.add(makeGoto("__after_"
0900:                                                + curAspectName
0901:                                                + "__start_point"));
0902:                                        tmpCompound.add(makeLabel("__"
0903:                                                + curAspectName
0904:                                                + "__return_point", null));
0905:                                    }
0906:                                    replacePriID(tmp);
0907:                                    tmpCompound.add(tmp);
0908:                                } else {
0909:                                    replacePriID(tmp);
0910:                                    tmpCompound.add(tmp);
0911:                                }
0912:                            }
0913:
0914:                            // Make sure there is a return statement for around advice that instrument on non-void 
0915:                            // return type function.
0916:                            if (isAround && !returnVoid && !gotReturn) {
0917:                                System.err
0918:                                        .println("Missing return statement in before advice("
0919:                                                + curAspectName
0920:                                                + ") for non-void function.");
0921:                                System.exit(1);
0922:                            }
0923:
0924:                            // If the funciton has void return type, then jump to the end of the funciton.
0925:                            if (isAround && returnVoid) {
0926:                                if (!gotProceed) {
0927:                                    tmpCompound.add(makeGoto("__after_"
0928:                                            + curAspectName + "__start_point"));
0929:                                    tmpCompound.add(makeLabel("__"
0930:                                            + curAspectName + "__return_point",
0931:                                            null));
0932:                                }
0933:                                tmpCompound.add(makeGoto("__return_point"));
0934:                            }
0935:                            if (isAround)
0936:                                bodyBegin = true;
0937:                            isAround = false;
0938:                            // No annotations.
0939:                            // tmpCompound.add(null);
0940:                            // Finally, add tmpCompound to replacementNode.
0941:                            replacementNode.add(tmpCompound);
0942:                        }
0943:                    }
0944:                    // <<<< ----------------------- Transforming Before Advice END
0945:
0946:                    // From here on now, proxyNode will either be an alias of replacementNode, or
0947:                    // a completely new node.
0948:                    GNode proxyNode = replacementNode;
0949:
0950:                    // body_begin label
0951:                    if (bodyBegin)
0952:                        proxyNode.add(makeLabel("__body_begin", null));
0953:
0954:                    // >>>> ----------------------- Transforming Body
0955:                    GNode returnVal = null;
0956:                    ArrayList body = funcAnalyzer.getBody();
0957:                    for (Iterator bodyIt = body.iterator(); bodyIt.hasNext();) {
0958:                        GNode tmp = (GNode) bodyIt.next();
0959:
0960:                        // Replace ReturnStatement (return __val__) with an Assignment __returned__ = __val__
0961:                        if (tmp.hasName("ReturnStatement")) {
0962:                            returnVal = tmp.getGeneric(0);
0963:                            // assignment
0964:                            if (!returnVoid)
0965:                                proxyNode.add(makeAssignment("__returned__",
0966:                                        returnVal));
0967:                            else
0968:                                printReturn = true;
0969:                            // goto
0970:                            proxyNode.add(makeGoto("__aspects_done"));
0971:                        } else {
0972:                            proxyNode.add(tmp);
0973:                        }
0974:                    }
0975:                    // <<<< ----------------------- Transforming Body END
0976:
0977:                    // >>>> ----------------------- ASPECTS_AFTER_PROLOGE
0978:                    proxyNode.add(makeLabel("__aspects_done", makeDoStmt(null,
0979:                            GNode.create("IntegerConstant", "0"))));
0980:                    // <<<< ----------------------- ASPECTS_AFTER_PROLOGE END
0981:
0982:                    // >>>> ----------------------- Transforming After Advice
0983:                    if (funcAnalyzer.hasAfter()) {
0984:                        // System.out.println("-------> After advice(s) detected. Start processing ..."); 
0985:                        GNode aspectStmtList = funcAnalyzer.getAfter();
0986:                        for (Iterator aclIt = aspectStmtList.iterator(); aclIt
0987:                                .hasNext();) {
0988:                            GNode tmpCompound = GNode
0989:                                    .create("CompoundStatement");
0990:                            GNode aspectStmt = (GNode) aclIt.next();
0991:                            curAspectName = aspectStmt.getString(1);
0992:                            if (aroundList.contains(curAspectName)) {
0993:                                aroundList.remove(curAspectName);
0994:                                isAround = true;
0995:                            }
0996:
0997:                            // Skip the Keyword and aspect name, and copy all the declarations or 
0998:                            // expressions over to tmpCompound.
0999:                            if (isAround) {
1000:                                tmpCompound
1001:                                        .add(makeLabel("__after_"
1002:                                                + curAspectName
1003:                                                + "__start_point", null));
1004:                            }
1005:                            for (int i = 2; i < aspectStmt.size(); ++i) {
1006:                                GNode tmp = (GNode) aspectStmt.get(i);
1007:                                result = engine.run(proceedCheck, tmp);
1008:                                if (result.size() > 0) {
1009:                                    System.err
1010:                                            .println("Calling proceed in after advice is not allowed.");
1011:                                    System.exit(1);
1012:                                }
1013:                                // System.out.println("-------> Adding " + tmp.getName());
1014:                                replacePriID(tmp);
1015:                                if (tmp.hasName("ReturnStatement")) {
1016:                                    GNode retVal = tmp.getGeneric(0);
1017:                                    tmpCompound.add(makeAssignment(
1018:                                            "__returned__", retVal));
1019:                                } else
1020:                                    tmpCompound.add(tmp);
1021:                            }
1022:                            tmpCompound.add(makeGoto("__"
1023:                                    + aspectStmt.getString(1) + "____out__"));
1024:                            //ASPECT_AFTER_END
1025:                            tmpCompound.add(makeLabel("__"
1026:                                    + aspectStmt.getString(1) + "____out__",
1027:                                    makeDoStmt(null, GNode.create(
1028:                                            "IntegerConstant", "0"))));
1029:
1030:                            if (isAround) {
1031:                                //tmpCompound.add(makeGoto("__" + curAspectName + "__return_point"));
1032:                                tmpCompound
1033:                                        .add(makeGotoWithAddress("gotoDest"));
1034:                            }
1035:
1036:                            isAround = false;
1037:                            // No annotations.
1038:                            // tmpCompound.add(null);
1039:                            // Finally, add tmpCompound to replacementNode.
1040:                            proxyNode.add(tmpCompound);
1041:                        }
1042:                    }
1043:                    // <<<< ----------------------- Transforming After Advice END
1044:
1045:                    // ASPECTS_AFTER_EPILOGUE
1046:                    proxyNode.add(makeLabel("__return_point", null));
1047:                    if (!returnVoid) {
1048:                        if (null != beforeAReturnVal)
1049:                            proxyNode.add(makeReturn(beforeAReturnVal));
1050:                        else
1051:                            proxyNode.add(makeReturn(GNode.create(
1052:                                    "PrimaryIdentifier", "__returned__")));
1053:                    } else if (printReturn)
1054:                        proxyNode.add(makeReturn(null));
1055:
1056:                    if (!proxyNode.equals(replacementNode)) {
1057:                        //System.out.println("-------> Proxy node is different from replacement node.");
1058:                        // proxyNode.add(null);
1059:                        replacementNode.add(proxyNode);
1060:                    }
1061:
1062:                    // No annotations.
1063:                    // replacementNode.add(null);
1064:                    // Replacing AspectCompoundStatement with a CompoundStatement.
1065:                    node.set(4, replacementNode);
1066:
1067:                    // XXX
1068:                    // Replace node with a FunctionDefinition.
1069:                    GNode functionDef = GNode.create("FunctionDefinition");
1070:                    for (Iterator nodeIt = node.iterator(); nodeIt.hasNext();) {
1071:                        functionDef.add(nodeIt.next());
1072:                    }
1073:
1074:                    root.set(nodeInx, functionDef);
1075:                    // XXX
1076:                }
1077:
1078:                if (aroundList.size() != 0) {
1079:                    for (int i = 0; i < aroundList.size(); ++i)
1080:                        System.err.println("Missing after advice for: "
1081:                                + aroundList.get(i));
1082:                    System.exit(1);
1083:                }
1084:            }
1085:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.