Skip to content

Commit 3ed28b2

Browse files
Fully support || and && in pluginToggleBooleanFlag (#15961)
* Fully support `||` and `&&` in `pluginToggleBooleanFlag` * Cleanup babel-standalone/src/available-plugins.ts * Cleanup `USE_ESM`
1 parent 90ef9e8 commit 3ed28b2

10 files changed

Lines changed: 217 additions & 201 deletions

File tree

babel.config.js

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -241,15 +241,6 @@ module.exports = function (api) {
241241
{ name: "IS_STANDALONE", value: env === "standalone" },
242242
"flag-IS_STANDALONE",
243243
],
244-
[
245-
pluginToggleBooleanFlag,
246-
{
247-
name: "USE_ESM_OR_STANDALONE",
248-
value: outputType === "module" || env === "standalone",
249-
},
250-
"flag-USE_ESM_OR_STANDALONE",
251-
],
252-
253244
[
254245
pluginToggleBooleanFlag,
255246
{
@@ -384,7 +375,7 @@ function importInteropTest(source) {
384375

385376
// env vars from the cli are always strings, so !!ENV_VAR returns true for "false"
386377
function bool(value) {
387-
return value && value !== "false" && value !== "0";
378+
return Boolean(value) && value !== "false" && value !== "0";
388379
}
389380

390381
// A minimum semver GTE implementation
@@ -507,24 +498,72 @@ function pluginPolyfillsOldNode({ template, types: t }) {
507498
* @returns {import("@babel/core").PluginObj}
508499
*/
509500
function pluginToggleBooleanFlag({ types: t }, { name, value }) {
510-
function check(test) {
511-
let keepConsequent = value;
501+
if (typeof value !== "boolean") throw new Error(`.value must be a boolean`);
502+
503+
function evaluate(test) {
504+
const res = {
505+
replace: replacement => ({ replacement, value: null, unrelated: false }),
506+
value: value => ({ replacement: null, value, unrelated: false }),
507+
unrelated: () => ({
508+
replacement: test.node,
509+
value: null,
510+
unrelated: true,
511+
}),
512+
};
513+
514+
if (test.isIdentifier({ name }) || test.matchesPattern(name)) {
515+
return res.value(value);
516+
}
512517

513518
if (test.isUnaryExpression({ operator: "!" })) {
514-
test = test.get("argument");
515-
keepConsequent = !keepConsequent;
519+
const arg = evaluate(test.get("argument"));
520+
return arg.unrelated
521+
? res.unrelated()
522+
: arg.replacement
523+
? res.replacement(t.unaryExpression("!", arg.replacement))
524+
: res.value(!arg.value);
516525
}
517-
return {
518-
test,
519-
keepConsequent,
520-
};
526+
527+
if (test.isLogicalExpression({ operator: "||" })) {
528+
const left = evaluate(test.get("left"));
529+
const right = evaluate(test.get("right"));
530+
531+
if (left.value === true || right.value === true) return res.value(true);
532+
if (left.value === false && right.value === false) {
533+
return res.value(false);
534+
}
535+
if (left.value === false) return res.replace(right.replacement);
536+
if (right.value === false) return res.replace(left.replacement);
537+
if (left.unrelated && right.unrelated) return res.unrelated();
538+
console.log(left, right);
539+
return res.replace(
540+
t.logicalExpression("||", left.replacement, right.replacement)
541+
);
542+
}
543+
544+
if (test.isLogicalExpression({ operator: "&&" })) {
545+
const left = evaluate(test.get("left"));
546+
const right = evaluate(test.get("right"));
547+
548+
if (left.value === true && right.value === true) return res.value(true);
549+
if (left.value === false || right.value === false) {
550+
return res.value(false);
551+
}
552+
if (left.value === true) return res.replace(right.replacement);
553+
if (right.value === true) return res.replace(left.replacement);
554+
if (left.unrelated && right.unrelated) return res.unrelated();
555+
return res.replace(
556+
t.logicalExpression("&&", left.replacement, right.replacement)
557+
);
558+
}
559+
560+
return res.unrelated();
521561
}
522562

523563
return {
524564
visitor: {
525565
"IfStatement|ConditionalExpression"(path) {
526-
// eslint-disable-next-line prefer-const
527-
let { test, keepConsequent } = check(path.get("test"));
566+
let test = path.get("test");
528567

529568
// yarn-plugin-conditions injects bool(process.env.BABEL_8_BREAKING)
530569
// tests, to properly cast the env variable to a boolean.
@@ -536,32 +575,26 @@ function pluginToggleBooleanFlag({ types: t }, { name, value }) {
536575
test = test.get("arguments")[0];
537576
}
538577

539-
if (!test.isIdentifier({ name }) && !test.matchesPattern(name)) return;
578+
const res = evaluate(test);
540579

541-
path.replaceWith(
542-
keepConsequent
543-
? path.node.consequent
544-
: path.node.alternate || t.emptyStatement()
545-
);
580+
if (res.unrelated) return;
581+
if (res.replacement) {
582+
path.get("test").replaceWith(res.replacement);
583+
} else {
584+
path.replaceWith(
585+
res.value
586+
? path.node.consequent
587+
: path.node.alternate || t.emptyStatement()
588+
);
589+
}
546590
},
547591
LogicalExpression(path) {
548-
const { test, keepConsequent } = check(path.get("left"));
549-
550-
if (!test.matchesPattern(name)) return;
551-
552-
switch (path.node.operator) {
553-
case "&&":
554-
path.replaceWith(
555-
keepConsequent ? path.node.right : t.booleanLiteral(false)
556-
);
557-
break;
558-
case "||":
559-
path.replaceWith(
560-
keepConsequent ? t.booleanLiteral(true) : path.node.right
561-
);
562-
break;
563-
default:
564-
throw path.buildCodeFrameError("This check could not be stripped.");
592+
const res = evaluate(path.get("test"));
593+
if (res.unrelated) return;
594+
if (res.replacement) {
595+
path.get("test").replaceWith(res.replacement);
596+
} else {
597+
path.replaceWith(t.booleanLiteral(res.value));
565598
}
566599
},
567600
MemberExpression(path) {

packages/babel-core/src/index.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
if (!process.env.IS_PUBLISH) {
2-
if (!USE_ESM) {
3-
if (process.env.BABEL_8_BREAKING) {
4-
throw new Error(
5-
"BABEL_8_BREAKING is only supported in ESM. Please run `make use-esm`.",
6-
);
7-
}
8-
}
1+
if (!process.env.IS_PUBLISH && !USE_ESM && process.env.BABEL_8_BREAKING) {
2+
throw new Error(
3+
"BABEL_8_BREAKING is only supported in ESM. Please run `make use-esm`.",
4+
);
95
}
106

117
export const version = PACKAGE_JSON.version;
@@ -83,29 +79,25 @@ export const DEFAULT_EXTENSIONS = Object.freeze([
8379

8480
import Module from "module";
8581
import * as thisFile from "./index.ts";
86-
if (USE_ESM) {
87-
if (!IS_STANDALONE) {
88-
// Pass this module to the CJS proxy, so that it can be synchronously accessed.
89-
const cjsProxy = Module.createRequire(import.meta.url)("../cjs-proxy.cjs");
90-
cjsProxy["__ initialize @babel/core cjs proxy __"] = thisFile;
91-
}
82+
if (USE_ESM && !IS_STANDALONE) {
83+
// Pass this module to the CJS proxy, so that it can be synchronously accessed.
84+
const cjsProxy = Module.createRequire(import.meta.url)("../cjs-proxy.cjs");
85+
cjsProxy["__ initialize @babel/core cjs proxy __"] = thisFile;
9286
}
9387

94-
if (!process.env.BABEL_8_BREAKING) {
88+
if (!process.env.BABEL_8_BREAKING && !USE_ESM) {
9589
// For easier backward-compatibility, provide an API like the one we exposed in Babel 6.
96-
if (!USE_ESM) {
97-
// eslint-disable-next-line no-restricted-globals
98-
exports.OptionManager = class OptionManager {
99-
init(opts: {}) {
100-
return loadOptionsSync(opts);
101-
}
102-
};
90+
// eslint-disable-next-line no-restricted-globals
91+
exports.OptionManager = class OptionManager {
92+
init(opts: {}) {
93+
return loadOptionsSync(opts);
94+
}
95+
};
10396

104-
// eslint-disable-next-line no-restricted-globals
105-
exports.Plugin = function Plugin(alias: string) {
106-
throw new Error(
107-
`The (${alias}) Babel 5 plugin is being run with an unsupported Babel version.`,
108-
);
109-
};
110-
}
97+
// eslint-disable-next-line no-restricted-globals
98+
exports.Plugin = function Plugin(alias: string) {
99+
throw new Error(
100+
`The (${alias}) Babel 5 plugin is being run with an unsupported Babel version.`,
101+
);
102+
};
111103
}

packages/babel-helper-environment-visitor/src/index.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
import type { NodePath, Visitor } from "@babel/traverse";
22
import type * as t from "@babel/types";
33

4-
if (!process.env.BABEL_8_BREAKING) {
5-
if (!USE_ESM) {
6-
if (!IS_STANDALONE) {
7-
// eslint-disable-next-line no-restricted-globals
8-
exports.skipAllButComputedKey = function skipAllButComputedKey(
9-
path: NodePath<t.Method | t.ClassProperty>,
10-
) {
11-
path.skip();
12-
if (path.node.computed) {
13-
// requeue the computed key
14-
path.context.maybeQueue(path.get("key"));
15-
}
16-
};
4+
if (!process.env.BABEL_8_BREAKING && !USE_ESM && !IS_STANDALONE) {
5+
// eslint-disable-next-line no-restricted-globals
6+
exports.skipAllButComputedKey = function skipAllButComputedKey(
7+
path: NodePath<t.Method | t.ClassProperty>,
8+
) {
9+
path.skip();
10+
if (path.node.computed) {
11+
// requeue the computed key
12+
path.context.maybeQueue(path.get("key"));
1713
}
18-
}
14+
};
1915
}
2016

2117
export function requeueComputedKeyAndDecorators(

packages/babel-helper-module-transforms/src/dynamic-import.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,17 @@
33

44
import { types as t, template } from "@babel/core";
55

6-
if (!process.env.BABEL_8_BREAKING) {
7-
if (!USE_ESM) {
8-
if (!IS_STANDALONE) {
9-
// eslint-disable-next-line no-restricted-globals
10-
exports.getDynamicImportSource = function getDynamicImportSource(
11-
node: t.CallExpression,
12-
): t.StringLiteral | t.TemplateLiteral {
13-
const [source] = node.arguments;
6+
if (!process.env.BABEL_8_BREAKING && !USE_ESM && !IS_STANDALONE) {
7+
// eslint-disable-next-line no-restricted-globals
8+
exports.getDynamicImportSource = function getDynamicImportSource(
9+
node: t.CallExpression,
10+
): t.StringLiteral | t.TemplateLiteral {
11+
const [source] = node.arguments;
1412

15-
return t.isStringLiteral(source) || t.isTemplateLiteral(source)
16-
? source
17-
: (template.expression.ast`\`\${${source}}\`` as t.TemplateLiteral);
18-
};
19-
}
20-
}
13+
return t.isStringLiteral(source) || t.isTemplateLiteral(source)
14+
? source
15+
: (template.expression.ast`\`\${${source}}\`` as t.TemplateLiteral);
16+
};
2117
}
2218

2319
export function buildDynamicImport(

packages/babel-helper-module-transforms/src/index.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,11 @@ const {
3737

3838
export { buildDynamicImport } from "./dynamic-import.ts";
3939

40-
if (!process.env.BABEL_8_BREAKING) {
41-
if (!USE_ESM) {
42-
if (!IS_STANDALONE) {
43-
// eslint-disable-next-line no-restricted-globals
44-
exports.getDynamicImportSource =
45-
// eslint-disable-next-line no-restricted-globals, import/extensions
46-
require("./dynamic-import").getDynamicImportSource;
47-
}
48-
}
40+
if (!process.env.BABEL_8_BREAKING && !USE_ESM && !IS_STANDALONE) {
41+
// eslint-disable-next-line no-restricted-globals
42+
exports.getDynamicImportSource =
43+
// eslint-disable-next-line no-restricted-globals, import/extensions
44+
require("./dynamic-import").getDynamicImportSource;
4945
}
5046

5147
export { default as getModuleName } from "./get-module-name.ts";

packages/babel-helper-replace-supers/src/index.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,13 @@ const {
1717
thisExpression,
1818
} = t;
1919

20-
if (!process.env.BABEL_8_BREAKING) {
21-
if (!USE_ESM) {
22-
if (!IS_STANDALONE) {
23-
// eslint-disable-next-line no-restricted-globals
24-
const ns = require("@babel/helper-environment-visitor");
25-
// eslint-disable-next-line no-restricted-globals
26-
exports.environmentVisitor = ns.default;
27-
// eslint-disable-next-line no-restricted-globals
28-
exports.skipAllButComputedKey = ns.skipAllButComputedKey;
29-
}
30-
}
20+
if (!process.env.BABEL_8_BREAKING && !USE_ESM && !IS_STANDALONE) {
21+
// eslint-disable-next-line no-restricted-globals
22+
const ns = require("@babel/helper-environment-visitor");
23+
// eslint-disable-next-line no-restricted-globals
24+
exports.environmentVisitor = ns.default;
25+
// eslint-disable-next-line no-restricted-globals
26+
exports.skipAllButComputedKey = ns.skipAllButComputedKey;
3127
}
3228

3329
type ThisRef =

packages/babel-highlight/src/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,9 @@ function getChalk(forceColor: boolean) {
262262
}
263263
return chalk;
264264
}
265-
if (!process.env.BABEL_8_BREAKING) {
266-
if (!USE_ESM) {
267-
// eslint-disable-next-line no-restricted-globals
268-
exports.getChalk = (options: Options) => getChalk(options.forceColor);
269-
}
265+
if (!process.env.BABEL_8_BREAKING && !USE_ESM) {
266+
// eslint-disable-next-line no-restricted-globals
267+
exports.getChalk = (options: Options) => getChalk(options.forceColor);
270268
}
271269

272270
/**

0 commit comments

Comments
 (0)