completeMappings = new ArrayList<>(allMappings.size());
+ for (Mapping mapping : allMappings) {
+ // If the node does not have an associated source file or source location
+ // is unknown, then the node does not have sufficient info for source map.
+ if (mapping.node.getSourceCodeLocation().isUnknown()) {
+ continue;
+ }
+ CompleteMapping completeMapping = new CompleteMapping(mapping);
+ if (completeMapping.sourceFile == null) {
+ continue;
+ }
+ completeMappings.add(completeMapping);
+ }
+ Collections.sort(completeMappings);
+ for (CompleteMapping completeMapping : completeMappings) {
+ // TODO: could pass in an optional symbol name
+ generator.addMapping(
+ completeMapping.sourceFile, null,
+ completeMapping.inputStart,
+ completeMapping.outputStart, completeMapping.outputEnd);
+ }
}
- /**
- * Gets the start line index in the source code of {@code node} adjusted to 0-based indices.
- *
- * Notes: Gss compiler uses a 1-based line number and source map V3 uses a 0-based line number.
- */
- private int getStartLineno(CssNode node) {
- return node.getSourceCodeLocation().getLineNumber() - 1;
- }
- /**
- * Gets the start character index in the output buffer for current {@code node}.
- */
- private int getStartCharIndex(CssNode node) {
- return node.getSourceCodeLocation().getCharacterIndex();
- }
+ private static final class CompleteMapping implements Comparable {
+ final String sourceFile;
+ final FilePosition inputStart;
+ final FilePosition outputStart;
+ final FilePosition outputEnd;
- /**
- * Generates the source map by passing all mappings to {@link #generator}.
- */
- private void generateSourceMap(){
- for (Mapping mapping : allMappings) {
- addMapping(mapping);
+ CompleteMapping(Mapping mapping) {
+ CssNode node = mapping.node;
+ this.sourceFile = getSourceFileName(node);
+ this.inputStart = new FilePosition(
+ getStartLineno(node), getStartCharIndex(node));
+ this.outputStart = mapping.start;
+ this.outputEnd = mapping.end;
+ }
+
+ @Override
+ public int compareTo(CompleteMapping m) {
+ int delta = outputStart.getLine() - m.outputStart.getLine();
+ if (delta == 0) {
+ delta = outputStart.getColumn() - m.outputStart.getColumn();
+ }
+ return delta;
+ }
+
+ /**
+ * Gets the source file file for current node.
+ */
+ private static String getSourceFileName(CssNode node) {
+ return node.getSourceCodeLocation().getSourceCode().getFileName();
+ }
+
+ /**
+ * Gets the start line index in the source code of {@code node} adjusted to 0-based indices.
+ *
+ *
+ * Note: Gss compiler uses a 1-based line number and source map V3 uses a 0-based line number.
+ */
+ private static int getStartLineno(CssNode node) {
+ return node.getSourceCodeLocation().getLineNumber() - 1;
+ }
+
+ /**
+ * Gets the start character index in the output buffer for current {@code node}.
+ */
+ private static int getStartCharIndex(CssNode node) {
+ return node.getSourceCodeLocation().getCharacterIndex();
}
}
}
diff --git a/src/com/google/common/css/compiler/passes/ProcessComponents.java b/src/com/google/common/css/compiler/passes/ProcessComponents.java
index d620dffb..2d5a04d0 100644
--- a/src/com/google/common/css/compiler/passes/ProcessComponents.java
+++ b/src/com/google/common/css/compiler/passes/ProcessComponents.java
@@ -219,6 +219,7 @@ private List transformNodes(
Set constants, CssComponentNode target, CssComponentNode source) {
CssBlockNode sourceBlock = source.getBlock();
CssBlockNode copyBlock = new CssBlockNode(false, sourceBlock.deepCopy().getChildren());
+ copyBlock.setSourceCodeLocation(source.getBlock().getSourceCodeLocation());
CssTree tree = new CssTree(
target.getSourceCodeLocation().getSourceCode(), new CssRootNode(copyBlock));
new TransformNodes(constants, target, target != source,
diff --git a/src/com/google/common/css/compiler/passes/SplitRulesetNodes.java b/src/com/google/common/css/compiler/passes/SplitRulesetNodes.java
index 685d15c8..87c5d3f4 100644
--- a/src/com/google/common/css/compiler/passes/SplitRulesetNodes.java
+++ b/src/com/google/common/css/compiler/passes/SplitRulesetNodes.java
@@ -61,6 +61,7 @@ public boolean enterRuleset(CssRulesetNode node) {
for (CssSelectorNode sel : selectors.childIterable()) {
for (CssNode child : declarations.childIterable()) {
CssRulesetNode ruleset = new CssRulesetNode();
+ ruleset.setSourceCodeLocation(node.getSourceCodeLocation());
ruleset.addDeclaration(child.deepCopy());
ruleset.addSelector(sel.deepCopy());
diff --git a/tests/com/google/common/css/compiler/ast/testing/NewFunctionalTestBase.java b/tests/com/google/common/css/compiler/ast/testing/NewFunctionalTestBase.java
index dccf0e0b..0e1ffa41 100644
--- a/tests/com/google/common/css/compiler/ast/testing/NewFunctionalTestBase.java
+++ b/tests/com/google/common/css/compiler/ast/testing/NewFunctionalTestBase.java
@@ -243,7 +243,9 @@ public void print(String message) {
if (exactMatch) {
assertEquals(expectedMessages[currentIndex], message);
} else {
- assertTrue(message.contains(expectedMessages[currentIndex]));
+ assertTrue("Expected error '" + message + "' to contain '"
+ + expectedMessages[currentIndex] + "'.",
+ message.contains(expectedMessages[currentIndex]));
}
currentIndex++;
}
diff --git a/tests/com/google/common/css/compiler/passes/CheckMissingRequireTest.java b/tests/com/google/common/css/compiler/passes/CheckMissingRequireTest.java
index ea2d867e..1389741b 100644
--- a/tests/com/google/common/css/compiler/passes/CheckMissingRequireTest.java
+++ b/tests/com/google/common/css/compiler/passes/CheckMissingRequireTest.java
@@ -42,7 +42,7 @@ protected void runPasses(TestErrorManager errorMgr) {
pass.runPass();
}
CollectProvideNamespaces collectProvides = new CollectProvideNamespaces(
- tree.getVisitController(), errorMgr);
+ tree.getVisitController());
collectProvides.runPass();
new CheckMissingRequire(
tree.getVisitController(),