You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by jo...@apache.org on 2016/04/06 01:56:20 UTC

[02/33] git commit: [flex-falcon] [refs/heads/develop] - Initial start on source maps

Initial start on source maps


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/c9751606
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/c9751606
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/c9751606

Branch: refs/heads/develop
Commit: c9751606fe2e589407b6d708159631537bacb764
Parents: f053f21
Author: Josh Tynjala <jo...@apache.org>
Authored: Wed Mar 23 15:50:07 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Wed Mar 23 15:50:07 2016 -0700

----------------------------------------------------------------------
 .../apache/flex/compiler/clients/MXMLJSC.java   |  43 +++-
 .../compiler/codegen/ISourceMapEmitter.java     |  30 +++
 .../flex/compiler/codegen/js/IJSEmitter.java    |  20 ++
 .../flex/compiler/codegen/js/IJSWriter.java     |  10 +
 .../flex/compiler/driver/js/IJSBackend.java     |  29 +++
 .../compiler/internal/codegen/as/ASEmitter.java |  24 +++
 .../compiler/internal/codegen/as/ASWriter.java  |   3 +-
 .../compiler/internal/codegen/js/JSEmitter.java | 208 +++++++++++++++++++
 .../internal/codegen/js/JSSourceMapEmitter.java |  67 ++++++
 .../compiler/internal/codegen/js/JSWriter.java  |  93 ++++++++-
 .../codegen/js/flexjs/JSFlexJSEmitter.java      |  26 +--
 .../internal/codegen/js/jx/FieldEmitter.java    |   6 +-
 .../codegen/js/jx/FunctionCallEmitter.java      |  12 ++
 .../codegen/js/jx/IdentifierEmitter.java        |   2 +
 .../internal/codegen/js/jx/LiteralEmitter.java  |   2 +
 .../codegen/js/jx/MemberAccessEmitter.java      |   9 +-
 .../internal/codegen/js/jx/MethodEmitter.java   |  15 +-
 .../codegen/js/jx/PackageFooterEmitter.java     |   1 +
 .../codegen/js/jx/VarDeclarationEmitter.java    |   6 +
 .../compiler/internal/driver/js/JSBackend.java  |  12 +-
 20 files changed, 570 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
index b534f59..98cd4d2 100644
--- a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
+++ b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java
@@ -37,6 +37,7 @@ import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
 import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
 import org.apache.flex.compiler.codegen.as.IASWriter;
 import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
 import org.apache.flex.compiler.config.Configuration;
 import org.apache.flex.compiler.config.ConfigurationBuffer;
 import org.apache.flex.compiler.config.Configurator;
@@ -448,21 +449,29 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider,
 
                         ICompilationUnit unit = cu;
 
