Merge pull request #4979 from davidaurelio/generator-raw-mappings

babel-generator: Expose raw mappings
This commit is contained in:
Christoph Pojer 2016-12-16 20:00:48 +00:00 committed by GitHub
commit 003d03789f
3 changed files with 162 additions and 20 deletions

View File

@ -38,10 +38,29 @@ export default class Buffer {
get(): Object {
this._flush();
return {
const map = this._map;
const result = {
code: trimEnd(this._buf.join("")),
map: this._map ? this._map.get() : null,
map: null,
rawMappings: map && map.getRawMappings(),
};
if (map) {
// The `.map` property is lazy to allow callers to use the raw mappings
// without any overhead
Object.defineProperty(result, "map", {
configurable: true,
enumerable: true,
get() {
return this.map = map.get();
},
set(value) {
Object.defineProperty(this, "map", {value, writable: true});
},
});
}
return result;
}
/**

View File

@ -6,19 +6,10 @@ import sourceMap from "source-map";
export default class SourceMap {
constructor(opts, code) {
this._opts = opts;
this._map = new sourceMap.SourceMapGenerator({
file: opts.sourceMapTarget,
sourceRoot: opts.sourceRoot
});
if (typeof code === "string") {
this._map.setSourceContent(opts.sourceFileName, code);
} else if (typeof code === "object") {
Object.keys(code).forEach((sourceFileName) => {
this._map.setSourceContent(sourceFileName, code[sourceFileName]);
});
}
this._cachedMap = null;
this._code = code;
this._opts = opts;
this._rawMappings = [];
}
/**
@ -26,7 +17,29 @@ export default class SourceMap {
*/
get() {
return this._map.toJSON();
if (!this._cachedMap) {
const map = this._cachedMap = new sourceMap.SourceMapGenerator({
file: this._opts.sourceMapTarget,
sourceRoot: this._opts.sourceRoot,
});
const code = this._code;
if (typeof code === "string") {
map.setSourceContent(this._opts.sourceFileName, code);
} else if (typeof code === "object") {
Object.keys(code).forEach((sourceFileName) => {
map.setSourceContent(sourceFileName, code[sourceFileName]);
});
}
this._rawMappings.forEach(map.addMapping, map);
}
return this._cachedMap.toJSON();
}
getRawMappings() {
return this._rawMappings.slice();
}
/**
@ -52,18 +65,22 @@ export default class SourceMap {
return;
}
this._cachedMap = null;
this._lastGenLine = generatedLine;
this._lastSourceLine = line;
this._lastSourceColumn = column;
this._map.addMapping({
name: identifierName,
// We are deliberately not using the `source-map` library here to allow
// callers to use these mappings without any overhead
this._rawMappings.push({
// undefined to allow for more compact json serialization
name: identifierName || undefined,
generated: {
line: generatedLine,
column: generatedColumn,
},
source: line == null ? null : filename || this._opts.sourceFileName,
original: line == null ? null : {
source: line == null ? undefined : filename || this._opts.sourceFileName,
original: line == null ? undefined : {
line: line,
column: column,
},

View File

@ -58,6 +58,69 @@ describe("generation", function () {
]
}, "sourcemap was incorrectly generated");
chai.expect(generated.rawMappings).to.deep.equal([
{ name: undefined,
generated: { line: 1, column: 0 },
source: "a.js",
original: { line: 1, column: 0 } },
{ name: "hi",
generated: { line: 1, column: 9 },
source: "a.js",
original: { line: 1, column: 9 } },
{ name: undefined,
generated: { line: 1, column: 11 },
source: "a.js",
original: { line: 1, column: 0 } },
{ name: "msg",
generated: { line: 1, column: 12 },
source: "a.js",
original: { line: 1, column: 13 } },
{ name: undefined,
generated: { line: 1, column: 15 },
source: "a.js",
original: { line: 1, column: 0 } },
{ name: undefined,
generated: { line: 1, column: 17 },
source: "a.js",
original: { line: 1, column: 18 } },
{ name: "console",
generated: { line: 2, column: 0 },
source: "a.js",
original: { line: 1, column: 20 } },
{ name: "log",
generated: { line: 2, column: 10 },
source: "a.js",
original: { line: 1, column: 28 } },
{ name: undefined,
generated: { line: 2, column: 13 },
source: "a.js",
original: { line: 1, column: 20 } },
{ name: "msg",
generated: { line: 2, column: 14 },
source: "a.js",
original: { line: 1, column: 32 } },
{ name: undefined,
generated: { line: 2, column: 17 },
source: "a.js",
original: { line: 1, column: 20 } },
{ name: undefined,
generated: { line: 3, column: 0 },
source: "a.js",
original: { line: 1, column: 39 } },
{ name: "hi",
generated: { line: 5, column: 0 },
source: "b.js",
original: { line: 1, column: 0 } },
{ name: undefined,
generated: { line: 5, column: 3 },
source: "b.js",
original: { line: 1, column: 3 } },
{ name: undefined,
generated: { line: 5, column: 10 },
source: "b.js",
original: { line: 1, column: 0 } },
], "raw mappings were incorrectly generated");
chai.expect(generated.code).to.equal(
"function hi(msg) {\n console.log(msg);\n}\n\nhi('hello');",
"code was incorrectly generated"
@ -92,11 +155,54 @@ describe("generation", function () {
sourcesContent: [ "function foo() { bar; }\n" ]
}, "sourcemap was incorrectly generated");
chai.expect(generated.rawMappings).to.deep.equal([
{ name: undefined,
generated: { line: 1, column: 0 },
source: "inline",
original: { line: 1, column: 0 } },
{ name: "foo",
generated: { line: 1, column: 9 },
source: "inline",
original: { line: 1, column: 9 } },
{ name: undefined,
generated: { line: 1, column: 13 },
source: "inline",
original: { line: 1, column: 0 } },
{ name: undefined,
generated: { line: 1, column: 16 },
source: "inline",
original: { line: 1, column: 15 } },
{ name: "bar",
generated: { line: 2, column: 0 },
source: "inline",
original: { line: 1, column: 17 } },
{ name: undefined,
generated: { line: 3, column: 0 },
source: "inline",
original: { line: 1, column: 23 } },
], "raw mappings were incorrectly generated");
chai.expect(generated.code).to.equal(
"function foo2() {\n bar2;\n}",
"code was incorrectly generated"
);
});
it("lazy source map generation", function() {
let code = "function hi (msg) { console.log(msg); }\n";
let ast = parse(code, { filename: "a.js" }).program;
let generated = generate.default(ast, {
sourceFileName: "a.js",
sourceMaps: true,
});
chai.expect(generated.rawMappings).to.be.an("array");
chai.expect(generated).ownPropertyDescriptor("map").not.to.have.property("value");
chai.expect(generated.map).to.be.an("object");
});
});