compiler-jx: source maps for fx:Script blocks
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/3ab47113 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/3ab47113 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/3ab47113 Branch: refs/heads/master Commit: 3ab4711313c4a48d5c2dd01be6213e5cc4b3647a Parents: 7a83126 Author: Josh Tynjala <[email protected]> Authored: Mon Mar 20 16:24:19 2017 -0700 Committer: Josh Tynjala <[email protected]> Committed: Tue Mar 21 16:07:16 2017 -0700 ---------------------------------------------------------------------- .../flex/compiler/codegen/INestingEmitter.java | 26 +++ .../flex/compiler/codegen/as/IASEmitter.java | 3 +- .../flex/compiler/codegen/js/IJSEmitter.java | 38 +--- .../compiler/codegen/js/IMappingEmitter.java | 66 +++++++ .../flex/compiler/driver/js/IJSBackend.java | 4 +- .../flex/compiler/internal/codegen/Emitter.java | 28 +++ .../compiler/internal/codegen/as/ASEmitter.java | 31 +++- .../compiler/internal/codegen/js/JSEmitter.java | 16 ++ .../internal/codegen/js/JSSourceMapEmitter.java | 10 +- .../compiler/internal/codegen/js/JSWriter.java | 7 +- .../internal/codegen/mxml/MXMLWriter.java | 25 ++- .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java | 179 ++++++++++++++++++- .../mxml/flexjs/MXMLFlexJSPublisher.java | 34 ---- .../compiler/internal/driver/js/JSBackend.java | 3 +- .../internal/test/SourceMapTestBase.java | 5 +- 15 files changed, 374 insertions(+), 101 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/INestingEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/INestingEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/INestingEmitter.java new file mode 100644 index 0000000..36889c5 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/INestingEmitter.java @@ -0,0 +1,26 @@ +/* + * + * 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; + +public interface INestingEmitter extends IEmitter +{ + IEmitter getParentEmitter(); + void setParentEmitter(IEmitter emitter); +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java index 928259b..3716aba 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java @@ -23,6 +23,7 @@ import java.io.Writer; import org.apache.flex.compiler.codegen.IDocEmitter; import org.apache.flex.compiler.codegen.IEmitter; +import org.apache.flex.compiler.codegen.INestingEmitter; import org.apache.flex.compiler.definitions.IPackageDefinition; import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode; import org.apache.flex.compiler.tree.as.IASNode; @@ -76,7 +77,7 @@ import org.apache.flex.compiler.visitor.IBlockWalker; * * @author Michael Schmalle */ -public interface IASEmitter extends IEmitter +public interface IASEmitter extends INestingEmitter { IBlockWalker getWalker(); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java index b686a3a..f71eb90 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java @@ -20,11 +20,8 @@ package org.apache.flex.compiler.codegen.js; import java.io.Writer; -import java.util.List; -import com.google.debugging.sourcemap.FilePosition; import org.apache.flex.compiler.codegen.as.IASEmitter; -import org.apache.flex.compiler.common.ISourceLocation; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.internal.codegen.js.JSSessionModel; import org.apache.flex.compiler.tree.as.IASNode; @@ -37,47 +34,14 @@ import org.apache.flex.compiler.visitor.IASNodeStrategy; * * @author Michael Schmalle */ -public interface IJSEmitter extends IASEmitter +public interface IJSEmitter extends IASEmitter, IMappingEmitter { JSSessionModel getModel(); - List<SourceMapMapping> getSourceMapMappings(); String formatQualifiedName(String name); - - /** - * Adds a node to the source map. - */ - void startMapping(ISourceLocation node); - - /** - * Adds a node to the source map using custom line and column values, - * instead of the node's own line and column. Useful for starting a mapping - * in the middle of the node. - */ - void startMapping(ISourceLocation node, int line, int column); - - /** - * Adds a node to the source map after a particular node instead using the - * node's own line and column. - */ - void startMapping(ISourceLocation node, ISourceLocation afterNode); - - /** - * Commits a mapping to the source map. - */ - void endMapping(ISourceLocation node); void emitSourceMapDirective(ITypeNode node); void emitClosureStart(); void emitClosureEnd(IASNode node, IDefinition nodeDef); - - 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/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IMappingEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IMappingEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IMappingEmitter.java new file mode 100644 index 0000000..dc4bb6b --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IMappingEmitter.java @@ -0,0 +1,66 @@ +/* + * + * 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.js; + +import java.util.List; + +import org.apache.flex.compiler.common.ISourceLocation; + +import com.google.debugging.sourcemap.FilePosition; + +/** + * Tracks mappings to generate source maps while it emits code. + */ +public interface IMappingEmitter +{ + List<SourceMapMapping> getSourceMapMappings(); + + /** + * Adds a node to the source map. + */ + void startMapping(ISourceLocation node); + + /** + * Adds a node to the source map using custom line and column values, + * instead of the node's own line and column. Useful for starting a mapping + * in the middle of the node. + */ + void startMapping(ISourceLocation node, int line, int column); + + /** + * Adds a node to the source map after a particular node instead using the + * node's own line and column. + */ + void startMapping(ISourceLocation node, ISourceLocation afterNode); + + /** + * Commits a mapping to the source map. + */ + void endMapping(ISourceLocation 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/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/driver/js/IJSBackend.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/driver/js/IJSBackend.java b/compiler-jx/src/main/java/org/apache/flex/compiler/driver/js/IJSBackend.java index eb0f4e2..80099b6 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/driver/js/IJSBackend.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/driver/js/IJSBackend.java @@ -20,10 +20,10 @@ 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.codegen.js.IMappingEmitter; import org.apache.flex.compiler.driver.IBackend; public interface IJSBackend extends IBackend { - ISourceMapEmitter createSourceMapEmitter(IJSEmitter emitter); + ISourceMapEmitter createSourceMapEmitter(IMappingEmitter emitter); } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/Emitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/Emitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/Emitter.java index c399d73..d559058 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/Emitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/Emitter.java @@ -108,6 +108,20 @@ public class Emitter implements IEmitter walker = value; } + private int currentLine = 0; + + protected int getCurrentLine() + { + return currentLine; + } + + private int currentColumn = 0; + + protected int getCurrentColumn() + { + return currentColumn; + } + public Emitter(FilterWriter out) { this.out = out; @@ -127,9 +141,23 @@ public class Emitter implements IEmitter try { if (!bufferWrite) + { + int newLineCount = value.length() - value.replace("\n", "").length(); + currentLine += newLineCount; + if (newLineCount > 0) + { + currentColumn = value.length() - value.lastIndexOf("\n") - 1; + } + else + { + currentColumn += value.length(); + } out.write(value); + } else + { builder.append(value); + } } catch (IOException e) { http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java index 0320d6a..c34eadb 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java @@ -109,6 +109,18 @@ public class ASEmitter implements IASEmitter, IEmitter { private final FilterWriter out; + private IEmitter parentEmitter; + + public IEmitter getParentEmitter() + { + return parentEmitter; + } + + public void setParentEmitter(IEmitter value) + { + parentEmitter = value; + } + private boolean bufferWrite; protected boolean isBufferWrite() @@ -223,17 +235,24 @@ public class ASEmitter implements IASEmitter, IEmitter { if (!bufferWrite) { - int newLineCount = value.length() - value.replace("\n", "").length(); - currentLine += newLineCount; - if (newLineCount > 0) + if (parentEmitter != null) { - currentColumn = value.length() - value.lastIndexOf("\n") - 1; + parentEmitter.write(value); } else { - currentColumn += value.length(); + int newLineCount = value.length() - value.replace("\n", "").length(); + currentLine += newLineCount; + if (newLineCount > 0) + { + currentColumn = value.length() - value.lastIndexOf("\n") - 1; + } + else + { + currentColumn += value.length(); + } + out.write(value); } - out.write(value); } else { http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java index 5b1f770..db31fa0 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java @@ -24,8 +24,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Stack; +import org.apache.flex.compiler.codegen.IEmitter; import org.apache.flex.compiler.codegen.ISubEmitter; import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import org.apache.flex.compiler.common.ASModifier; import org.apache.flex.compiler.common.ISourceLocation; import org.apache.flex.compiler.definitions.IDefinition; @@ -391,6 +393,13 @@ public class JSEmitter extends ASEmitter implements IJSEmitter { return; } + IEmitter parentEmitter = getParentEmitter(); + if (parentEmitter != null && parentEmitter instanceof IMappingEmitter) + { + IMappingEmitter mappingParent = (IMappingEmitter) parentEmitter; + mappingParent.startMapping(node, line, column); + return; + } if (lastMapping != null) { FilePosition sourceStartPosition = lastMapping.sourceStartPosition; @@ -436,6 +445,13 @@ public class JSEmitter extends ASEmitter implements IJSEmitter { return; } + IEmitter parentEmitter = getParentEmitter(); + if (parentEmitter != null && parentEmitter instanceof IMappingEmitter) + { + IMappingEmitter mappingParent = (IMappingEmitter) parentEmitter; + mappingParent.endMapping(node); + return; + } if (lastMapping == null) { throw new IllegalStateException("Cannot end mapping when a mapping has not been started"); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java index bcdeed5..5b6c26c 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java @@ -23,16 +23,16 @@ import java.io.IOException; import java.util.List; import org.apache.flex.compiler.codegen.ISourceMapEmitter; -import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import com.google.debugging.sourcemap.SourceMapGeneratorV3; public class JSSourceMapEmitter implements ISourceMapEmitter { - private IJSEmitter emitter; + private IMappingEmitter emitter; private SourceMapGeneratorV3 sourceMapGenerator; - public JSSourceMapEmitter(IJSEmitter emitter) + public JSSourceMapEmitter(IMappingEmitter emitter) { this.emitter = emitter; sourceMapGenerator = new SourceMapGeneratorV3(); @@ -40,8 +40,8 @@ public class JSSourceMapEmitter implements ISourceMapEmitter public String emitSourceMap(String fileName, String sourceMapPath, String sourceRoot) { - List<IJSEmitter.SourceMapMapping> mappings = this.emitter.getSourceMapMappings(); - for (IJSEmitter.SourceMapMapping mapping : mappings) + List<IMappingEmitter.SourceMapMapping> mappings = this.emitter.getSourceMapMappings(); + for (IMappingEmitter.SourceMapMapping mapping : mappings) { sourceMapGenerator.addMapping(mapping.sourcePath, mapping.name, mapping.sourceStartPosition, http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java index 0eb6c9b..7076009 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java @@ -31,6 +31,7 @@ import java.util.Stack; 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.codegen.js.IMappingEmitter; import org.apache.flex.compiler.driver.js.IJSBackend; import org.apache.flex.compiler.internal.projects.FlexJSProject; import org.apache.flex.compiler.problems.ICompilerProblem; @@ -131,10 +132,10 @@ public class JSWriter implements IJSWriter } } - protected void convertMappingSourcePathsToRelative(IJSEmitter emitter, File relativeToFile) + protected void convertMappingSourcePathsToRelative(IMappingEmitter emitter, File relativeToFile) { - List<IJSEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings(); - for (IJSEmitter.SourceMapMapping mapping : mappings) + List<IMappingEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings(); + for (IMappingEmitter.SourceMapMapping mapping : mappings) { mapping.sourcePath = relativePath(mapping.sourcePath, relativeToFile.getAbsolutePath()); } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/MXMLWriter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/MXMLWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/MXMLWriter.java index 84d9421..c127e7b 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/MXMLWriter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/MXMLWriter.java @@ -19,13 +19,18 @@ package org.apache.flex.compiler.internal.codegen.mxml; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; +import org.apache.flex.compiler.codegen.ISourceMapEmitter; import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter; +import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter; import org.apache.flex.compiler.driver.js.IJSBackend; import org.apache.flex.compiler.internal.codegen.js.JSFilterWriter; import org.apache.flex.compiler.internal.codegen.js.JSWriter; @@ -62,6 +67,7 @@ public class MXMLWriter extends JSWriter IMXMLEmitter mxmlEmitter = backend.createMXMLEmitter(writer); IMXMLBlockWalker mxmlBlockWalker = backend.createMXMLWalker( project, problems, mxmlEmitter, asEmitter, asBlockWalker); + asEmitter.setParentEmitter(mxmlEmitter); mxmlBlockWalker.visitCompilationUnit(compilationUnit); @@ -76,8 +82,23 @@ public class MXMLWriter extends JSWriter if (sourceMapOut != null) { - String fileName = new File(compilationUnit.getAbsoluteFilename()).getName(); - System.out.println("Source map cannot be generated for '" + fileName + "'."); + convertMappingSourcePathsToRelative((IMappingEmitter) mxmlEmitter, sourceMapOut); + + File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename()); + ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter((IMappingEmitter) mxmlEmitter); + try + { + String fileName = compilationUnitFile.getName(); + fileName = fileName.replace(".mxml", ".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(); + } } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java index 0b87cd6..207e671 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java @@ -34,8 +34,10 @@ import org.apache.flex.abc.semantics.MethodInfo; import org.apache.flex.abc.semantics.Name; import org.apache.flex.abc.semantics.Namespace; import org.apache.flex.compiler.codegen.as.IASEmitter; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter; import org.apache.flex.compiler.common.ASModifier; +import org.apache.flex.compiler.common.ISourceLocation; import org.apache.flex.compiler.constants.IASKeywordConstants; import org.apache.flex.compiler.constants.IASLanguageConstants; import org.apache.flex.compiler.definitions.IClassDefinition; @@ -58,6 +60,7 @@ import org.apache.flex.compiler.internal.codegen.js.jx.BindableEmitter; import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter; import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils; import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter; +import org.apache.flex.compiler.internal.driver.js.flexjs.JSCSSCompilationSession; import org.apache.flex.compiler.internal.projects.FlexJSProject; import org.apache.flex.compiler.internal.projects.FlexProject; import org.apache.flex.compiler.internal.scopes.ASProjectScope; @@ -81,12 +84,13 @@ import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker; import org.apache.flex.swc.ISWC; import com.google.common.base.Joiner; +import com.google.debugging.sourcemap.FilePosition; /** * @author Erik de Bruin */ public class MXMLFlexJSEmitter extends MXMLEmitter implements - IMXMLFlexJSEmitter + IMXMLFlexJSEmitter, IMappingEmitter { // the instances in a container @@ -130,10 +134,20 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements * deferred instance = local3[ nodeToIndexMap.get(an instance) ] */ protected Map<IMXMLNode, Integer> nodeToIndexMap; + + private SourceMapMapping lastMapping; + + private List<SourceMapMapping> sourceMapMappings; + + public List<SourceMapMapping> getSourceMapMappings() + { + return sourceMapMappings; + } public MXMLFlexJSEmitter(FilterWriter out) { super(out); + sourceMapMappings = new ArrayList<SourceMapMapping>(); } @Override @@ -163,8 +177,10 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements boolean stillSearching = true; ArrayList<String> namesToAdd = new ArrayList<String>(); ArrayList<String> foundRequires = new ArrayList<String>(); - for (String line : lines) - { + int len = lines.length; + for (int i = 0; i < len; i++) + { + String line = lines[i]; if (stillSearching) { int c = line.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()); @@ -179,7 +195,10 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements sawRequires = true; foundRequires.add(s); if (!usedNames.contains(s)) - continue; + { + removeLineFromMappings(i); + continue; + } } else if (sawRequires) { @@ -202,8 +221,8 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements } for (String nameToAdd : namesToAdd) { - //System.out.println("adding late requires:"+nameToAdd); finalLines.add(createRequireLine(nameToAdd,false)); + addLineToMappings(i); } endRequires = finalLines.size(); @@ -223,7 +242,8 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken()); appendString.append(ASEmitterTokens.SEMICOLON.getToken()); finalLines.add(endRequires, appendString.toString()); - // TODO (aharui) addLineToMappings(finalLines.size()); + addLineToMappings(endRequires); + endRequires++; } // append info() structure if main CU ICompilerProject project = getMXMLWalker().getProject(); @@ -265,12 +285,12 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements appendString.append(ASEmitterTokens.PAREN_CLOSE.getToken()); appendString.append(ASEmitterTokens.SEMICOLON.getToken()); finalLines.add(endRequires, appendString.toString()); - //addLineToMappings(finalLines.size()); + addLineToMappings(endRequires); + endRequires++; } mixinInject += "]"; infoInject += mixinInject; sep = ",\n"; - //addLineToMappings(finalLines.size()); } boolean isMX = false; List<ISWC> swcs = flexJSProject.getLibraries(); @@ -303,11 +323,154 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements } infoInject += "}};"; finalLines.add(infoInject); + int newLineIndex = 0; + while((newLineIndex = infoInject.indexOf('\n', newLineIndex)) != -1) + { + addLineToMappings(finalLines.size()); + newLineIndex++; + } + + String cssInject = "\n\n" + thisDef + ".prototype.cssData = ["; + JSCSSCompilationSession cssSession = (JSCSSCompilationSession) flexJSProject.getCSSCompilationSession(); + String s = cssSession.getEncodedCSS(); + if (s != null) + { + int reqidx = s.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()); + if (reqidx != -1) + { + String cssRequires = s.substring(reqidx); + s = s.substring(0, reqidx - 1); + String[] cssRequireLines = cssRequires.split("\n"); + for(String require : cssRequireLines) + { + finalLines.add(endRequires, require); + addLineToMappings(endRequires); + endRequires++; + } + } + cssInject += s; + finalLines.add(cssInject); + newLineIndex = 0; + while((newLineIndex = cssInject.indexOf('\n', newLineIndex)) != -1) + { + addLineToMappings(finalLines.size()); + newLineIndex++; + } + } } } } + return Joiner.on("\n").join(finalLines); } + + public void startMapping(ISourceLocation node) + { + startMapping(node, node.getLine(), node.getColumn()); + } + + public void startMapping(ISourceLocation node, int line, int column) + { + if (isBufferWrite()) + { + return; + } + 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, line, column); + return; + } + } + } + + SourceMapMapping mapping = new SourceMapMapping(); + mapping.sourcePath = sourcePath; + mapping.sourceStartPosition = new FilePosition(line, column); + mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn()); + lastMapping = mapping; + } + + public void startMapping(ISourceLocation node, ISourceLocation afterNode) + { + startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn()); + } + + public void endMapping(ISourceLocation node) + { + if (isBufferWrite()) + { + return; + } + 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; + } + + /** + * Adjusts the line numbers saved in the source map when a line should be + * added during post processing. + * + * @param lineIndex + */ + protected void addLineToMappings(int lineIndex) + { + for (SourceMapMapping mapping : sourceMapMappings) + { + FilePosition destStartPosition = mapping.destStartPosition; + int startLine = destStartPosition.getLine(); + if(startLine > lineIndex) + { + mapping.destStartPosition = new FilePosition(startLine + 1, destStartPosition.getColumn()); + FilePosition destEndPosition = mapping.destEndPosition; + mapping.destEndPosition = new FilePosition(destEndPosition.getLine() + 1, destEndPosition.getColumn()); + } + } + } + + /** + * Adjusts the line numbers saved in the source map when a line should be + * removed during post processing. + * + * @param lineIndex + */ + protected void removeLineFromMappings(int lineIndex) + { + for (SourceMapMapping mapping : sourceMapMappings) + { + FilePosition destStartPosition = mapping.destStartPosition; + int startLine = destStartPosition.getLine(); + if(startLine > lineIndex) + { + mapping.destStartPosition = new FilePosition(startLine - 1, destStartPosition.getColumn()); + FilePosition destEndPosition = mapping.destEndPosition; + mapping.destEndPosition = new FilePosition(destEndPosition.getLine() - 1, destEndPosition.getColumn()); + } + } + } @Override protected String getIndent(int numIndent) http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java index 3b11121..a614592 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java @@ -249,10 +249,6 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements IJSPublisher ///////////////////////////////////////////////////////////////////////////////// final File projectIntermediateMainFile = new File(intermediateDir, outputFileName); - if (!googConfiguration.getSkipTranspile()) - { - appendEncodedCSS(projectIntermediateMainFile, projectName); - } ///////////////////////////////////////////////////////////////////////////////// @@ -381,36 +377,6 @@ public class MXMLFlexJSPublisher extends JSGoogPublisher implements IJSPublisher return true; } - private void appendEncodedCSS(File targetFile, String projectName) throws IOException - { - StringBuilder appendString = new StringBuilder(); - appendString.append("\n\n"); - appendString.append(projectName); - appendString.append(".prototype.cssData = ["); - JSCSSCompilationSession cssSession = (JSCSSCompilationSession) project.getCSSCompilationSession(); - String s = cssSession.getEncodedCSS(); - if (s != null) - { - int reqidx = s.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()); - if (reqidx != -1) - { - String reqs = s.substring(reqidx); - s = s.substring(0, reqidx - 1); - String fileData = readCode(targetFile); - reqidx = fileData.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken()); - String after = fileData.substring(reqidx); - String before = fileData.substring(0, reqidx - 1); - s = before + reqs + after + appendString.toString() + s; - writeFile(targetFile, s, false); - } - else - { - appendString.append(s); - writeFile(targetFile, appendString.toString(), true); - } - } - } - protected List<SourceFile> closureFilesInOrder(String path, List<SourceFile> files, String entryPoint) { ArrayList<String> sortedFiles = new ArrayList<String>(); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/JSBackend.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/JSBackend.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/JSBackend.java index 9d6eb66..502609d 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/JSBackend.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/JSBackend.java @@ -29,6 +29,7 @@ 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; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter; import org.apache.flex.compiler.config.Configuration; import org.apache.flex.compiler.config.Configurator; @@ -139,7 +140,7 @@ public class JSBackend implements IJSBackend } @Override - public ISourceMapEmitter createSourceMapEmitter(IJSEmitter emitter) + public ISourceMapEmitter createSourceMapEmitter(IMappingEmitter emitter) { return new JSSourceMapEmitter(emitter); } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3ab47113/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/SourceMapTestBase.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/SourceMapTestBase.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/SourceMapTestBase.java index 783a340..c8a6cb7 100644 --- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/SourceMapTestBase.java +++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/SourceMapTestBase.java @@ -21,6 +21,7 @@ package org.apache.flex.compiler.internal.test; import java.util.List; import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.codegen.js.IMappingEmitter; import org.apache.flex.compiler.tree.as.IASNode; import com.google.debugging.sourcemap.FilePosition; @@ -48,8 +49,8 @@ public class SourceMapTestBase extends ASTestBase sourceStartColumn += node.getColumn(); } boolean foundMapping = false; - List<IJSEmitter.SourceMapMapping> mappings = jsEmitter.getSourceMapMappings(); - for (IJSEmitter.SourceMapMapping mapping : mappings) + List<IMappingEmitter.SourceMapMapping> mappings = jsEmitter.getSourceMapMappings(); + for (IMappingEmitter.SourceMapMapping mapping : mappings) { FilePosition sourcePosition = mapping.sourceStartPosition; FilePosition startPosition = mapping.destStartPosition;
