From 8013b23d33271f571e2f3367fd98da4343251df6 Mon Sep 17 00:00:00 2001 From: Chad Killingsworth Date: Tue, 22 May 2018 11:32:49 -0700 Subject: [PATCH] When composing source maps, use the original mapping even if the source file cannot be located Closes https://github.com/google/closure-compiler/pull/2921 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=197595899 --- .../google/javascript/jscomp/Compiler.java | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/com/google/javascript/jscomp/Compiler.java b/src/com/google/javascript/jscomp/Compiler.java index 79398dd97f2..4eb9cfaae76 100644 --- a/src/com/google/javascript/jscomp/Compiler.java +++ b/src/com/google/javascript/jscomp/Compiler.java @@ -69,6 +69,7 @@ import java.io.Serializable; import java.util.AbstractSet; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -2928,18 +2929,23 @@ public OriginalMapping getSourceMapping(String sourceName, int lineNumber, int c return null; } - // The sourcemap will return a path relative to the sourcemap's file. - // Translate it to one relative to our base directory. - SourceFile source = - SourceMapResolver.getRelativePath(sourceMap.getOriginalPath(), result.getOriginalFile()); + // First check to see if the original file was loaded from an input source map. + String sourceMapOriginalPath = sourceMap.getOriginalPath(); + String resultOriginalPath = result.getOriginalFile(); + String relativePath = resolveSibling(sourceMapOriginalPath, resultOriginalPath); + + SourceFile source = getSourceFileByName(relativePath); if (source == null) { - return null; + source = + SourceMapResolver.getRelativePath(sourceMap.getOriginalPath(), result.getOriginalFile()); + if (source != null) { + sourceMapOriginalSources.putIfAbsent(relativePath, source); + } } - String originalPath = source.getOriginalPath(); - sourceMapOriginalSources.putIfAbsent(originalPath, source); + return result .toBuilder() - .setOriginalFile(originalPath) + .setOriginalFile(relativePath) .setColumnPosition(result.getColumnPosition() - 1) .build(); } @@ -3711,4 +3717,33 @@ public CompilerState call() throws Exception { CompilerInput.ModuleType getModuleTypeByName(String moduleName) { return moduleTypesByName.get(moduleName); } + + /** + * Simplistic implementation of the java.nio.file.Path resolveSibling method that works + * with GWT. + * + * @param path1 from path - must be a file (not directory) + * @param path2 to path - must be a file (not directory) + */ + private static String resolveSibling(String path1, String path2) { + List path1Parts = new ArrayList<>(Arrays.asList(path1.split("/"))); + List path2Parts = new ArrayList<>(Arrays.asList(path2.split("/"))); + if (path1Parts.size() > 0) { + path1Parts.remove(path1Parts.size() - 1); + } + + while (path1Parts.size() > 0 && path2Parts.size() > 0) { + if (path2Parts.get(0).equals(".")) { + path2Parts.remove(0); + } else if (path2Parts.get(0).equals("..")) { + path2Parts.remove(0); + path1Parts.remove(path1Parts.size() - 1); + } else { + break; + } + } + + path1Parts.addAll(path2Parts); + return String.join("/", path1Parts); + } }