diff --git a/README.md b/README.md
index 6a50cf50..60631840 100644
--- a/README.md
+++ b/README.md
@@ -387,7 +387,7 @@ Streamline also provides _stream wrappers_ that simplify stream programming. The
You can seamlessly debug streamline code thanks to [JavaScript source maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). See [this video](https://www.youtube.com/watch?v=duC1Sqy66IE) for a quick demo.
-To activate this feature, pass the `--source-map` options to `_node` or `_coffee`, or set the `sourcemap` option if you register via a loader.
+To activate this feature, pass the `--source-map` options to `_node` or `_coffee`, or set the `sourceMap` option if you register via a loader.
# Monitoring performance with flame graphs
@@ -460,7 +460,7 @@ For support and discussion, please join the [streamline.js mailing list](http://
See the [AUTHORS](https://github.com/Sage/streamlinejs/blob/master/AUTHORS) file.
-Special thanks to Marcel Laverdet who contributed the _fibers_ implementation and to Geoffry Song who contributed sourcemap support.
+Special thanks to Marcel Laverdet who contributed the _fibers_ implementation and to Geoffry Song who contributed source map support.
# License
diff --git a/lib/callbacks/transform.js b/lib/callbacks/transform.js
index fff3fb47..b4eb0dd5 100644
--- a/lib/callbacks/transform.js
+++ b/lib/callbacks/transform.js
@@ -276,6 +276,7 @@ if (typeof exports !== 'undefined') {
return child;
}, true);
node = _flatten(node);
+ node.loc = node.loc || loc;
return node;
}
}
@@ -1881,6 +1882,7 @@ if (typeof exports !== 'undefined') {
var node = esprima.parse(source, {
loc: true,
range: true,
+ source: options.sourceName || '',
});
node = node.body[0].body;
if (node.type !== 'BlockStatement') throw new Error("source wrapper error: " + node.type);
@@ -1904,22 +1906,38 @@ if (typeof exports !== 'undefined') {
var used = {};
node = _simplify(node, options, used);
//fixRanges(node);
- addNewlines(node);
- var result = escodegen.generate(node, {
+ if (options.lines === "preserve") addNewlines(node);
+
+ // transform top node into Program to avoid extra curly braces
+ if (node.type === "BlockStatement") node.type = "Program";
+
+ var ecopts = options.sourceMap ? {
+ sourceMap: true,
+ sourceMapWithCode: true,
+ } : options.lines === "preserve" ? {
comment: true,
- });
- // remove curly braces around generated source
- result = result[0] === '{' ? result.substring(1, result.length - 1) : result;
- // turn comments into newlines
- //result = result.replace(/\n\s*/g, ' ').replace(/\/\*undefined\*\//g, '\n');
- result = result.split(/\/\*undefined\*\/\n/).map(function(s) {
- return s.replace(/\n\s*/g, ' ');
- }).join('\n');
+ } : {};
+ var result = escodegen.generate(node, ecopts);
+ if (options.sourceMap) {
+ // convert result into a SourceNode.
+ // would be much easier (and faster) if escodegen had an option to return SourceNode directly
+ var SourceNode = require('source-map').SourceNode;
+ var SourceMapConsumer = require('source-map').SourceMapConsumer;
+ result = SourceNode.fromStringWithSourceMap(result.code, new SourceMapConsumer(result.map.toString()));
+ }
+
+ if (options.lines === "preserve") {
+ // turn comments into newlines
+ //result = result.replace(/\n\s*/g, ' ').replace(/\/\*undefined\*\//g, '\n');
+ result = result.split(/\/\*undefined\*\/\n/).map(function(s) {
+ return s.replace(/\n\s*/g, ' ');
+ }).join('\n');
+ };
// add helpers at beginning so that __g is initialized before any other code
if (!options.noHelpers) {
var s = exports.helpersSource(options, used, strict);
- if (options.lines == "sourcemap") {
+ if (options.sourceMap) {
result.prepend(s);
} else {
result = s + result;
diff --git a/lib/compiler/compile._js b/lib/compiler/compile._js
index 0153eb30..69b4de4f 100644
--- a/lib/compiler/compile._js
+++ b/lib/compiler/compile._js
@@ -113,12 +113,13 @@ function outputFile(_, inFile, options) {
}
function fixSourceMap(sourceMap) {
- var keys = {};
+ var prev;
sourceMap._mappings._array = sourceMap._mappings._array.filter(function(mapping) {
if (!mapping.originalLine) return false;
- var key = mapping.originalLine + '/' + mapping.originalColumn;
- if (keys[key]) return false;
- keys[key] = true;
+ if (prev && mapping.source === prev.source //
+ && mapping.originalLine === prev.originalLine //
+ && mapping.originalColumn === prev.originalColumn) return false;
+ prev = mapping;
return true;
});
}
@@ -315,7 +316,7 @@ function cachedTransform(_, content, path, transform, banner, options) {
}
// no luck in cache
if (options.verbose) console.log("streamline: transforming: " + path);
- options.lines = options.lines || "sourcemap";
+ options.lines = options.lines || (options.sourceMap ? "sourcemap" : "preserve");
transformed = banner + _transform(transform, content, options);
if (options.cache && path.indexOf('/tmp--') < 0) fs.writeFile(f, transformed, "utf8", ~_);
return transformed;
diff --git a/lib/compiler/compileSync.js b/lib/compiler/compileSync.js
index e25bf779..750e2981 100644
--- a/lib/compiler/compileSync.js
+++ b/lib/compiler/compileSync.js
@@ -154,7 +154,7 @@ function cachedTransformSync(content, path, transform, banner, options, testOnly
r[k] = options[k];
return r;
}, {});
- opts.lines = opts.lines || "sourcemap";
+ opts.lines = opts.lines || (opts.sourceMap ? "sourcemap" : "preserve");
transformed = banner + _transform(transform, content, opts);
if (options.cache && path.indexOf('/tmp--') < 0) fs.writeFileSync(f, transformed, "utf8");
return transformed;