Source Code Cross Referenced for CommonGenerator.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:        /**
004:         * Common Code for Translation and Code Generation
005:         *
006:         * @author steele@osteele.com
007:         * @author ptw@openlaszlo.org
008:         * @author dda@ddanderson.com
009:         * @description: Common baseclass for code generators
010:         *
011:         * This class is extended by CodeGenerator, JavascriptGenerator.
012:         */package org.openlaszlo.sc;
013:
014:        import java.io.*;
015:        import java.util.*;
016:        import java.nio.ByteBuffer;
017:
018:        import org.openlaszlo.sc.parser.*;
019:        import org.openlaszlo.sc.Instructions;
020:        import org.openlaszlo.sc.Instructions.Instruction;
021:
022:        import org.openlaszlo.cache.PersistentMap;
023:
024:        // The code generator dispatches a node whose class is named ASTName to
025:        // a method visitName, passing the node, a context, and the node's
026:        // children as arguments.  The context for a statement visitor is a
027:        // TranslationContext, defined above.  The context for an expression
028:        // visitor is a boolean value, that is true iff the value of the
029:        // expression is used.  The return value of a statement visitor is
030:        // ignored.  The return value of an expression visitor is true iff it
031:        // generated code that did NOT leave a value on the stack.  (This is so
032:        // that an expression visitor that ignores its context need do nothing
033:        // special to indicate that it ignored it: the default return value of
034:        // null signals this.)
035:        //
036:        // Methods of the form visitName are AST node visitors, and follow the
037:        // protocol described above.  Methods of the form translateName are
038:        // helper functions for the visitors, and have arbitrary parameter
039:        // lists and return values.
040:
041:        // TODO: [2006-01-17 ptw] Remove some day
042:        // Replace instruction subsequences by a BLOB instruction that
043:        // represents the same bytes.  By default, the BLOB instructions are
044:        // separated by PUSH's (which depend on the constant pool), and
045:        // branches and targets (since they can't be resolved until the size of
046:        // the PUSH instructions is known).  When noConstantPool=true, PUSH's
047:        // are compiled against a null constant pool, and branches and targets
048:        // are compiled, so the instructions combine to a single BLOB.
049:        // public void combineInstructions(instrsIn, noConstantPool=false) {
050:        //     instrsOut = [];
051:        //     buffer = ByteBuffer.allocate(64000);
052:        //     public void flush(instrsOut=instrsOut,buffer=buffer) {
053:        //         if (buffer.position()) {
054:        //             import jarray;
055:        //             bytes = jarray.zeros(buffer.position(), "b");
056:        //             buffer.flip();
057:        //             buffer.get(bytes);
058:        //             buffer.clear();
059:        //             instrsOut.append(BLOB("bytes", bytes));
060:        //     for (instr in instrsIn) {
061:        //         if (noConstantPool || instr.isPush || instr.isLabel || instr.hasTarget) {
062:        //             flush();
063:        //             instrsOut.append(instr);
064:        //         } else {
065:        //             instr.writeBytes(buffer, null);
066:        //     flush();
067:        //     return instrsOut;
068:        // }
069:
070:        public abstract class CommonGenerator implements  ASTVisitor {
071:
072:            Compiler.OptionMap options = new Compiler.OptionMap();
073:            String runtime;
074:            TranslationContext context = null;
075:            boolean debugVisit = false;
076:            InstructionCollector collector = null;
077:
078:            public Compiler.OptionMap getOptions() {
079:                return options;
080:            }
081:
082:            public TranslationContext getContext() {
083:                return context;
084:            }
085:
086:            protected abstract void setRuntime(String runtime);
087:
088:            public void setOptions(Compiler.OptionMap options) {
089:                this .options = options;
090:                this .runtime = ((String) options.get(Compiler.RUNTIME))
091:                        .intern();
092:                setRuntime(this .runtime);
093:            }
094:
095:            public InstructionCollector getCollector() {
096:                return collector;
097:            }
098:
099:            // Options that don't affect code generation.  This is used to decide
100:            // what it's okay to cache across LFC build versions.  It's okay if
101:            // it's too small.
102:            static Set NonCodeGenerationOptions = new HashSet();
103:            static {
104:                NonCodeGenerationOptions.add(Compiler.CACHE_COMPILES);
105:                NonCodeGenerationOptions.add(Compiler.INSTR_STATS);
106:                NonCodeGenerationOptions.add(Compiler.PRINT_COMPILER_OPTIONS);
107:                NonCodeGenerationOptions.add(Compiler.PRINT_CONSTRAINTS);
108:                NonCodeGenerationOptions.add(Compiler.PROFILE_COMPILER);
109:                NonCodeGenerationOptions.add(Compiler.PROGRESS);
110:                NonCodeGenerationOptions.add(Compiler.RESOLVER);
111:                // These affect the default settings for the options above, but
112:                // do not themselves make a difference.
113:                NonCodeGenerationOptions.add(Compiler.DEBUG);
114:            }
115:
116:            static class LessHalfAssedHashMap extends HashMap {
117:                LessHalfAssedHashMap() {
118:                    super ();
119:                }
120:
121:                Object get(int key) {
122:                    return get(new Integer(key));
123:                }
124:
125:                Object put(int key, Object value) {
126:                    return put(new Integer(key), value);
127:                }
128:
129:                Object put(int key, int value) {
130:                    return put(new Integer(key), new Integer(value));
131:                }
132:            }
133:
134:            static SimpleNode parseFragment(String code) {
135:                if (code.equals("\"\"") || code == null) {
136:                    code = "";
137:                }
138:                code = "{"
139:                        + "\n#pragma 'warnUndefinedReferences=false'\n"
140:                        + "\n#file JavascriptGenerator.parseFragment\n#line 0\n"
141:                        + code + "}";
142:                // Extract the statement list from the program
143:                try {
144:                    return (new Compiler.Parser()).parse(code).get(0);
145:                } catch (ParseException e) {
146:                    System.err.println("while compiling " + code);
147:                    throw e;
148:                }
149:            }
150:
151:            // TODO: [2007-08-20 ptw] Replace with Java 1.5 UUID
152:            private Boolean usePredictable = null;
153:            private Random rand = new Random();
154:            private int uuidCounter = 1;
155:
156:            protected Integer UUID() {
157:                if (usePredictable == null) {
158:                    usePredictable = new Boolean(options
159:                            .getBoolean(Compiler.GENERATE_PREDICTABLE_TEMPS));
160:                }
161:                if (usePredictable.equals(Boolean.TRUE)) {
162:                    return new Integer(uuidCounter++);
163:                } else {
164:                    return new Integer(rand.nextInt(Integer.MAX_VALUE));
165:                }
166:            }
167:
168:            Boolean evaluateCompileTimeConditional(SimpleNode node) {
169:                Object value = null;
170:                if (node instanceof  ASTIdentifier) {
171:                    String name = ((ASTIdentifier) node).getName();
172:                    Map constants = (Map) options
173:                            .get(Compiler.COMPILE_TIME_CONSTANTS);
174:                    if (constants != null) {
175:                        if (constants.containsKey(name)) {
176:                            value = constants.get(name);
177:                            //           if (value != null) {
178:                            //             + ": " + value + "(" + value.getClass() + ")");
179:                            //           }
180:                        }
181:                    }
182:                }
183:                //     if (value != null) {
184:                //       System.err.println(" => " + value + "(" + value.getClass() + ")");
185:                //     }
186:                return (Boolean) value;
187:            }
188:
189:            static class ParseResult {
190:                SimpleNode parse;
191:                boolean hasIncludes;
192:
193:                ParseResult(SimpleNode parse, boolean hasIncludes) {
194:                    this .parse = parse;
195:                    this .hasIncludes = hasIncludes;
196:                }
197:
198:                public boolean equals(Object o) {
199:                    if (o != null && o instanceof  ParseResult) {
200:                        ParseResult pr = (ParseResult) o;
201:                        return parse.equals(pr.parse)
202:                                && hasIncludes == pr.hasIncludes;
203:                    }
204:                    return false;
205:                }
206:            }
207:
208:            static java.util.regex.Pattern includePattern = java.util.regex.Pattern
209:                    .compile(".*#\\s*include\\s*\".*",
210:                            java.util.regex.Pattern.DOTALL);
211:
212:            ParseResult parseFile(File file, String userfname, String source) {
213:                if (Compiler.CachedParses == null) {
214:                    Compiler.CachedParses = new ScriptCompilerCache();
215:                }
216:                String sourceKey = file.getAbsolutePath();
217:                String sourceChecksum = "" + file.lastModified(); // source;
218:                ParseResult entry = (ParseResult) Compiler.CachedParses.get(
219:                        sourceKey, sourceChecksum);
220:                if ((entry == null)
221:                        || options.getBoolean(Compiler.VALIDATE_CACHES)) {
222:                    boolean hasIncludes = includePattern.matcher(source)
223:                            .matches();
224:                    if (options.getBoolean(Compiler.PROGRESS)) {
225:                        // Even though code generation is re-run
226:                        // for every file, just print this for
227:                        // files that are re-parsed, to indicate
228:                        // what's being changed.
229:                        System.err.println("Compiling " + userfname + "...");
230:                    }
231:                    SimpleNode program = (new Compiler.Parser()).parse(source);
232:                    // Always cache the parse tree, since this
233:                    // helps even when the compilation is only one
234:                    // once.  This is because each pass processes
235:                    // the #include again.
236:                    ParseResult realentry = new ParseResult(program,
237:                            hasIncludes);
238:                    Compiler.CachedParses.put(sourceKey, sourceChecksum,
239:                            realentry);
240:                    if ((entry != null)
241:                            && options.getBoolean(Compiler.VALIDATE_CACHES)) {
242:                        if (!realentry.equals(entry)) {
243:                            System.err.println("Bad parse cache for "
244:                                    + sourceKey + ": " + entry + " != "
245:                                    + realentry);
246:                        }
247:                    }
248:                    entry = realentry;
249:                }
250:                return entry;
251:            }
252:
253:            private String mapToString(Map map) {
254:                StringBuffer result = new StringBuffer();
255:                result.append("{");
256:                TreeMap sorted = new TreeMap(map);
257:                for (Iterator i = sorted.keySet().iterator(); i.hasNext();) {
258:                    Object key = i.next();
259:                    result.append(key);
260:                    result.append(": ");
261:                    result.append(sorted.get(key));
262:                    if (i.hasNext()) {
263:                        result.append(", ");
264:                    }
265:                }
266:                result.append("}");
267:                return result.toString();
268:            }
269:
270:            String getCodeGenerationOptionsKey(List ignore) {
271:                Map options = new HashMap(this .options);
272:                options.keySet().removeAll(NonCodeGenerationOptions);
273:                if (ignore != null) {
274:                    options.keySet().removeAll(ignore);
275:                }
276:                return mapToString(options);
277:            }
278:
279:            public SimpleNode visitPragmaDirective(SimpleNode node,
280:                    SimpleNode[] children) {
281:                String key = (String) ((ASTLiteral) children[0]).getValue();
282:                String value = "true";
283:                int equals = key.indexOf('=');
284:                if (equals > 0) {
285:                    value = key.substring(equals + 1);
286:                    key = key.substring(0, equals);
287:                }
288:                if ("false".equalsIgnoreCase(value)
289:                        || "true".equalsIgnoreCase(value)) {
290:                    options.putBoolean(key, value);
291:                } else {
292:                    options.put(key, value);
293:                }
294:                return new ASTEmptyExpression(0);
295:            }
296:
297:            // Flatten nested StatementList structures
298:            private List flatten(SimpleNode[] src) {
299:                List dst = new ArrayList();
300:                for (int i = 0; i < src.length; i++) {
301:                    SimpleNode node = src[i];
302:                    if (node instanceof  ASTStatementList) {
303:                        dst.addAll(flatten(node.getChildren()));
304:                    } else {
305:                        dst.add(node);
306:                    }
307:                }
308:                return dst;
309:            }
310:
311:            public SimpleNode visitClassDefinition(SimpleNode node,
312:                    SimpleNode[] children) {
313:                //     System.err.println("enter visitClassDefinition: " +  (new ParseTreePrinter()).visit(node));
314:                ASTIdentifier classortrait = (ASTIdentifier) children[0];
315:                ASTIdentifier classname = (ASTIdentifier) children[1];
316:                String classnameString = classname.getName();
317:                SimpleNode super class = children[2];
318:                SimpleNode traits = children[3];
319:                SimpleNode traitsandsuper ;
320:                if (traits instanceof  ASTEmptyExpression) {
321:                    if (super class instanceof  ASTEmptyExpression) {
322:                        traitsandsuper  = new ASTLiteral(null);
323:                    } else {
324:                        traitsandsuper  = super class;
325:                    }
326:                } else {
327:                    traitsandsuper  = new ASTArrayLiteral(0);
328:                    traitsandsuper .setChildren(traits.getChildren());
329:                    if (!(super class instanceof  ASTEmptyExpression)) {
330:                        traitsandsuper .set(traitsandsuper .size(), super class);
331:                    }
332:                }
333:
334:                SimpleNode[] dirs = (SimpleNode[]) (Arrays.asList(children)
335:                        .subList(4, children.length).toArray(new SimpleNode[0]));
336:                List props = new ArrayList();
337:                List classProps = new ArrayList();
338:                List stmts = new ArrayList();
339:                translateClassDirectivesBlock(dirs, classnameString, props,
340:                        classProps, stmts);
341:
342:                SimpleNode instanceProperties;
343:                if (props.isEmpty()) {
344:                    instanceProperties = new ASTLiteral(null);
345:                } else {
346:                    instanceProperties = new ASTArrayLiteral(0);
347:                    instanceProperties.setChildren((SimpleNode[]) (props
348:                            .toArray(new SimpleNode[0])));
349:                }
350:                SimpleNode classProperties;
351:                if (classProps.isEmpty()) {
352:                    classProperties = new ASTLiteral(null);
353:                } else {
354:                    classProperties = new ASTArrayLiteral(0);
355:                    classProperties.setChildren((SimpleNode[]) (classProps
356:                            .toArray(new SimpleNode[0])));
357:                }
358:
359:                Map map = new HashMap();
360:                String xtor = "class".equals(classortrait.getName()) ? "Class"
361:                        : "Trait";
362:                map.put("_1", classname);
363:                map.put("_2", traitsandsuper );
364:                map.put("_3", instanceProperties);
365:                map.put("_4", classProperties);
366:                SimpleNode newNode = (new Compiler.Parser()).substitute(xtor
367:                        + ".make(" + ScriptCompiler.quote(classnameString)
368:                        + ", _2, _3, _4);", map);
369:                SimpleNode varNode = new ASTVariableDeclaration(0);
370:                varNode.set(0, classname);
371:                varNode.set(1, newNode);
372:                SimpleNode replNode = varNode;
373:
374:                if (!stmts.isEmpty()) {
375:                    SimpleNode statements = new ASTStatementList(0);
376:                    statements.setChildren((SimpleNode[]) (stmts
377:                            .toArray(new SimpleNode[0])));
378:                    map.put("_5", statements);
379:                    SimpleNode stmtNode = (new Compiler.Parser())
380:                            .substitute(
381:                                    "(function () { with(_1) with(_1.prototype) { _5 }})()",
382:                                    map);
383:                    replNode = new ASTStatementList(0);
384:                    replNode.set(0, varNode);
385:                    replNode.set(1, stmtNode);
386:                }
387:                //     System.err.println("exit visitClassDefinition: " +  (new ParseTreePrinter()).visit(replNode));
388:                return visitStatement(replNode);
389:            }
390:
391:            public void translateClassDirectivesBlock(SimpleNode[] dirs,
392:                    String classnameString, List props, List classProps,
393:                    List stmts) {
394:                dirs = (SimpleNode[]) (flatten(dirs).toArray(new SimpleNode[0]));
395:
396:                // Scope #pragma directives to block
397:                Compiler.OptionMap savedOptions = options;
398:                try {
399:                    options = options.copy();
400:                    for (int i = 0; i < dirs.length; i++) {
401:                        SimpleNode n = dirs[i];
402:                        List p = props;
403:
404:                        // any modifiers, like 'static', 'final' are kept in mod.
405:                        ASTModifiedDefinition mod = null;
406:                        if (n instanceof  ASTModifiedDefinition) {
407:                            assert (n.getChildren().length == 1);
408:                            mod = (ASTModifiedDefinition) n;
409:                            if (mod.isStatic()) {
410:                                p = classProps;
411:                            }
412:                            n = n.get(0);
413:                            mod.verifyClassLevel(n);
414:                        }
415:                        if (n instanceof  ASTFunctionDeclaration) {
416:                            SimpleNode[] c = n.getChildren();
417:                            assert c.length == 3;
418:                            String fname = ((ASTIdentifier) c[0]).getName();
419:                            // Transform constructor into '$lzsc$initialize' method
420:                            if (classnameString.equals(fname)) {
421:                                fname = "$lzsc$initialize";
422:                                c[0] = new ASTIdentifier(fname);
423:                            }
424:                            p.add(new ASTLiteral(fname));
425:                            SimpleNode funexpr = new ASTFunctionExpression(0);
426:                            funexpr.setBeginLocation(n.filename, n.beginLine,
427:                                    n.beginColumn);
428:                            funexpr.setChildren(c);
429:                            p.add(funexpr);
430:                        } else if (n instanceof  ASTVariableStatement) {
431:                            SimpleNode[] c = n.getChildren();
432:                            for (int j = 0, len = c.length; j < len; j++) {
433:                                SimpleNode v = c[j];
434:                                assert v instanceof  ASTVariableDeclaration : v
435:                                        .getClass();
436:                                p.add(new ASTLiteral(((ASTIdentifier) v.get(0))
437:                                        .getName()));
438:                                if (v.getChildren().length > 1) {
439:                                    p.add(v.get(1));
440:                                } else {
441:                                    p.add(new ASTLiteral(null));
442:                                }
443:                            }
444:                        } else if (n instanceof  ASTClassDirectiveBlock) {
445:                            translateClassDirectivesBlock(n.getChildren(),
446:                                    classnameString, props, classProps, stmts);
447:                        } else if (n instanceof  ASTClassIfDirective) {
448:                            Boolean value = evaluateCompileTimeConditional(n
449:                                    .get(0));
450:                            if (value == null) {
451:                                stmts.add(n);
452:                            } else if (value.booleanValue()) {
453:                                SimpleNode clause = n.get(1);
454:                                translateClassDirectivesBlock(clause
455:                                        .getChildren(), classnameString, props,
456:                                        classProps, stmts);
457:                            } else if (n.size() > 2) {
458:                                SimpleNode clause = n.get(2);
459:                                translateClassDirectivesBlock(clause
460:                                        .getChildren(), classnameString, props,
461:                                        classProps, stmts);
462:                            }
463:                        } else if (n instanceof  ASTPragmaDirective) {
464:                            visitPragmaDirective(n, n.getChildren());
465:                        } else {
466:                            stmts.add(n);
467:                        }
468:                    }
469:                } finally {
470:                    options = savedOptions;
471:                }
472:            }
473:
474:            //
475:            // Statements
476:            //
477:
478:            public SimpleNode visitStatement(SimpleNode node) {
479:                return visitStatement(node, node.getChildren());
480:            }
481:
482:            public SimpleNode visitStatement(SimpleNode node,
483:                    SimpleNode[] children) {
484:                /* This function, unlike the other statement visitors, can be
485:                   applied to any statement node, so it dispatches based on the
486:                   node's class. */
487:                assert context instanceof  TranslationContext;
488:                showStats(node);
489:                SimpleNode newNode = node;
490:
491:                if (this .debugVisit) {
492:                    System.err.println("visitStatement: " + node.getClass());
493:                }
494:
495:                // Are we doing OO programming yet?
496:                if (node instanceof  ASTPragmaDirective) {
497:                    newNode = visitPragmaDirective(node, children);
498:                } else if (node instanceof  ASTClassDefinition) {
499:                    newNode = visitClassDefinition(node, children);
500:                } else if (node instanceof  ASTStatementList) {
501:                    newNode = visitStatementList(node, children);
502:                } else if (node instanceof  ASTDirectiveBlock) {
503:                    newNode = visitDirectiveBlock(node, children);
504:                } else if (node instanceof  ASTFunctionDeclaration) {
505:                    newNode = visitFunctionDeclaration(node, children);
506:                } else if (node instanceof  ASTStatement) {
507:                    // an empty statement, introduced by an extra ";", has no children
508:                    if (children.length > 0) {
509:                        children[0] = visitStatement(children[0], children[0]
510:                                .getChildren());
511:                    } else {
512:                        newNode = new ASTEmptyExpression(0);
513:                    }
514:                } else if (node instanceof  ASTLabeledStatement) {
515:                    newNode = visitLabeledStatement(node, children);
516:                } else if (node instanceof  ASTVariableDeclaration) {
517:                    newNode = visitVariableDeclaration(node, children);
518:                } else if (node instanceof  ASTVariableDeclarationList) {
519:                    newNode = visitVariableDeclarationList(node, children);
520:                } else if (node instanceof  ASTVariableStatement) {
521:                    newNode = visitVariableStatement(node, children);
522:                } else if (node instanceof  ASTIfStatement) {
523:                    newNode = visitIfStatement(node, children);
524:                } else if (node instanceof  ASTIfDirective) {
525:                    newNode = visitIfDirective(node, children);
526:                } else if (node instanceof  ASTWhileStatement) {
527:                    newNode = visitWhileStatement(node, children);
528:                } else if (node instanceof  ASTDoWhileStatement) {
529:                    newNode = visitDoWhileStatement(node, children);
530:                } else if (node instanceof  ASTForStatement) {
531:                    newNode = visitForStatement(node, children);
532:                } else if (node instanceof  ASTForVarStatement) {
533:                    newNode = visitForVarStatement(node, children);
534:                } else if (node instanceof  ASTForInStatement) {
535:                    newNode = visitForInStatement(node, children);
536:                } else if (node instanceof  ASTForVarInStatement) {
537:                    newNode = visitForVarInStatement(node, children);
538:                } else if (node instanceof  ASTContinueStatement) {
539:                    newNode = visitContinueStatement(node, children);
540:                } else if (node instanceof  ASTBreakStatement) {
541:                    newNode = visitBreakStatement(node, children);
542:                } else if (node instanceof  ASTReturnStatement) {
543:                    newNode = visitReturnStatement(node, children);
544:                } else if (node instanceof  ASTWithStatement) {
545:                    newNode = visitWithStatement(node, children);
546:                } else if (node instanceof  ASTTryStatement) {
547:                    newNode = visitTryStatement(node, children);
548:                } else if (node instanceof  ASTThrowStatement) {
549:                    newNode = visitThrowStatement(node, children);
550:                } else if (node instanceof  ASTSwitchStatement) {
551:                    newNode = visitSwitchStatement(node, children);
552:                } else if (node instanceof  ASTModifiedDefinition) {
553:                    newNode = visitModifiedDefinition(node, children);
554:                } else if (node instanceof  Compiler.PassThroughNode) {
555:                    newNode = node;
556:                } else {
557:                    // Not a statement, must be an expression
558:                    newNode = visitExpression(node, false);
559:                }
560:                // Check for elided statments
561:                if (newNode == null) {
562:                    newNode = new ASTEmptyExpression(0);
563:                }
564:                if (this .debugVisit) {
565:                    if (!newNode.equals(node)) {
566:                        System.err.println("statement: " + node + " -> "
567:                                + newNode);
568:                    }
569:                }
570:                return newNode;
571:            }
572:
573:            public SimpleNode visitStatementList(SimpleNode node,
574:                    SimpleNode[] stmts) {
575:                int i = 0;
576:                // ensure dynamic extent of #pragma in a block
577:                Compiler.OptionMap prevOptions = options;
578:                Compiler.OptionMap newOptions = options.copy();
579:                // TODO: [2003-04-15 ptw] bind context slot macro
580:                try {
581:                    options = newOptions;
582:                    while (i < stmts.length) {
583:                        SimpleNode stmt = stmts[i];
584:                        stmts[i] = visitStatement(stmt);
585:                        i += 1;
586:                    }
587:                } finally {
588:                    options = prevOptions;
589:                }
590:                return node;
591:            }
592:
593:            public SimpleNode visitVariableDeclarationList(SimpleNode node,
594:                    SimpleNode[] children) {
595:                for (int i = 0, len = children.length; i < len; i++) {
596:                    children[i] = visitStatement(children[i]);
597:                }
598:                return node;
599:            }
600:
601:            // for function prefix/suffix parsing
602:            public SimpleNode visitDirectiveBlock(SimpleNode node,
603:                    SimpleNode[] children) {
604:                return visitStatementList(node, children);
605:            }
606:
607:            public SimpleNode visitModifiedDefinition(SimpleNode node,
608:                    SimpleNode[] children) {
609:                // Modifiers, like 'final', are ignored unless this is handled
610:                // by the runtime.
611:
612:                assert children.length == 1;
613:                SimpleNode child = children[0];
614:
615:                ((ASTModifiedDefinition) node).verifyTopLevel(child);
616:
617:                return visitStatement(child);
618:            }
619:
620:            public SimpleNode visitLabeledStatement(SimpleNode node,
621:                    SimpleNode[] children) {
622:                ASTIdentifier name = (ASTIdentifier) children[0];
623:                SimpleNode stmt = children[1];
624:                // TODO: [2003-04-15 ptw] bind context slot macro
625:                try {
626:                    context = new TranslationContext(ASTLabeledStatement.class,
627:                            context, name.getName());
628:                    // TODO: [2002 ows] throw semantic error for duplicate label
629:                    children[1] = visitStatement(stmt);
630:                    return node;
631:                } finally {
632:                    context = context.parent;
633:                }
634:            }
635:
636:            // for function prefix/suffix parsing
637:            public SimpleNode visitIfDirective(SimpleNode node,
638:                    SimpleNode[] children) {
639:                return visitIfStatement(node, children);
640:            }
641:
642:            public SimpleNode visitForVarInStatement(SimpleNode node,
643:                    SimpleNode[] children) {
644:                SimpleNode var = children[0];
645:                // SimpleNode _ = children[1];
646:                SimpleNode obj = children[2];
647:                SimpleNode body = children[3];
648:                if (options.getBoolean(Compiler.ACTIVATION_OBJECT)) {
649:                    return translateForInStatement(node, var,
650:                            Instructions.SetVariable, obj, body);
651:                }
652:                return translateForInStatement(node, var,
653:                        Instructions.VarEquals, obj, body);
654:            }
655:
656:            public SimpleNode visitContinueStatement(SimpleNode node,
657:                    SimpleNode[] children) {
658:                SimpleNode label = children.length > 0 ? children[0] : null;
659:                return translateAbruptCompletion(node, "continue",
660:                        (ASTIdentifier) label);
661:            }
662:
663:            public SimpleNode visitBreakStatement(SimpleNode node,
664:                    SimpleNode[] children) {
665:                SimpleNode label = children.length > 0 ? children[0] : null;
666:                return translateAbruptCompletion(node, "break",
667:                        (ASTIdentifier) label);
668:            }
669:
670:            public SimpleNode visitAndExpressionSequence(SimpleNode node,
671:                    boolean isReferenced, SimpleNode[] children) {
672:                SimpleNode a = children[0];
673:                SimpleNode b = children[1];
674:                return translateAndOrExpression(node, true, a, b);
675:            }
676:
677:            public SimpleNode visitOrExpressionSequence(SimpleNode node,
678:                    boolean isReferenced, SimpleNode[] children) {
679:                SimpleNode a = children[0];
680:                SimpleNode b = children[1];
681:                return translateAndOrExpression(node, false, a, b);
682:            }
683:
684:            static class DoubleCollator implements  Comparator {
685:                public boolean equals(Object o1, Object o2) {
686:                    return ((Double) o1).equals((Double) o2);
687:                }
688:
689:                public int compare(Object o1, Object o2) {
690:                    return ((Double) o1).compareTo((Double) o2);
691:                }
692:            }
693:
694:            public SimpleNode visitChildren(SimpleNode node) {
695:                SimpleNode[] children = node.getChildren();
696:                for (int i = 0, len = children.length; i < len; i++) {
697:                    SimpleNode child = children[i];
698:                    children[i] = visitStatement(child);
699:                }
700:                return node;
701:            }
702:
703:            public SimpleNode translateSuperCallExpression(SimpleNode node,
704:                    boolean isReferenced, SimpleNode[] children) {
705:
706:                assert children.length == 3;
707:                SimpleNode fname = children[0];
708:                SimpleNode callapply = children[1];
709:                SimpleNode args = children[2];
710:                String name;
711:                String ca = null;
712:                String pattern = "(arguments.callee.superclass?arguments.callee.superclass.prototype[_1]:this.nextMethod(arguments.callee, _1)).call(this, _2)";
713:                if (fname instanceof  ASTEmptyExpression) {
714:                    // super with no selector is the constructor, which will be
715:                    // renamed to $lzsc$initialize in translateClassDirective to
716:                    // mesh with lfc/compiler/Class.lzs framework
717:                    name = "$lzsc$initialize";
718:                } else {
719:                    name = ((ASTIdentifier) fname).getName();
720:                }
721:                if (callapply instanceof  ASTIdentifier) {
722:                    ca = ((ASTIdentifier) callapply).getName();
723:                }
724:                // FIXME: [2005-03-09 ptw] (LPP-98 "Compiler source-source
725:                // transformations should be in separate phase") This should be
726:                // in a phase before the compiler, so that register analysis
727:                // sees it.  [Or this should be eliminated altogether and we
728:                // should use swf7's real super call, but that will mean we
729:                // have to solve the __proto__ vs. super in constructor
730:                // problem.]
731:                Map map = new HashMap();
732:                map.put("_1", new ASTLiteral(name));
733:                map.put("_2", new Compiler.Splice(args.getChildren()));
734:                if (ca == null) {
735:                    ;
736:                } else if ("call".equals(ca)) {
737:                    pattern = "(arguments.callee.superclass?arguments.callee.superclass.prototype[_1]:this.nextMethod(arguments.callee, _1)).call(_2)";
738:                } else if ("apply".equals(ca)) {
739:                    pattern = "(arguments.callee.superclass?arguments.callee.superclass.prototype[_1]:this.nextMethod(arguments.callee, _1)).apply(_2)";
740:                } else {
741:                    assert false : "Unhandled super call " + ca;
742:                }
743:                SimpleNode n = (new Compiler.Parser()).substitute(pattern, map);
744:                return n;
745:            }
746:
747:            public SimpleNode visitVariableStatement(SimpleNode node,
748:                    SimpleNode[] children) {
749:                return visitChildren(node);
750:            }
751:
752:            boolean isExpressionType(SimpleNode node) {
753:                // There are several AST types that end with each of the names that
754:                // endsWith tests for.
755:                String name = node.getClass().getName();
756:                return name.endsWith("Expression")
757:                        || name.endsWith("FunctionCallParameters")
758:                        || name.endsWith("ExpressionList")
759:                        || name.endsWith("ExpressionSequence")
760:                        || name.endsWith("Identifier")
761:                        || name.endsWith("Literal")
762:                        || name.endsWith("Reference");
763:            }
764:
765:            public SimpleNode dispatchExpression(SimpleNode node,
766:                    boolean isReferenced) {
767:                // Are we doing OO programming yet?
768:                SimpleNode[] children = node.getChildren();
769:                SimpleNode newNode = null;
770:
771:                if (node instanceof  ASTIdentifier) {
772:                    newNode = visitIdentifier(node, isReferenced, children);
773:                } else if (node instanceof  ASTLiteral) {
774:                    newNode = visitLiteral(node, isReferenced, children);
775:                } else if (node instanceof  ASTExpressionList) {
776:                    newNode = visitExpressionList(node, isReferenced, children);
777:                } else if (node instanceof  ASTEmptyExpression) {
778:                    newNode = visitEmptyExpression(node, isReferenced, children);
779:                } else if (node instanceof  ASTThisReference) {
780:                    newNode = visitThisReference(node, isReferenced, children);
781:                } else if (node instanceof  ASTArrayLiteral) {
782:                    newNode = visitArrayLiteral(node, isReferenced, children);
783:                } else if (node instanceof  ASTObjectLiteral) {
784:                    newNode = visitObjectLiteral(node, isReferenced, children);
785:                } else if (node instanceof  ASTFunctionExpression) {
786:                    newNode = visitFunctionExpression(node, isReferenced,
787:                            children);
788:                } else if (node instanceof  ASTFunctionCallParameters) {
789:                    newNode = visitFunctionCallParameters(node, isReferenced,
790:                            children);
791:                } else if (node instanceof  ASTPropertyIdentifierReference) {
792:                    newNode = visitPropertyIdentifierReference(node,
793:                            isReferenced, children);
794:                } else if (node instanceof  ASTPropertyValueReference) {
795:                    newNode = visitPropertyValueReference(node, isReferenced,
796:                            children);
797:                } else if (node instanceof  ASTCallExpression) {
798:                    newNode = visitCallExpression(node, isReferenced, children);
799:                } else if (node instanceof  ASTSuperCallExpression) {
800:                    newNode = visitSuperCallExpression(node, isReferenced,
801:                            children);
802:                } else if (node instanceof  ASTNewExpression) {
803:                    newNode = visitNewExpression(node, isReferenced, children);
804:                } else if (node instanceof  ASTPostfixExpression) {
805:                    newNode = visitPostfixExpression(node, isReferenced,
806:                            children);
807:                } else if (node instanceof  ASTUnaryExpression) {
808:                    newNode = visitUnaryExpression(node, isReferenced, children);
809:                } else if (node instanceof  ASTBinaryExpressionSequence) {
810:                    newNode = visitBinaryExpressionSequence(node, isReferenced,
811:                            children);
812:                } else if (node instanceof  ASTAndExpressionSequence) {
813:                    newNode = visitAndExpressionSequence(node, isReferenced,
814:                            children);
815:                } else if (node instanceof  ASTOrExpressionSequence) {
816:                    newNode = visitOrExpressionSequence(node, isReferenced,
817:                            children);
818:                } else if (node instanceof  ASTConditionalExpression) {
819:                    newNode = visitConditionalExpression(node, isReferenced,
820:                            children);
821:                } else if (node instanceof  ASTAssignmentExpression) {
822:                    newNode = visitAssignmentExpression(node, isReferenced,
823:                            children);
824:                } else if (node instanceof  Compiler.PassThroughNode) {
825:                    newNode = node;
826:                } else {
827:                    throw new CompilerImplementationError("unknown expression "
828:                            + node, node);
829:                }
830:                return newNode;
831:            }
832:
833:            abstract SimpleNode translateForInStatement(SimpleNode node,
834:                    SimpleNode var, Instructions.Instruction varset,
835:                    SimpleNode obj, SimpleNode body);
836:
837:            abstract SimpleNode translateAbruptCompletion(SimpleNode node,
838:                    String type, ASTIdentifier label);
839:
840:            abstract SimpleNode translateAndOrExpression(SimpleNode node,
841:                    boolean isand, SimpleNode a, SimpleNode b);
842:
843:            /** Collect runtime statistics at this point in the program if asked for.
844:             */
845:            abstract void showStats(SimpleNode node);
846:
847:            File includeNameToFile(String userfname) {
848:                try {
849:                    String fname = userfname;
850:
851:                    if (options.containsKey(Compiler.RESOLVER)) {
852:                        fname = ((lzsc.Resolver) options.get(Compiler.RESOLVER))
853:                                .resolve(userfname);
854:                    }
855:                    return new File(new File(fname).getCanonicalPath());
856:                } catch (IOException e) {
857:                    throw new CompilerError("error reading include: " + e);
858:                }
859:            }
860:
861:            String includeFileToSourceString(File file, String userfname) {
862:                String source;
863:                try {
864:                    FileInputStream stream = new FileInputStream(file);
865:                    try {
866:                        int n = stream.available();
867:                        byte[] b = new byte[n];
868:                        stream.read(b);
869:                        source = "#file " + userfname + "\n#line 1\n"
870:                                + new String(b, "UTF-8");
871:                    } finally {
872:                        stream.close();
873:                    }
874:                } catch (FileNotFoundException e) {
875:                    throw new CompilerError("error reading include: " + e);
876:                } catch (UnsupportedEncodingException e) {
877:                    throw new CompilerError("error reading include: " + e);
878:                } catch (IOException e) {
879:                    throw new CompilerError("error reading include: " + e);
880:                }
881:                return source;
882:            }
883:        }
884:
885:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
886:         * Copyright 2001-2008 Laszlo Systems, Inc.  All Rights Reserved.              *
887:         * Use is subject to license terms.                                            *
888:         * J_LZ_COPYRIGHT_END *********************************************************/
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.