flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aha...@apache.org
Subject svn commit: r1413061 [11/14] - in /incubator/flex/falcon/trunk/compiler.js: ./ bin/ build/ in/ intermediates/ localization/ localization/src/ localization/src/org/ localization/src/org/apache/ localization/src/org/apache/flex/ localization/src/org/apac...
Date Fri, 23 Nov 2012 20:58:56 GMT
Added: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSWriter.java
URL: http://svn.apache.org/viewvc/incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSWriter.java?rev=1413061&view=auto
==============================================================================
--- incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSWriter.java (added)
+++ incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSWriter.java Fri Nov 23 20:58:50 2012
@@ -0,0 +1,1443 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.as.codegen;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.flex.abc.ABCConstants;
+import org.apache.flex.abc.semantics.Name;
+import org.apache.flex.abc.semantics.Namespace;
+import org.apache.flex.compiler.clients.MXMLJSC;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.definitions.INamespaceDefinition;
+import org.apache.flex.compiler.definitions.metadata.IMetaTag;
+import org.apache.flex.compiler.internal.scopes.ASProjectScope;
+import org.apache.flex.compiler.internal.units.SWCCompilationUnit;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.units.requests.IABCBytesRequestResult;
+import org.apache.flex.swf.ISWF;
+import org.apache.flex.swf.SWFFrame;
+import org.apache.flex.swf.io.ISWFWriter;
+import org.apache.flex.swf.io.OutputBitStream;
+import org.apache.flex.swf.tags.DoABCTag;
+import org.apache.flex.swf.tags.ITag;
+import org.apache.flex.swf.TagType;
+
+import com.google.javascript.jscomp.CompilationLevel;
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.CompilerOptions;
+import com.google.javascript.jscomp.CommandLineRunner;
+import com.google.javascript.jscomp.JSError;
+import com.google.javascript.jscomp.JSSourceFile;
+
+/**
+ * The implementation of SWF tag, type encoding logic. The SWF file body are
+ * buffered in memory using {@code IOutputBitStream}. ZLIB compression is
+ * optional. If enabled, compression is on-the-fly via a filtered output stream.
+ * JSWriter is modeled after SWFWriter and emits the resulting JS file collected
+ * from JSEmitters. JSEmitter only collects JS from one JSCompilationUnit
+ * (usually one class) while JSWriter combines all JS code into one JS file with
+ * some extra code for static initializers etc. JSDriver creates and uses
+ * JSWriter for writing SWFs, which are JS files in FalconJS's world. This
+ * implementation is part of FalconJS. For more details on FalconJS see
+ * org.apache.flex.compiler.JSDriver
+ */
+public class JSWriter implements ISWFWriter
+{
+    private ICompilerProject m_project;
+    List<ICompilerProblem> m_problems;
+
+    // SWF model
+    private final ISWF swf;
+
+    private final Collection<ICompilationUnit> compilationUnits;
+
+    // This buffer contains the SWF data after FileLength field. 
+    private final OutputBitStream outputBuffer;
+
+    private Boolean hasStage = false;
+
+    /**
+     * Create a SWF writer.
+     * 
+     * @param swf the SWF model to be encoded
+     * @param useCompression use ZLIB compression if true
+     */
+    public JSWriter(ICompilerProject project, List<ICompilerProblem> problems, ISWF swf, boolean useCompression, boolean enableDebug)
+    {
+        this.m_project = project;
+        this.m_problems = problems;
+        this.swf = swf;
+        this.compilationUnits = null;
+        this.outputBuffer = new OutputBitStream(useCompression);
+    }
+
+    /**
+     * Create a SWF writer.
+     * 
+     * @param abc the ABC bytes to be encoded
+     * @param useCompression use ZLIB compression if true
+     */
+    public JSWriter(ICompilerProject project, List<ICompilerProblem> problems, Collection<ICompilationUnit> compilationUnits, boolean useCompression)
+    {
+        this.m_project = project;
+        this.m_problems = problems;
+        this.swf = null;
+        this.compilationUnits = compilationUnits;
+        this.outputBuffer = new OutputBitStream(useCompression);
+    }
+
+    private Boolean isStageCompilationUnit(ICompilationUnit cu)
+    {
+        if (cu != null)
+        {
+            final String name = cu.getName();
+            if (name.endsWith("(flash.display:Stage)"))
+                return true;
+        }
+        return false;
+    }
+
+    public String getTopLevelClass()
+    {
+        if (swf != null)
+            return swf.getTopLevelClass();
+        return null;
+    }
+
+    private void writeCode(List<byte[]> abcByteList, Boolean createSharedLib) throws InterruptedException
+    {
+        // start with the time stamp
+        // write time stamp to outputBuffer
+        if (JSSharedData.OUTPUT_TIMESTAMPS)
+            writeString("/** @preserve " + JSGeneratingReducer.getTimeStampString() + " */\n");
+
+        if (!JSSharedData.OUTPUT_ISOLATED)
+        {
+            // open function closure: function() { ... } 
+            writePrologue(createSharedLib);
+
+            // write out the framework root first.
+            writeFrameworkRoot(createSharedLib);
+
+            // write out DOM extensions.
+            writeDomExtensions();
+
+            // write out copyright notes
+            writeCopyrightNotes();
+
+            // write out package names
+            writePackageNames(createSharedLib);
+
+            // writeExternNames();
+
+            // write out namespace names
+            writeNamepaceNames();
+
+        }
+
+        // Current frame index. Updated in writeFrames().
+        for (byte[] abcBytes : abcByteList)
+        {
+            /*
+             * Extract abc from frame, see JSCompilationUnit::addToFrame():
+             * doABC.setAbcData(abc.getABCBytes()); doABC.setName("as3");
+             * frame.addTag(doABC);
+             */
+            {
+                // see SWFWriter::writeTag
+                {
+                    // see SWFWriter::writeDoABC
+
+                    Boolean isBinary = false;
+                    /*
+                     * see avm2overview.pdf, chapter 4.2 abcFile { u16
+                     * minor_version u16 major_version cpool_info constant_pool
+                     * u30 method_count method_info method[method_count] u30
+                     * metadata_count metadata_info metadata[metadata_count] u30
+                     * class_count instance_info instance[class_count]
+                     * class_info class[class_count] u30 script_count
+                     * script_info script[script_count] u30 method_body_count
+                     * method_body_info method_body[method_body_count] }
+                     */
+                    if (abcBytes.length > 2)
+                    {
+                        // 16 00 46 00
+                        final int minorVersion = 16;
+                        final int majorVersion = 46;
+                        if (abcBytes[0] == minorVersion &&
+                            abcBytes[2] == majorVersion)
+                        {
+                            isBinary = true;
+
+                            // throw new Error( "Embedded data is not supported yet." );
+
+                            /*
+                             * final AbcDump abcDump = new AbcDump();
+                             * abcDump.out = JSSharedData.STDOUT; ABCParser
+                             * parser = new ABCParser(abcBytes);
+                             * parser.parseAbc(abcDump);
+                             */
+                            /*
+                             * try { FileOutputStream out = new
+                             * FileOutputStream("/tmp/falcon-js.abc"); try {
+                             * out.write(abcBytes); out.close(); } catch(
+                             * IOException e ) { } } catch(
+                             * FileNotFoundException e ) { }
+                             */
+                        }
+                    }
+
+                    if (!isBinary)
+                        outputBuffer.write(abcBytes);
+                }
+            }
+        }
+
+        if (createSharedLib || !JSSharedData.OUTPUT_ISOLATED)
+        {
+            // write out adobe.finalize();
+            writeFinalize(createSharedLib);
+
+            // close closure: function() { ... } 
+            writeEpilogue(createSharedLib);
+        }
+    }
+
+    /*
+     * private Boolean hasEncryptedJS( ICompilationUnit cu ) throws
+     * InterruptedException { final JSSharedData sharedData =
+     * JSSharedData.instance; final List<IDefinition> defs =
+     * MXMLJSC.getDefinitions(cu, false); for( IDefinition def: defs ) { final
+     * String fullName = def.getQualifiedName(); if(
+     * sharedData.hasJavaScript(fullName) && sharedData.hasEncryptedJS(fullName)
+     * ) return true; } return false; }
+     */
+
+    private List<byte[]> getAbcData(ISWF swf, Boolean createSharedLib) throws InterruptedException
+    {
+        final JSSharedData sharedData = JSSharedData.instance;
+        final List<byte[]> abcByteList = new ArrayList<byte[]>();
+        if (swf == null)
+        {
+            for (ICompilationUnit cu : compilationUnits)
+            {
+                // only add topLevelClass to Stage if the Stage gets emitted.
+                if (!hasStage)
+                    hasStage = isStageCompilationUnit(cu);
+
+                final Boolean isSWC = cu instanceof SWCCompilationUnit;
+                if (createSharedLib == isSWC)
+                {
+                    final List<IDefinition> defs = MXMLJSC.getDefinitions(cu, false);
+                    for (IDefinition def : defs)
+                    {
+                        final String fullName = def.getQualifiedName();
+                        if (sharedData.hasJavaScript(fullName))
+                        {
+                            final String jsCode = sharedData.getJavaScript(fullName);
+                            abcByteList.add(jsCode.getBytes());
+                        }
+                    }
+
+                    final IABCBytesRequestResult codegenResult = cu.getABCBytesRequest().get();
+                    final byte[] abcBytes = codegenResult.getABCBytes();
+                    abcByteList.add(abcBytes);
+                }
+            }
+            return abcByteList;
+        }
+
+        // Current frame index. Updated in writeFrames().
+        for (int currentFrameIndex = 0; currentFrameIndex < swf.getFrameCount(); currentFrameIndex++)
+        {
+            final SWFFrame frame = swf.getFrameAt(currentFrameIndex);
+
+            // If the SWF has a top level class name, the first frame must contain a SymbolClass tag.
+            if (0 == currentFrameIndex && null != getTopLevelClass())
+            {
+                SWFFrame.forceSymbolClassTag(frame);
+            }
+
+            /*
+             * Extract abc from frame, see JSCompilationUnit::addToFrame():
+             * doABC.setAbcData(abc.getABCBytes()); doABC.setName("as3");
+             * frame.addTag(doABC);
+             */
+            for (final ITag tag : frame)
+            {
+                // see SWFWriter::writeTag
+                if (tag.getTagType() == TagType.DoABC)
+                {
+                    // see SWFWriter::writeDoABC
+                    final DoABCTag abcTag = ((DoABCTag)tag);
+                    byte[] abcBytes = abcTag.getABCData();
+
+                    Boolean isBinary = false;
+                    /*
+                     * see avm2overview.pdf, chapter 4.2 abcFile { u16
+                     * minor_version u16 major_version cpool_info constant_pool
+                     * u30 method_count method_info method[method_count] u30
+                     * metadata_count metadata_info metadata[metadata_count] u30
+                     * class_count instance_info instance[class_count]
+                     * class_info class[class_count] u30 script_count
+                     * script_info script[script_count] u30 method_body_count
+                     * method_body_info method_body[method_body_count] }
+                     */
+                    if (abcBytes.length > 2)
+                    {
+                        // 16 00 46 00
+                        final int minorVersion = 16;
+                        final int majorVersion = 46;
+                        if (abcBytes[0] == minorVersion &&
+                            abcBytes[2] == majorVersion)
+                        {
+                            isBinary = true;
+
+                            // throw new Error( "Embedded data is not supported yet." );
+
+                            if (abcTag.getName().startsWith("#"))
+                                sharedData.verboseMessage("ABC: " + abcTag.getName());
+
+                            /*
+                             * final AbcDump abcDump = new AbcDump();
+                             * abcDump.out = JSSharedData.STDOUT; ABCParser
+                             * parser = new ABCParser(abcBytes);
+                             * parser.parseAbc(abcDump);
+                             */
+                            /*
+                             * try { FileOutputStream out = new
+                             * FileOutputStream("/tmp/falcon-js.abc"); try {
+                             * out.write(abcBytes); out.close(); } catch(
+                             * IOException e ) { } } catch(
+                             * FileNotFoundException e ) { }
+                             */
+                        }
+                    }
+
+                    if (!isBinary)
+                    {
+                        final ICompilationUnit cu = sharedData.getCompilationUnit(frame);
+                        final Boolean isSWC = cu instanceof SWCCompilationUnit;
+
+                        // only add topLevelClass to Stage if the Stage gets emitted.
+                        if (!hasStage)
+                            hasStage = isStageCompilationUnit(cu);
+
+                        if (createSharedLib == isSWC)
+                        {
+                            if (cu != null && sharedData.isVerbose())
+                            {
+                                String str = cu.toString() + ": ";
+                                if (cu instanceof SWCCompilationUnit)
+                                {
+                                    Boolean comma = false;
+                                    final List<IDefinition> defs = MXMLJSC.getDefinitions(cu, true);
+                                    for (IDefinition def : defs)
+                                    {
+                                        if (comma)
+                                            str += ", ";
+                                        else
+                                            comma = true;
+                                        str += JSGeneratingReducer.createFullNameFromDefinition(cu.getProject(), def);
+                                    }
+                                }
+                                str += " " + abcBytes.length + " bytes.";
+                                sharedData.verboseMessage(str);
+                            }
+
+                            abcByteList.add(abcBytes);
+                        }
+                    }
+                }
+            }
+        }
+
+        return abcByteList;
+    }
+
+    public void writeTo(OutputStream output)
+    {
+        writeTo(output, false);
+    }
+
+    public void writeLibTo(OutputStream output)
+    {
+        writeTo(output, true);
+    }
+
+    private void writeTo(OutputStream output, Boolean createSharedLib)
+    {
+        assert output != null;
+
+        try
+        {
+            outputBuffer.reset();
+
+            List<byte[]> abcByteList = getAbcData(swf, createSharedLib);
+            if (!abcByteList.isEmpty())
+            {
+                writeCode(abcByteList, createSharedLib);
+
+                // if we are pulling in encrypted JS through a SWC that JS should probably 
+                // go into the shared lib and obfuscated with ADVANCED_OPTIMIZATIONS. Otherwise the whole point
+                // of encrypting JS would be defeated.
+                // At this point protecting intellectual property of JS and -js-generate-shared-library 
+                // have a lower priority than other features.
+                // DISABLED for now:
+                // if( JSSharedData.OPTIMIZE || (createSharedLib && JSSharedData.instance.hasAnyEncryptedJS()) )
+                // 		optimize( outputBuffer, createSharedLib );
+
+                // support for optimize=true
+                if (JSSharedData.OPTIMIZE)
+                    optimize(outputBuffer, createSharedLib);
+
+                output.write(outputBuffer.getBytes(), 0, outputBuffer.size());
+                output.flush();
+            }
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (InterruptedException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Close the internal output buffer that stores the encoded SWF tags and
+     * part of the SWF header.
+     */
+    public void close() throws IOException
+    {
+        outputBuffer.close();
+    }
+
+    private void writeString(String s)
+    {
+        outputBuffer.write(s.getBytes());
+    }
+
+    protected void writeCopyrightNotes()
+    {
+        if (!JSSharedData.m_useClosureLib)
+        {
+            // Source: http://ejohn.org/blog/simple-javascript-inheritance/
+            final String jresigNote =
+                    "/* Simple JavaScript Inheritance\n" +
+                            " * By John Resig http://ejohn.org/\n" +
+                            " * MIT Licensed.\n" +
+                            " *\n" +
+                            " * Adobe Systems Inc. 2010.  Modifications:\n" +
+                            " * - added support for getter and setter.\n" +
+                            " * - all objects become jQuery objects if jQuery is present.\n" +
+                            " * - support for calling constructor functions directly, i.e. var s = Sprite();\n" +
+                            " * - ported to ActionScript so this code can be cross-compiled.\n" +
+                            " */\n" +
+                            "// Inspired by base2 and Prototype";
+
+            // write out the copyright note for John Resig's simple class inheritance in JS:
+            // http://ejohn.org/blog/simple-javascript-inheritance/
+            writeString(jresigNote + "\n\n");
+        }
+    }
+
+    protected void writePackageNames(Boolean createSharedLib)
+    {
+        writeString("\n");
+        writeString("/**\n");
+        writeString(" * Packages \n");
+        writeString(" */\n");
+
+        final Set<String> visited = new HashSet<String>();
+        final Set<String> packages = JSSharedData.instance.getPackages();
+        for (String name : packages)
+        {
+            String packageName = JSSharedData.ROOT_NAME;
+            String[] parts = name.split("\\.");
+            for (String part : parts)
+            {
+                if (!part.isEmpty())
+                {
+                    if (!packageName.isEmpty())
+                        packageName += ".";
+
+                    packageName += part;
+                    if (!visited.contains(packageName))
+                    {
+                        visited.add(packageName);
+
+                        writeString("/** @typedef { Object } */\n");
+                        if (!packageName.contains("."))
+                            writeString("var ");
+
+                        writeString(packageName + " = { _FULLNAME: \"" + packageName + "\"};\n");
+                    }
+                }
+            }
+        }
+        writeString("\n");
+    }
+
+    /*
+     * protected void writeExternNames() { final Set<String> externs =
+     * JSSharedData.instance.getUsedExterns(); if( !externs.isEmpty() ) {
+     * writeString( "\n" ); writeString( "/ **\n" ); writeString(
+     * " * Externs \n" ); writeString( " * /\n" ); for( String defName: externs
+     * ) { if( JSSharedData.instance.isReferencedDefinition(defName) ) { final
+     * IDefinition def = JSSharedData.instance.getDefinition(defName); String
+     * name = null; final IMetaTag extern =
+     * def.getMetaTagByName(JSSharedData.EXTERN_METATAG); if( extern != null )
+     * name = extern.getAttributeValue("name"); if( name == null ) name =
+     * def.getShortName(); // TODO: get rid of the hard-coded checks. String
+     * fullName = def.getPackageName(); if( !fullName.isEmpty() ) fullName +=
+     * "."; fullName += def.getName(); if( !fullName.equals(name) ) writeString(
+     * fullName + " = " + name + ";\n" ); } } writeString( "\n" ); } }
+     */
+
+    protected void writeNamepaceNames()
+    {
+        final Map<String, INamespaceDefinition> namespaces = JSSharedData.instance.getNamespaces();
+
+        if (!namespaces.isEmpty())
+        {
+            writeString("\n");
+            writeString("/**\n");
+            writeString(" * Namespace identifiers \n");
+            writeString(" */\n");
+
+            // see JSGeneratingReducer.reduce_namespaceDeclarationConstantInitializer() for where these get registered
+
+            for (Map.Entry<String, INamespaceDefinition> entry : namespaces.entrySet())
+            {
+                String uri = entry.getKey();
+                INamespaceDefinition nsDef = entry.getValue();
+
+                // TODO: should there be a package qualifier prefix?
+                String name = nsDef.getBaseName();
+
+                // TODO: value should really be an object of type Namespace, not a String; see FJS-65
+                writeString("var " + name + " = \"" + uri + "\";\n");
+            }
+            writeString("\n");
+        }
+
+    }
+
+    protected void writeFrameworkRoot(Boolean createSharedLib)
+    {
+        writeString("// Declaring missing types\n");
+        writeString("var IntClass = function(){};\n");
+        writeString("var UIntClass = function(){};\n");
+        writeString("\n");
+
+        // write out framework root object
+        if (JSSharedData.m_useClosureLib)
+        {
+            writeString("/**\n");
+            writeString(" * Framework: " + JSSharedData.JS_FRAMEWORK_NAME + "\n");
+            writeString(" */\n");
+            // writeString( "goog.provide(\"" + JSSharedData.JS_FRAMEWORK_NAME + "\");\n\n" ); 
+
+            if (createSharedLib)
+                writeString("var " + JSSharedData.JS_FRAMEWORK_NAME + " = __adobe || {};\n\n");
+            else
+                writeString("var " + JSSharedData.JS_FRAMEWORK_NAME + " = {};\n\n");
+
+            if (!JSSharedData.ROOT_NAME.isEmpty())
+            {
+                String rootName = JSSharedData.ROOT_NAME;
+                // remove trailing dot
+                if (rootName.endsWith("."))
+                    rootName = rootName.substring(0, rootName.length() - 1);
+
+                writeString("/**\n");
+                writeString(" * Root: " + rootName + "\n");
+                writeString(" */\n");
+                writeString("goog.provide(\"" + rootName + "\");\n");
+            }
+        }
+        else
+        {
+            writeString("/**\n");
+            writeString(" * Framework: " + JSSharedData.JS_FRAMEWORK_NAME + "\n");
+            writeString(" * @type {object}\n");
+            writeString(" */\n");
+            writeString("var " + JSSharedData.JS_FRAMEWORK_NAME + " = {};\n");
+
+        }
+
+        writeString(JSSharedData.JS_SYMBOLS + "= {};\n");
+
+        writeString("\n");
+    }
+
+    protected void writeDomExtensions()
+    {
+        if (JSSharedData.EXTEND_DOM)
+        {
+            final String indent = "\t";
+
+            // see also:
+            // http://hg.mozilla.org/tamarin-redux/file/758198237dc1/test/acceptance/ecma3
+            // http://qfox.nl/ecma/275
+            // http://code.google.com/p/sputniktests/
+            // http://es5.github.com/
+
+            writeString("\n");
+
+            writeString("// Additions to DOM classes necessary for passin Tamarin's acceptance tests.\n");
+            writeString("// Please use -js-extend-dom=false if you want to prevent DOM core objects changes.\n");
+            writeString("if( typeof(__global[\"Math\"].NaN) != \"number\" )\n");
+            writeString("{\n");
+
+            writeString(indent + "/**\n");
+            writeString(indent + " * @const\n");
+            writeString(indent + " * @type {function()}\n");
+            writeString(indent + " */\n");
+            writeString(indent + "var fnToString = function() { return \"function Function() {}\"; };\n");
+
+            writeString(indent + "/** @type {object} */\n");
+            writeString(indent + "var proto = {};\n");
+
+            // see e15_8_1.as
+            writeString("\n");
+            writeString(indent + "// Additions to Math\n");
+            writeString(indent + "__global[\"Math\"].NaN = NaN;\n");
+
+            // see e15_8_1.as, ecma3/Array/e15_4_2_1_3.
+            writeString("\n");
+            writeString(indent + "// Additions to Array (see e15_4_1_1, e15_4_2_1_1, e15_4_2_1_3, e15_4_2_2_1)\n");
+            writeString(indent + "proto = __global[\"Array\"].prototype;\n");
+            writeString(indent + "proto.toString.toString = fnToString;\n");
+            writeString(indent + "proto.join.toString = fnToString;\n");
+            writeString(indent + "proto.sort.toString = fnToString;\n");
+            writeString(indent + "proto.reverse.toString = fnToString;\n");
+
+            // In browsers, Array.prototype.unshift.length = 1, because
+            // the this value is coerced to an object.
+
+            // We need to hide unshift after setting it.
+            // Otherwise we'll get "unshift" for:
+            // var arr = new Array(); for( n in arr ) { console.info(n); }
+            writeString(indent + "if( Object.defineProperty )\n");
+            writeString(indent + "{\n");
+            writeString(indent + indent + "proto.unshift = (function ()\n");
+            writeString(indent + indent + "{\n");
+            writeString(indent + indent + indent + "/** @type {function()} */\n");
+            writeString(indent + indent + indent + "var f = proto.unshift;\n");
+            writeString(indent + indent + indent + "return function() { return f.apply(this,arguments); };\n");
+            writeString(indent + indent + "})();\n");
+            writeString(indent + indent + "Object.defineProperty( proto, \"unshift\", {enumerable: false} );\n");
+            writeString(indent + "}\n");
+
+            // see ecma3/ErrorObject/e15_11_2_1.as
+            writeString("\n");
+            writeString(indent + "// Additions to Error (see e15_11_2_1)\n");
+            writeString(indent + "proto = __global[\"Error\"].prototype;\n");
+            writeString(indent + "proto.getStackTrace = proto.getStackTrace || function() { return null; };\n");
+            writeString(indent + "proto.toString = (function ()\n");
+            writeString(indent + "{\n");
+            writeString(indent + indent + "/** @type {function()} */\n");
+            writeString(indent + indent + "var f = proto.toString;\n");
+            writeString(indent + indent + "return function () { return (this.name == this.message || this.message == \"\") ? this.name : f.call(this); };\n");
+            writeString(indent + "})();\n");
+
+            // see ecma3/ErrorObject/e15_11_2_1.as
+            writeString("\n");
+            writeString(indent + "proto = __global[\"Object\"].prototype;\n");
+            writeString(indent + "// Additions to Object (see e15_11_2_1)\n");
+            writeString(indent + "proto.toString = (function ()\n");
+            writeString(indent + "{\n");
+            writeString(indent + indent + "/** @type {function()} */\n");
+            writeString(indent + indent + "var f = proto.toString;\n");
+            writeString(indent + indent + "return function () { return (this instanceof Error) ? (\"[object \" + this.name + \"]\") : f.call(this); };\n");
+            writeString(indent + "})();\n");
+
+            writeString("}\n");
+        }
+
+    }
+
+    private void emitSettings()
+    {
+        final String topLevelClass = getTopLevelClass();
+        if (topLevelClass != null)
+        {
+            // support for no export 
+            if (!JSSharedData.NO_EXPORTS)
+            {
+                // We are now using createMain() isntead of m_topLevelClass
+                // writeString( "\tadobe.m_topLevelClass = " + JSSharedData.ROOT_NAME + getTopLevelClass() + ";\n" );
+                writeString("\tadobe.m_topLevelClass = null;\n");
+                writeString("\tgoog.exportSymbol(\"" + JSSharedData.JS_FRAMEWORK_NAME + ".m_topLevelClass\", " + JSSharedData.JS_FRAMEWORK_NAME + ".m_topLevelClass);\n");
+            }
+
+            // emit createMain
+            String create = "new " + JSSharedData.ROOT_NAME + topLevelClass + "()";
+            final String symbolName = JSSharedData.instance.getSymbol(topLevelClass);
+            if (symbolName != null && !symbolName.isEmpty())
+                create = symbolName + "." + JSSharedData.SYMBOL_INSTANCE + "." + JSSharedData.SYMBOL_INIT + "(" + create + ")";
+            writeString("\tadobe.createMain = function() { return " + create + "; };\n");
+
+        }
+
+        // shell.as is using flash.system.Capabilities.playerType, which must be set to "AVMPlus"
+        // var playerType /* : String */ = flash.system.Capabilities.playerType;
+        // flash.system.Capabilities.__static_init() must be called before we set playerType, see http://watsonexp.corp.adobe.com/#bug=3021707
+        if (JSSharedData.GENERATE_TEST_CASE)
+        {
+            writeString("\n");
+            writeString("\t// Setting playerType to AVMPlus for running Tamarin's acceptance tests.\n");
+            writeString("\tif( flash && flash.system && flash.system.Capabilities )\n");
+            writeString("\t{\n");
+            writeString("\t\tflash.system.Capabilities.__static_init();\n");
+            writeString("\t\tflash.system.Capabilities.playerType = \"AVMPlus\";\n");
+            writeString("\t}\n");
+        }
+    }
+
+    /*
+     * private void emitClassInfo() { writeString( "\n" ); writeString(
+     * "\t// Class Information \n" ); writeString( "\t" +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".info = {};\n" ); Map<String,String>map
+     * = JSSharedData.instance.getClassInfo(); // sorted output final
+     * TreeSet<String> keys = new TreeSet<String>(map.keySet()); for(String key
+     * : keys) { final String value = map.get(key); writeString( "\t" +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".info[\"" + key + "\"] = \"" + value +
+     * "\";\n" ); } }
+     */
+    /*
+     * private void emitExports() { writeString( "\n" ); writeString(
+     * "\t// Exported Symbols\n" ); writeString( "\t" +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".root = {};\n" ); final Set<String>
+     * visited = new HashSet<String>(); final Set<Name> classes =
+     * JSSharedData.instance.getClasses(); List<String> sorted = new
+     * ArrayList<String>(); for(Name name : classes ) { if( name != null &&
+     * JSSharedData.instance.hasClassBeenEmitted(name) ) { String fullName = "";
+     * final String packageName =
+     * JSGeneratingReducer.getPackageNameFromName(name, false); if( packageName
+     * != null && !packageName.isEmpty() ) fullName += packageName + ".";
+     * fullName += name.getBaseName(); String[] parts = fullName.split("\\.");
+     * fullName = JSSharedData.ROOT_NAME; for( String part: parts ) { if(
+     * !part.isEmpty() ) { if( !fullName.isEmpty() ) fullName += "."; fullName
+     * += part; if(!visited.contains(fullName)) { visited.add(fullName); //
+     * collect symbols for later sorted.add("\tgoog.exportSymbol(\"" + fullName
+     * + "\", " + fullName + ", " + JSSharedData.JS_FRAMEWORK_NAME +
+     * ".root);\n"); } } } } } java.util.Collections.sort(sorted); for( String
+     * s: sorted ) { writeString( s ); } writeString( "\n" ); }
+     */
+
+    private void emitInterfacesInfo()
+    {
+        writeString("\n");
+        writeString("\t// Interfaces Information \n");
+        writeString("\t" + JSSharedData.JS_FRAMEWORK_NAME + ".interfaces = {};\n");
+
+        Map<Name, Set<Name>> map = JSSharedData.instance.getAllInterfaces();
+        Iterator<Map.Entry<Name, Set<Name>>> it = map.entrySet().iterator();
+        while (it.hasNext())
+        {
+            Map.Entry<Name, Set<Name>> pair = it.next();
+            final IDefinition def = JSSharedData.instance.getDefinition(pair.getKey());
+            final String className = def.getQualifiedName();
+            writeString("\t" + JSSharedData.JS_FRAMEWORK_NAME + ".interfaces[\"" + className + "\"] = ");
+            writeString("[");
+
+            Boolean emitComma = false;
+            Set<Name> interfaces = pair.getValue();
+            for (Name name : interfaces)
+            {
+                if (emitComma)
+                    writeString(", ");
+                else
+                    emitComma = true;
+                // writeString( JSGeneratingReducer.getFullNameFromName(name, true) );
+
+                String fullName = "";
+                if (name.getQualifiers().length() > 1)
+                {
+                    if (!JSSharedData.ROOT_NAME.isEmpty())
+                        fullName += JSSharedData.ROOT_NAME;
+
+                    // Picking a package qualifier at random (if there's more than one). We skip other things like
+                    // namespace qualifiers since their names might be URLs (not syntactically valid).
+                    Namespace packageNS = findAnyPackageQualifier(name);
+                    assert packageNS != null : "Unable to find a usable qualifier for " + name;
+
+                    fullName += packageNS.getName();
+                    fullName += "." + name.getBaseName();
+                }
+                else
+                {
+                    final IDefinition idef = JSSharedData.instance.getDefinition(name);
+                    fullName = idef.getQualifiedName();
+                }
+                writeString(fullName);
+            }
+
+            writeString("];\n");
+        }
+    }
+
+    private static Namespace findAnyPackageQualifier(Name name)
+    {
+        for (Namespace ns : name.getQualifiers())
+        {
+            if (ns.getKind() == ABCConstants.CONSTANT_PackageNs || ns.getKind() == ABCConstants.CONSTANT_PackageInternalNs)
+                return ns;
+        }
+        return null;
+    }
+
+    /*
+     * private void emitStaticInits() { writeString( "\n" ); writeString(
+     * "\t// Static inits \n" ); // writeString(
+     * JSSharedData.instance.getStaticInits("\t", "\n") ); // auto-register
+     * static inits. writeString( "\t" + JSSharedData.JS_RUN_STATIC_INITS + "("
+     * + JSSharedData.JS_STATIC_INITS + ");\n" ); writeString( "\tdelete(" +
+     * JSSharedData.JS_STATIC_INITS + ");\n" ); }
+     */
+
+    private void emitScriptInfos()
+    {
+        final Set<String> scriptInfos = JSSharedData.instance.getScriptInfos();
+        if (!scriptInfos.isEmpty())
+        {
+            writeString("\n");
+            for (String si : scriptInfos)
+            {
+                writeString(si);
+            }
+        }
+    }
+
+    private void emitSymbolInstances()
+    {
+        if (JSSharedData.instance.hasSymbols())
+        {
+            writeString("\n");
+            writeString("\n");
+            writeString("\t// Symbols \n");
+
+            final List<String> list = JSSharedData.instance.getSymbols();
+            for (String symbol : list)
+            {
+                writeString("\t" + JSSharedData.ROOT_NAME + symbol + "." + JSSharedData.SYMBOL_INSTANCE + " = new " + JSSharedData.ROOT_NAME + symbol + "();\n");
+            }
+        }
+    }
+
+    // support for generating test cases for JsTestDriver.
+    // see http://code.google.com/p/js-test-driver/wiki/TestCase
+    /*
+     * private void emitTestCase(String topLevelClass) { if(
+     * JSSharedData.GENERATE_TEST_CASE && topLevelClass != null ) { // support
+     * for [TestCase(name="...")] String testCaseName = topLevelClass;
+     * ASProjectScope projectScope = (ASProjectScope)m_project.getScope();
+     * IDefinition rootClassDef =
+     * projectScope.findDefinitionByName(topLevelClass); if (rootClassDef !=
+     * null) { final IMetaTag testCaseTag =
+     * rootClassDef.getMetaTagByName(JSSharedData.TESTCASE_METATAG );
+     * if(testCaseTag!= null) { final String testCaseAttr =
+     * testCaseTag.getAttributeValue("name"); if( testCaseAttr != null &&
+     * !testCaseAttr.isEmpty() ) testCaseName = testCaseAttr; } } writeString(
+     * "\n" ); writeString( "\t// Create and export " +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".mainTestCase\n" ); writeString(
+     * "\tif(typeof(TestCase) != \"undefined\")\n" ); writeString( "\t{\n" );
+     * writeString( "\t\tadobe.mainTestCase = TestCase(\"" + testCaseName +
+     * "\");\n" ); writeString(
+     * "\t\tadobe.mainTestCase.prototype.testMain = function()\n" );
+     * writeString( "\t\t{\n" ); if( JSSharedData.MAIN != null ) { writeString(
+     * "\t\t\tconsole.info(\"Running " + JSSharedData.MAIN + "() ...\")\n" );
+     * writeString( "\t\t\t" + JSSharedData.MAIN + "();\n" ); } else {
+     * writeString( "\t\t\tconsole.info(\"Running " + testCaseName + " ...\")\n"
+     * ); writeString( "\t\t\tnew " + topLevelClass + "();\n" ); } writeString(
+     * "\t\t}\n" ); writeString( "\t\tgoog.exportSymbol( \"" +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".mainTestCase\", " +
+     * JSSharedData.JS_FRAMEWORK_NAME + ".mainTestCase );\n" ); writeString(
+     * "\t\tgoog.exportSymbol( \"" + JSSharedData.JS_FRAMEWORK_NAME +
+     * ".mainTestCase.prototype.testMain\", " + JSSharedData.JS_FRAMEWORK_NAME +
+     * ".mainTestCase.prototype.testMain );\n" ); writeString( "\t}\n" ); } }
+     */
+    protected void writePrologue(Boolean createSharedLib)
+    {
+        if (createSharedLib)
+        {
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {function()}\n");
+            writeString(" */\n");
+            writeString("var __libInit = function(__global, __adobe) {\n");
+        }
+        else if (JSSharedData.GENERATE_TEST_CASE)
+        {
+            // ensure there is always a TestCase.
+            String testCaseName;
+            String topLevelClass = getTopLevelClass();
+            if (topLevelClass == null)
+            {
+                final Date now = new Date();
+                testCaseName = topLevelClass = "Test_" + now.getTime();
+            }
+            else
+            {
+                testCaseName = topLevelClass;
+                final ASProjectScope projectScope = (ASProjectScope)m_project.getScope();
+                final IDefinition rootClassDef = projectScope.findDefinitionByName(topLevelClass);
+                if (rootClassDef != null)
+                {
+                    final IMetaTag testCaseTag = rootClassDef.getMetaTagByName(JSSharedData.TESTCASE_METATAG);
+                    if (testCaseTag != null)
+                    {
+                        final String testCaseAttr = testCaseTag.getAttributeValue("name");
+                        if (testCaseAttr != null && !testCaseAttr.isEmpty())
+                            testCaseName = testCaseAttr;
+                    }
+                }
+            }
+
+            // TODO: emit type annotations for Google's closure compiler.
+            writeString("var __global = this;\n");
+
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @typedef {string}\n");
+            writeString(" */\n");
+            writeString("var testCaseName = \"" + testCaseName + "\";\n");
+            writeString("\n");
+
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @typedef {boolean}\n");
+            writeString(" */\n");
+            writeString("var hasTestCase = typeof(TestCase) != \"undefined\";\n");
+            writeString("\n");
+
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {array}\n");
+            writeString(" */\n");
+            writeString("var __testCases = [];\n");
+
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {function()}\n");
+            writeString(" */\n");
+            writeString("var __runTestCases = function()\n");
+            writeString("{\n");
+            writeString("\tif(hasTestCase)\n");
+            writeString("\t\treturn;\n\n");
+            writeString("\twhile( __testCases.length > 0 )\n");
+            writeString("\t{\n");
+            writeString("\t\tvar tc = __testCases.shift();\n");
+            writeString("\t\tfor( var method in tc )\n");
+            writeString("\t\t{\n");
+            writeString("\t\t\tif( method.substring(0,4) == \"test\" )\n");
+            writeString("\t\t\t\ttc[method]();\n");
+            writeString("\t\t}\n");
+            writeString("\t}\n");
+            writeString("}\n");
+
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {function(...)}\n");
+            writeString(" */\n");
+            writeString("var TestCase = hasTestCase ? TestCase : (function(name,testcase)\n");
+            writeString("\t{\n");
+            writeString("\t\tvar tc = testcase;\n");
+            writeString("\t\tif( tc )\n");
+            writeString("\t\t{\n");
+            writeString("\t\t\t__testCases.push(tc);\n");
+            writeString("\t\t}\n");
+            writeString("\t\telse\n");
+            writeString("\t\t{\n");
+            writeString("\t\t\ttc = function(){};\n");
+            writeString("\t\t\t __testCases.push(new tc());\n");
+            writeString("\t\t}\n");
+            writeString("\t\treturn tc;\n");
+            writeString("\t});\n");
+
+            writeString("\n");
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {function(...)}\n");
+            writeString(" */\n");
+            writeString("var AsyncTestCase = hasTestCase ? AsyncTestCase : TestCase;\n");
+
+            writeString("\n");
+            writeString("/**\n");
+            writeString(" * @const\n");
+            writeString(" * @type {function(...)}\n");
+            writeString(" */\n");
+            writeString("var MainTestCase = TestCase(testCaseName);\n");
+            writeString("MainTestCase.prototype.testMain = function() {\n");
+            writeString("console.info(\"START TEST: \" + testCaseName );\n");
+            writeString("(function(__global) {\n");
+        }
+        else
+        {
+            writeString("(function(__global) {\n");
+        }
+    }
+
+    protected void writeEpilogue(Boolean createSharedLib)
+    {
+        if (createSharedLib)
+        {
+            writeString("}; // __libInit() \n\n");
+            writeString("goog.exportSymbol( \"__libInit\", __libInit);\n");
+        }
+        else if (JSSharedData.GENERATE_TEST_CASE)
+        {
+            writeString("})(__global);\n");
+            writeString("console.info(\"END TEST: \" + testCaseName );\n");
+            writeString("} // MainTestCase.prototype.testMain \n\n");
+
+            writeString("goog.exportSymbol( \"MainTestCase\", MainTestCase);\n");
+            writeString("goog.exportSymbol( \"MainTestCase.prototype.testMain\", MainTestCase.prototype.testMain);\n");
+
+            writeString("__runTestCases();\n");
+        }
+        else
+        {
+            writeString("})(this);\n");
+        }
+    }
+
+    protected void writeFinalize(Boolean createSharedLib)
+    {
+        writeString("\n");
+
+        // ASProjectScope projectScope = applicationProject.getScope();
+        // IDefinition rootClassDef = projectScope.findDefinitionByName(getTopLevelClass());
+
+        // export toplevel class
+
+        // support for no export 
+        final String topLevelClass = getTopLevelClass();
+        if (topLevelClass != null && !JSSharedData.NO_EXPORTS)
+        {
+            writeString("// Top Level Class\n");
+            writeString("goog.exportSymbol(\"" + JSSharedData.ROOT_NAME + topLevelClass + "\", "
+                                                + JSSharedData.ROOT_NAME + topLevelClass + ");\n");
+            writeString("// Export " + JSSharedData.JS_FRAMEWORK_NAME + ".createStage\n");
+            writeString("goog.exportSymbol( \"" + JSSharedData.JS_FRAMEWORK_NAME + ".createStage\", " + JSSharedData.JS_FRAMEWORK_NAME + ".createStage );\n\n");
+        }
+
+        final String finalize = "staticInits";
+
+        // generated finalize() function 
+        writeString("/** \n");
+        writeString(" * Generated finalizer.\n");
+        writeString(" * @param {DOMWindow} global Global object\n");
+        writeString(" * @param {" + JSSharedData.ROOT_NAME + "browser.IFramework} framework Framework to use\n");
+        writeString(" */\n");
+        writeString(JSSharedData.JS_FRAMEWORK_NAME + "." + finalize + " = function(global,framework)\n");
+        writeString("{\n");
+        writeString("\tadobe.globals = global;\n");
+        writeString("\tadobe.m_framework = framework;\n");
+
+        writeString("\tadobe.uintClass = UIntClass;\n");
+        writeString("\tadobe.intClass = IntClass;\n");
+
+        emitSettings();
+        // emitExports();
+        // emitClassInfo();
+        emitInterfacesInfo();
+        // emitStaticInits();
+        emitSymbolInstances();
+        // emitTestCase(topLevelClass);
+        writeString("}\n\n");
+
+        // select framework 
+        writeString("/** \n");
+        writeString(" * Selected framework, i.e. JQueryFramework, or GoogleFramework\n");
+        writeString(" * @typedef {" + JSSharedData.ROOT_NAME + "browser.IFramework}\n");
+        writeString(" */\n");
+        writeString("var framework = new " + JSSharedData.ROOT_NAME + JSSharedData.FRAMEWORK_CLASS + "();\n\n");
+
+        // call finalize() 
+        writeString("// Call static initialization chain\n");
+        writeString(JSSharedData.JS_FRAMEWORK_NAME + "." + finalize + "(goog.global,framework);\n\n");
+
+        emitScriptInfos();
+
+        // support for no export
+        if (!createSharedLib)
+        {
+            if (JSSharedData.MAIN != null)
+            {
+                writeString("// Main entry point: " + JSSharedData.MAIN + "\n");
+                writeString(JSSharedData.MAIN + "();\n\n");
+            }
+            else if (topLevelClass != null)
+            {
+                if (hasStage)
+                {
+                    writeString("// Main entry point: wrapper for adding " + topLevelClass + " to the stage.\n");
+                    writeString("function main()\n");
+                    writeString("{\n");
+                    writeString("\t/** @type {flash.display.Stage} */\n");
+                    writeString("\tvar stage /* : Stage */ = flash.display.Stage.instance();\n");
+                    writeString("\t/** @type {flash.display.DisplayObject} */\n");
+                    writeString("\tvar sprite /* : DisplayObject */ = (new " + JSSharedData.ROOT_NAME + topLevelClass + "());\n");
+                    writeString("\tstage.addChild(sprite);\n");
+                    writeString("}\n\n");
+
+                    writeString("// Delay creation of " + topLevelClass + "\n");
+                    writeString("document.addEventListener( \"DOMContentLoaded\", main, false );\n\n");
+                }
+                else
+                {
+                    writeString("// Main entry point: wrapper for creating " + topLevelClass + "\n");
+                    writeString("\t/** @type {flash.display.DisplayObject} */\n");
+                    writeString("\tvar sprite /* : DisplayObject */ = (new " + JSSharedData.ROOT_NAME + topLevelClass + "());\n");
+                }
+            }
+        }
+    }
+
+    // see http://blog.bolinfest.com/2009/11/calling-closure-compiler-from-java.html
+    private void optimize(OutputBitStream outputbuffer, Boolean createSharedLib) throws IOException
+    {
+        /*
+         * <arg value="--compilation_level=ADVANCED_OPTIMIZATIONS"/> <arg value=
+         * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jquery-1.5.js"
+         * /> <arg value=
+         * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/svg.js"
+         * /> <arg value=
+         * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jsTestDriver.js"
+         * /> <arg value="--formatting=PRETTY_PRINT"/> <arg
+         * value="--js=${falcon-sdk}/frameworks/javascript/goog/base.js"/> <arg
+         * value="--js=${build.target.js}"/> <arg
+         * value="--js_output_file=${build.target.compiled.js}"/> <arg
+         * value="--create_source_map=${build.target.compiled.map}"/>
+         */
+        String code = new String(outputbuffer.getBytes());
+        code = code.substring(0, outputBuffer.size());
+        Compiler compiler = new Compiler();
+
+        CompilerOptions options = new CompilerOptions();
+
+        if (JSSharedData.CLOSURE_compilation_level.equals("ADVANCED_OPTIMIZATIONS"))
+            CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
+        else if (createSharedLib && JSSharedData.instance.hasAnyEncryptedJS())
+            CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
+        else if (JSSharedData.CLOSURE_compilation_level.equals("WHITESPACE_ONLY"))
+            CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel(options);
+        else
+            CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
+
+        String sdkPath = null;
+        if (JSSharedData.CLOSURE_externs == null || JSSharedData.CLOSURE_js == null)
+        {
+            sdkPath = JSSharedData.SDK_PATH;
+        }
+
+        // To get the complete set of externs, the logic in
+        // CompilerRunner.getDefaultExterns() should be used here.
+        final List<JSSourceFile> extern = CommandLineRunner.getDefaultExterns();
+        if (JSSharedData.CLOSURE_externs != null)
+        {
+            for (String externsFile : JSSharedData.CLOSURE_externs)
+                extern.add(JSSourceFile.fromFile(externsFile));
+        }
+        else if (sdkPath != null)
+        {
+            /*
+             * <arg value=
+             * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jquery-1.5.js"
+             * /> <arg value=
+             * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/svg.js"
+             * /> <arg value=
+             * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jsTestDriver.js"
+             * />
+             */
+            extern.add(JSSourceFile.fromFile(sdkPath + "/lib/google/closure-compiler/contrib/externs/svg.js"));
+            if (JSSharedData.FRAMEWORK_CLASS.equals("browser.JQueryFramework"))
+                extern.add(JSSourceFile.fromFile(sdkPath + "/lib/google/closure-compiler/contrib/externs/jquery-1.5.js"));
+            if (JSSharedData.GENERATE_TEST_CASE)
+                extern.add(JSSourceFile.fromFile(sdkPath + "/lib/google/closure-compiler/contrib/externs/jsTestDriver.js"));
+        }
+
+        final List<JSSourceFile> input = new ArrayList<JSSourceFile>();
+        if (JSSharedData.CLOSURE_js != null)
+        {
+            for (String inputFile : JSSharedData.CLOSURE_js)
+                input.add(JSSourceFile.fromFile(inputFile));
+        }
+        else if (sdkPath != null)
+        {
+            // <arg value="--js=${falcon-sdk}/frameworks/javascript/goog/base.js"/>
+            input.add(JSSourceFile.fromFile(sdkPath + "/frameworks/javascript/goog/base.js"));
+        }
+
+        // The dummy input name "input.js" is used here so that any warnings or
+        // errors will cite line numbers in terms of input.js.
+        input.add(JSSourceFile.fromCode("input.js", code.toString()));
+        // input.add( JSSourceFile.fromCode("input.js", "/** @preserve CROSS-COMPILED BY FALCONJS (320588.13) ON 2011-09-09 22:18:10 */\nvar __global = this;\n") );
+
+        if (JSSharedData.CLOSURE_create_source_map != null)
+            options.sourceMapOutputPath = JSSharedData.CLOSURE_create_source_map;
+
+        if (JSSharedData.CLOSURE_formatting != null)
+        {
+            if (JSSharedData.CLOSURE_formatting.equals("PRETTY_PRINT"))
+                options.prettyPrint = true;
+            else if (JSSharedData.CLOSURE_formatting.equals("PRINT_INPUT_DELIMITER"))
+                options.prettyPrint = true;
+            else
+                throw new RuntimeException("Unknown formatting option: " + JSSharedData.CLOSURE_formatting);
+        }
+        else if (JSSharedData.DEBUG)
+        {
+            options.prettyPrint = true;
+        }
+
+        // turn off closure's logger depending on verbose mode.
+        if (!JSSharedData.instance.isVerbose())
+        {
+            final Logger logger = Logger.getLogger("com.google.javascript.jscomp");
+            logger.setLevel(Level.OFF);
+        }
+
+        try
+        {
+            // compile() returns a Result, but it is not needed here.
+            compiler.compile(extern, input, options);
+
+            if (compiler.getErrorCount() == 0)
+            {
+                // The compiler is responsible for generating the compiled code; it is not
+                // accessible via the Result.
+                final String optimizedCode = compiler.toSource();
+                outputbuffer.reset();
+                outputbuffer.write(optimizedCode.getBytes());
+            }
+            else if (m_problems != null)
+            {
+                final JSError[] errors = compiler.getErrors();
+                for (JSError err : errors)
+                    m_problems.add(new ClosureProblem(err));
+            }
+        }
+
+        /*
+         * internal compiler error generated with optimize enabled compiling
+         * as3_enumerate.fla and fails to release the JS file
+         * http://watsonexp.corp.adobe.com/#bug=3047880 This is part #3 of the
+         * fix: The closure compiler throws RTEs on internal compiler errors,
+         * that don't get caught until they bubble up to MXMLJSC's scope. On
+         * their way out files remain unclosed and cause problems, because Flame
+         * cannot delete open files. The change below addresses this problem.
+         */
+        catch (RuntimeException rte)
+        {
+            if (m_problems != null)
+            {
+                final ICompilerProblem problem = new InternalCompilerProblem(rte);
+                m_problems.add(problem);
+            }
+        }
+    }
+
+    /**
+     * {@inherit}
+     */
+    @Override
+    public int writeTo(File outputFile) throws FileNotFoundException, IOException
+    {
+        return 0;
+    }
+
+    public class ClosureProblem implements ICompilerProblem
+    {
+        private JSError m_error;
+
+        public ClosureProblem(JSError error)
+        {
+            m_error = error;
+        }
+
+        /**
+         * Returns a unique identifier for this type of problem.
+         * <p>
+         * Clients can use this identifier to look up, in a .properties file, a
+         * localized template string describing the problem. The template string
+         * can have named placeholders such as ${name} to be filled in, based on
+         * correspondingly-named fields in the problem instance.
+         * <p>
+         * Clients can also use this identifier to decide whether the problem is
+         * an error, a warning, or something else; for example, they might keep
+         * a list of error ids and a list of warning ids.
+         * <p>
+         * The unique identifier happens to be the fully-qualified classname of
+         * the problem class.
+         * 
+         * @return A unique identifier for the type of problem.
+         */
+        public String getID()
+        {
+            // Return the fully-qualified classname of the CompilerProblem subclass
+            // as a String to identify the type of problem that occurred.
+            return getClass().getName();
+        }
+
+        /**
+         * Gets the path of the file in which the problem occurred.
+         * 
+         * @return The path of the source file, or null if unknown.
+         */
+        public String getFilePath()
+        {
+            return m_error.sourceName;
+        }
+
+        /**
+         * Gets the offset within the source buffer at which the problem starts.
+         * 
+         * @return The starting offset, or -1 if unknown.
+         */
+        public int getStart()
+        {
+            return m_error.getCharno();
+        }
+
+        /**
+         * Gets the offset within the source buffer at which the problem ends.
+         * 
+         * @return The ending offset, or -1 if unknown.
+         */
+        public int getEnd()
+        {
+            return -1;
+        }
+
+        /**
+         * Gets the line number within the source buffer at which the problem
+         * starts. Line numbers start at 0, not 1.
+         * 
+         * @return The line number, or -1 if unknown.
+         */
+        public int getLine()
+        {
+            return m_error.lineNumber;
+        }
+
+        /**
+         * Gets the column number within the source buffer at which the problem
+         * starts. Column numbers start at 0, not 1.
+         * 
+         * @return The column number, of -1 if unknown.
+         */
+        public int getColumn()
+        {
+            return -1;
+        }
+
+        /**
+         * Returns a readable description of the problem, by substituting field
+         * values for named placeholders such as ${name} in the localized
+         * template.
+         * 
+         * @param template A localized template string describing the problem,
+         * determined by the client from the problem ID. If this parameter is
+         * null, an English template string, stored as the DESCRIPTION of the
+         * problem class, will be used.
+         * @return A readable description of the problem.
+         */
+        public String getDescription(String template)
+        {
+            return m_error.description;
+        }
+
+        /**
+         * Compares this problem to another problem by path, line, and column so
+         * that problems can be sorted.
+         */
+        final public int compareTo(final ICompilerProblem other)
+        {
+            if (getFilePath() != null && other.getSourcePath() != null)
+            {
+                final int pathCompare = getFilePath().compareTo(other.getSourcePath());
+                if (pathCompare != 0)
+                    return pathCompare;
+            }
+            else if (getFilePath() != null && other.getSourcePath() == null)
+            {
+                return 1;
+            }
+            else if (getFilePath() == null && other.getSourcePath() != null)
+            {
+                return -1;
+            }
+
+            if (getLine() < other.getLine())
+                return -1;
+            else if (getLine() > other.getLine())
+                return 1;
+
+            if (getColumn() < other.getColumn())
+                return -1;
+            else if (getColumn() > other.getColumn())
+                return 1;
+
+            return 0;
+        }
+
+        public int getAbsoluteEnd()
+        {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public int getAbsoluteStart()
+        {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        public String getSourcePath()
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+}

Propchange: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/cmc-js.jbg
URL: http://svn.apache.org/viewvc/incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/cmc-js.jbg?rev=1413061&view=auto
==============================================================================
--- incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/cmc-js.jbg (added)
+++ incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/cmc-js.jbg Fri Nov 23 20:58:50 2012
@@ -0,0 +1,328 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/**
+ * cmc-js.jbg mirrors cmc.jbg and contains FalconJS's definitions for JBurg.
+ *
+ * After making changes to cmc-js.jbg or JSCmcRules.jbg you need to run this command 
+ * in the ./compiler/trunk folder:
+ *  
+ *      ant -f build-js.xml
+ * 
+ * This implementation is part of FalconJS.
+ * For more details on FalconJS see org.apache.flex.compiler.JSDriver.
+ * 
+ */
+
+package org.apache.flex.compiler.internal.as.codegen;
+
+header
+{
+    import org.apache.flex.compiler.problems.ICompilerProblem;
+    import org.apache.flex.compiler.problems.*;
+
+    import static org.apache.flex.abc.ABCConstants.*;
+
+    import org.apache.flex.abc.semantics.Label;
+    import org.apache.flex.abc.semantics.Name;
+    import org.apache.flex.abc.semantics.Namespace;
+    import org.apache.flex.abc.instructionlist.InstructionList;
+
+    import org.apache.flex.compiler.constants.IASLanguageConstants;
+
+    import org.apache.flex.compiler.tree.ASTNodeID;
+    import static org.apache.flex.compiler.tree.ASTNodeID.*;
+
+    import org.apache.flex.compiler.internal.semantics.SemanticUtils;
+
+    import org.apache.flex.compiler.tree.as.IASNode;
+    import org.apache.flex.compiler.tree.as.ITryNode;
+
+	import org.apache.flex.abc.semantics.ECMASupport;
+}
+
+INodeType IASNode;
+OpcodeType ASTNodeID;
+
+/*
+ *  The I-node type is IASNode, and it has its own adapter.
+ */
+INodeAdapter org.apache.flex.compiler.internal.as.codegen.IASNodeAdapter;
+
+//  Generate Java output.
+Language java;
+
+ReturnType String;
+ReturnType InstructionList = String;
+
+ReturnType name = Binding;
+ReturnType type_name = Binding;
+ReturnType decl_name = Name;
+ReturnType new_type_name = Binding;
+ReturnType qualifiedName = Binding;
+ReturnType qualifiedNamePart = String;
+ReturnType return_type_name = Binding;
+
+ReturnType dottedNamePart = String;
+
+ReturnType conditionalElements = JSGeneratingReducer.ConditionalFragment;
+
+ReturnType ifElseIf = JSGeneratingReducer.ConditionalFragment;
+
+ReturnType catch_block = JSGeneratingReducer.CatchPrototype;
+
+ReturnType integer_constant = Integer;
+ReturnType uint_constant = Long;
+ReturnType double_constant = Double;
+ReturnType string_constant = String;
+ReturnType boolean_constant = Boolean;
+ReturnType float_constant = Float;
+
+ReturnType numeric_constant = Number;
+
+ReturnType constant_value = Object;
+ReturnType required_constant_value = Object;
+
+ReturnType non_resolving_identifier = String;
+
+ReturnType runtime_name_expression = JSGeneratingReducer.RuntimeMultiname;
+ReturnType multinameL = Name;
+ReturnType stmt_label = String;
+ReturnType e4x_literal = String;
+
+JBurg.Constant ERROR_TRAP = 268435456;
+
+{
+    final static boolean NEED_VALUE = true;
+    final static boolean DISCARD_VALUE = false;
+
+
+    /**
+     *  The reducer has all the implementation
+     *  logic for the rewrite; the BURM constructed
+     *  by this specification drives that logic.
+     */
+    JSGeneratingReducer reducer;
+
+    /**
+     *  Delegate calls to pushNumericConstant to the reducer.
+     *  This routine is called from other parts of the code generator,
+     *  so it's necessary to keep this layer of indirection.
+     */
+    public static void pushNumericConstant(long value, String result_list)
+    {
+        JSGeneratingReducer.pushNumericConstant(value, result_list);
+    }
+
+    /*
+     *  **  Cost functions  **
+     */
+
+
+    /**
+     *  @return "feasible" if the reducer can reduce this to a dotted name.
+     */
+    int isDottedName(IASNode iNode)
+    {
+       return reducer.isDottedName(iNode);
+    }
+
+    /**
+     *  @return "feasible" if the reducer can reduce this to a dotted name.
+     */
+    int isPackageName(IASNode iNode)
+    {
+       return reducer.isPackageName(iNode);
+    }
+
+    /**
+     *  @return "feasible" if this node's qualifier is a compile-time constant.
+     */
+    int qualifierIsCompileTimeConstant(IASNode iNode)
+    {
+       return reducer.qualifierIsCompileTimeConstant(iNode);
+    }
+
+    /**
+    /**
+     *  @return "feasible" if this node's qualifier is an interface.
+     */
+    int qualifierIsInterface(IASNode iNode)
+    {
+       return reducer.qualifierIsInterface(iNode);
+    }
+
+    /**
+     *  @return "feasible" if this node can be resolved to a compile-time constant.
+     */
+    int isCompileTimeConstant(IASNode iNode)
+    {
+       return reducer.isCompileTimeConstant(iNode);
+    }
+
+    /**
+     *  @return "feasible" if this function call node can be resolved to a compile-time constant function.
+     */
+    int isCompileTimeConstantFunction(IASNode iNode)
+    {
+       return reducer.isCompileTimeConstantFunction(iNode);
+    }
+
+    /**
+     *  @return "feasible" if this node is for 'new Array()'.
+     */
+    int isEmptyArrayConstructor(IASNode iNode)
+    {
+        return reducer.isEmptyArrayConstructor(iNode);
+    }
+
+    /**
+     *  @return "feasible" if this node is for 'new Object()'.
+     */
+    int isEmptyObjectConstructor(IASNode iNode)
+    {
+        return reducer.isEmptyObjectConstructor(iNode);
+    }
+    
+    /**
+     *  @return "feasible" if this node is "super(this)".
+     */
+    int isSuperThisForFieldAccess(IASNode iNode)
+    {
+        return SemanticUtils.isSuperThisForFieldAccess(iNode);
+    }
+
+    /**
+     * @return "feasible" if the base and parameter types of
+     * a parameterized type are both known types.
+     */
+    int parameterTypeIsConstant(IASNode iNode)
+    {
+        return reducer.parameterTypeIsConstant(iNode);
+    }
+
+    /**
+     * @return "feasible" if a standalone "super" expression is in a parameter list.
+     */
+    int isValidStandaloneSuper(IASNode iNode)
+    {
+        return /* SemanticUtils.isValidStandaloneSuper(iNode)? 1: */ Integer.MAX_VALUE;
+    }
+    
+    /**
+     * @return "feasible" if this node resolves to a type definition.
+     */
+    int isKnownType(IASNode iNode)
+    {
+        return reducer.isKnownType(iNode);
+    }
+
+    /*
+     *  ******************************
+     *  **  IASNodeAdapter Support  **
+     *  ******************************
+     */
+    /**
+     *  Get the default child of a node type that requires special handling.
+     *  @param parent - the child's parent node.
+     *  @param index - the desired child.
+     *  @return the child at the specified (abstract) index, or null
+     *    if no such child exists.
+     */
+    public static IASNode getDefaultChild(IASNode parent, int index)
+    {
+        switch(parent.getNodeID())
+        {
+            case VariableID:
+            case BindableVariableID:
+                {
+                    //  Look for chained variable definitions.
+                    IASNode candidate = parent.getChild(index);
+
+                    if ( candidate != null )
+                    {
+                        ASTNodeID candidateID = candidate.getNodeID();
+                        if( candidateID == VariableID || candidateID == BindableVariableID )
+                        {
+                            return candidate;
+                        }
+                    }
+                    return null;
+                }
+
+            case Op_CommaID:
+                return parent.getChild(index-1);
+
+            case FunctionID:
+            case GetterID:
+            case SetterID:
+                return null;
+
+            case TryID:
+                {
+                    //  Note: If the try has a contents and finally nodes,
+                    //  they are presented to the CG by getNthChild() as child
+                    //  nodes 0 and 1 before the n-ary tail of catch nodes.
+                    if (((ITryNode)parent).getStatementContentsNode() != null)
+                    	index--;
+                    if (((ITryNode)parent).getFinallyNode() != null)
+                    	index--;
+                    return ((ITryNode)parent).getCatchNode(index);
+                }
+            default:
+                return parent.getChild(index);
+        }
+    }
+
+    /**
+     *  recordError is a convenience method for error reductions;
+     *  it adds a problem to the current set of problems and
+     *  returns an empty String.
+     *  @return an empty String.
+     */
+    String recordError(ICompilerProblem problem)
+    {
+        reducer.getProblems().add(problem);
+        return "";
+    }
+}
+
+/*
+ *  Error recovery routine: deduce what we can from the problem
+ *  tree, then abort this BURM with an exception that the caller
+ *  can catch and ignore.
+ */
+
+/* 
+bparadie, 2011-12-01: Tom recommends not using DefaultErrorHandler at all.
+
+DefaultErrorHandler
+{
+    new UnknownTreeHandler(reducer.getProblems()).analyze(p);
+    throw new BURMAbortException();
+}
+*/
+
+/*
+ *  Patterns and rules are stored in their own, shareable file.
+ */
+JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/CmcPatterns.jbg"
+JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/CmcRules.jbg"
+JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/SemanticErrors.jbg"
+

Propchange: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/cmc-js.jbg
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/IBackend.java
URL: http://svn.apache.org/viewvc/incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/IBackend.java?rev=1413061&view=auto
==============================================================================
--- incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/IBackend.java (added)
+++ incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/IBackend.java Fri Nov 23 20:58:50 2012
@@ -0,0 +1,89 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.driver;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.flex.abc.visitors.IABCVisitor;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.internal.as.codegen.CmcJSEmitter;
+import org.apache.flex.compiler.internal.as.codegen.InterfaceDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSEmitter;
+import org.apache.flex.compiler.internal.as.codegen.JSGeneratingReducer;
+import org.apache.flex.compiler.internal.as.codegen.JSGenerator;
+import org.apache.flex.compiler.internal.as.codegen.JSGlobalDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSClassDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSWriter;
+import org.apache.flex.compiler.internal.as.codegen.LexicalScope;
+import org.apache.flex.compiler.internal.projects.CompilerProject;
+import org.apache.flex.compiler.internal.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.tree.as.ClassNode;
+import org.apache.flex.compiler.internal.tree.as.InterfaceNode;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ISWFTarget;
+import org.apache.flex.compiler.targets.ITargetProgressMonitor;
+import org.apache.flex.compiler.targets.ITargetSettings;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.swf.ISWF;
+import org.apache.flex.swf.io.ISWFWriter;
+
+public interface IBackend
+{
+    // called by MXMLJSC
+    public Configurator createConfigurator();
+
+    public ISWFWriter createSWFWriter(ICompilerProject project, List<ICompilerProblem> problems, ISWF swf, boolean useCompression, boolean enableDebug);
+
+    public JSWriter createJSWriter(ICompilerProject project, List<ICompilerProblem> problems, Collection<ICompilationUnit> compilationUnits, boolean useCompression);
+
+    public ISWFTarget createSWFTarget(CompilerProject project, ITargetSettings targetSettings, ITargetProgressMonitor progressMonitor) throws InterruptedException;
+
+    public ISourceFileHandler getSourceFileHandlerInstance();
+
+    // TODO: can all reducers be derived from IGenerator?
+    // called by JSCompilationUnit.
+    public JSGenerator createGenerator();
+
+    // called by JSGenerator.
+    public JSEmitter createEmitter(ICompilationUnit.Operation buildPhase, ICompilerProject project);
+
+    // TODO: can all reducers be derived from ICmcEmitter?
+    // called by JSGenerator.
+    public CmcJSEmitter createCmcJSEmitter();
+
+    // TODO: can all reducers be derived from IReducer?
+    // called by JSGenerator.
+    public JSGeneratingReducer createReducer();
+
+    // TODO: GlobalDirectiveProcessor is not visible
+    // called by JSGenerator.
+    public JSGlobalDirectiveProcessor createGlobalDirectiveProcessor(JSGenerator generator, LexicalScope current_scope, IABCVisitor emitter);
+
+    // TODO: ClassDirectiveProcessor is not visible
+    public JSClassDirectiveProcessor createClassDirectiveProcessor(JSGenerator generator, ClassNode c, LexicalScope enclosing_scope, IABCVisitor emitter);
+
+    public InterfaceDirectiveProcessor createInterfaceDirectiveProcessor(JSGenerator jsGenerator, InterfaceNode in, LexicalScope enclosing_scope, IABCVisitor emitter);
+
+    public RuntimeException createException(String msg);
+
+    public String getOutputExtension();
+}

Propchange: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/IBackend.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/JSBackend.java
URL: http://svn.apache.org/viewvc/incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/JSBackend.java?rev=1413061&view=auto
==============================================================================
--- incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/JSBackend.java (added)
+++ incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/JSBackend.java Fri Nov 23 20:58:50 2012
@@ -0,0 +1,135 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.driver;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.flex.abc.visitors.IABCVisitor;
+import org.apache.flex.compiler.clients.JSCommandLineConfiguration;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.internal.as.codegen.CmcJSEmitter;
+import org.apache.flex.compiler.internal.as.codegen.InterfaceDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSEmitter;
+import org.apache.flex.compiler.internal.as.codegen.JSGeneratingReducer;
+import org.apache.flex.compiler.internal.as.codegen.JSGenerator;
+import org.apache.flex.compiler.internal.as.codegen.JSGlobalDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSClassDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSInterfaceDirectiveProcessor;
+import org.apache.flex.compiler.internal.as.codegen.JSSharedData;
+import org.apache.flex.compiler.internal.as.codegen.JSWriter;
+import org.apache.flex.compiler.internal.as.codegen.LexicalScope;
+import org.apache.flex.compiler.internal.projects.CompilerProject;
+import org.apache.flex.compiler.internal.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.tree.as.ClassNode;
+import org.apache.flex.compiler.internal.tree.as.InterfaceNode;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ISWFTarget;
+import org.apache.flex.compiler.targets.ITargetProgressMonitor;
+import org.apache.flex.compiler.targets.ITargetSettings;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.swf.ISWF;
+import org.apache.flex.swf.io.ISWFWriter;
+
+public class JSBackend implements IBackend
+{
+    // called by MXMLJSC
+    public Configurator createConfigurator()
+    {
+        return new Configurator(JSCommandLineConfiguration.class);
+    }
+
+    public ISWFWriter createSWFWriter(ICompilerProject project, List<ICompilerProblem> problems, ISWF swf, boolean useCompression, boolean enableDebug)
+    {
+        return new JSWriter(project, problems, swf, useCompression, enableDebug);
+    }
+
+    public JSWriter createJSWriter(ICompilerProject project, List<ICompilerProblem> problems, Collection<ICompilationUnit> compilationUnits, boolean useCompression)
+    {
+        return new JSWriter(project, problems, compilationUnits, useCompression);
+    }
+
+    public ISWFTarget createSWFTarget(CompilerProject project, ITargetSettings targetSettings, ITargetProgressMonitor progressMonitor) throws InterruptedException
+    {
+        // see FlexProject::createSWFTarget()
+        return new JSTarget(project, targetSettings, progressMonitor);
+    }
+
+    public ISourceFileHandler getSourceFileHandlerInstance()
+    {
+        return JSSourceFileHandler.INSTANCE;
+    }
+
+    // TODO: can all reducers be derived from IGenerator?
+    // called by JSCompilationUnit.
+    public JSGenerator createGenerator()
+    {
+        return new JSGenerator();
+    }
+
+    // called by JSGenerator.
+    public JSEmitter createEmitter(ICompilationUnit.Operation buildPhase, ICompilerProject project)
+    {
+        return new JSEmitter(JSSharedData.instance, buildPhase, project);
+    }
+
+    // TODO: can all reducers be derived from ICmcEmitter?
+    // called by JSGenerator.
+    public CmcJSEmitter createCmcJSEmitter()
+    {
+        return new CmcJSEmitter();
+    }
+
+    // TODO: can all reducers be derived from IReducer?
+    // called by JSGenerator.
+    public JSGeneratingReducer createReducer()
+    {
+        return new JSGeneratingReducer(JSSharedData.instance);
+    }
+
+    // TODO: GlobalDirectiveProcessor is not visible
+    // called by JSGenerator.
+    public JSGlobalDirectiveProcessor createGlobalDirectiveProcessor(JSGenerator generator, LexicalScope current_scope, IABCVisitor emitter)
+    {
+        return new JSGlobalDirectiveProcessor(generator, current_scope, emitter);
+    }
+
+    // TODO: ClassDirectiveProcessor is not visible
+    public JSClassDirectiveProcessor createClassDirectiveProcessor(JSGenerator generator, ClassNode c, LexicalScope enclosing_scope, IABCVisitor emitter)
+    {
+        return new JSClassDirectiveProcessor(generator, c, enclosing_scope, emitter);
+    }
+
+    public InterfaceDirectiveProcessor createInterfaceDirectiveProcessor(JSGenerator generator, InterfaceNode in, LexicalScope enclosing_scope, IABCVisitor emitter)
+    {
+        return new JSInterfaceDirectiveProcessor(generator, in, enclosing_scope, emitter);
+    }
+
+    public RuntimeException createException(String msg)
+    {
+        return new RuntimeException(msg);
+    }
+
+    public String getOutputExtension()
+    {
+        return "js";
+    }
+}

Propchange: incubator/flex/falcon/trunk/compiler.js/src/org/apache/flex/compiler/internal/driver/JSBackend.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message