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


001:        /* -*- mode: Java; c-basic-offset: 2; -*- */
002:
003:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
004:         * Copyright 2001-2008 Laszlo Systems, Inc.  All Rights Reserved.              *
005:         * Use is subject to license terms.                                            *
006:         * J_LZ_COPYRIGHT_END *********************************************************/
007:
008:        /***
009:         * ParseTreePrinter.java
010:         * Author: Oliver Steele, P T Withington
011:         * Description: unparses the AST into Javascript.
012:         */package org.openlaszlo.sc;
013:
014:        import java.io.*;
015:        import java.util.*;
016:        import java.util.regex.Pattern;
017:        import java.text.SimpleDateFormat;
018:        import java.text.DecimalFormat;
019:
020:        import org.openlaszlo.server.LPS;
021:        import org.openlaszlo.sc.parser.*;
022:        import org.openlaszlo.sc.Translator;
023:        import org.openlaszlo.sc.Compiler.Ops;
024:        import org.openlaszlo.sc.Compiler.PassThroughNode;
025:
026:        // Values
027:        import org.openlaszlo.sc.Values;
028:
029:        // Instructions
030:        import org.openlaszlo.sc.Instructions;
031:        import org.openlaszlo.sc.Instructions.Instruction;
032:        import org.openlaszlo.sc.InstructionPrinter;
033:
034:        // This class supports the Javascript translator
035:        public class ParseTreePrinter {
036:
037:            boolean compress;
038:            String SPACE;
039:            String NEWLINE;
040:            String COMMA;
041:            String COLON;
042:            String ASSIGN;
043:            String CONDITIONAL;
044:            String ALTERNATIVE;
045:            String OPENPAREN;
046:            String CLOSEPAREN;
047:            String SEMI;
048:            String OPTIONAL_SEMI;
049:            String OPENCURLY;
050:            String CLOSECURLY;
051:
052:            public ParseTreePrinter() {
053:                this (false, false);
054:            }
055:
056:            public ParseTreePrinter(boolean compress) {
057:                this (compress, false);
058:            }
059:
060:            public ParseTreePrinter(boolean compress, boolean obfuscate) {
061:                this .compress = compress;
062:                // Set whitespace
063:                this .SPACE = compress ? "" : " ";
064:                this .NEWLINE = obfuscate ? "" : "\n";
065:                // Set punctuation
066:                this .COMMA = "," + SPACE;
067:                this .COLON = ":" + SPACE;
068:                this .ASSIGN = SPACE + "=" + SPACE;
069:                this .CONDITIONAL = SPACE + "?" + SPACE;
070:                this .ALTERNATIVE = SPACE + ":" + SPACE;
071:                this .OPENPAREN = SPACE + "(";
072:                this .CLOSEPAREN = ")" + SPACE;
073:                this .SEMI = ";";
074:                this .OPTIONAL_SEMI = (compress && "\n".equals(NEWLINE)) ? NEWLINE
075:                        : SEMI;
076:            }
077:
078:            public void print(SimpleNode node) {
079:                print(node, System.out);
080:            }
081:
082:            public void print(SimpleNode node, OutputStream output) {
083:                PrintStream where = new PrintStream(output);
084:                print(node, where);
085:            }
086:
087:            public void print(SimpleNode node, PrintStream where) {
088:                where.println(visit(node));
089:            }
090:
091:            public String delimit(String phrase, boolean force) {
092:                if (phrase.length() > 0) {
093:                    return ((('(' != phrase.charAt(0)) && force) ? " " : SPACE)
094:                            + phrase;
095:                }
096:                return phrase;
097:            }
098:
099:            public String delimit(String phrase) {
100:                return delimit(phrase, true);
101:            }
102:
103:            public String elideSemi(String phrase) {
104:                if (phrase.endsWith(SEMI)) {
105:                    return phrase.substring(0, phrase.length() - SEMI.length());
106:                }
107:                return phrase;
108:            }
109:
110:            public String makeBlock(String body) {
111:                body = elideSemi(body);
112:                // NEWLINE is for debug/readability, so our code is not _all_ on
113:                // one line
114:                return "{" + NEWLINE + elideSemi(body)
115:                        + (body.endsWith("}") ? "" : NEWLINE) + "}";
116:            }
117:
118:            public static String join(String token, String[] strings) {
119:                StringBuffer sb = new StringBuffer();
120:                int l = strings.length - 1;
121:                for (int x = 0; x < l; x++) {
122:                    sb.append(strings[x]);
123:                    sb.append(token);
124:                }
125:                if (l >= 0) {
126:                    sb.append(strings[l]);
127:                }
128:                return (sb.toString());
129:            }
130:
131:            public String visit(SimpleNode node) {
132:                if (node instanceof  PassThroughNode) {
133:                    node = ((PassThroughNode) node).realNode;
134:                }
135:
136:                int size = node.size();
137:                SimpleNode[] childnodes = node.getChildren();
138:                String[] children = new String[size];
139:                for (int i = 0; i < size; i++) {
140:                    SimpleNode n = childnodes[i];
141:                    if (n instanceof  PassThroughNode) {
142:                        n = childnodes[i] = ((PassThroughNode) n).realNode;
143:                    }
144:                    children[i] = visit(n);
145:                }
146:
147:                Class nt = node.getClass();
148:
149:                // Are we doing OOP yet?
150:                if (node instanceof  ASTProgram
151:                        || node instanceof  ASTStatementList
152:                        || node instanceof  ASTDirectiveBlock) {
153:                    // Conditional join
154:                    StringBuffer sb = new StringBuffer();
155:                    String sep = "";
156:                    int l = children.length;
157:                    for (int x = 0; x < l; x++) {
158:                        String child = children[x];
159:                        // Elide empty nodes
160:                        if (!"".equals(child)) {
161:                            sb.append(sep);
162:                            sb.append(child);
163:                            if (!child.endsWith(SEMI)) {
164:                                sep = SEMI + (compress ? SPACE : NEWLINE);
165:                            } else {
166:                                sep = (compress ? SPACE : NEWLINE);
167:                            }
168:                        }
169:                    }
170:                    return sb.toString();
171:                }
172:                if (node instanceof  ASTStatement) {
173:                    assert children.length == 1;
174:                    String child = children[0];
175:                    // Ensure an expression becomes a statement by appending an
176:                    // explicit semicolon
177:                    if ((!"".equals(child)) && (!child.endsWith(SEMI))) {
178:                        return child + SEMI;
179:                    } else {
180:                        return child;
181:                    }
182:                }
183:                if (node instanceof  ASTAssignmentExpression) {
184:                    return visitAssignmentExpression(node, children);
185:                }
186:                if (node instanceof  ASTCallExpression) {
187:                    return visitCallExpression(node, children);
188:                }
189:                if (node instanceof  ASTSuperCallExpression) {
190:                    return visitSuperCallExpression(node, children);
191:                }
192:                if (node instanceof  ASTConditionalExpression) {
193:                    return visitConditionalExpression(node, children);
194:                }
195:                if (node instanceof  ASTEmptyExpression) {
196:                    return visitEmptyExpression(node, children);
197:                }
198:                if (node instanceof  ASTForVarInStatement) {
199:                    return visitForVarInStatement(node, children);
200:                }
201:                if (node instanceof  ASTForInStatement) {
202:                    return visitForInStatement(node, children);
203:                }
204:                if (node instanceof  ASTForVarStatement
205:                        || node instanceof  ASTForStatement) {
206:                    return visitForVarStatement(node, children);
207:                }
208:                if (node instanceof  ASTNewExpression) {
209:                    return visitNewExpression(node, children);
210:                }
211:                if (node instanceof  ASTIfStatement
212:                        || node instanceof  ASTIfDirective) {
213:                    return visitIfStatement(node, children);
214:                }
215:                if (node instanceof  ASTPragmaDirective) {
216:                    return visitPragmaDirective(node, children);
217:                }
218:                if (node instanceof  ASTPostfixExpression) {
219:                    return visitPostfixExpression(node, children);
220:                }
221:                if (node instanceof  ASTPropertyIdentifierReference) {
222:                    return visitPropertyIdentifierReference(node, children);
223:                }
224:                if (node instanceof  ASTPropertyValueReference) {
225:                    return visitPropertyValueReference(node, children);
226:                }
227:                if (node instanceof  ASTReturnStatement) {
228:                    return visitReturnStatement(node, children);
229:                }
230:                if (node instanceof  ASTThisReference) {
231:                    return visitThisReference(node, children);
232:                }
233:                if (node instanceof  ASTContinueStatement) {
234:                    return visitContinueStatement(node, children);
235:                }
236:                if (node instanceof  ASTBreakStatement) {
237:                    return visitBreakStatement(node, children);
238:                }
239:                if (node instanceof  ASTUnaryExpression) {
240:                    return visitUnaryExpression(node, children);
241:                }
242:                if (node instanceof  ASTWithStatement) {
243:                    return visitWithStatement(node, children);
244:                }
245:                if (node instanceof  ASTDoWhileStatement) {
246:                    return visitDoWhileStatement(node, children);
247:                }
248:                if (node instanceof  ASTWhileStatement) {
249:                    return visitWhileStatement(node, children);
250:                }
251:                if (node instanceof  ASTSwitchStatement) {
252:                    return visitSwitchStatement(node, children);
253:                }
254:                if (node instanceof  ASTCaseClause) {
255:                    return visitCaseClause(node, children);
256:                }
257:                if (node instanceof  ASTDefaultClause) {
258:                    return visitDefaultClause(node, children);
259:                }
260:                if (node instanceof  ASTArrayLiteral) {
261:                    return visitArrayLiteral(node, children);
262:                }
263:                if (node instanceof  ASTBinaryExpressionSequence) {
264:                    return visitBinaryExpressionSequence(node, children);
265:                }
266:                if (node instanceof  ASTExpressionList
267:                        || node instanceof  ASTFunctionCallParameters
268:                        || node instanceof  ASTFormalParameterList) {
269:                    return visitExpressionList(node, children);
270:                }
271:                if (node instanceof  ASTAndExpressionSequence) {
272:                    return visitAndOrExpressionSequence(true, node, children);
273:                }
274:                if (node instanceof  ASTOrExpressionSequence) {
275:                    return visitAndOrExpressionSequence(false, node, children);
276:                }
277:                if (node instanceof  ASTFunctionDeclaration) {
278:                    return visitFunctionDeclaration(node, children);
279:                }
280:                if (node instanceof  ASTFunctionExpression) {
281:                    return visitFunctionExpression(node, children);
282:                }
283:                if (node instanceof  ASTIdentifier) {
284:                    return visitIdentifier(node, children);
285:                }
286:                if (node instanceof  ASTLiteral) {
287:                    return visitLiteral(node, children);
288:                }
289:                if (node instanceof  ASTObjectLiteral) {
290:                    return visitObjectLiteral(node, children);
291:                }
292:                if (node instanceof  ASTOperator) {
293:                    return visitOperator(node, children);
294:                }
295:                if (node instanceof  ASTVariableStatement) {
296:                    return visitVariableStatement(node, children);
297:                }
298:                if (node instanceof  ASTVariableDeclaration) {
299:                    return visitVariableDeclaration(node, children);
300:                }
301:                if (node instanceof  ASTVariableDeclarationList) {
302:                    return visitVariableDeclarationList(node, children);
303:                }
304:                if (node instanceof  ASTTryStatement) {
305:                    return visitTryStatement(node, children);
306:                }
307:                if (node instanceof  ASTCatchClause) {
308:                    return visitCatchClause(node, children);
309:                }
310:                if (node instanceof  ASTFinallyClause) {
311:                    return visitFinallyClause(node, children);
312:                }
313:                if (node instanceof  ASTThrowStatement) {
314:                    return visitThrowStatement(node, children);
315:                }
316:                return defaultVisitor(node, children);
317:            }
318:
319:            public String defaultVisitor(SimpleNode node, String[] children) {
320:                return "//\u00AB" + node.toString() + "("
321:                        + join(COMMA, children) + ")\u00BB";
322:            }
323:
324:            // Copied (and massaged) from Parser.jjt
325:            public static String[] OperatorNames = {};
326:            static {
327:                ArrayList on = new ArrayList();
328:                // TODO: [2005-11-17 ptw] Not quite right, but javacc doesn't
329:                // tell us the range of its Ops
330:                for (int i = 0; i < 256; i++) {
331:                    on.add("<" + Integer.toString(i) + ">");
332:                }
333:                on.set(Ops.LPAREN, "(");
334:                on.set(Ops.LBRACKET, "[");
335:                on.set(Ops.DOT, ".");
336:                on.set(Ops.ASSIGN, "=");
337:                on.set(Ops.COMMA, ",");
338:                on.set(Ops.GT, ">");
339:                on.set(Ops.LT, "<");
340:                on.set(Ops.BANG, "!");
341:                on.set(Ops.TILDE, "~");
342:                on.set(Ops.HOOK, "?");
343:                on.set(Ops.COLON, ":");
344:                on.set(Ops.EQ, "==");
345:                on.set(Ops.LE, "<=");
346:                on.set(Ops.GE, ">=");
347:                on.set(Ops.NE, "!=");
348:                on.set(Ops.SEQ, "===");
349:                on.set(Ops.SNE, "!==");
350:                on.set(Ops.SC_OR, "||");
351:                on.set(Ops.SC_AND, "&&");
352:                on.set(Ops.INCR, "++");
353:                on.set(Ops.DECR, "--");
354:                on.set(Ops.PLUS, "+");
355:                on.set(Ops.MINUS, "-");
356:                on.set(Ops.STAR, "*");
357:                on.set(Ops.SLASH, "/");
358:                on.set(Ops.BIT_AND, "&");
359:                on.set(Ops.BIT_OR, "|");
360:                on.set(Ops.XOR, "^");
361:                on.set(Ops.REM, "%");
362:                on.set(Ops.LSHIFT, "<<");
363:                on.set(Ops.RSIGNEDSHIFT, ">>");
364:                on.set(Ops.RUNSIGNEDSHIFT, ">>>");
365:                on.set(Ops.PLUSASSIGN, "+=");
366:                on.set(Ops.MINUSASSIGN, "-=");
367:                on.set(Ops.STARASSIGN, "*=");
368:                on.set(Ops.SLASHASSIGN, "/=");
369:                on.set(Ops.ANDASSIGN, "&=");
370:                on.set(Ops.ORASSIGN, "|=");
371:                on.set(Ops.XORASSIGN, "^=");
372:                on.set(Ops.REMASSIGN, "%=");
373:                on.set(Ops.LSHIFTASSIGN, "<<=");
374:                on.set(Ops.RSIGNEDSHIFTASSIGN, ">>=");
375:                on.set(Ops.RUNSIGNEDSHIFTASSIGN, ">>>=");
376:
377:                on.set(Ops.IN, "in");
378:                on.set(Ops.INSTANCEOF, "instanceof");
379:                on.set(Ops.TYPEOF, "typeof");
380:                on.set(Ops.DELETE, "delete");
381:                on.set(Ops.VOID, "void");
382:                on.set(Ops.NEW, "new");
383:
384:                OperatorNames = (String[]) on.toArray(OperatorNames);
385:            }
386:
387:            public String visitAssignmentExpression(SimpleNode node,
388:                    String[] children) {
389:                int this Prec = prec(((ASTOperator) node.get(1)).getOperator(),
390:                        false);
391:                assert children.length == 3;
392:                children[2] = maybeAddParens(this Prec, node.get(2),
393:                        children[2], true);
394:                return children[0] + SPACE + children[1]
395:                        + delimit(children[2], false);
396:            }
397:
398:            public String visitCallExpression(SimpleNode node, String[] children) {
399:                int this Prec = prec(Ops.LPAREN, true);
400:                children[0] = maybeAddParens(this Prec, node.get(0),
401:                        children[0], true);
402:                return children[0] + "(" + children[1] + ")";
403:            }
404:
405:            public String visitSuperCallExpression(SimpleNode node,
406:                    String[] children) {
407:                // Same as above
408:                return "super." + children[0]
409:                        + ("".equals(children[1]) ? "" : ("." + children[1]))
410:                        + "(" + children[2] + ")";
411:            }
412:
413:            public String visitConditionalExpression(SimpleNode node,
414:                    String[] children) {
415:                int this Prec = prec(Ops.COLON, false);
416:                for (int i = 0; i < children.length; i++) {
417:                    children[i] = maybeAddParens(this Prec, node.get(i),
418:                            children[i]);
419:                }
420:                return children[0] + CONDITIONAL + children[1] + ALTERNATIVE
421:                        + children[2];
422:            }
423:
424:            public String visitEmptyExpression(SimpleNode node,
425:                    String[] children) {
426:                return "";
427:            }
428:
429:            public String visitForVarInStatement(SimpleNode node,
430:                    String[] children) {
431:                return "for" + OPENPAREN + "var " + children[0] + " in "
432:                        + children[2] + CLOSEPAREN + makeBlock(children[3]);
433:            }
434:
435:            public String visitForInStatement(SimpleNode node, String[] children) {
436:                return "for" + OPENPAREN + children[0] + " in " + children[1]
437:                        + CLOSEPAREN + makeBlock(children[2]);
438:            }
439:
440:            public String visitForVarStatement(SimpleNode node,
441:                    String[] children) {
442:                // Need explicit semi because init clause may be empty
443:                return "for" + OPENPAREN + elideSemi(children[0]) + SEMI
444:                        + children[1] + SEMI + children[2] + CLOSEPAREN
445:                        + makeBlock(children[3]);
446:            }
447:
448:            public String visitIfStatement(SimpleNode node, String[] children) {
449:                if (children.length == 2) {
450:                    return "if" + OPENPAREN + children[0] + CLOSEPAREN
451:                            + makeBlock(children[1]);
452:                } else if (children.length == 3) {
453:                    return "if" + OPENPAREN + children[0] + CLOSEPAREN
454:                            + makeBlock(children[1]) + SPACE + "else" + SPACE
455:                            + makeBlock(children[2]);
456:                }
457:                return defaultVisitor(node, children);
458:            }
459:
460:            public String visitNewExpression(SimpleNode node, String[] children) {
461:                int this Prec = prec(Ops.NEW, true);
462:                SimpleNode c = node.get(0);
463:                children[0] = maybeAddParens(this Prec, c, children[0]);
464:                return "new " + children[0] + "(" + children[1] + ")";
465:            }
466:
467:            public String visitPragmaDirective(SimpleNode node,
468:                    String[] children) {
469:                return "#pragma " + children[0];
470:            }
471:
472:            public String visitPostfixExpression(SimpleNode node,
473:                    String[] children) {
474:                int op = ((ASTOperator) node.get(1)).getOperator();
475:                int this Prec = prec(op, true);
476:                children[0] = maybeAddParens(this Prec, node.get(0), children[0]);
477:                return children[0] + children[1];
478:            }
479:
480:            public String visitPropertyIdentifierReference(SimpleNode node,
481:                    String[] children) {
482:                // These have prec of 0 even though they don't have ops
483:                int this Prec = 0;
484:                for (int i = 0; i < children.length; i++) {
485:                    children[i] = maybeAddParens(this Prec, node.get(i),
486:                            children[i], true);
487:                }
488:                return children[0] + "." + children[1];
489:            }
490:
491:            public String visitPropertyValueReference(SimpleNode node,
492:                    String[] children) {
493:                // These have prec of 0 even though they don't have ops
494:                int this Prec = 0;
495:                children[0] = maybeAddParens(this Prec, node.get(0),
496:                        children[0], true);
497:                return children[0] + "[" + children[1] + "]";
498:            }
499:
500:            public String visitReturnStatement(SimpleNode node,
501:                    String[] children) {
502:                return "return" + delimit(children[0]);
503:            }
504:
505:            public String visitThisReference(SimpleNode node, String[] children) {
506:                return "this";
507:            }
508:
509:            public String visitContinueStatement(SimpleNode node,
510:                    String[] children) {
511:                return "continue"
512:                        + (children.length > 0 ? delimit(children[0]) : "");
513:            }
514:
515:            public String visitBreakStatement(SimpleNode node, String[] children) {
516:                return "break"
517:                        + (children.length > 0 ? delimit(children[0]) : "");
518:            }
519:
520:            public String visitUnaryExpression(SimpleNode node,
521:                    String[] children) {
522:                // Prefix and Unary are the same node
523:                int op = ((ASTOperator) node.get(0)).getOperator();
524:                boolean letter = java.lang.Character.isLetter(OperatorNames[op]
525:                        .charAt(0));
526:                int this Prec = prec(op, true);
527:                children[1] = maybeAddParens(this Prec, node.get(1), children[1]);
528:                return children[0] + (letter ? " " : "") + children[1];
529:            }
530:
531:            public String visitWithStatement(SimpleNode node, String[] children) {
532:                return "with" + OPENPAREN + children[0] + CLOSEPAREN
533:                        + makeBlock(children[1]);
534:            }
535:
536:            public String visitWhileStatement(SimpleNode node, String[] children) {
537:                return "while" + OPENPAREN + children[0] + CLOSEPAREN
538:                        + makeBlock(children[1]);
539:            }
540:
541:            public String visitDoWhileStatement(SimpleNode node,
542:                    String[] children) {
543:                return "do" + makeBlock(children[0]) + SPACE + "while"
544:                        + OPENPAREN + children[1] + ")";
545:            }
546:
547:            public String visitDefaultClause(SimpleNode node, String[] children) {
548:                return "default:"
549:                        + NEWLINE
550:                        + (children.length > 0 ? (children[0] + OPTIONAL_SEMI)
551:                                : "");
552:            }
553:
554:            public String visitCaseClause(SimpleNode node, String[] children) {
555:                return "case"
556:                        + delimit(children[0])
557:                        + ":"
558:                        + NEWLINE
559:                        + (children.length > 1 ? (children[1] + OPTIONAL_SEMI)
560:                                : "");
561:            }
562:
563:            public String visitSwitchStatement(SimpleNode node,
564:                    String[] children) {
565:                String body = "";
566:                for (int i = 1, len = children.length; i < len; i++) {
567:                    body += children[i];
568:                }
569:                return "switch" + OPENPAREN + children[0] + CLOSEPAREN
570:                        + makeBlock(body);
571:            }
572:
573:            // TODO: [2005-11-15 ptw] Make this a simple lookup table based on
574:            // the operator
575:            public int prec(int op, boolean unary) {
576:                String n = OperatorNames[op];
577:                String classes[][] = {
578:                        { "(", "[", ".", "new" },
579:                        { "!", "~", "-", "+", "--", "++", "typeof", "void",
580:                                "delete" },
581:                        { "*", "/", "%" },
582:                        { "+", "-" },
583:                        { "<<", ">>", ">>>" },
584:                        { "<", "<=", ">", ">=", "instanceof", "in", "is",
585:                                "cast" },
586:                        { "==", "!=", "===", "!==" },
587:                        { "&" },
588:                        { "^" },
589:                        { "|" },
590:                        { "&&" },
591:                        { "||" },
592:                        { "?", ":" },
593:                        { "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=",
594:                                ">>>=", "&=", "^=", "|=" }, { "," } };
595:                for (int i = (unary ? 0 : 2), il = classes.length; i < il; i++) {
596:                    for (int j = 0, jl = classes[i].length; j < jl; j++) {
597:                        if (classes[i][j].equals(n)) {
598:                            return -i;
599:                        }
600:                    }
601:                }
602:                assert false : "unknown operator: " + n;
603:                return 1;
604:            }
605:
606:            public String visitArrayLiteral(SimpleNode node, String[] children) {
607:                int this Prec = prec(Ops.COMMA, false);
608:                for (int i = 0; i < children.length; i++) {
609:                    children[i] = maybeAddParens(this Prec, node.get(i),
610:                            children[i], false);
611:                }
612:                return "[" + join(COMMA, children) + "]";
613:            }
614:
615:            public String maybeAddParens(int parentPrec, SimpleNode node,
616:                    String nodeRep) {
617:                return maybeAddParens(parentPrec, node, nodeRep, false);
618:            }
619:
620:            // Set assoc to true if the sub-expression appears in a place
621:            // where operator associativity implies the parens, e.g. on the
622:            // left operand of a binary operator that is left-to-right
623:            // associative.  (It is always safe to leave it false, you will
624:            // just end up with extra parens where you don't need them, which
625:            // will impact compression but not correctness.)
626:            public String maybeAddParens(int parentPrec, SimpleNode node,
627:                    String nodeRep, boolean assoc) {
628:                int this Prec = Integer.MAX_VALUE;
629:                if (node instanceof  ASTBinaryExpressionSequence
630:                        || node instanceof  ASTAssignmentExpression) {
631:                    this Prec = prec(((ASTOperator) node.get(1)).getOperator(),
632:                            false);
633:                } else if (node instanceof  ASTUnaryExpression) {
634:                    this Prec = prec(((ASTOperator) node.get(0)).getOperator(),
635:                            true);
636:                } else if (node instanceof  ASTPostfixExpression) {
637:                    this Prec = prec(((ASTOperator) node.get(1)).getOperator(),
638:                            true);
639:                } else if (node instanceof  ASTAndExpressionSequence) {
640:                    this Prec = prec(Ops.SC_AND, false);
641:                } else if (node instanceof  ASTOrExpressionSequence) {
642:                    this Prec = prec(Ops.SC_OR, false);
643:                } else if (node instanceof  ASTConditionalExpression) {
644:                    this Prec = prec(Ops.COLON, false);
645:                } else if (node instanceof  ASTNewExpression) {
646:                    this Prec = prec(Ops.NEW, true);
647:                } else if (node instanceof  ASTCallExpression
648:                        || node instanceof  ASTSuperCallExpression) {
649:                    this Prec = prec(Ops.LPAREN, true);
650:                } else if (node instanceof  ASTPropertyValueReference) {
651:                    this Prec = prec(Ops.LBRACKET, true);
652:                } else if (node instanceof  ASTPropertyIdentifierReference) {
653:                    this Prec = prec(Ops.DOT, true);
654:                } else if (node instanceof  ASTExpressionList) {
655:                    this Prec = prec(Ops.COMMA, false);
656:                } else if (// Our compiler is broken -- if one of these shows up
657:                // in an expression, it had to have been in an
658:                // expression list initially
659:                node instanceof  ASTFunctionExpression
660:                        || node instanceof  ASTFunctionDeclaration) {
661:                    this Prec = prec(Ops.ASSIGN, false);
662:                } else if (node instanceof  ASTObjectLiteral
663:                        || node instanceof  ASTArrayLiteral
664:                        || node instanceof  ASTIdentifier
665:                        || node instanceof  ASTThisReference
666:                        || node instanceof  ASTLiteral) {
667:                    ;
668:                } else {
669:                    System.err.println("No prec for " + node + " in "
670:                            + Compiler.nodeString(node));
671:                    (new CompilerException()).printStackTrace();
672:                }
673:
674:                if (assoc ? (this Prec < parentPrec) : (this Prec <= parentPrec)) {
675:                    nodeRep = "(" + nodeRep + ")";
676:                }
677:                return nodeRep;
678:            }
679:
680:            public String visitAndOrExpressionSequence(boolean isAnd,
681:                    SimpleNode node, String[] children) {
682:                int this Prec = prec(isAnd ? Ops.SC_AND : Ops.SC_OR, false);
683:                children[0] = maybeAddParens(this Prec, node.get(0),
684:                        children[0], true);
685:                for (int i = 1; i < children.length; i++) {
686:                    children[i] = delimit(maybeAddParens(this Prec, node.get(i),
687:                            children[i]), false);
688:                }
689:                return join(isAnd ? (SPACE + "&&") : (SPACE + "||"), children);
690:            }
691:
692:            public String visitExpressionList(SimpleNode node, String[] children) {
693:                int this Prec = prec(Ops.COMMA, false);
694:                for (int i = 0; i < children.length; i++) {
695:                    children[i] = maybeAddParens(this Prec, node.get(i),
696:                            children[i]);
697:                }
698:                return join(COMMA, children);
699:            }
700:
701:            public String visitBinaryExpressionSequence(SimpleNode node,
702:                    String[] children) {
703:                int this Prec = prec(((ASTOperator) node.get(1)).getOperator(),
704:                        false);
705:                for (int i = 0; i < children.length; i += (i == 0 ? 2 : 1)) {
706:                    children[i] = maybeAddParens(this Prec, node.get(i),
707:                            children[i], i == 0);
708:                }
709:
710:                String op = children[1];
711:                char opChar = op.charAt(op.length() - 1);
712:                StringBuffer sb = new StringBuffer();
713:                boolean required = java.lang.Character.isLetter(op.charAt(0));
714:                String space = required ? " " : SPACE;
715:                sb.append(children[0]);
716:                for (int x = 2; x < (children.length); x++) {
717:                    String child = children[x];
718:                    sb.append(space);
719:                    sb.append(op);
720:                    // Disambiguate `a + ++b`, `a++ + b` etc.
721:                    sb.append(delimit(child, required
722:                            || opChar == child.charAt(0)));
723:                }
724:                return (sb.toString());
725:            }
726:
727:            public String visitFunctionDeclaration(SimpleNode node,
728:                    String[] children) {
729:                return doFunctionDeclaration(node, children, true);
730:            }
731:
732:            public String visitFunctionExpression(SimpleNode node,
733:                    String[] children) {
734:                // Elide optional name if compressing, otherwise leave it for debugging
735:                return doFunctionDeclaration(node, children,
736:                        this .compress ? false : true);
737:            }
738:
739:            String doFunctionDeclaration(SimpleNode node, String[] children,
740:                    boolean useName) {
741:                String name, args, body;
742:                if (children.length == 2) {
743:                    name = "";
744:                    args = children[0];
745:                    body = children[1];
746:                } else if (children.length == 3) {
747:                    name = children[0];
748:                    args = children[1];
749:                    body = children[2];
750:                } else {
751:                    return defaultVisitor(node, children);
752:                }
753:                String loc = "";
754:                // Add location information if not compressing
755:                if ((!this .compress) && (node.filename != null)
756:                        && (node.beginLine != 0)) {
757:                    loc = ("\n/* -*- file: " + Compiler.getLocationString(node) + " -*- */\n");
758:                }
759:                return loc + "function" + (useName ? (" " + name) : "")
760:                        + OPENPAREN + args + CLOSEPAREN + makeBlock(body);
761:            }
762:
763:            public String visitIdentifier(SimpleNode node, String[] children) {
764:                return ((ASTIdentifier) node).getName();
765:            }
766:
767:            static Double zero = new Double(0);
768:
769:            public String visitLiteral(SimpleNode node, String[] children) {
770:                Object value = ((ASTLiteral) node).getValue();
771:                if (value instanceof  String) {
772:                    return ScriptCompiler.quote((String) value);
773:                }
774:                if (value instanceof  Double) {
775:                    // Make integers compact
776:                    Double n = (Double) value;
777:                    long l = n.longValue();
778:                    if ((double) l == n.doubleValue()) {
779:                        if (l == 0) {
780:                            return "0";
781:                        } else {
782:                            String d = Long.toString(l);
783:                            if (compress && l > 0) {
784:                                String h = "0x" + Long.toHexString(l);
785:                                if (h.length() <= d.length()) {
786:                                    return h;
787:                                }
788:                            }
789:                            return d;
790:                        }
791:                    }
792:                }
793:                return "" + value;
794:            }
795:
796:            public String visitObjectLiteral(SimpleNode node, String[] children) {
797:                StringBuffer s = new StringBuffer("{");
798:                int len = children.length - 1;
799:                int this Prec = prec(Ops.COMMA, false);
800:                for (int i = 0; i < len; i++) {
801:                    if (i % 2 != 0) {
802:                        children[i] = maybeAddParens(this Prec, node.get(i),
803:                                children[i], false);
804:                        s.append(children[i]);
805:                        s.append(COMMA);
806:                    } else {
807:                        s.append(children[i]);
808:                        s.append(COLON);
809:                    }
810:                }
811:                if (len > 0) {
812:                    children[len] = maybeAddParens(this Prec, node.get(len),
813:                            children[len], false);
814:                    s.append(children[len]);
815:                }
816:                s.append("}");
817:                return s.toString();
818:            }
819:
820:            public String visitOperator(SimpleNode op, String[] children) {
821:                int operator = ((ASTOperator) op).getOperator();
822:                return OperatorNames[operator];
823:            }
824:
825:            public String visitVariableStatement(SimpleNode node,
826:                    String[] children) {
827:                assert children.length == 1;
828:                // Ensure an expression becomes a statement by appending an
829:                // explicit semicolon
830:                return "var " + children[0] + SEMI;
831:            }
832:
833:            public String visitVariableDeclaration(SimpleNode node,
834:                    String[] children) {
835:                if (children.length > 1) {
836:                    int this Prec = prec(Ops.ASSIGN, false);
837:                    assert children.length == 2;
838:                    children[1] = maybeAddParens(this Prec, node.get(1),
839:                            children[1], true);
840:                    return children[0] + ASSIGN + children[1];
841:                } else {
842:                    return children[0];
843:                }
844:            }
845:
846:            public String visitVariableDeclarationList(SimpleNode node,
847:                    String[] children) {
848:                return join(COMMA, children);
849:            }
850:
851:            public String visitTryStatement(SimpleNode node, String[] children) {
852:                if (children.length == 2) {
853:                    return "try" + SPACE + makeBlock(children[0]) + NEWLINE
854:                            + children[1];
855:                } else if (children.length == 3) {
856:                    return "try" + SPACE + makeBlock(children[0]) + NEWLINE
857:                            + children[1] + NEWLINE + children[2];
858:                }
859:                return defaultVisitor(node, children);
860:            }
861:
862:            public String visitCatchClause(SimpleNode node, String[] children) {
863:                return "catch" + OPENPAREN + children[0] + CLOSEPAREN
864:                        + makeBlock(children[1]);
865:            }
866:
867:            public String visitFinallyClause(SimpleNode node, String[] children) {
868:                return "finally" + SPACE + makeBlock(children[0]);
869:            }
870:
871:            public String visitThrowStatement(SimpleNode node, String[] children) {
872:                return "throw" + delimit(children[0]);
873:            }
874:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.