-                        IASWriter writer;
+                        IJSWriter writer;
                         if (cuType == ICompilationUnit.UnitType.AS_UNIT)
                         {
-                            writer = JSSharedData.backend.createWriter(project,
+                            writer = (IJSWriter) JSSharedData.backend.createWriter(project,
                                     errors, unit, false);
                         }
                         else
                         {
-                            writer = JSSharedData.backend.createMXMLWriter(
+                            writer = (IJSWriter) JSSharedData.backend.createMXMLWriter(
                                     project, errors, unit, false);
                         }
 
                         BufferedOutputStream out = new BufferedOutputStream(
                                 new FileOutputStream(outputClassFile));
-                        writer.writeTo(out);
+
+                        File outputSourceMapFile = null;
+                        if (project.config.getSourceMap())
+                        {
+                            outputSourceMapFile = getOutputSourceMapFile(
+                                    cu.getQualifiedNames().get(0), outputFolder);
+                        }
+                        
+                        writer.writeTo(out, outputSourceMapFile);
                         out.flush();
                         out.close();
                         writer.close();
@@ -596,6 +605,32 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider,
     }
 
     /**
+     * @param qname
+     * @param outputFolder
+     * @return output source map file path
+     */
+    private File getOutputSourceMapFile(String qname, File outputFolder)
+    {
+        String[] cname = qname.split("\\.");
+        String sdirPath = outputFolder + File.separator;
+        if (cname.length > 0)
+        {
+            for (int i = 0, n = cname.length - 1; i < n; i++)
+            {
+                sdirPath += cname[i] + File.separator;
+            }
+
+            File sdir = new File(sdirPath);
+            if (!sdir.exists())
+                sdir.mkdirs();
+
+            qname = cname[cname.length - 1];
+        }
+
+        return new File(sdirPath + qname + "." + JSSharedData.OUTPUT_EXTENSION + ".map");
+    }
+
+    /**
      * Mxmlc uses target file as the main compilation unit and derive the output
      * SWF file name from this file.
      * 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/codegen/ISourceMapEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/ISourceMapEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/ISourceMapEmitter.java
new file mode 100644
index 0000000..3fef28e
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/ISourceMapEmitter.java
@@ -0,0 +1,30 @@
+/*
+ *
+ *  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.codegen;
+
+/**
+ * Base interface for source map emitters.
+ *
+ * @author Josh Tynjala
+ */
+public interface ISourceMapEmitter
+{
+    String emitSourceMap(String sourceFilePath, String sourceMapPath, String sourceRoot);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
index 4972b39..f660fc3 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
@@ -20,10 +20,15 @@
 package org.apache.flex.compiler.codegen.js;
 
 import java.io.Writer;
+import java.util.List;
 
+import com.google.debugging.sourcemap.FilePosition;
+import com.google.debugging.sourcemap.SourceMapGenerator;
 import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.common.ISourceLocation;
 import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
 import org.apache.flex.compiler.visitor.IASNodeStrategy;
 
 /**
@@ -35,9 +40,24 @@ import org.apache.flex.compiler.visitor.IASNodeStrategy;
 public interface IJSEmitter extends IASEmitter
 {
     JSSessionModel getModel();
+    List<SourceMapMapping> getSourceMapMappings();
     
     String formatQualifiedName(String name);
     
+    void startMapping(ISourceLocation node);
+    void endMapping(ISourceLocation node);
+    
+    void emitSourceMapDirective(ITypeNode node);
+    
     void emitClosureStart();
     void emitClosureEnd(IASNode node);
+    
+    class SourceMapMapping
+    {
+        public String sourcePath;
+        public String name;
+        public FilePosition sourceStartPosition;
+        public FilePosition destStartPosition;
+        public FilePosition destEndPosition;
+    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSWriter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSWriter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSWriter.java
index 2e711fa..aae8011 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSWriter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSWriter.java
@@ -19,6 +19,9 @@
 
 package org.apache.flex.compiler.codegen.js;
 
+import java.io.File;
+import java.io.OutputStream;
+
 import org.apache.flex.compiler.codegen.as.IASWriter;
 
 /**
@@ -29,5 +32,12 @@ import org.apache.flex.compiler.codegen.as.IASWriter;
  */
 public interface IJSWriter extends IASWriter
 {
+    /**
+     * Write JS file and source map.
+     *
+     * @param jsOut JS output stream
+     * @param sourceMapOut Source map file
+     */
+    void writeTo(OutputStream jsOut, File sourceMapOut);
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/driver/js/IJSBackend.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/driver/js/IJSBackend.java b/compiler.jx/src/org/apache/flex/compiler/driver/js/IJSBackend.java
new file mode 100644
index 0000000..eb0f4e2
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/driver/js/IJSBackend.java
@@ -0,0 +1,29 @@
+/*
+ *
+ *  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.driver.js;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.driver.IBackend;
+
+public interface IJSBackend extends IBackend
+{
+    ISourceMapEmitter createSourceMapEmitter(IJSEmitter emitter);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
index 107e809..14ae6c5 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
@@ -182,6 +182,20 @@ public class ASEmitter implements IASEmitter, IEmitter
     public void setDocEmitter(IDocEmitter value)
     {
     }
+    
+    private int currentLine = 0;
+
+    protected int getCurrentLine()
+    {
+        return currentLine;
+    }
+
+    private int currentColumn = 0;
+
+    protected int getCurrentColumn()
+    {
+        return currentColumn;
+    }
 
     public ASEmitter(FilterWriter out)
     {
@@ -206,6 +220,16 @@ public class ASEmitter implements IASEmitter, IEmitter
     {
         try
         {
+            int newLineCount = value.length() - value.replace("\n", "").length();
+            currentLine += newLineCount;
+            if (newLineCount > 0)
+            {
+                currentColumn = value.length() - value.lastIndexOf("\n") - 1;
+            }
+            else
+            {
+                currentColumn += value.length();
+            }
             if (!bufferWrite)
                 out.write(value);
             else

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASWriter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
index 32e1671..9d127e4 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
@@ -26,6 +26,7 @@ import java.io.OutputStream;
 import java.util.List;
 
 import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.codegen.as.IASWriter;
 import org.apache.flex.compiler.codegen.js.IJSWriter;
 import org.apache.flex.compiler.internal.codegen.js.JSSharedData;
 import org.apache.flex.compiler.problems.ICompilerProblem;
@@ -33,7 +34,7 @@ import org.apache.flex.compiler.projects.IASProject;
 import org.apache.flex.compiler.units.ICompilationUnit;
 import org.apache.flex.compiler.visitor.as.IASBlockWalker;
 
-public class ASWriter implements IJSWriter
+public class ASWriter implements IASWriter
 {
     private IASProject project;
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
index c5d3e2b..e903094 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@ -20,14 +20,34 @@
 package org.apache.flex.compiler.internal.codegen.js;
 
 import java.io.FilterWriter;
+import java.util.ArrayList;
+import java.util.List;
 
+import com.google.debugging.sourcemap.FilePosition;
+import org.apache.flex.compiler.clients.JSConfiguration;
 import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.tree.ASTNodeID;
 import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
 import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
+import org.apache.flex.compiler.tree.as.IKeywordNode;
+import org.apache.flex.compiler.tree.as.INumericLiteralNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IReturnNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.visitor.IBlockWalker;
 
 /**
  * @author Michael Schmalle
@@ -41,12 +61,22 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
     {
         return model;
     }
+    
+    private SourceMapMapping lastMapping;
+    
+    private List<SourceMapMapping> sourceMapMappings;
+    
+    public List<SourceMapMapping> getSourceMapMappings()
+    {
+        return sourceMapMappings;
+    }
 
     public JSEmitter(FilterWriter out)
     {
         super(out);
         
         model = new JSSessionModel();
+        sourceMapMappings = new ArrayList<SourceMapMapping>();
     }
 
     @Override
@@ -58,10 +88,12 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
     @Override
     public void emitLocalNamedFunction(IFunctionNode node)
     {
+        startMapping(node);
         FunctionNode fnode = (FunctionNode)node;
         write(ASEmitterTokens.FUNCTION);
         write(ASEmitterTokens.SPACE);
         write(fnode.getName());
+        endMapping(node);
         emitParameters(fnode.getParameterNodes());
         emitFunctionScope(fnode.getScopedNode());
     }
@@ -69,8 +101,10 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
     @Override
     public void emitFunctionObject(IFunctionObjectNode node)
     {
+        startMapping(node);
         FunctionNode fnode = node.getFunctionNode();
         write(ASEmitterTokens.FUNCTION);
+        endMapping(node);
         emitParameters(fnode.getParameterNodes());
         emitFunctionScope(fnode.getScopedNode());
     }
@@ -84,5 +118,179 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
     {
     	
     }
+    
+    public void emitSourceMapDirective(ITypeNode node)
+    {
+        boolean sourceMap = false;
+        
+        IBlockWalker walker = getWalker();
+        FlexJSProject project = (FlexJSProject) walker.getProject();
+        if (project != null)
+        {
+            JSConfiguration config = project.config;
+            if (config != null)
+            {
+                sourceMap = config.getSourceMap();
+            }
+        }
+        
+        if (sourceMap)
+        {
+            writeNewline();
+            write("//# sourceMappingURL=./" + node.getName() + ".js.map");
+        }
+    }
+
+    public void emitParameters(IParameterNode[] nodes)
+    {
+        write(ASEmitterTokens.PAREN_OPEN);
+        int len = nodes.length;
+        for (int i = 0; i < len; i++)
+        {
+            IParameterNode node = nodes[i];
+            getWalker().walk(node); //emitParameter
+            if (i < len - 1)
+            {
+                writeToken(ASEmitterTokens.COMMA);
+            }
+        }
+        write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+    @Override
+    public void emitParameter(IParameterNode node)
+    {
+        startMapping(node);
+        super.emitParameter(node);
+        endMapping(node);
+    }
+
+    @Override
+    public void emitNumericLiteral(INumericLiteralNode node)
+    {
+        startMapping((ISourceLocation) node);
+        super.emitNumericLiteral(node);
+        endMapping((ISourceLocation) node);
+    }
+
+    @Override
+    public void emitReturn(IReturnNode node)
+    {
+        startMapping(node);
+        write(ASEmitterTokens.RETURN);
+        endMapping(node);
+        IExpressionNode rnode = node.getReturnValueNode();
+        if (rnode != null && rnode.getNodeID() != ASTNodeID.NilID)
+        {
+            write(ASEmitterTokens.SPACE);
+            getWalker().walk(rnode);
+        }
+    }
+
+    @Override
+    public void emitMemberKeyword(IDefinitionNode node)
+    {
+        IKeywordNode keywordNode = null;
+        for(int i = 0; i < node.getChildCount(); i++)
+        {
+            IASNode childNode = node.getChild(i);
+            if (childNode instanceof IKeywordNode)
+            {
+                keywordNode = (IKeywordNode) childNode;
+                break; 
+            }
+        }
+        if (keywordNode != null)
+        {
+            startMapping(keywordNode);
+        }
+        if (node instanceof IFunctionNode)
+        {
+            writeToken(ASEmitterTokens.FUNCTION);
+        }
+        else if (node instanceof IVariableNode)
+        {
+            writeToken(ASEmitterTokens.VAR);
+        }
+        if (keywordNode != null)
+        {
+            endMapping(keywordNode);
+        }
+    }
+    
+    public void startMapping(ISourceLocation node)
+    {
+        if (lastMapping != null)
+        {
+            FilePosition sourceStartPosition = lastMapping.sourceStartPosition;
+            throw new IllegalStateException("Cannot start new mapping when another mapping is already started. "
+                    + "Previous mapping at Line " + sourceStartPosition.getLine()
+                    + " and Column " + sourceStartPosition.getColumn()
+                    + " in file " + lastMapping.sourcePath);
+        }
+        
+        String sourcePath = node.getSourcePath();
+        if (sourcePath == null)
+        {
+            //if the source path is null, this node may have been generated by
+            //the compiler automatically. for example, an untyped variable will
+            //have a node for the * type.
+            if (node instanceof IASNode)
+            {
+                IASNode parentNode = ((IASNode) node).getParent();
+                if (parentNode != null)
+                {
+                    //try the parent node
+                    startMapping(parentNode);
+                }
+            }
+            return;
+        }
+        
+        String nodeName = null;
+        if (node instanceof IDefinitionNode)
+        {
+            IDefinitionNode definitionNode = (IDefinitionNode) node; 
+            nodeName = definitionNode.getQualifiedName();
+
+            ITypeDefinition typeDef = EmitterUtils.getTypeDefinition(definitionNode);
+            if (typeDef != null)
+            {
+                boolean isConstructor = node instanceof IFunctionNode &&
+                        ((IFunctionNode) node).isConstructor();
+                boolean isStatic = definitionNode.hasModifier(ASModifier.STATIC);
+                if (isConstructor)
+                {
+                    nodeName = typeDef.getQualifiedName() + ".constructor";
+                }
+                else if (isStatic)
+                {
+                    nodeName = typeDef.getQualifiedName() + "." + nodeName;
+                }
+                else
+                {
+                    nodeName = typeDef.getQualifiedName() + ".prototype." + nodeName;
+                }
+            }
+        }
+        SourceMapMapping mapping = new SourceMapMapping();
+        mapping.sourcePath = sourcePath;
+        mapping.name = nodeName;
+        mapping.sourceStartPosition = new FilePosition(node.getLine(), node.getColumn());
+        mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+        lastMapping = mapping;
+    }
+
+    public void endMapping(ISourceLocation node)
+    {
+        if (lastMapping == null)
+        {
+            throw new IllegalStateException("Cannot end mapping when a mapping has not been started");
+        }
+        
+        lastMapping.destEndPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+        sourceMapMappings.add(lastMapping);
+        lastMapping = null;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
new file mode 100644
index 0000000..bcdeed5
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
@@ -0,0 +1,67 @@
+/*
+ *
+ *  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.codegen.js;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+
+import com.google.debugging.sourcemap.SourceMapGeneratorV3;
+
+public class JSSourceMapEmitter implements ISourceMapEmitter
+{
+    private IJSEmitter emitter;
+    private SourceMapGeneratorV3 sourceMapGenerator;
+
+    public JSSourceMapEmitter(IJSEmitter emitter)
+    {
+        this.emitter = emitter;
+        sourceMapGenerator = new SourceMapGeneratorV3();
+    }
+    
+    public String emitSourceMap(String fileName, String sourceMapPath, String sourceRoot)
+    {
+        List<IJSEmitter.SourceMapMapping> mappings = this.emitter.getSourceMapMappings();
+        for (IJSEmitter.SourceMapMapping mapping : mappings)
+        {
+            sourceMapGenerator.addMapping(mapping.sourcePath, mapping.name,
+                    mapping.sourceStartPosition,
+                    mapping.destStartPosition, mapping.destEndPosition);
+        }
+        if (sourceRoot != null)
+        {
+            sourceMapGenerator.setSourceRoot(sourceRoot);
+        }
+
+        StringBuilder builder = new StringBuilder();
+        try
+        {
+            sourceMapGenerator.appendTo(builder, fileName);
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+        
+        return builder.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSWriter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
index 16a4d4d..0e60a93 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
@@ -19,14 +19,19 @@
 
 package org.apache.flex.compiler.internal.codegen.js;
 
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
+import java.util.Stack;
 
-import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
 import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.driver.js.IJSBackend;
 import org.apache.flex.compiler.problems.ICompilerProblem;
 import org.apache.flex.compiler.projects.IASProject;
 import org.apache.flex.compiler.units.ICompilationUnit;
@@ -67,28 +72,96 @@ public class JSWriter implements IJSWriter
     @Override
     public void writeTo(OutputStream out)
     {
-        JSFilterWriter writer = (JSFilterWriter) JSSharedData.backend
-                .createWriterBuffer(project);
-        IASEmitter emitter = JSSharedData.backend.createEmitter(writer);
-        IASBlockWalker walker = JSSharedData.backend.createWalker(project,
+        writeTo(out, null);
+    }
+
+    @Override
+    public int writeTo(File out) throws FileNotFoundException, IOException
+    {
+        return 0;
+    }
+
+    public void writeTo(OutputStream jsOut, File sourceMapOut)
+    {
+        IJSBackend backend = (IJSBackend) JSSharedData.backend;
+        JSFilterWriter writer = (JSFilterWriter) backend.createWriterBuffer(project);
+        IJSEmitter emitter = (IJSEmitter) backend.createEmitter(writer);
+        IASBlockWalker walker = backend.createWalker(project,
                 problems, emitter);
 
         walker.visitCompilationUnit(compilationUnit);
 
         try
         {
-            out.write(emitter.postProcess(writer.toString()).getBytes());
+            jsOut.write(emitter.postProcess(writer.toString()).getBytes());
         }
         catch (IOException e)
         {
             e.printStackTrace();
         }
-    }
 
-    @Override
-    public int writeTo(File out) throws FileNotFoundException, IOException
+        if (sourceMapOut != null)
+        {
+            convertMappingSourcePathsToRelative(emitter, sourceMapOut);
+            
+
+            File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename());
+            ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter(emitter);
+            try
+            {
+                String fileName = compilationUnitFile.getName();
+                fileName = fileName.replace(".as", ".js");
+                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapOut.getAbsolutePath(), null);
+                BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(sourceMapOut));
+                outStream.write(sourceMap.getBytes());
+                outStream.flush();
+                outStream.close();
+            } catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    private void convertMappingSourcePathsToRelative(IJSEmitter emitter, File relativeToFile)
     {
-        return 0;
+        List<IJSEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings();
+        for (IJSEmitter.SourceMapMapping mapping : mappings)
+        {
+            mapping.sourcePath = relativePath(mapping.sourcePath, relativeToFile.getAbsolutePath());
+        }
     }
 
+    //if we ever support Java 7, the java.nio.file.Path relativize() method
+    //should be able to replace this method
+    private String relativePath(String filePath, String relativeToFilePath)
+    {
+        File currentFile = new File(filePath);
+        Stack<String> stack = new Stack<String>();
+        stack.push(currentFile.getName());
+        currentFile = currentFile.getParentFile();
+        while (currentFile != null)
+        {
+            String absoluteCurrentFile = currentFile.getAbsolutePath() + File.separator;
+            if (relativeToFilePath.startsWith(absoluteCurrentFile))
+            {
+                String relativeRelativeToFile = relativeToFilePath.substring(absoluteCurrentFile.length());
+                int separatorCount = relativeRelativeToFile.length() - relativeRelativeToFile.replace(File.separator, "").length();
+                String result = "";
+                while (separatorCount > 0)
+                {
+                    result += ".." + File.separator;
+                    separatorCount--;
+                }
+                while (stack.size() > 0)
+                {
+                    result += stack.pop();
+                }
+                return result;
+            }
+            stack.push(currentFile.getName() + File.separator);
+            currentFile = currentFile.getParentFile();
+        }
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index c4c72da..a907ea7 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -81,7 +81,6 @@ import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
 import org.apache.flex.compiler.tree.as.IGetterNode;
 import org.apache.flex.compiler.tree.as.IIdentifierNode;
 import org.apache.flex.compiler.tree.as.IInterfaceNode;
-import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode;
 import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.flex.compiler.tree.as.INamespaceNode;
@@ -137,6 +136,8 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     @Override
     public String postProcess(String output)
     {
+        output = super.postProcess(output);
+        
     	String[] lines = output.split("\n");
     	ArrayList<String> finalLines = new ArrayList<String>();
     	boolean sawRequires = false;
@@ -152,7 +153,7 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
 	                String s = line.substring(c + 14, c2 - 1);
 	    			sawRequires = true;
 	    			if (!usedNames.contains(s))
-	    				continue;
+                        continue;
 	    		}
 	    		else if (sawRequires)
 	    			stillSearching = false;
@@ -239,12 +240,6 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     }
 
     @Override
-    public void emitLiteralContainer(ILiteralContainerNode node)
-    {
-        super.emitLiteralContainer(node);
-    }
-
-    @Override
     public void emitLocalNamedFunction(IFunctionNode node)
     {
 		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
@@ -308,19 +303,6 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     }
     
     @Override
-    public void emitMemberKeyword(IDefinitionNode node)
-    {
-        if (node instanceof IFunctionNode)
-        {
-            writeToken(ASEmitterTokens.FUNCTION);
-        }
-        else if (node instanceof IVariableNode)
-        {
-            writeToken(ASEmitterTokens.VAR);
-        }
-    }
-    
-    @Override
     public void emitNamespace(INamespaceNode node)
     {
         write(formatQualifiedName(node.getName()));
@@ -424,7 +406,7 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
                 getModel().getInternalClasses().put(className, mainClassName + "." + className);
             }
         }
-
+        
         packageHeaderEmitter.emit(definition);
     }
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
index 756d07e..b22c41d 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
@@ -85,8 +85,10 @@ public class FieldEmitter extends JSSubEmitter implements
                 definition = ndef.getContainingScope().getDefinition();
             
             write(getEmitter().formatQualifiedName(definition.getQualifiedName())
-                    + ASEmitterTokens.MEMBER_ACCESS.getToken() + root
-                    + node.getName());
+                    + ASEmitterTokens.MEMBER_ACCESS.getToken() + root);
+            getEmitter().startMapping(node);
+            write(node.getName());
+            getEmitter().endMapping(node);
         }
 
         if (node.getNodeID() == ASTNodeID.BindableVariableID)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FunctionCallEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
index c38d820..a71b4dd 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/FunctionCallEmitter.java
@@ -71,7 +71,9 @@ public class FunctionCallEmitter extends JSSubEmitter implements ISubEmitter<IFu
             {
                 if (!(node.getChild(1) instanceof VectorLiteralNode))
                 {
+                    getEmitter().startMapping(node.getNewKeywordNode());
                     writeToken(ASEmitterTokens.NEW);
+                    getEmitter().endMapping(node.getNewKeywordNode());
                 }
                 else
                 {
@@ -104,7 +106,11 @@ public class FunctionCallEmitter extends JSSubEmitter implements ISubEmitter<IFu
                 def = node.resolveCalledExpression(getProject());
                 // all new calls to a class should be fully qualified names
                 if (def instanceof ClassDefinition)
+                {
+                    getEmitter().startMapping(node);
                     write(getEmitter().formatQualifiedName(def.getQualifiedName()));
+                    getEmitter().endMapping(node);
+                }
                 else
                 {
                     IExpressionNode nameNode = node.getNameNode();
@@ -119,9 +125,15 @@ public class FunctionCallEmitter extends JSSubEmitter implements ISubEmitter<IFu
                     if (nameNode.hasParenthesis())
                         write(ASEmitterTokens.PAREN_CLOSE);                        
                 }
+                getEmitter().startMapping(node.getArgumentsNode());
                 write(ASEmitterTokens.PAREN_OPEN);
+                getEmitter().endMapping(node.getArgumentsNode());
+                
                 fjs.walkArguments(node.getArgumentNodes());
+                
+                getEmitter().startMapping(node.getArgumentsNode());
                 write(ASEmitterTokens.PAREN_CLOSE);
+                getEmitter().endMapping(node.getArgumentsNode());
             }
             else if (!isClassCast)
             {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
index 7d64896..69217c1 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
@@ -217,6 +217,7 @@ public class IdentifierEmitter extends JSSubEmitter implements
                     //member access expression, it shouldn't be fully qualified
                     needsFormattedName = parentMemberAccessNode.getLeftOperandNode() == node;
                 }
+                getEmitter().startMapping(node);
                 if (parentNodeId == ASTNodeID.MemberAccessExpressionID)
                 {
                     if (needsFormattedName)
@@ -234,6 +235,7 @@ public class IdentifierEmitter extends JSSubEmitter implements
                     write(getEmitter().formatQualifiedName(qname));
                 else
                     write(qname);
+                getEmitter().endMapping(node);
             }
             else
                 write(node.getName());

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
index a4b276c..e3827e6 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
@@ -122,7 +122,9 @@ public class LiteralEmitter extends JSSubEmitter implements
 
         if (!isWritten)
         {
+			getEmitter().startMapping(node);
             write(s);
+			getEmitter().endMapping(node);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
index 305b2e9..5175a79 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
@@ -63,12 +63,7 @@ public class MemberAccessEmitter extends JSSubEmitter implements
 
         IASNode leftNode = node.getLeftOperandNode();
         IASNode rightNode = node.getRightOperandNode();
-
-        String leftName = "";
-        if (leftNode instanceof IdentifierNode)
-        {
-        	leftName = ((IdentifierNode)leftNode).getName();
-        }
+        
     	JSFlexJSEmitter fjs = (JSFlexJSEmitter)getEmitter();
         IDefinition def = node.resolve(getProject());
         if (def == null)
@@ -314,7 +309,9 @@ public class MemberAccessEmitter extends JSSubEmitter implements
         }
         else
         {
+            getEmitter().startMapping(leftNode);
             write(ASEmitterTokens.THIS);
+            getEmitter().endMapping(leftNode);
         }
         return true;
     }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java
index 66210ca..15d9fa7 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java
@@ -27,6 +27,7 @@ import org.apache.flex.compiler.common.ASModifier;
 import org.apache.flex.compiler.definitions.IFunctionDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitter;
 import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
@@ -80,8 +81,16 @@ public class MethodEmitter extends JSSubEmitter implements
             }
             if (qname != null && !qname.equals(""))
             {
+                if (isConstructor)
+                {
+                    getEmitter().startMapping(node);
+                }
                 write(fjs.formatQualifiedName(qname));
-                if (!isConstructor)
+                if (isConstructor)
+                {
+                    getEmitter().endMapping(node);
+                }
+                else
                 {
                     write(ASEmitterTokens.MEMBER_ACCESS);
                     if (!fn.hasModifier(ASModifier.STATIC))
@@ -92,7 +101,11 @@ public class MethodEmitter extends JSSubEmitter implements
                 }
             }
             if (!isConstructor)
+            {
+                getEmitter().startMapping(node);
                 fjs.emitMemberName(node);
+                getEmitter().endMapping(node);
+            }
         }
 
         write(ASEmitterTokens.SPACE);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
index fa99a54..eab3413 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
@@ -72,6 +72,7 @@ public class PackageFooterEmitter extends JSSubEmitter implements
         if (type == null)
             return;
 
+        getEmitter().emitSourceMapDirective(type.getNode());
     }
 
     public void emitClassInfo(ITypeNode tnode)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
index 171be76..b945282 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
@@ -56,15 +56,21 @@ public class VarDeclarationEmitter extends JSSubEmitter implements
         IExpressionNode avnode = node.getAssignedValueNode();
         if (avnode != null)
         {
+            getEmitter().startMapping(node.getVariableTypeNode());
             IDefinition def = avnode.resolveType(getWalker().getProject());
 
             String opcode = avnode.getNodeID().getParaphrase();
             if (opcode != "AnonymousFunction")
+            {
                 fjs.getDocEmitter().emitVarDoc(node, def, getWalker().getProject());
+            }
+            getEmitter().endMapping(node.getVariableTypeNode());
         }
         else
         {
+            getEmitter().startMapping(node.getVariableTypeNode());
             fjs.getDocEmitter().emitVarDoc(node, null, getWalker().getProject());
+            getEmitter().endMapping(node.getVariableTypeNode());
         }
 
         if (!(node instanceof ChainedVariableNode) && node.isConst())

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c9751606/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java
index 20ff965..a8b7737 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.flex.compiler.clients.JSConfiguration;
 import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
 import org.apache.flex.compiler.codegen.as.IASEmitter;
 import org.apache.flex.compiler.codegen.js.IJSEmitter;
 import org.apache.flex.compiler.codegen.js.IJSWriter;
@@ -33,6 +34,7 @@ import org.apache.flex.compiler.config.Configuration;
 import org.apache.flex.compiler.config.Configurator;
 import org.apache.flex.compiler.driver.IBackend;
 import org.apache.flex.compiler.driver.IPublisher;
+import org.apache.flex.compiler.driver.js.IJSBackend;
 import org.apache.flex.compiler.internal.codegen.as.ASAfterNodeStrategy;
 import org.apache.flex.compiler.internal.codegen.as.ASBeforeNodeStrategy;
 import org.apache.flex.compiler.internal.codegen.as.ASBlockWalker;
@@ -40,6 +42,7 @@ import org.apache.flex.compiler.internal.codegen.js.JSDocEmitter;
 import org.apache.flex.compiler.internal.codegen.js.JSEmitter;
 import org.apache.flex.compiler.internal.codegen.js.JSFilterWriter;
 import org.apache.flex.compiler.internal.codegen.js.JSPublisher;
+import org.apache.flex.compiler.internal.codegen.js.JSSourceMapEmitter;
 import org.apache.flex.compiler.internal.codegen.js.JSWriter;
 import org.apache.flex.compiler.internal.projects.ISourceFileHandler;
 import org.apache.flex.compiler.internal.targets.JSTarget;
@@ -61,9 +64,8 @@ import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker;
  * 
  * @author Michael Schmalle
  */
-public class JSBackend implements IBackend
+public class JSBackend implements IJSBackend
 {
-
     @Override
     public String getOutputExtension()
     {
@@ -137,6 +139,12 @@ public class JSBackend implements IBackend
     }
 
     @Override
+    public ISourceMapEmitter createSourceMapEmitter(IJSEmitter emitter)
+    {
+        return new JSSourceMapEmitter(emitter);
+    }
+
+    @Override
     public IDocEmitter createDocEmitter(IASEmitter emitter)
     {
         return new JSDocEmitter((IJSEmitter) emitter);