From 0963dbddea0c541467965d3d42552b7618777e4a Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Mon, 14 May 2018 14:56:21 -0700 Subject: [PATCH] Rely on Babylon for interpreter directive parsing, instead of babel/core. --- .../src/transformation/file/file.js | 21 ++++++-- .../src/transformation/file/generate.js | 7 +-- .../src/transformation/normalize-file.js | 11 ---- packages/babel-core/test/api.js | 54 +++++++++++++++++++ .../output.js | 3 +- .../source-map.json | 4 +- 6 files changed, 76 insertions(+), 24 deletions(-) diff --git a/packages/babel-core/src/transformation/file/file.js b/packages/babel-core/src/transformation/file/file.js index 896a5cf63c..47900a0374 100644 --- a/packages/babel-core/src/transformation/file/file.js +++ b/packages/babel-core/src/transformation/file/file.js @@ -28,14 +28,12 @@ export default class File { metadata: {} = {}; hub: Hub = new Hub(this); code: string = ""; - shebang: string | null = ""; inputMap: Object | null = null; - constructor(options: {}, { code, ast, shebang, inputMap }: NormalizedFile) { + constructor(options: {}, { code, ast, inputMap }: NormalizedFile) { this.opts = options; this.code = code; this.ast = ast; - this.shebang = shebang; this.inputMap = inputMap; this.path = NodePath.get({ @@ -48,6 +46,23 @@ export default class File { this.scope = this.path.scope; } + /** + * Provide backward-compatible access to the interpreter directive handling + * in Babel 6.x. If you are writing a plugin for Babel 7.x, it would be + * best to use 'program.interpreter' directly. + */ + get shebang(): string { + const { interpreter } = this.path.node; + return interpreter ? interpreter.value : ""; + } + set shebang(value: string): void { + if (value) { + this.path.get("interpreter").replaceWith(t.interpreterDirective(value)); + } else { + this.path.get("interpreter").remove(); + } + } + set(key: mixed, val: mixed) { this._map.set(key, val); } diff --git a/packages/babel-core/src/transformation/file/generate.js b/packages/babel-core/src/transformation/file/generate.js index f2b776d7b7..e124c16fc4 100644 --- a/packages/babel-core/src/transformation/file/generate.js +++ b/packages/babel-core/src/transformation/file/generate.js @@ -14,7 +14,7 @@ export default function generateCode( outputCode: string, outputMap: SourceMap | null, } { - const { opts, ast, shebang, code, inputMap } = file; + const { opts, ast, code, inputMap } = file; const results = []; for (const plugins of pluginPasses) { @@ -53,11 +53,6 @@ export default function generateCode( let { code: outputCode, map: outputMap } = result; - if (shebang) { - // add back shebang - outputCode = `${shebang}\n${outputCode}`; - } - if (outputMap && inputMap) { outputMap = mergeSourceMap(inputMap.toObject(), outputMap); } diff --git a/packages/babel-core/src/transformation/normalize-file.js b/packages/babel-core/src/transformation/normalize-file.js index ae2d9a1d8c..f458cb3285 100644 --- a/packages/babel-core/src/transformation/normalize-file.js +++ b/packages/babel-core/src/transformation/normalize-file.js @@ -8,12 +8,9 @@ import { codeFrameColumns } from "@babel/code-frame"; import File from "./file/file"; import generateMissingPluginMessage from "./util/missing-plugin-helper"; -const shebangRegex = /^#!.*/; - export type NormalizedFile = { code: string, ast: {}, - shebang: string | null, inputMap: Converter | null, }; @@ -25,7 +22,6 @@ export default function normalizeFile( ): File { code = `${code || ""}`; - let shebang = null; let inputMap = null; if (options.inputSourceMap !== false) { inputMap = convertSourceMap.fromSource(code); @@ -36,12 +32,6 @@ export default function normalizeFile( } } - const shebangMatch = shebangRegex.exec(code); - if (shebangMatch) { - shebang = shebangMatch[0]; - code = code.replace(shebangRegex, ""); - } - if (ast) { if (ast.type === "Program") { ast = t.file(ast, [], []); @@ -58,7 +48,6 @@ export default function normalizeFile( return new File(options, { code, ast, - shebang, inputMap, }); } diff --git a/packages/babel-core/test/api.js b/packages/babel-core/test/api.js index 2d99f799b8..8f8d378477 100644 --- a/packages/babel-core/test/api.js +++ b/packages/babel-core/test/api.js @@ -370,6 +370,60 @@ describe("api", function() { ); }); + it("interpreter directive backward-compat", function() { + function doTransform(code, preHandler) { + return transform(code, { + plugins: [ + { + pre: preHandler, + }, + ], + }).code; + } + + // Writes value properly. + expect( + doTransform("", file => { + file.shebang = "env node"; + }), + ).toBe(`#!env node`); + expect( + doTransform("#!env node", file => { + file.shebang = "env node2"; + }), + ).toBe(`#!env node2`); + expect( + doTransform("", file => { + file.shebang = ""; + }), + ).toBe(``); + expect( + doTransform("#!env node", file => { + file.shebang = ""; + }), + ).toBe(``); + + // Reads value properly. + doTransform("", file => { + expect(file.shebang).toBe(""); + }); + doTransform("#!env node", file => { + expect(file.shebang).toBe("env node"); + }); + + // Reads and writes properly. + expect( + doTransform("#!env node", file => { + expect(file.shebang).toBe("env node"); + + file.shebang = "env node2"; + expect(file.shebang).toBe("env node2"); + + file.shebang = "env node3"; + }), + ).toBe(`#!env node3`); + }); + it("source map merging", function() { const result = transform( [ diff --git a/packages/babel-core/test/fixtures/transformation/misc/retain-lines-interpreter-directive/output.js b/packages/babel-core/test/fixtures/transformation/misc/retain-lines-interpreter-directive/output.js index d80bd4fad6..1f1709b94e 100644 --- a/packages/babel-core/test/fixtures/transformation/misc/retain-lines-interpreter-directive/output.js +++ b/packages/babel-core/test/fixtures/transformation/misc/retain-lines-interpreter-directive/output.js @@ -1,3 +1,2 @@ #!env node -"use strict"; -var someFirstLine; +"use strict";var someFirstLine; diff --git a/packages/babel-core/test/fixtures/transformation/source-maps/interpreter-directive-prefix/source-map.json b/packages/babel-core/test/fixtures/transformation/source-maps/interpreter-directive-prefix/source-map.json index 85e289c689..0a465c324b 100644 --- a/packages/babel-core/test/fixtures/transformation/source-maps/interpreter-directive-prefix/source-map.json +++ b/packages/babel-core/test/fixtures/transformation/source-maps/interpreter-directive-prefix/source-map.json @@ -1,5 +1,5 @@ { - "mappings": "AAEAA,QAAQC,GAAR,CAAY,eAAZ", + "mappings": "AAAA;AAEAA,QAAQC,GAAR,CAAY,eAAZ", "names": [ "console", "log" @@ -8,7 +8,7 @@ "source-maps/interpreter-directive-prefix/input.js" ], "sourcesContent": [ - "\n\nconsole.log(\"Hello, world!\");" + "#!env node\n\nconsole.log(\"Hello, world!\");" ], "version": 3 }