Source Code Cross Referenced for JS2Doc.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » js2doc » 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 » Ajax » Laszlo 4.0.10 » org.openlaszlo.js2doc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* *****************************************************************************
0002:         * JS2Doc.java
0003:         * ****************************************************************************/
0004:
0005:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
0006:         * Copyright 2006-2007 Laszlo Systems, Inc.  All Rights Reserved.              *
0007:         * Use is subject to license terms.                                            *
0008:         * J_LZ_COPYRIGHT_END *********************************************************/
0009:
0010:        package org.openlaszlo.js2doc;
0011:
0012:        import java.io.*;
0013:        import java.util.*;
0014:        import java.util.logging.*;
0015:        import java.util.regex.*;
0016:        import org.openlaszlo.js2doc.JS2DocUtils.InternalError;
0017:        import org.openlaszlo.sc.Compiler;
0018:        import org.openlaszlo.sc.parser.*;
0019:        import org.openlaszlo.utils.FileUtils;
0020:        import org.w3c.dom.*;
0021:
0022:        /**
0023:         * 
0024:         *
0025:         */
0026:        public class JS2Doc {
0027:
0028:            static private Logger logger = Logger
0029:                    .getLogger("org.openlaszlo.js2doc");
0030:
0031:            static public class DocumentationError extends RuntimeException {
0032:                /** Constructs an instance.
0033:                 * @param message a string
0034:                 */
0035:                public DocumentationError(String message) {
0036:                    super ("js2doc Error " + message);
0037:                }
0038:            }
0039:
0040:            private static class Visitor {
0041:
0042:                String baseDirectory;
0043:                String relativeBase;
0044:                String libraryID;
0045:                String unitID;
0046:                String objectID;
0047:                ConditionalState currentState;
0048:
0049:                Set runtimeOptions;
0050:                Map runtimeAliases;
0051:                List buildOptions;
0052:
0053:                // TODO [jgrandy 12/3/2006] turn into parameter
0054:                static private String unitCommentMarker = "copyright";
0055:
0056:                public Visitor(String baseDirectory, String relativeBase,
0057:                        String libraryID, Set runtimeOptions,
0058:                        Map runtimeAliases, List buildOptions) {
0059:
0060:                    this .baseDirectory = baseDirectory;
0061:                    this .relativeBase = relativeBase;
0062:                    this .libraryID = libraryID;
0063:                    this .unitID = null;
0064:                    this .objectID = null;
0065:                    this .runtimeOptions = new HashSet(runtimeOptions);
0066:                    this .runtimeAliases = new HashMap(runtimeAliases);
0067:                    this .buildOptions = new ArrayList(buildOptions);
0068:                    this .currentState = new ConditionalState(
0069:                            ConditionalState.trueValue, this .runtimeOptions,
0070:                            this .buildOptions);
0071:                }
0072:
0073:                public Visitor(Visitor previous) {
0074:                    this (previous.baseDirectory, previous.relativeBase,
0075:                            previous.libraryID, previous.runtimeOptions,
0076:                            previous.runtimeAliases, previous.buildOptions);
0077:                }
0078:
0079:                public void setConditionalState(ConditionalState startingState) {
0080:                    if (startingState == null)
0081:                        this .currentState = new ConditionalState(
0082:                                ConditionalState.trueValue,
0083:                                this .runtimeOptions, this .buildOptions);
0084:                    else
0085:                        this .currentState = new ConditionalState(startingState);
0086:                }
0087:
0088:                public void visitToplevelStatement(SimpleNode parseNode,
0089:                        org.w3c.dom.Element docNode) {
0090:                    //logger.fine(parseNode.getClass().getName());
0091:                    if (parseNode instanceof  ASTProgram
0092:                            || parseNode instanceof  ASTStatement
0093:                            || parseNode instanceof  ASTDirectiveBlock) {
0094:                        SimpleNode[] children = parseNode.getChildren();
0095:                        for (int i = 0; i < children.length; i++) {
0096:                            this .visitToplevelStatement(children[i], docNode);
0097:                        }
0098:                    } else if (parseNode instanceof  ASTVariableStatement) {
0099:                        visitVariableStatement(parseNode, docNode);
0100:                    } else if (parseNode instanceof  ASTAssignmentExpression) {
0101:                        visitTopLevelAssignmentExpression(parseNode, docNode);
0102:                    } else if (parseNode instanceof  ASTFunctionDeclaration) {
0103:                        visitFunctionDeclaration(parseNode, docNode);
0104:                    } else if (parseNode instanceof  ASTClassDefinition) {
0105:                        visitClassDeclaration(parseNode, docNode, null);
0106:                    } else if (parseNode instanceof  ASTIfDirective) {
0107:                        visitTopLevelIfDirective(parseNode, docNode);
0108:                    } else if (parseNode instanceof  ASTIncludeDirective) {
0109:                        visitIncludeDirective(parseNode, docNode, true);
0110:                    } else if (parseNode instanceof  ASTCallExpression) {
0111:                        visitCallExpression(parseNode, docNode);
0112:                    } else if (parseNode instanceof  ASTModifiedDefinition) {
0113:                        visitModifiedDefinition(parseNode, docNode);
0114:                    } else if (parseNode instanceof  ASTPragmaDirective) {
0115:                        // do nothing
0116:                    } else {
0117:                        logger.warning("Unhandled toplevel statement type "
0118:                                + parseNode.getClass().getName());
0119:                    }
0120:                }
0121:
0122:                public void visitUnit(SimpleNode parseNode,
0123:                        org.w3c.dom.Element docNode, String unitPath) {
0124:                    String oldUnitID = this .unitID;
0125:                    try {
0126:                        org.w3c.dom.Element unitNode = docNode
0127:                                .getOwnerDocument().createElement("unit");
0128:                        docNode.appendChild(unitNode);
0129:
0130:                        String comment = parseNode.getComment();
0131:                        if (comment != null) {
0132:                            Comment parsedComment = Comment
0133:                                    .extractFirstJS2DocFromCommentSequence(comment);
0134:                            if (parsedComment != null
0135:                                    && parsedComment
0136:                                            .hasField(unitCommentMarker))
0137:                                this .processComment(unitNode, parsedComment);
0138:                        }
0139:
0140:                        // no need to use java.io.File.separatorChar here, since the separator
0141:                        // will appear unix-style (as '/') in the source code
0142:                        String relativePath = this .relativeBase + '/'
0143:                                + unitPath;
0144:                        // relativeBase may (erroneously) start with a '/', or may be the empty
0145:                        // string, so cover both cases here to ensure we have a truly relative
0146:                        // path.
0147:                        if (relativePath.charAt(0) == '/')
0148:                            relativePath = relativePath.substring(1);
0149:
0150:                        unitNode.setAttribute("path", relativePath);
0151:                        //unitNode.setAttribute("path", unitPath);
0152:
0153:                        // no need to use java.io.File.separatorChar here, since the separator
0154:                        // will appear unix-style (as '/') in the source code
0155:                        this .unitID = unitPath.replace('/', '.').replace(' ',
0156:                                '_');
0157:                        if (this .libraryID != null)
0158:                            this .unitID = this .libraryID + "." + this .unitID;
0159:                        unitNode.setAttribute("id", this .unitID);
0160:
0161:                        //System.out.println("visiting '" + this.unitID + "' from '" + oldUnitID + "'");
0162:
0163:                        if (oldUnitID != null)
0164:                            unitNode.setAttribute("unitid", oldUnitID);
0165:
0166:                        describeConditionalState(unitNode);
0167:
0168:                        // *don't* nest -- we're building a flat list            
0169:                        this .visitToplevelStatement(parseNode, docNode);
0170:                    } finally {
0171:                        this .unitID = oldUnitID;
0172:                    }
0173:                }
0174:
0175:                protected void visitVariableStatement(SimpleNode parseNode,
0176:                        org.w3c.dom.Element docNode) {
0177:                    VariableDeclarationsInfo decls = collectVariableDeclarations(parseNode);
0178:                    SimpleNode[] vars = decls.variables;
0179:                    for (int i = 0; i < vars.length; i++) {
0180:                        this .visitVariableDeclaration(vars[i], docNode,
0181:                                decls.commonComment);
0182:                    }
0183:                }
0184:
0185:                class VariableDeclarationsInfo {
0186:                    String commonComment;
0187:                    SimpleNode[] variables;
0188:                }
0189:
0190:                protected VariableDeclarationsInfo collectVariableDeclarations(
0191:                        SimpleNode parseNode) {
0192:                    VariableDeclarationsInfo decls = new VariableDeclarationsInfo();
0193:
0194:                    SimpleNode[] children = parseNode.getChildren();
0195:                    checkChildrenLowerBounds(parseNode, 1, 1,
0196:                            "collectVariableDeclarations");
0197:
0198:                    SimpleNode child = children[0];
0199:                    decls.commonComment = parseNode.getComment();
0200:                    if (child instanceof  ASTVariableDeclaration) {
0201:                        decls.variables = children;
0202:                    } else if (child instanceof  ASTStatementList) {
0203:                        // children of StatementList are VariableDeclarations
0204:                        decls.variables = child.getChildren();
0205:                    } else {
0206:                        throw new InternalError(
0207:                                "Unexpected node type in collectVariableDeclarations"
0208:                                        + parseNode.getClass().getName(),
0209:                                parseNode);
0210:                    }
0211:                    return decls;
0212:                }
0213:
0214:                private void processObjectLiteral(
0215:                        ASTObjectLiteral objectLiteralNode,
0216:                        org.w3c.dom.Element objectNode) {
0217:                    SimpleNode[] children = objectLiteralNode.getChildren();
0218:
0219:                    int i = 0;
0220:                    while (i < children.length) {
0221:                        SimpleNode idNode = children[i++];
0222:                        SimpleNode valueNode = children[i++];
0223:
0224:                        String ivarName;
0225:                        if (idNode instanceof  ASTIdentifier) {
0226:                            ivarName = ((ASTIdentifier) idNode).getName();
0227:
0228:                            PropertyReference propRef = new PropertyReference(
0229:                                    objectNode, ivarName, this .currentState);
0230:
0231:                            String comment = objectLiteralNode.getComment();
0232:                            if (comment == null)
0233:                                comment = idNode.getComment();
0234:                            if (comment == null)
0235:                                comment = valueNode.getComment();
0236:
0237:                            propRef.redefineProperty(comment);
0238:
0239:                            if (propRef.hasProperty())
0240:                                propRef.redefineValue(valueNode);
0241:                            else
0242:                                logger
0243:                                        .warning("couldn't redefine object ivar value b/c ivar name couldn't be resolved");
0244:                        }
0245:                    }
0246:                }
0247:
0248:                protected void visitVariableDeclaration(SimpleNode parseNode,
0249:                        org.w3c.dom.Element docNode, String commonComment) {
0250:
0251:                    SimpleNode[] children = parseNode.getChildren();
0252:                    // child 1 is the variable name, child 2 is the (optional) initial value
0253:                    checkChildrenLowerBounds(parseNode, 1, 2,
0254:                            "visitVariableDeclaration");
0255:
0256:                    ASTIdentifier nameNode = (ASTIdentifier) children[0];
0257:                    String propertyName = nameNode.getName();
0258:
0259:                    PropertyReference propRef = new PropertyReference(docNode,
0260:                            propertyName, this .currentState);
0261:
0262:                    String comment = parseNode.getComment();
0263:                    if (comment == null) {
0264:                        comment = commonComment;
0265:                    } else if (commonComment != null) {
0266:                        logger
0267:                                .warning("Conflict between comments associated with property declaration and property statement; choosing comment closer to declaration");
0268:                    }
0269:
0270:                    org.w3c.dom.Element property = propRef
0271:                            .redefineProperty(comment);
0272:
0273:                    if (this .unitID != null)
0274:                        property.setAttribute("unitid", unitID);
0275:
0276:                    if (children.length == 2) {
0277:                        if (propRef.hasProperty()) {
0278:                            SimpleNode valueNode = children[1];
0279:                            propRef.redefineValue(valueNode);
0280:
0281:                            if (valueNode instanceof  ASTObjectLiteral) {
0282:                                this .processObjectLiteral(
0283:                                        (ASTObjectLiteral) valueNode, propRef
0284:                                                .getValue());
0285:                            }
0286:
0287:                        } else
0288:                            logger
0289:                                    .warning("tried to redefine variable decl but variable was not found");
0290:                    }
0291:                }
0292:
0293:                protected void visitTopLevelAssignmentExpression(
0294:                        SimpleNode parseNode, org.w3c.dom.Element docNode) {
0295:                    // child 1 is the lhs, child 2 is the assignment operator, child 3 is the rhs
0296:                    checkChildrenLowerBounds(parseNode, 3, 3,
0297:                            "visitTopLevelAssignmentExpression");
0298:                    SimpleNode[] children = parseNode.getChildren();
0299:
0300:                    SimpleNode lhs = children[0], op = children[1], rhs = children[2];
0301:
0302:                    boolean opIsSimpleAssignment = (((ASTOperator) op)
0303:                            .getOperator() == ParserConstants.ASSIGN);
0304:
0305:                    if (opIsSimpleAssignment) {
0306:
0307:                        try {
0308:                            PropertyReference propRef = this .resolveBinding(
0309:                                    docNode, lhs, this .currentState);
0310:
0311:                            if (propRef.isValid()) {
0312:                                org.w3c.dom.Element property = propRef
0313:                                        .redefineProperty(parseNode
0314:                                                .getComment());
0315:                                if (this .unitID != null)
0316:                                    property.setAttribute("unitid", unitID);
0317:
0318:                                if (propRef.hasProperty()) {
0319:                                    propRef.redefineValue(rhs);
0320:
0321:                                    if (rhs instanceof  ASTObjectLiteral) {
0322:                                        this .processObjectLiteral(
0323:                                                (ASTObjectLiteral) rhs, propRef
0324:                                                        .getValue());
0325:                                    }
0326:
0327:                                } else
0328:                                    logger
0329:                                            .warning("tried to redefine property but couldn't resolve property reference");
0330:                            } else {
0331:                                logger.fine("unresolved assignment target");
0332:                            }
0333:                        } catch (JS2DocUtils.InternalError e) {
0334:                            logger
0335:                                    .warning("error while processing toplevel assignment expression (rhs)");
0336:                        }
0337:                    }
0338:                }
0339:
0340:                protected void visitFunctionDeclaration(SimpleNode parseNode,
0341:                        org.w3c.dom.Element docNode) {
0342:                    SimpleNode[] children = parseNode.getChildren();
0343:                    // child 1 is the function name, child 2 is the parameter list, child 3 is the function body
0344:                    checkChildrenLowerBounds(parseNode, 3, 3,
0345:                            "visitFunctionDeclaration");
0346:
0347:                    ASTIdentifier nameNode = (ASTIdentifier) children[0];
0348:                    String fnName = nameNode.getName();
0349:
0350:                    PropertyReference propRef = new PropertyReference(docNode,
0351:                            fnName, this .currentState);
0352:
0353:                    org.w3c.dom.Element property = propRef
0354:                            .redefineProperty(parseNode.getComment());
0355:
0356:                    if (this .unitID != null)
0357:                        property.setAttribute("unitid", unitID);
0358:
0359:                    if (propRef.hasProperty())
0360:                        propRef.redefineValue(parseNode);
0361:                    else
0362:                        logger
0363:                                .warning("tried to redefine function but couldn't resolve function name");
0364:                }
0365:
0366:                protected void visitClassDeclaration(SimpleNode parseNode,
0367:                        org.w3c.dom.Element docNode,
0368:                        ASTModifiedDefinition moddef) {
0369:                    SimpleNode[] children = parseNode.getChildren();
0370:                    checkChildrenLowerBounds(parseNode, 2, 0,
0371:                            "visitClassDefinition");
0372:
0373:                    ASTIdentifier nameNode = (ASTIdentifier) children[1];
0374:                    String className = nameNode.getName();
0375:
0376:                    SimpleNode parseNodeForDoc = (moddef != null) ? moddef
0377:                            : parseNode;
0378:
0379:                    PropertyReference propRef = new PropertyReference(docNode,
0380:                            className, this .currentState);
0381:
0382:                    org.w3c.dom.Element property = propRef
0383:                            .redefineProperty(parseNodeForDoc.getComment());
0384:
0385:                    if (this .unitID != null)
0386:                        property.setAttribute("unitid", unitID);
0387:
0388:                    org.w3c.dom.Element classNode = propRef
0389:                            .redefineValue(parseNode);
0390:
0391:                    if (classNode == null)
0392:                        throw new InternalError(
0393:                                "null element returned from PropertyReference.redefineValue",
0394:                                parseNode);
0395:
0396:                    if (children.length > 4) {
0397:                        String oldObjectID = this .objectID;
0398:                        ConditionalState oldState = this .currentState;
0399:                        try {
0400:                            this .objectID = property.getAttribute("id");
0401:
0402:                            this .currentState = new ConditionalState(
0403:                                    ConditionalState.trueValue,
0404:                                    this .runtimeOptions, this .buildOptions);
0405:
0406:                            final int n = children.length;
0407:                            for (int i = 4; i < n; i++) {
0408:                                SimpleNode decl = children[i];
0409:                                this .visitClassStatement(decl, classNode, null);
0410:                            }
0411:                        } finally {
0412:                            this .objectID = oldObjectID;
0413:                            this .currentState = oldState;
0414:                        }
0415:                    }
0416:                }
0417:
0418:                protected void visitClassStatement(SimpleNode parseNode,
0419:                        org.w3c.dom.Element docNode,
0420:                        ASTModifiedDefinition moddef) {
0421:                    if (parseNode instanceof  ASTStatement
0422:                            || parseNode instanceof  ASTClassDirectiveBlock) {
0423:                        SimpleNode[] children = parseNode.getChildren();
0424:                        for (int i = 0; i < children.length; i++) {
0425:                            this 
0426:                                    .visitClassStatement(children[i], docNode,
0427:                                            null);
0428:                        }
0429:                    } else if (parseNode instanceof  ASTVariableStatement) {
0430:                        visitFieldStatement(parseNode, docNode, moddef, null);
0431:                    } else if (parseNode instanceof  ASTFunctionDeclaration) {
0432:                        visitMethodDeclaration(parseNode, docNode, moddef, null);
0433:                    } else if (parseNode instanceof  ASTCallExpression) {
0434:                        visitCallExpression(parseNode, docNode);
0435:                    } else if (parseNode instanceof  ASTAssignmentExpression) {
0436:                        visitClassAssignmentExpression(parseNode, docNode);
0437:                    } else if (parseNode instanceof  ASTClassIfDirective) {
0438:                        visitClassIfDirective(parseNode, docNode);
0439:                    } else if (parseNode instanceof  ASTIncludeDirective) {
0440:                        visitIncludeDirective(parseNode, docNode, false);
0441:                    } else if (parseNode instanceof  ASTModifiedDefinition) {
0442:                        visitModifiedDefinition(parseNode, docNode);
0443:                    } else if (parseNode instanceof  ASTPragmaDirective) {
0444:                        // do nothing
0445:                    } else {
0446:                        logger.warning("Unhandled class statement type "
0447:                                + parseNode.getClass().getName());
0448:                    }
0449:                }
0450:
0451:                protected void visitFieldStatement(SimpleNode parseNode,
0452:                        org.w3c.dom.Element docNode,
0453:                        ASTModifiedDefinition moddef, String commonComment) {
0454:                    VariableDeclarationsInfo decls = collectVariableDeclarations(parseNode);
0455:                    String comment = (decls.commonComment != null) ? decls.commonComment
0456:                            : commonComment;
0457:                    SimpleNode[] vars = decls.variables;
0458:                    for (int i = 0; i < vars.length; i++) {
0459:                        this .visitFieldDeclaration(vars[i], docNode, comment,
0460:                                moddef.isStatic());
0461:                    }
0462:                }
0463:
0464:                protected org.w3c.dom.Element ensurePrototypeNode(
0465:                        org.w3c.dom.Element docNode) {
0466:                    PropertyReference propRef = new PropertyReference(docNode,
0467:                            "prototype", null);
0468:                    propRef.ensureProperty();
0469:                    return propRef.getValue();
0470:                }
0471:
0472:                protected org.w3c.dom.Element ensureIVarsNode(
0473:                        org.w3c.dom.Element docNode) {
0474:                    PropertyReference propRef = new PropertyReference(docNode,
0475:                            "__ivars__", null);
0476:                    propRef.ensureProperty();
0477:                    return propRef.getValue();
0478:                }
0479:
0480:                protected void visitFieldDeclaration(SimpleNode parseNode,
0481:                        org.w3c.dom.Element docNode, String commonComment,
0482:                        boolean isStatic) {
0483:                    SimpleNode[] children = parseNode.getChildren();
0484:                    checkChildrenLowerBounds(parseNode, 1, 2,
0485:                            "visitFieldDeclaration");
0486:
0487:                    ASTIdentifier nameNode = (ASTIdentifier) children[0];
0488:                    String fieldName = nameNode.getName();
0489:
0490:                    org.w3c.dom.Element targetNode = docNode;
0491:
0492:                    if (isStatic == false)
0493:                        targetNode = this .ensureIVarsNode(docNode);
0494:
0495:                    if (targetNode != null) {
0496:                        PropertyReference propRef = new PropertyReference(
0497:                                targetNode, fieldName, this .currentState);
0498:
0499:                        String comment = parseNode.getComment();
0500:                        if (comment == null) {
0501:                            comment = commonComment;
0502:                        } else if (commonComment != null) {
0503:                            logger
0504:                                    .warning("Conflict between comments associated with property declaration and property statement; choosing comment closer to declaration");
0505:                        }
0506:
0507:                        propRef.redefineProperty(comment);
0508:
0509:                        if (children.length > 1) {
0510:                            if (propRef.hasProperty())
0511:                                propRef.redefineValue(children[1]);
0512:                            else
0513:                                logger
0514:                                        .warning("couldn't redefine field value b/c field name couldn't be resolved");
0515:                        }
0516:                    }
0517:                }
0518:
0519:                protected void visitMethodDeclaration(SimpleNode parseNode,
0520:                        org.w3c.dom.Element docNode,
0521:                        ASTModifiedDefinition moddef, String comment) {
0522:                    SimpleNode[] children = parseNode.getChildren();
0523:                    checkChildrenLowerBounds(parseNode, 3, 3,
0524:                            "visitMethodDeclaration");
0525:
0526:                    ASTIdentifier nameNode = (ASTIdentifier) children[0];
0527:                    String fieldName = nameNode.getName();
0528:
0529:                    org.w3c.dom.Element targetNode = docNode;
0530:
0531:                    if (moddef.isStatic() == false)
0532:                        targetNode = this .ensurePrototypeNode(docNode);
0533:
0534:                    if (targetNode != null) {
0535:                        PropertyReference propRef = new PropertyReference(
0536:                                targetNode, fieldName, this .currentState);
0537:
0538:                        String nearComment = parseNode.getComment();
0539:                        if (nearComment == null)
0540:                            nearComment = comment;
0541:
0542:                        propRef.redefineProperty(nearComment);
0543:
0544:                        if (propRef.hasProperty())
0545:                            propRef.redefineValue(parseNode);
0546:                        else
0547:                            logger.warning("couldn't resolve method name");
0548:                    }
0549:                }
0550:
0551:                protected void visitModifiedDefinition(SimpleNode parseNode,
0552:                        org.w3c.dom.Element docNode) {
0553:                    SimpleNode[] children = parseNode.getChildren();
0554:                    checkChildrenLowerBounds(parseNode, 1, 1,
0555:                            "visitModifiedDefinition");
0556:
0557:                    String comment = parseNode.getComment();
0558:                    ASTModifiedDefinition moddef = (ASTModifiedDefinition) parseNode;
0559:
0560:                    SimpleNode child = children[0];
0561:                    if (child instanceof  ASTVariableStatement)
0562:                        this .visitFieldStatement(child, docNode, moddef,
0563:                                comment);
0564:                    else if (child instanceof  ASTFunctionDeclaration)
0565:                        this .visitMethodDeclaration(child, docNode, moddef,
0566:                                comment);
0567:                    else if (child instanceof  ASTClassDefinition)
0568:                        this .visitClassDeclaration(child, docNode, moddef);
0569:                    else
0570:                        throw new InternalError("Unexpected node type "
0571:                                + parseNode.getClass().getName(), parseNode);
0572:                }
0573:
0574:                protected void visitClassAssignmentExpression(
0575:                        SimpleNode parseNode, org.w3c.dom.Element docNode) {
0576:                    SimpleNode[] children = parseNode.getChildren();
0577:                    checkChildrenLowerBounds(parseNode, 3, 3,
0578:                            "visitClassAssignmentExpression");
0579:
0580:                    // JS2DocUtils.debugPrintNode(parseNode);
0581:
0582:                    SimpleNode lhs = children[0];
0583:                    SimpleNode op = children[1];
0584:                    SimpleNode rhs = children[2];
0585:
0586:                    boolean opIsSimpleAssignment = (((ASTOperator) op)
0587:                            .getOperator() == ParserConstants.ASSIGN);
0588:
0589:                    if (opIsSimpleAssignment) {
0590:                        PropertyReference propRef = this .resolveBinding(
0591:                                docNode, lhs, this .currentState);
0592:                        propRef.redefineProperty(parseNode.getComment());
0593:                        if (propRef.hasProperty())
0594:                            propRef.redefineValue(rhs);
0595:                        else {
0596:                            logger
0597:                                    .fine("couldn't resolve class assignment target");
0598:                        }
0599:                    }
0600:                }
0601:
0602:                protected void visitIncludeDirective(SimpleNode parseNode,
0603:                        org.w3c.dom.Element docNode, boolean isTopLevel) {
0604:                    SimpleNode[] children = parseNode.getChildren();
0605:                    checkChildrenLowerBounds(parseNode, 1, 1,
0606:                            "visitIncludeDirective");
0607:
0608:                    ASTLiteral path = (ASTLiteral) children[0];
0609:
0610:                    if (this .baseDirectory == null)
0611:                        throw new InternalError(
0612:                                "include directive encountered without having file base",
0613:                                parseNode);
0614:
0615:                    // ?? error checking?
0616:
0617:                    String sourcePath = (String) path.getValue();
0618:                    File sourceFile = new File(baseDirectory + File.separator
0619:                            + sourcePath);
0620:
0621:                    try {
0622:                        org.openlaszlo.sc.Compiler.Parser p = new org.openlaszlo.sc.Compiler.Parser();
0623:                        SimpleNode parseRoot = p.parse(FileUtils
0624:                                .readFileString(sourceFile));
0625:
0626:                        // TODO [jgrandy 11/24/06] process first comment into unit's <doc> element
0627:                        //  -- in particular, objectID won't be propagated
0628:
0629:                        Visitor visitor = new Visitor(this );
0630:                        visitor.setConditionalState(this .currentState);
0631:                        visitor.unitID = this .unitID;
0632:                        visitor.visitUnit(parseRoot, docNode, sourcePath);
0633:
0634:                    } catch (IOException e) {
0635:                        throw new DocumentationError(
0636:                                "Could not read included file " + sourceFile);
0637:                    }
0638:                }
0639:
0640:                protected void visitEventValue(SimpleNode parseNode,
0641:                        org.w3c.dom.Element docNode) {
0642:                    docNode.setAttribute("type", "LzEvent");
0643:                    docNode.setAttribute("value", "LzNullEvent");
0644:                }
0645:
0646:                protected void visitEventDeclaration(SimpleNode parseNode,
0647:                        org.w3c.dom.Element docNode) {
0648:                    SimpleNode[] children = parseNode.getChildren();
0649:                    SimpleNode argList = children[1];
0650:                    SimpleNode[] args = argList.getChildren();
0651:                    checkChildrenLowerBounds(parseNode, 2, 2,
0652:                            "visitEventDeclaration argList");
0653:
0654:                    SimpleNode eventOwnerNode = args[0];
0655:                    PropertyReference propRef = this .resolveBinding(docNode,
0656:                            eventOwnerNode, this .currentState);
0657:
0658:                    if (propRef.hasProperty()) {
0659:                        logger.fine("found referent "
0660:                                + propRef.getProperty().getTagName());
0661:
0662:                        org.w3c.dom.Element propValue = propRef.getValue();
0663:
0664:                        if (propValue != null) {
0665:                            SimpleNode secondArg = args[1];
0666:                            if (!(secondArg instanceof  ASTLiteral))
0667:                                throw new InternalError(
0668:                                        "Expected literal second argument to DeclareEvent",
0669:                                        parseNode);
0670:
0671:                            String eventName = (String) ((ASTLiteral) secondArg)
0672:                                    .getValue();
0673:
0674:                            propRef = new PropertyReference(propValue,
0675:                                    eventName, this .currentState);
0676:                            propRef.redefineProperty(parseNode.getComment());
0677:
0678:                            this .visitEventValue(parseNode, propRef
0679:                                    .getProperty());
0680:                        }
0681:                    } else {
0682:                        logger.warning("Dangling referent in DeclareEvent");
0683:                    }
0684:                }
0685:
0686:                protected void visitCallExpression(SimpleNode parseNode,
0687:                        org.w3c.dom.Element docNode) {
0688:                    SimpleNode[] children = parseNode.getChildren();
0689:                    checkChildrenLowerBounds(parseNode, 2, 2,
0690:                            "visitCallExpression");
0691:
0692:                    SimpleNode functionName = children[0];
0693:                    if (functionName instanceof  ASTIdentifier) {
0694:
0695:                        String nameString = ((ASTIdentifier) functionName)
0696:                                .getName();
0697:
0698:                        if (nameString.equals("DeclareEvent"))
0699:                            visitEventDeclaration(parseNode, docNode);
0700:                    }
0701:                }
0702:
0703:                protected void visitIfDirective(SimpleNode parseNode,
0704:                        org.w3c.dom.Element docNode, boolean isTopLevel) {
0705:                    SimpleNode[] children = parseNode.getChildren();
0706:
0707:                    checkChildrenLowerBounds(parseNode, 2, 3,
0708:                            "visitIfDirective");
0709:
0710:                    // children[0] is conditional
0711:                    // children[1] is first directive block
0712:                    // children[2] is optional second directive block
0713:                    // "if (x) {} else if (y) {}" is handled recursively: the second
0714:                    // directive block will contain a new if directive.
0715:
0716:                    //JS2DocUtils.debugPrintNode(parseNode);
0717:                    //System.out.println("\n");
0718:
0719:                    SimpleNode conditional = children[0];
0720:                    SimpleNode trueDirective = children[1];
0721:                    SimpleNode falseDirective = ((children.length > 2) ? children[2]
0722:                            : null);
0723:
0724:                    ConditionalState previousState = this .currentState;
0725:
0726:                    ConditionalState directiveCondState = visitDirectiveConditional(
0727:                            conditional, docNode);
0728:                    if (directiveCondState == null)
0729:                        throw new InternalError(
0730:                                "ConditionalState returned is null", parseNode);
0731:
0732:                    ConditionalState positiveState = previousState
0733:                            .and(directiveCondState);
0734:
0735:                    logger.fine("previousState before lhs of if statement: "
0736:                            + previousState.toString());
0737:                    logger.finer("directiveCondState for lhs of if statement: "
0738:                            + directiveCondState.toString());
0739:                    logger.finer("positiveState for lhs of if statement: "
0740:                            + positiveState.toString());
0741:
0742:                    if (positiveState.inferredValue != ConditionalState.falseValue) {
0743:                        try {
0744:                            this .currentState = positiveState;
0745:
0746:                            if (isTopLevel)
0747:                                this .visitToplevelStatement(trueDirective,
0748:                                        docNode);
0749:                            else
0750:                                this .visitClassStatement(trueDirective,
0751:                                        docNode, null);
0752:                        } finally {
0753:                            this .currentState = previousState;
0754:                        }
0755:                    }
0756:
0757:                    if (falseDirective != null) {
0758:
0759:                        ConditionalState negativeState = previousState
0760:                                .and(directiveCondState.not());
0761:                        logger.finer("negativeState for rhs of if statement: "
0762:                                + negativeState.toString());
0763:
0764:                        if (negativeState.inferredValue == ConditionalState.falseValue) {
0765:                            logger
0766:                                    .fine("Branch of if statement is not reachable");
0767:                        } else {
0768:                            SimpleNode[] condChildren = falseDirective
0769:                                    .getChildren();
0770:
0771:                            try {
0772:                                this .currentState = negativeState;
0773:                                for (int i = 0; i < condChildren.length; i++) {
0774:                                    SimpleNode condChild = condChildren[i];
0775:                                    if (isTopLevel)
0776:                                        this .visitToplevelStatement(condChild,
0777:                                                docNode);
0778:                                    else
0779:                                        this .visitClassStatement(condChild,
0780:                                                docNode, null);
0781:                                }
0782:                            } finally {
0783:                                this .currentState = previousState;
0784:                            }
0785:                        }
0786:                    }
0787:                }
0788:
0789:                protected void visitTopLevelIfDirective(SimpleNode parseNode,
0790:                        org.w3c.dom.Element docNode) {
0791:                    visitIfDirective(parseNode, docNode, true);
0792:                }
0793:
0794:                protected void visitClassIfDirective(SimpleNode parseNode,
0795:                        org.w3c.dom.Element docNode) {
0796:                    visitIfDirective(parseNode, docNode, false);
0797:                }
0798:
0799:                protected ConditionalState visitDirectiveConditional(
0800:                        SimpleNode conditional, org.w3c.dom.Element docNode) {
0801:
0802:                    ConditionalState condState = new ConditionalState(
0803:                            ConditionalState.falseValue, this .runtimeOptions,
0804:                            this .buildOptions);
0805:
0806:                    if (conditional == null)
0807:                        throw new InternalError(
0808:                                "Null conditional in DirectiveConditional",
0809:                                conditional);
0810:
0811:                    if (conditional instanceof  ASTLiteral) {
0812:                        Object value = ((ASTLiteral) conditional).getValue();
0813:                        if (value instanceof  Boolean) {
0814:                            boolean bval = ((Boolean) value).booleanValue();
0815:                            condState.inferredValue = (bval == true) ? ConditionalState.trueValue
0816:                                    : ConditionalState.falseValue;
0817:                            condState.trueCases.clear();
0818:                            if (condState.inferredValue == ConditionalState.trueValue) {
0819:                                condState.trueCases
0820:                                        .addAll(condState.falseCases);
0821:                                condState.falseCases.clear();
0822:                            }
0823:                        } else {
0824:                            logger.warning("Conditional: Unknown literal type "
0825:                                    + conditional.getClass().getName());
0826:                        }
0827:                    } else if (conditional instanceof  ASTIdentifier) {
0828:                        String value = ((ASTIdentifier) conditional).getName();
0829:                        if (value.startsWith("$")) {
0830:                            String token = value.substring(1);
0831:                            if (this .runtimeOptions.contains(token)
0832:                                    || this .buildOptions.contains(token)) {
0833:                                condState.trueCases.clear();
0834:                                condState.addTrueCase(token);
0835:                            } else if (this .runtimeAliases.containsKey(token)) {
0836:                                condState = new ConditionalState(
0837:                                        (ConditionalState) this .runtimeAliases
0838:                                                .get(token));
0839:                            } else {
0840:                                logger
0841:                                        .warning("Conditional: Unmatched '$' identifier "
0842:                                                + value);
0843:                            }
0844:                        } else {
0845:                            // warning: unmatched conditional
0846:                            logger.warning("Conditional: Unmatched identifier "
0847:                                    + value);
0848:                        }
0849:                    } else if (conditional instanceof  ASTOrExpressionSequence) {
0850:                        SimpleNode[] orChildren = conditional.getChildren();
0851:                        if (orChildren.length != 2)
0852:                            throw new InternalError(
0853:                                    "Unexpected number of child nodes in ASTOrExpressionSequence",
0854:                                    conditional);
0855:                        ConditionalState op1State = visitDirectiveConditional(
0856:                                orChildren[0], docNode);
0857:                        ConditionalState op2State = visitDirectiveConditional(
0858:                                orChildren[1], docNode);
0859:                        condState = op1State.or(op2State);
0860:
0861:                    } else if (conditional instanceof  ASTAndExpressionSequence) {
0862:                        SimpleNode[] andChildren = conditional.getChildren();
0863:                        if (andChildren.length != 2)
0864:                            throw new InternalError(
0865:                                    "Unexpected number of child nodes in ASTAndExpressionSequence",
0866:                                    conditional);
0867:                        ConditionalState op1State = visitDirectiveConditional(
0868:                                andChildren[0], docNode);
0869:                        ConditionalState op2State = visitDirectiveConditional(
0870:                                andChildren[1], docNode);
0871:
0872:                        // punt if we have a combination of two indeterminate values, since we don't know
0873:                        // how to represent "a && b" using the ConditionalState class
0874:                        if (op1State.inferredValue == ConditionalState.indeterminateValue
0875:                                && op2State.inferredValue == ConditionalState.indeterminateValue) {
0876:                            condState = new ConditionalState(
0877:                                    ConditionalState.trueValue,
0878:                                    this .runtimeOptions, this .buildOptions);
0879:                        } else {
0880:                            condState = op1State.and(op2State);
0881:                        }
0882:                    } else if (conditional instanceof  ASTUnaryExpression) {
0883:                        SimpleNode[] opChildren = conditional.getChildren();
0884:                        if (opChildren.length != 2)
0885:                            throw new InternalError(
0886:                                    "Unexpected number of child nodes in ASTUnaryExpression",
0887:                                    conditional);
0888:
0889:                        SimpleNode operator = opChildren[0];
0890:                        SimpleNode operand = opChildren[1];
0891:
0892:                        if (!(operator instanceof  ASTOperator))
0893:                            throw new InternalError(
0894:                                    "Expected operator inside ASTUnaryExpression",
0895:                                    conditional);
0896:                        if (((ASTOperator) operator).getOperator() == ParserConstants.BANG) {
0897:                            ConditionalState opState = visitDirectiveConditional(
0898:                                    operand, docNode);
0899:                            condState = opState.not();
0900:                        } else {
0901:                            logger.warning("Unhandled unary operator"
0902:                                    + ((ASTOperator) operator).getOperator());
0903:                        }
0904:
0905:                    } else {
0906:                        logger.fine("Unhandled conditional type"
0907:                                + conditional.getClass().getName());
0908:                        // warning: unmatched conditional
0909:                    }
0910:
0911:                    return condState;
0912:                }
0913:
0914:                private void describeConditionalState(
0915:                        org.w3c.dom.Element docNode) {
0916:                    JS2DocUtils.describeConditionalState(this .currentState,
0917:                            docNode);
0918:                }
0919:
0920:                private void checkChildrenLowerBounds(SimpleNode node, int min,
0921:                        int expectedMax, String methodName) {
0922:                    JS2DocUtils.checkChildrenLowerBounds(node, min,
0923:                            expectedMax, methodName);
0924:                }
0925:
0926:                protected PropertyReference resolveBinding(
0927:                        org.w3c.dom.Element owner, SimpleNode lvalDesc,
0928:                        ConditionalState state) {
0929:                    return new PropertyReference(owner, lvalDesc, state);
0930:                }
0931:
0932:                protected void processComment(org.w3c.dom.Element node,
0933:                        Comment parsedComment) {
0934:
0935:                    if (!parsedComment.isEmpty()) {
0936:                        parsedComment.appendAsXML(node);
0937:
0938:                    }
0939:                }
0940:            }
0941:
0942:            static public Document toXML(String inputString, File sourceFile,
0943:                    String sourceRoot, String libraryID, Set runtimeOptions,
0944:                    List runtimeAliases, List buildOptions) {
0945:                org.openlaszlo.sc.Compiler.Parser p = new org.openlaszlo.sc.Compiler.Parser();
0946:                SimpleNode parseRoot = p.parse(inputString);
0947:
0948:                org.w3c.dom.Document doc = null;
0949:
0950:                Map runtimeAliasesMap = new HashMap();
0951:                final int n = runtimeAliases.size();
0952:                for (int i = 0; i < n; i++) {
0953:                    String[] e = (String[]) runtimeAliases.get(i);
0954:                    if (e.length == 0)
0955:                        throw new InternalError("invalid runtime alias",
0956:                                parseRoot);
0957:                    ConditionalState aliasState = new ConditionalState(
0958:                            ConditionalState.falseValue, runtimeOptions,
0959:                            buildOptions);
0960:                    for (int j = 1; j < e.length; j++) {
0961:                        aliasState.addTrueCase(e[j]);
0962:                    }
0963:                    runtimeAliasesMap.put(e[0], aliasState);
0964:                }
0965:
0966:                javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory
0967:                        .newInstance();
0968:
0969:                try {
0970:                    doc = factory.newDocumentBuilder().newDocument();
0971:
0972:                    Element docRoot = doc.createElement("js2doc");
0973:                    doc.appendChild(docRoot);
0974:
0975:                    if (runtimeOptions != null)
0976:                        docRoot.setAttribute("runtimeoptions", JS2DocUtils
0977:                                .optionsToString(runtimeOptions));
0978:                    if (buildOptions != null)
0979:                        docRoot.setAttribute("buildoptions", JS2DocUtils
0980:                                .optionsToString(buildOptions));
0981:
0982:                    if (sourceFile != null) {
0983:                        String baseDirectory = sourceFile.getParent();
0984:                        if (baseDirectory == null)
0985:                            throw new InternalError(
0986:                                    "couldn't get base directory for source file",
0987:                                    parseRoot);
0988:                        if (sourceRoot == null)
0989:                            throw new InternalError("source root is null",
0990:                                    parseRoot);
0991:
0992:                        String relativeBase = FileUtils.relativePath(
0993:                                baseDirectory, sourceRoot);
0994:
0995:                        Visitor visitor = new Visitor(baseDirectory,
0996:                                relativeBase, libraryID, runtimeOptions,
0997:                                runtimeAliasesMap, buildOptions);
0998:
0999:                        visitor.visitUnit(parseRoot, docRoot, sourceFile
1000:                                .getName());
1001:                    } else {
1002:                        Visitor visitor = new Visitor(null, null, null,
1003:                                runtimeOptions, runtimeAliasesMap, buildOptions);
1004:                        visitor.visitToplevelStatement(parseRoot, docRoot);
1005:                    }
1006:
1007:                    ReprocessComments.reprocess(docRoot, true);
1008:
1009:                    doc.normalizeDocument();
1010:
1011:                } catch (javax.xml.parsers.ParserConfigurationException e) {
1012:                    doc = null;
1013:                    e.printStackTrace();
1014:                } catch (InternalError e) {
1015:                    doc = null;
1016:                    if (e.node != null)
1017:                        JS2DocUtils.debugPrintNode(e.node);
1018:                    e.printStackTrace();
1019:                }
1020:
1021:                return doc;
1022:            }
1023:
1024:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.