From dc89c5eb4ddef2eb4f14d4e61a58940384837251 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Mon, 8 Jun 2020 19:14:01 -0400 Subject: [PATCH 1/3] Allow templates to parse v8intrinsics The `v8intrinsic` and `placeholders` parser plugins conflict, so enabling `placeholders` unconditionally was causing errors for V8's internal codemods. This allows them to set `syntacticPlaceholders = false` (so they'll use the legacy identifier format) and enable `v8intrinsic` by itself. --- packages/babel-template/src/parse.js | 11 +++++--- packages/babel-template/test/index.js | 39 ++++++++++++++++++++------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/babel-template/src/parse.js b/packages/babel-template/src/parse.js index b704d5b3195d..ced577575199 100644 --- a/packages/babel-template/src/parse.js +++ b/packages/babel-template/src/parse.js @@ -27,8 +27,6 @@ export default function parseAndBuildMetadata( code: string, opts: TemplateOpts, ): Metadata { - const ast = parseWithCodeFrame(code, opts.parser); - const { placeholderWhitelist, placeholderPattern, @@ -36,6 +34,8 @@ export default function parseAndBuildMetadata( syntacticPlaceholders, } = opts; + const ast = parseWithCodeFrame(code, opts.parser, syntacticPlaceholders); + t.removePropertiesDeep(ast, { preserveComments, }); @@ -191,15 +191,20 @@ type MetadataState = { function parseWithCodeFrame( code: string, parserOpts: ParserOpts, + syntacticPlaceholders: boolean, ): BabelNodeFile { parserOpts = { allowReturnOutsideFunction: true, allowSuperOutsideMethod: true, sourceType: "module", ...parserOpts, - plugins: (parserOpts.plugins || []).concat("placeholders"), + plugins: parserOpts.plugins || [], }; + if (syntacticPlaceholders !== false) { + parserOpts.plugins.push("placeholders"); + } + try { // $FlowFixMe - The parser AST is not the same type as the babel-types type. return parse(code, parserOpts); diff --git a/packages/babel-template/test/index.js b/packages/babel-template/test/index.js index cae920c2b5b4..0e983d167099 100644 --- a/packages/babel-template/test/index.js +++ b/packages/babel-template/test/index.js @@ -4,36 +4,36 @@ import * as t from "@babel/types"; const comments = "// Sum two numbers\nconst add = (a, b) => a + b;"; -describe("@babel/template", function () { - it("import statements are allowed by default", function () { - expect(function () { +describe("@babel/template", function() { + it("import statements are allowed by default", function() { + expect(function() { template("import foo from 'foo'")({}); }).not.toThrow(); }); - it("with statements are allowed with sourceType: script", function () { - expect(function () { + it("with statements are allowed with sourceType: script", function() { + expect(function() { template("with({}){}", { sourceType: "script" })({}); }).not.toThrow(); }); - it("should strip comments by default", function () { + it("should strip comments by default", function() { const code = "const add = (a, b) => a + b;"; const output = template(comments)(); expect(generator(output).code).toBe(code); }); - it("should preserve comments with a flag", function () { + it("should preserve comments with a flag", function() { const output = template(comments, { preserveComments: true })(); expect(generator(output).code).toBe(comments); }); - it("should preserve comments with a flag", function () { + it("should preserve comments with a flag", function() { const output = template(comments, { preserveComments: true })(); expect(generator(output).code).toBe(comments); }); - it("should preserve comments with a flag when using .ast", function () { + it("should preserve comments with a flag when using .ast", function() { const output1 = template.ast(comments, { preserveComments: true }); const output2 = template({ preserveComments: true }).ast(comments); expect(generator(output1).code).toBe(comments); @@ -294,6 +294,17 @@ describe("@babel/template", function () { template(`%%FOO%%`, { syntacticPlaceholders: false })({ FOO: t.numericLiteral(1), }); + }).toThrow(/Unexpected token.*/); + }); + + it("disallow manually enabled placeholders", () => { + expect(() => { + template(`%%FOO%%`, { + syntacticPlaceholders: false, + plugins: ["placeholders"], + })({ + FOO: t.numericLiteral(1), + }); }).toThrow(/%%.*placeholders can't be used/); }); @@ -303,6 +314,16 @@ describe("@babel/template", function () { }); expect(generator(output).code).toMatchInlineSnapshot(`"1;"`); }); + + it("allows v8intrinsics", () => { + const output = template(`%DebugPrint(1)`, { + syntacticPlaceholders: false, + plugins: ["v8intrinsic"], + })(); + expect(generator(output).code).toMatchInlineSnapshot( + `"%DebugPrint(1);"`, + ); + }); }); describe("undefined", () => { From c60314515ffd958f6d7d689bd61a4383f70101be Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Mon, 8 Jun 2020 19:59:36 -0400 Subject: [PATCH 2/3] Fix linter --- packages/babel-template/src/parse.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/babel-template/src/parse.js b/packages/babel-template/src/parse.js index ced577575199..3a0b6596d402 100644 --- a/packages/babel-template/src/parse.js +++ b/packages/babel-template/src/parse.js @@ -191,20 +191,21 @@ type MetadataState = { function parseWithCodeFrame( code: string, parserOpts: ParserOpts, - syntacticPlaceholders: boolean, + syntacticPlaceholders?: boolean, ): BabelNodeFile { + const plugins = (parserOpts.plugins || []).slice(); + if (syntacticPlaceholders !== false) { + plugins.push("placeholders"); + } + parserOpts = { allowReturnOutsideFunction: true, allowSuperOutsideMethod: true, sourceType: "module", ...parserOpts, - plugins: parserOpts.plugins || [], + plugins, }; - if (syntacticPlaceholders !== false) { - parserOpts.plugins.push("placeholders"); - } - try { // $FlowFixMe - The parser AST is not the same type as the babel-types type. return parse(code, parserOpts); From 0a973219fabb465f33ed4ca9e709eab7678c85e3 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Tue, 9 Jun 2020 14:06:33 -0400 Subject: [PATCH 3/3] Linter --- packages/babel-template/test/index.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/babel-template/test/index.js b/packages/babel-template/test/index.js index 0e983d167099..117254bc6fb4 100644 --- a/packages/babel-template/test/index.js +++ b/packages/babel-template/test/index.js @@ -4,36 +4,36 @@ import * as t from "@babel/types"; const comments = "// Sum two numbers\nconst add = (a, b) => a + b;"; -describe("@babel/template", function() { - it("import statements are allowed by default", function() { - expect(function() { +describe("@babel/template", function () { + it("import statements are allowed by default", function () { + expect(function () { template("import foo from 'foo'")({}); }).not.toThrow(); }); - it("with statements are allowed with sourceType: script", function() { - expect(function() { + it("with statements are allowed with sourceType: script", function () { + expect(function () { template("with({}){}", { sourceType: "script" })({}); }).not.toThrow(); }); - it("should strip comments by default", function() { + it("should strip comments by default", function () { const code = "const add = (a, b) => a + b;"; const output = template(comments)(); expect(generator(output).code).toBe(code); }); - it("should preserve comments with a flag", function() { + it("should preserve comments with a flag", function () { const output = template(comments, { preserveComments: true })(); expect(generator(output).code).toBe(comments); }); - it("should preserve comments with a flag", function() { + it("should preserve comments with a flag", function () { const output = template(comments, { preserveComments: true })(); expect(generator(output).code).toBe(comments); }); - it("should preserve comments with a flag when using .ast", function() { + it("should preserve comments with a flag when using .ast", function () { const output1 = template.ast(comments, { preserveComments: true }); const output2 = template({ preserveComments: true }).ast(comments); expect(generator(output1).code).toBe(comments);