This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git


The following commit(s) were added to refs/heads/develop by this push:
     new 3ceee57  JSConfiguration: add new --source-map-source-root compiler 
option
3ceee57 is described below

commit 3ceee572c331770f3852a7b77c5e5c5c2f414909
Author: Josh Tynjala <[email protected]>
AuthorDate: Wed Oct 28 14:35:06 2020 -0700

    JSConfiguration: add new --source-map-source-root compiler option
    
    In source maps, instead of using the relative path from the original 
AS/MXML source files to the generated JS files, allows an optional custom path 
where all of the original source files may be found. In other words, allows the 
original source files to be moved from their original location at compile-time 
to a new location during debugging.
---
 .../royale/compiler/clients/JSConfiguration.java   |  19 ++
 .../compiler/internal/graph/GoogDepsWriter.java    | 327 ++++++---------------
 .../royale/compiler/utils/SourceMapUtils.java      | 257 ++++++++++++++++
 3 files changed, 373 insertions(+), 230 deletions(-)

diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
index 938a9f3..874fdea 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/JSConfiguration.java
@@ -133,6 +133,25 @@ public class JSConfiguration extends Configuration
     }
 
     //
+    // 'source-map-source-root'
+    //
+
+    private String sourceMapSourceRoot = null;
+
+    public String getSourceMapSourceRoot()
+    {
+        return sourceMapSourceRoot;
+    }
+
+    @Config
+    @Mapping("source-map-source-root")
+    public void setSourceMapSourceRoot(ConfigurationValue cv, String value)
+            throws ConfigurationException
+    {
+        sourceMapSourceRoot = value;
+    }
+
+    //
     // 'js-default-initializers'
     //
 
diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
index da29ceb..5f2f828 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/graph/GoogDepsWriter.java
@@ -50,6 +50,7 @@ import 
org.apache.royale.compiler.problems.FileNotFoundProblem;
 import org.apache.royale.compiler.problems.MainDefinitionQNameProblem;
 import org.apache.royale.compiler.problems.UnexpectedExceptionProblem;
 import org.apache.royale.compiler.units.ICompilationUnit;
+import org.apache.royale.compiler.utils.SourceMapUtils;
 import org.apache.royale.swc.ISWC;
 import org.apache.royale.swc.ISWCFileEntry;
 
