diff --git a/README.md b/README.md index b8868ad923..f175700d17 100644 --- a/README.md +++ b/README.md @@ -148,10 +148,16 @@ to5.transformFile("filename.js", options, function (err, result) { // If truthy, adds a `map` property to returned output. // If set to "inline", a comment with a sourceMappingURL directive is added to // the bottom of the returned code. - sourceMap: false, + // Default: false + sourceMap: true, + + // Adds an `ast` property to returned output containing the ast tree used. + // Default: false + ast: true, // Filename for use in errors etc. - filename: "unknown" + // Default: "unknown" + filename: "filename" } ``` diff --git a/lib/6to5/transform.js b/lib/6to5/transform.js index f27d3d0fbb..3005eb6621 100644 --- a/lib/6to5/transform.js +++ b/lib/6to5/transform.js @@ -1,7 +1,8 @@ -var traverse = require("./traverse"); -var recast = require("recast"); -var util = require("./util"); -var _ = require("lodash"); +var sourceMap = require("source-map"); +var traverse = require("./traverse"); +var recast = require("recast"); +var util = require("./util"); +var _ = require("lodash"); var ensureTransformerNames = function (type, keys) { _.each(keys, function (key) { @@ -20,7 +21,8 @@ var transform = module.exports = function (code, opts) { whitelist: [], sourceMap: false, filename: "unknown", - format: {} + format: {}, + ast: false }); ensureTransformerNames("blacklist", opts.blacklist); @@ -56,6 +58,14 @@ transform._run = function (code, tree, opts) { result.code += "\n" + util.sourceMapToComment(result.map); } + result.map = result.map || null; + + if (opts.ast) { + result.ast = tree; + } else { + result.ast = null; + } + return result; }; @@ -76,25 +86,29 @@ transform.test = function (task, assert) { var opts = task.options; opts.filename = actual.filename; + opts.ast = true; var actualCode = actual.code.trim(); - var transformedResult = transform(actualCode, opts); - var transformedCode = transformedResult.code; + var actualResult = transform(actualCode, opts); + var actualAst = actualResult.ast; + actualCode = recast.prettyPrint(actualAst).code; - var actualAst = util.parse(actual.filename, transformedCode); - var actualResult = recast.prettyPrint(actualAst); - actualCode = actualResult.code; - - var expectCode = expect.code.trim(); - var expectAst = util.parse(expect.filename, expectCode); + var expectCode = expect.code.trim(); + var expectAst = util.parse(expect.filename, expectCode); var expectResult = recast.prettyPrint(expectAst); - expectCode = expectResult.code; + expectCode = expectResult.code; assert.equal(actualCode, expectCode); - if (opts.sourceMap && task.sourceMap) { - assert.deepEqual(util.formatJSON(transformedResult.map), util.formatJSON(task.sourceMap)); + if (task.sourceMappings) { + var consumer = new sourceMap.SourceMapConsumer(actualResult.map); + + _.each(task.sourceMappings, function (mapping, i) { + var pos = consumer.originalPositionFor(mapping.generated); + var msg = "source mapping " + ++i + " - generated: " + mapping.generated.line + ":" + mapping.generated.column; + assert.equal(pos.line + ":" + pos.column, mapping.original.line + ":" + mapping.original.column, msg); + }); } }; diff --git a/package.json b/package.json index aa558be67a..3084236f01 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "jstransform": "^6.3.2", "uglify-js": "^2.4.15", "browserify": "^6.0.3", - "proclaim": "^2.0.0" + "proclaim": "^2.0.0", + "source-map": "^0.1.40" } } diff --git a/test/_helper.js b/test/_helper.js index 1fdecca05e..0777a87609 100644 --- a/test/_helper.js +++ b/test/_helper.js @@ -71,7 +71,6 @@ exports.getTests = function () { var taskOpts = _.merge({ filename: actualLoc }, _.cloneDeep(suite.options)); if (fs.existsSync(taskOptsLoc)) _.merge(taskOpts, require(taskOptsLoc)); - var test = { title: humanise(taskName), options: taskOpts, @@ -87,10 +86,10 @@ exports.getTests = function () { suite.tests.push(test); - var sourceMapLoc = taskDir + "/source-map.json"; - if (fs.existsSync(sourceMapLoc)) { + var sourceMappingsLoc = taskDir + "/source-mappings.json"; + if (fs.existsSync(sourceMappingsLoc)) { test.options.sourceMap = true; - test.sourceMap = require(sourceMapLoc); + test.sourceMappings = require(sourceMappingsLoc); } }); }); diff --git a/test/fixtures/source-maps/simple/actual.js b/test/fixtures/source-maps/arrow-function/actual.js similarity index 100% rename from test/fixtures/source-maps/simple/actual.js rename to test/fixtures/source-maps/arrow-function/actual.js diff --git a/test/fixtures/source-maps/arrow-function/expected.js b/test/fixtures/source-maps/arrow-function/expected.js new file mode 100644 index 0000000000..3ce826a33f --- /dev/null +++ b/test/fixtures/source-maps/arrow-function/expected.js @@ -0,0 +1,3 @@ +var t = function(x) { + return x * x; +}; diff --git a/test/fixtures/source-maps/arrow-function/source-mappings.json b/test/fixtures/source-maps/arrow-function/source-mappings.json new file mode 100644 index 0000000000..88886e7423 --- /dev/null +++ b/test/fixtures/source-maps/arrow-function/source-mappings.json @@ -0,0 +1,10 @@ +[{ + "original": { + "line": 1, + "column": 15 + }, + "generated": { + "line": 2, + "column": 11 + } +}] diff --git a/test/fixtures/source-maps/class/actual.js b/test/fixtures/source-maps/class/actual.js new file mode 100644 index 0000000000..a1a7204a7d --- /dev/null +++ b/test/fixtures/source-maps/class/actual.js @@ -0,0 +1,8 @@ +class Test { + get bar() { + throw new Error("wow"); + } +} + +var test = new Test; +test.bar; diff --git a/test/fixtures/source-maps/class/expected.js b/test/fixtures/source-maps/class/expected.js new file mode 100644 index 0000000000..012e6129cd --- /dev/null +++ b/test/fixtures/source-maps/class/expected.js @@ -0,0 +1,16 @@ +var Test = function() { + function Test() {} + + Object.defineProperties(Test.prototype, { + bar: { + get: function() { + throw new Error("wow"); + } + } + }); + + return Test; +}(); + +var test = new Test; +test.bar; diff --git a/test/fixtures/source-maps/class/source-mappings.json b/test/fixtures/source-maps/class/source-mappings.json new file mode 100644 index 0000000000..b3f7bdab14 --- /dev/null +++ b/test/fixtures/source-maps/class/source-mappings.json @@ -0,0 +1,10 @@ +[{ + "original": { + "line": 3, + "column": 11 + }, + "generated": { + "line": 7, + "column": 15 + } +}] diff --git a/test/fixtures/source-maps/simple/expected.js b/test/fixtures/source-maps/simple/expected.js deleted file mode 100644 index f7f53950c8..0000000000 --- a/test/fixtures/source-maps/simple/expected.js +++ /dev/null @@ -1 +0,0 @@ -var t = function (x) { return x * x; }; diff --git a/test/fixtures/source-maps/simple/source-map.json b/test/fixtures/source-maps/simple/source-map.json deleted file mode 100644 index 7246019e42..0000000000 --- a/test/fixtures/source-maps/simple/source-map.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 3, - "file": "actual.js", - "sources": [ - "actual.js" - ], - "names": [], - "mappings": "AAAA,CAAC,CAAC,EAAE,EAAE,WAAE;SAAK,EAAE,EAAE;CAAC", - "sourcesContent": [ - "var t = x => x * x;" - ] -}