@@ -68,6 +69,7 @@ public class GoogDepsWriter {
                this.mainName = mainClassName;
                removeCirculars = config.getRemoveCirculars();
                sourceMaps = config.getSourceMap();
+               sourceMapsSourceRoot = config.getSourceMapSourceRoot();
                otherPaths = config.getSDKJSLib();
                verbose = config.isVerbose();
                otherPaths.add(new File(outputFolder.getParent(), 
"royale/Royale/src").getPath());
@@ -89,6 +91,7 @@ public class GoogDepsWriter {
        private List<ISWC> swcs;
        private boolean removeCirculars = false;
        private boolean sourceMaps = false;
+       private String sourceMapsSourceRoot = null;
        private boolean verbose = false;
        private ArrayList<GoogDep> dps;
        private DependencyGraph graph;
@@ -122,7 +125,12 @@ public class GoogDepsWriter {
                        else
                                files.add(gd.filePath);
                        visited.put(gd.className, gd);
+                       if(sourceMaps && sourceMapsSourceRoot != null)
+                       {
+                               rewriteSourceMapSourceRoot(gd);
+                       }
                }
+               rewriteSourceMapSourceRoot(depMap.get(mainName));
                if (removeCirculars)
                {
                        GoogDep mainDep = depMap.get(mainName);
@@ -141,6 +149,55 @@ public class GoogDepsWriter {
                }
                return files;
        }
+
+       private void rewriteSourceMapSourceRoot(GoogDep gd)
+       {
+               if (!sourceMaps || sourceMapsSourceRoot == null || 
sourceMapsSourceRoot.length() == 0)
+               {
+                       return;
+               }
+               File sourceMapFile = new File(gd.filePath + ".map");
+               if (!sourceMapFile.exists())
+               {
+                       return;
+               }
+               String sourceMapContents = null;
+               try
+               {
+                       sourceMapContents = 
FileUtils.readFileToString(sourceMapFile, Charset.forName("utf8"));
+               }
+               catch(IOException e)
+               {
+                       return;
+               }
+               SourceMapConsumerV3 sourceMapConsumer = new 
SourceMapConsumerV3();
+               try
+               {
+                       sourceMapConsumer.parse(sourceMapContents);
+               }
+               catch(SourceMapParseException e)
+               {
+                       sourceMapConsumer = null;
+               }
+               if (sourceMapConsumer != null)
+               {
+                       if 
(sourceMapsSourceRoot.equals(sourceMapConsumer.getSourceRoot()))
+                       {
+                               //no need to rewrite
+                               return;
+                       }
+                       SourceMapGeneratorV3 sourceMapGenerator = 
SourceMapUtils.sourceMapConsumerToGeneratorWithRemappedSourceRoot(sourceMapConsumer,
 sourceMapsSourceRoot, gd.className);
+                       String newSourceMapContents = 
SourceMapUtils.sourceMapGeneratorToString(sourceMapGenerator, new 
File(gd.filePath).getName());
+                       try
+                       {
+                               FileUtils.write(sourceMapFile, 
newSourceMapContents, "utf8");
+                       }
+                       catch(IOException e)
+                       {
+                               return;
+                       }
+               }
+       }
        
        public String generateDeps(CompilerProject project, ProblemQuery 
problems) throws FileNotFoundException
        {
@@ -588,7 +645,7 @@ public class GoogDepsWriter {
                 if (!isGoogProvided(s))
                 {
                        fileLines.remove(j);
-                                       sourceMapConsumer = 
removeLineFromSourceMap(sourceMapConsumer, mainFile.getName(), j);
+                                       sourceMapConsumer = 
SourceMapUtils.removeLineFromSourceMap(sourceMapConsumer, mainFile.getName(), 
j);
                 }
                                else
                                {
@@ -606,15 +663,15 @@ public class GoogDepsWriter {
                                        .append(dep)
                                        .append("');");
                                fileLines.add(main.fileInfo.googProvideLine + 
1, lineBuilder.toString());
-                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, mainFile.getName(), 
main.fileInfo.googProvideLine + 1);
+                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, mainFile.getName(), 
main.fileInfo.googProvideLine + 1);
                        }
 
                        FileUtils.writeLines(mainFile, "utf8", fileLines);
 
                        if (sourceMapConsumer != null)
                        {
-                               String newSourceMap = 
sourceMapConsumerToString(sourceMapConsumer, mainFile.getName());
-                               FileUtils.write(sourceMapFile, newSourceMap, 
"utf8");
+                               String newSourceMapContents = 
SourceMapUtils.sourceMapConsumerToString(sourceMapConsumer, mainFile.getName());
+                               FileUtils.write(sourceMapFile, 
newSourceMapContents, "utf8");
                        }
                } catch (IOException e) {
                        // TODO Auto-generated catch block
@@ -759,7 +816,7 @@ public class GoogDepsWriter {
                                        sb.append(",");
                                sb.append(s);
                                                        firstDependency = false;
-                                                       sourceMapConsumer = 
removeLineFromSourceMap(sourceMapConsumer, depFile.getName(), 
finalLines.size());
+                                                       sourceMapConsumer = 
SourceMapUtils.removeLineFromSourceMap(sourceMapConsumer, depFile.getName(), 
finalLines.size());
                                continue;
                            }
                         else
@@ -788,7 +845,7 @@ public class GoogDepsWriter {
                                                        .append(dep)
                                                        .append("');");
                                finalLines.add(lastRequireLine++, 
lineBuilder.toString());
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, new File(gd.filePath).getName(), 
lastRequireLine);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, new 
File(gd.filePath).getName(), lastRequireLine);
                                if (verbose)
                                                {
                                                        
System.out.println("adding require for static dependency " + dep + " to " + 
className);
@@ -825,7 +882,7 @@ public class GoogDepsWriter {
                                {
                                        // there is already a fileOverview but 
no @suppress
                                        finalLines.add(fi.fileoverviewLine + 1, 
" *  @suppress {missingRequire}");
-                                                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.fileoverviewLine + 
1);
+                                                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.fileoverviewLine + 1);
                                }
                                else if (fi.googProvideLine > -1)
                                {
@@ -833,10 +890,10 @@ public class GoogDepsWriter {
                                        finalLines.add(fi.googProvideLine, " *  
@suppress {missingRequire}");
                                        finalLines.add(fi.googProvideLine, " *  
@fileoverview");
                                        finalLines.add(fi.googProvideLine, 
"/**");
-                                                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
+                                                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
                                }
                                else
                                {
@@ -850,7 +907,7 @@ public class GoogDepsWriter {
                        {
                                // there is already a fileoverview but no 
@suppress
                                finalLines.add(fi.fileoverviewLine + 1, " *  
@suppress {missingRequire}");
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.fileoverviewLine + 
1);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.fileoverviewLine + 1);
                        }
                        else if (fi.googProvideLine > -1)
                        {
@@ -858,10 +915,10 @@ public class GoogDepsWriter {
                                finalLines.add(fi.googProvideLine, " *  
@suppress {missingRequire}");
                                finalLines.add(fi.googProvideLine, " *  
@fileoverview");
                                finalLines.add(fi.googProvideLine, "/**");
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
-                                               sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), fi.googProvideLine);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
+                                               sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
fi.googProvideLine);
                        }
                        else
                        {
@@ -872,14 +929,14 @@ public class GoogDepsWriter {
 
             sb.append("*/");
             finalLines.add(gd.fileInfo.googProvideLine + 1, sb.toString());
-                       sourceMapConsumer = 
addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
gd.fileInfo.googProvideLine + 1);
+                       sourceMapConsumer = 
SourceMapUtils.addLineToSourceMap(sourceMapConsumer, depFile.getName(), 
gd.fileInfo.googProvideLine + 1);
 
                        FileUtils.writeLines(depFile, "utf8", finalLines);
 
                        if (sourceMapConsumer != null)
                        {
-                               String newSourceMap = 
sourceMapConsumerToString(sourceMapConsumer, depFile.getName());
-                               FileUtils.write(sourceMapFile, newSourceMap, 
"utf8");
+                               String newSourceMapContents = 
SourceMapUtils.sourceMapConsumerToString(sourceMapConsumer, depFile.getName());
+                               FileUtils.write(sourceMapFile, 
newSourceMapContents, "utf8");
                        }
         }
         catch (IOException e)
@@ -887,187 +944,6 @@ public class GoogDepsWriter {
             e.printStackTrace();
         }              
        }
-
-       String sourceMapConsumerToString(SourceMapConsumerV3 consumer, String 
file)
-       {
-               SourceMapGeneratorV3 generator = 
sourceMapConsumerToGenerator(consumer);
-               StringBuilder builder = new StringBuilder();
-               try
-               {
-                       generator.appendTo(builder, file);
-               }
-               catch(IOException e)
-               {
-                       return "";
-               }
-               return builder.toString();
-       }
-
-       private void appendExtraMappingToGenerator(SourceMapGeneratorV3 
generator,
-               String sourceName,
-               String symbolName,
-               FilePosition sourceStartPosition,
-               FilePosition startPosition,
-               FilePosition endPosition)
-       {
-               //add an extra mapping because there seems to be a bug in
-               //SourceMapGeneratorV3's appendTo() that omits the last
-               //entry, for some reason
-               FilePosition newEndPosition = new 
FilePosition(endPosition.getLine(), endPosition.getColumn() + 1);
-               generator.addMapping(sourceName, null, sourceStartPosition, 
endPosition, newEndPosition);
-       }
-
-       private SourceMapGeneratorV3 
sourceMapConsumerToGenerator(SourceMapConsumerV3 consumer)
-       {
-               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
-               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
-               generator.setSourceRoot(consumer.getSourceRoot());
-               consumer.visitMappings(counter);
-               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
-               {
-                       private int index = 0;
-
-                       @Override
-                       public void visit(String sourceName,
-                               String symbolName,
-                               FilePosition sourceStartPosition,
-                               FilePosition startPosition,
-                               FilePosition endPosition) {
-                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               index++;
-                               if(index == counter.count)
-                               {
-                                       //add an extra mapping because there 
seems to be a bug in
-                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
-                                       //entry, for some reason
-                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               }
-                       }
-               });
-               return generator;
-       }
-
-       class SourceMapEntryCounter implements SourceMapConsumerV3.EntryVisitor
-       {
-               private int count = 0;
-
-               @Override
-               public void visit(String sourceName,
-                       String symbolName,
-                       FilePosition sourceStartPosition,
-                       FilePosition startPosition,
-                       FilePosition endPosition) {
-                       count++;
-               }
-       }
-
-       SourceMapConsumerV3 sourceMapGeneratorToConsumer(SourceMapGeneratorV3 
generator, String fileName)
-       {
-               StringBuilder builder = new StringBuilder();
-               try
-               {
-                       generator.appendTo(builder, fileName);
-               }
-               catch(IOException e)
-               {
-                       return null;
-               }
-               SourceMapConsumerV3 consumer = new SourceMapConsumerV3();
-               try
-               {
-                       consumer.parse(builder.toString());
-               }
-               catch(SourceMapParseException e)
-               {
-                       return null;
-               }
-               return consumer;
-       }
-
-       SourceMapConsumerV3 addLineToSourceMap(SourceMapConsumerV3 consumer, 
String sourceFileName, final int lineToAdd)
-       {
-               if (consumer == null)
-               {
-                       return null;
-               }
-               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
-               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
-               generator.setSourceRoot(consumer.getSourceRoot());
-               consumer.visitMappings(counter);
-               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
-               {
-                       private int index = 0;
-
-                       @Override
-                       public void visit(String sourceName,
-                               String symbolName,
-                               FilePosition sourceStartPosition,
-                               FilePosition startPosition,
-                               FilePosition endPosition) {
-                               if(startPosition.getLine() >= lineToAdd)
-                               {
-                                       startPosition = new 
FilePosition(startPosition.getLine() + 1, startPosition.getColumn());
-                                       endPosition = new 
FilePosition(endPosition.getLine() + 1, endPosition.getColumn());
-                               }
-                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               index++;
-                               if(index == counter.count)
-                               {
-                                       //add an extra mapping because there 
seems to be a bug in
-                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
-                                       //entry, for some reason
-                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               }
-                       }
-               });
-               return sourceMapGeneratorToConsumer(generator, sourceFileName);
-       }
-
-       SourceMapConsumerV3 removeLineFromSourceMap(SourceMapConsumerV3 
consumer, String sourceFileName, final int lineToRemove)
-       {
-               if (consumer == null)
-               {
-                       return null;
-               }
-               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
-               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
-               generator.setSourceRoot(consumer.getSourceRoot());
-               consumer.visitMappings(counter);
-               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
-               {
-                       private int index = 0;
-
-                       @Override
-                       public void visit(String sourceName,
-                               String symbolName,
-                               FilePosition sourceStartPosition,
-                               FilePosition startPosition,
-                               FilePosition endPosition) {
-                               if(startPosition.getLine() == lineToRemove)
-                               {
-                                       return;
-                               }
-                               if(startPosition.getLine() > lineToRemove)
-                               {
-                                       startPosition = new 
FilePosition(startPosition.getLine() - 1, startPosition.getColumn());
-                               }
-                               if(endPosition.getLine() > lineToRemove)
-                               {
-                                       endPosition = new 
FilePosition(endPosition.getLine() - 1, endPosition.getColumn());
-                               }
-                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               index++;
-                               if(index == counter.count)
-                               {
-                                       //add an extra mapping because there 
seems to be a bug in
-                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
-                                       //entry, for some reason
-                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
-                               }
-                       }
-               });
-               return sourceMapGeneratorToConsumer(generator, sourceFileName);
-       }
                
        FileInfo getFileInfo(List<String> lines, String className)
        {
@@ -1353,42 +1229,33 @@ public class GoogDepsWriter {
                                                        File sourceMapDestFile 
= new File(sourceMapFn);
                                                        inStream = 
sourceMapFileEntry.createInputStream();
                                                        String 
sourceMapContents = IOUtils.toString(inStream, Charset.forName("utf8"));
-                                                       SourceMapConsumerV3 
sourceMapConsumer = new SourceMapConsumerV3();
-                                                       try
-                                                       {
-                                                               
sourceMapConsumer.parse(sourceMapContents);
-                                                       }
-                                                       
catch(SourceMapParseException e)
+                                                       if 
(sourceMapsSourceRoot == null)
                                                        {
-                                                               
sourceMapConsumer = null;
-                                                       }
-                                                       if(sourceMapConsumer != 
null)
-                                                       {
-                                                               String 
sourceRoot = sourceMapConsumer.getSourceRoot();
-                                                               int index = 
sourceRoot.indexOf("/frameworks/js/projects/");
-                                                               if(index != -1)
+                                                               
SourceMapConsumerV3 sourceMapConsumer = new SourceMapConsumerV3();
+                                                               try
                                                                {
-                                                                       File 
royalelib = new File(System.getProperty("royalelib"));
-                                                                       File 
newSourceRoot = new File(royalelib.getParent(), sourceRoot.substring(index + 
1));
-                                                                       
SourceMapGeneratorV3 sourceMapGenerator = 
sourceMapConsumerToGenerator(sourceMapConsumer);
-                                                                       String 
newSourceRootUri = convertSourcePathToURI(newSourceRoot.getAbsolutePath());
-                                                                       
sourceMapGenerator.setSourceRoot(newSourceRootUri);
-                                                                       
StringBuilder builder = new StringBuilder();
-                                                                       try
-                                                                       {
-                                                                               
sourceMapGenerator.appendTo(builder, destFile.getName());
-                                                                       }
-                                                                       
catch(IOException e)
-                                                                       {
-                                                                               
return "";
-                                                                       }
-                                                                       
FileUtils.writeStringToFile(sourceMapDestFile, builder.toString(), 
Charset.forName("utf8"));
+                                                                       
sourceMapConsumer.parse(sourceMapContents);
                                                                }
-                                                               else
+                                                               
catch(SourceMapParseException e)
                                                                {
-                                                                       
FileUtils.writeStringToFile(sourceMapDestFile, sourceMapContents, 
Charset.forName("utf8"));
+                                                                       
sourceMapConsumer = null;
+                                                               }
+                                                               
if(sourceMapConsumer != null)
+                                                               {
+                                                                       String 
sourceRoot = sourceMapConsumer.getSourceRoot();
+                                                                       int 
index = sourceRoot.indexOf("/frameworks/js/projects/");
+                                                                       
if(index != -1)
+                                                                       {
+                                                                               
File royalelib = new File(System.getProperty("royalelib"));
+                                                                               
File newSourceRoot = new File(royalelib.getParent(), sourceRoot.substring(index 
+ 1));
+                                                                               
SourceMapGeneratorV3 sourceMapGenerator = 
SourceMapUtils.sourceMapConsumerToGenerator(sourceMapConsumer);
+                                                                               
String newSourceRootUri = 
convertSourcePathToURI(newSourceRoot.getAbsolutePath());
+                                                                               
sourceMapGenerator.setSourceRoot(newSourceRootUri);
+                                                                               
sourceMapContents = 
SourceMapUtils.sourceMapGeneratorToString(sourceMapGenerator, 
destFile.getName());
+                                                                       }
                                                                }
                                                        }
+                                                       
FileUtils.writeStringToFile(sourceMapDestFile, sourceMapContents, 
Charset.forName("utf8"));
                                                }
                                        }
 
diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java
new file mode 100644
index 0000000..ba2d9bb
--- /dev/null
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java
@@ -0,0 +1,257 @@
+/*
+ *
+ *  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.royale.compiler.utils;
+
+import java.io.IOException;
+
+import com.google.debugging.sourcemap.FilePosition;
+import com.google.debugging.sourcemap.SourceMapConsumerV3;
+import com.google.debugging.sourcemap.SourceMapGeneratorV3;
+import com.google.debugging.sourcemap.SourceMapParseException;
+
+public class SourceMapUtils
+{
+       public static String sourceMapConsumerToString(SourceMapConsumerV3 
consumer, String file)
+       {
+               SourceMapGeneratorV3 generator = 
sourceMapConsumerToGenerator(consumer);
+               StringBuilder builder = new StringBuilder();
+               try
+               {
+                       generator.appendTo(builder, file);
+               }
+               catch(IOException e)
+               {
+                       return "";
+               }
+               return builder.toString();
+       }
+
+       public static SourceMapGeneratorV3 
sourceMapConsumerToGenerator(SourceMapConsumerV3 consumer)
+       {
+               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
+               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
+               generator.setSourceRoot(consumer.getSourceRoot());
+               consumer.visitMappings(counter);
+               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
+               {
+                       private int index = 0;
+
+                       @Override
+                       public void visit(String sourceName,
+                               String symbolName,
+                               FilePosition sourceStartPosition,
+                               FilePosition startPosition,
+                               FilePosition endPosition) {
+                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               index++;
+                               if(index == counter.count)
+                               {
+                                       //add an extra mapping because there 
seems to be a bug in
+                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
+                                       //entry, for some reason
+                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               }
+                       }
+               });
+               return generator;
+       }
+
+       public static SourceMapGeneratorV3 
sourceMapConsumerToGeneratorWithRemappedSourceRoot(SourceMapConsumerV3 
consumer, String sourceRoot, String className)
+       {
+               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
+               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
+               final String startPath = "/" + className.replace(".", "/") + 
".";
+               generator.setSourceRoot(sourceRoot);
+               consumer.visitMappings(counter);
+               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
+               {
+                       private int index = 0;
+
+                       @Override
+                       public void visit(String sourceName,
+                                       String symbolName,
+                                       FilePosition sourceStartPosition,
+                                       FilePosition startPosition,
+                                       FilePosition endPosition) {
+                               String newSourceName = sourceName;
+                               int startPathIndex = 
newSourceName.indexOf(startPath);
+                               if(startPathIndex != -1)
+                               {
+                                       newSourceName = 
newSourceName.substring(startPathIndex + 1);
+                               }
+                               generator.addMapping(newSourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               index++;
+                               if(index == counter.count)
+                               {
+                                       //add an extra mapping because there 
seems to be a bug in
+                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
+                                       //entry, for some reason
+                                       
appendExtraMappingToGenerator(generator, newSourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               }
+                       }
+               });
+               return generator;
+       }
+
+       public static SourceMapConsumerV3 
addLineToSourceMap(SourceMapConsumerV3 consumer, String sourceFileName, final 
int lineToAdd)
+       {
+               if (consumer == null)
+               {
+                       return null;
+               }
+               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
+               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
+               generator.setSourceRoot(consumer.getSourceRoot());
+               consumer.visitMappings(counter);
+               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
+               {
+                       private int index = 0;
+
+                       @Override
+                       public void visit(String sourceName,
+                               String symbolName,
+                               FilePosition sourceStartPosition,
+                               FilePosition startPosition,
+                               FilePosition endPosition) {
+                               if(startPosition.getLine() >= lineToAdd)
+                               {
+                                       startPosition = new 
FilePosition(startPosition.getLine() + 1, startPosition.getColumn());
+                                       endPosition = new 
FilePosition(endPosition.getLine() + 1, endPosition.getColumn());
+                               }
+                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               index++;
+                               if(index == counter.count)
+                               {
+                                       //add an extra mapping because there 
seems to be a bug in
+                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
+                                       //entry, for some reason
+                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               }
+                       }
+               });
+               return sourceMapGeneratorToConsumer(generator, sourceFileName);
+       }
+
+       public static SourceMapConsumerV3 
removeLineFromSourceMap(SourceMapConsumerV3 consumer, String sourceFileName, 
final int lineToRemove)
+       {
+               if (consumer == null)
+               {
+                       return null;
+               }
+               final SourceMapGeneratorV3 generator = new 
SourceMapGeneratorV3();
+               final SourceMapEntryCounter counter = new 
SourceMapEntryCounter();
+               generator.setSourceRoot(consumer.getSourceRoot());
+               consumer.visitMappings(counter);
+               consumer.visitMappings(new SourceMapConsumerV3.EntryVisitor()
+               {
+                       private int index = 0;
+
+                       @Override
+                       public void visit(String sourceName,
+                               String symbolName,
+                               FilePosition sourceStartPosition,
+                               FilePosition startPosition,
+                               FilePosition endPosition) {
+                               if(startPosition.getLine() == lineToRemove)
+                               {
+                                       return;
+                               }
+                               if(startPosition.getLine() > lineToRemove)
+                               {
+                                       startPosition = new 
FilePosition(startPosition.getLine() - 1, startPosition.getColumn());
+                               }
+                               if(endPosition.getLine() > lineToRemove)
+                               {
+                                       endPosition = new 
FilePosition(endPosition.getLine() - 1, endPosition.getColumn());
+                               }
+                               generator.addMapping(sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               index++;
+                               if(index == counter.count)
+                               {
+                                       //add an extra mapping because there 
seems to be a bug in
+                                       //SourceMapGeneratorV3's appendTo() 
that omits the last
+                                       //entry, for some reason
+                                       
appendExtraMappingToGenerator(generator, sourceName, symbolName, 
sourceStartPosition, startPosition, endPosition);
+                               }
+                       }
+               });
+               return sourceMapGeneratorToConsumer(generator, sourceFileName);
+       }
+
+       private static void appendExtraMappingToGenerator(SourceMapGeneratorV3 
generator,
+               String sourceName,
+               String symbolName,
+               FilePosition sourceStartPosition,
+               FilePosition startPosition,
+               FilePosition endPosition)
+       {
+               //add an extra mapping because there seems to be a bug in
+               //SourceMapGeneratorV3's appendTo() that omits the last
+               //entry, for some reason
+               FilePosition newEndPosition = new 
FilePosition(endPosition.getLine(), endPosition.getColumn() + 1);
+               generator.addMapping(sourceName, null, sourceStartPosition, 
endPosition, newEndPosition);
+       }
+
+       private static class SourceMapEntryCounter implements 
SourceMapConsumerV3.EntryVisitor
+       {
+               private int count = 0;
+
+               @Override
+               public void visit(String sourceName,
+                       String symbolName,
+                       FilePosition sourceStartPosition,
+                       FilePosition startPosition,
+                       FilePosition endPosition) {
+                       count++;
+               }
+       }
+
+       public static String sourceMapGeneratorToString(SourceMapGeneratorV3 
generator, String fileName)
+       {
+               StringBuilder builder = new StringBuilder();
+               try
+               {
+                       generator.appendTo(builder, fileName);
+               }
+               catch(IOException e)
+               {
+                       return null;
+               }
+               return builder.toString();
+       }
+
+       public static SourceMapConsumerV3 
sourceMapGeneratorToConsumer(SourceMapGeneratorV3 generator, String fileName)
+       {
+               String generatorString = sourceMapGeneratorToString(generator, 
fileName);
+               if(generatorString == null)
+               {
+                       return null;
+               }
+               SourceMapConsumerV3 consumer = new SourceMapConsumerV3();
+               try
+               {
+                       consumer.parse(generatorString);
+               }
+               catch(SourceMapParseException e)
+               {
+                       return null;
+               }
+               return consumer;
+       }
+}

Reply via email to