From 1a3f9c27a318e030cf601763f6f7ceb3cb5bb26a Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Wed, 28 Jul 2021 16:54:42 +0200 Subject: [PATCH 1/7] perf: partially replace `.concat` with `.push` --- .../babel-cli/src/babel-external-helpers.ts | 6 ++- packages/babel-cli/src/babel/options.ts | 9 ++++- packages/babel-helper-define-map/src/index.js | 3 +- packages/babel-helpers/src/helpers.js | 4 +- packages/babel-node/src/_babel-node.js | 8 +++- packages/babel-node/src/babel-node.js | 4 +- .../babel-parser/src/plugins/flow/index.js | 3 +- .../src/index.js | 2 +- .../src/transformer-legacy.js | 6 +-- .../src/transformClass.ts | 8 ++-- .../src/no-helper-implementation.js | 2 +- .../src/index.js | 10 +++-- .../src/rest.js | 3 +- packages/babel-traverse/src/path/family.ts | 37 +++++++++++-------- .../src/path/inference/inferer-reference.ts | 2 +- .../babel-types/src/comments/addComments.ts | 2 +- .../flow/removeTypeDuplicates.ts | 2 +- .../typescript/removeTypeDuplicates.ts | 2 +- 18 files changed, 70 insertions(+), 43 deletions(-) diff --git a/packages/babel-cli/src/babel-external-helpers.ts b/packages/babel-cli/src/babel-external-helpers.ts index 5c6ef24de6ca..ca09b8ae0bc7 100755 --- a/packages/babel-cli/src/babel-external-helpers.ts +++ b/packages/babel-cli/src/babel-external-helpers.ts @@ -10,7 +10,11 @@ function collect( const values = value.split(","); - return previousValue ? previousValue.concat(values) : values; + if (previousValue) { + Array.prototype.push.apply(previousValue, values); + return previousValue; + } + return values; } commander.option( diff --git a/packages/babel-cli/src/babel/options.ts b/packages/babel-cli/src/babel/options.ts index 19eb9b20c62c..98f67bb0b6d3 100644 --- a/packages/babel-cli/src/babel/options.ts +++ b/packages/babel-cli/src/babel/options.ts @@ -192,7 +192,8 @@ export default function parseArgv(args: Array): CmdOptions | null { let filenames = commander.args.reduce(function (globbed, input) { let files = glob.sync(input); if (!files.length) files = [input]; - return globbed.concat(files); + Array.prototype.push.apply(globbed, files); + return globbed; }, []); filenames = Array.from(new Set(filenames)); @@ -353,5 +354,9 @@ function collect( const values = value.split(","); - return previousValue ? previousValue.concat(values) : values; + if (previousValue) { + Array.prototype.push.apply(previousValue, values); + return previousValue; + } + return values; } diff --git a/packages/babel-helper-define-map/src/index.js b/packages/babel-helper-define-map/src/index.js index 290a50c20202..463026389064 100644 --- a/packages/babel-helper-define-map/src/index.js +++ b/packages/babel-helper-define-map/src/index.js @@ -42,7 +42,8 @@ export function push( if (node.decorators) { const decorators = (map.decorators = map.decorators || t.arrayExpression([])); - decorators.elements = decorators.elements.concat( + Array.prototype.push.apply( + decorators.elements, node.decorators.map(dec => dec.expression).reverse(), ); } diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 73c4e1a4d8bd..59e5c0418d2d 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -316,7 +316,7 @@ helpers.extends = helper("7.0.0-beta.0")` } `; -// This old helper can be removed in babel v8 +// TODO(babel-8): This old helper can be removed in babel v8 helpers.objectSpread = helper("7.0.0-beta.0")` import defineProperty from "defineProperty"; @@ -325,7 +325,7 @@ helpers.objectSpread = helper("7.0.0-beta.0")` var source = (arguments[i] != null) ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { - ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + Array.prototype.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } diff --git a/packages/babel-node/src/_babel-node.js b/packages/babel-node/src/_babel-node.js index 9792d975831a..52f03b40a932 100644 --- a/packages/babel-node/src/_babel-node.js +++ b/packages/babel-node/src/_babel-node.js @@ -21,7 +21,11 @@ function collect(value, previousValue): Array { const values = value.split(","); - return previousValue ? previousValue.concat(values) : values; + if (previousValue) { + Array.prototype.push.apply(previousValue, values); + return previousValue; + } + return values; } program.option("-e, --eval [script]", "Evaluate script"); @@ -197,7 +201,7 @@ if (program.eval || program.print) { } // add back on node and concat the sliced args - process.argv = ["node"].concat(args); + process.argv = ["node", ...args]; process.execArgv.push(fileURLToPath(import.meta.url)); Module.runMain(); diff --git a/packages/babel-node/src/babel-node.js b/packages/babel-node/src/babel-node.js index 8ef4607f58f2..5fd1885c1b37 100755 --- a/packages/babel-node/src/babel-node.js +++ b/packages/babel-node/src/babel-node.js @@ -8,7 +8,7 @@ import path from "path"; import child_process from "child_process"; import { fileURLToPath } from "url"; -let args = [ +const args = [ path.join(path.dirname(fileURLToPath(import.meta.url)), "_babel-node"), ]; @@ -69,7 +69,7 @@ getV8Flags(async function (err, v8Flags) { // append arguments passed after -- if (argSeparator > -1) { - args = args.concat(userArgs); + Array.prototype.push.apply(args, userArgs); } try { diff --git a/packages/babel-parser/src/plugins/flow/index.js b/packages/babel-parser/src/plugins/flow/index.js index 5b5bae52ea2e..2a29bae384c3 100644 --- a/packages/babel-parser/src/plugins/flow/index.js +++ b/packages/babel-parser/src/plugins/flow/index.js @@ -1961,7 +1961,8 @@ export default (superClass: Class): Class => if (failed && valid.length === 1) { this.state = state; - this.state.noArrowAt = noArrowAt.concat(valid[0].start); + noArrowAt.push(valid[0].start); + this.state.noArrowAt = noArrowAt; ({ consequent, failed } = this.tryParseConditionalConsequent()); } } diff --git a/packages/babel-plugin-proposal-async-generator-functions/src/index.js b/packages/babel-plugin-proposal-async-generator-functions/src/index.js index a81607084357..4711f9e2b3fa 100644 --- a/packages/babel-plugin-proposal-async-generator-functions/src/index.js +++ b/packages/babel-plugin-proposal-async-generator-functions/src/index.js @@ -47,7 +47,7 @@ export default declare(api => { } // push the rest of the original loop body onto our new body - block.body = block.body.concat(node.body.body); + Array.prototype.push.apply(block.body, node.body.body); t.inherits(loop, node); t.inherits(loop.body, node.body); diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js index e19a775524cf..5b8dd8d202b8 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js +++ b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js @@ -157,7 +157,7 @@ function applyTargetDecorators(path, state, decoratedProps) { WARNING_CALLS.add(node.value); - acc = acc.concat([ + acc.push( t.assignmentExpression( "=", t.cloneNode(descriptor), @@ -184,9 +184,9 @@ function applyTargetDecorators(path, state, decoratedProps) { ]), ]), ), - ]); + ); } else { - acc = acc.concat( + acc.push( t.callExpression(state.addHelper("applyDecoratedDescriptor"), [ t.cloneNode(target), t.cloneNode(property), diff --git a/packages/babel-plugin-transform-classes/src/transformClass.ts b/packages/babel-plugin-transform-classes/src/transformClass.ts index 4f4a8b6b332e..a7bd7593f952 100644 --- a/packages/babel-plugin-transform-classes/src/transformClass.ts +++ b/packages/babel-plugin-transform-classes/src/transformClass.ts @@ -136,7 +136,8 @@ export default function transformClass( if (classState.userConstructor) { const { constructorBody, userConstructor, construct } = classState; - constructorBody.body = constructorBody.body.concat( + Array.prototype.push.apply( + constructorBody.body, userConstructor.body.body, ); t.inherits(construct, userConstructor); @@ -695,7 +696,7 @@ export default function transformClass( extractDynamicKeys(); - let { body } = classState; + const { body } = classState; const { closureParams, closureArgs } = setupClosureParamsArgs(); buildBody(); @@ -712,7 +713,8 @@ export default function transformClass( ); } - body = body.concat( + Array.prototype.push.apply( + body, classState.staticPropBody.map(fn => fn(t.cloneNode(classState.classRef))), ); diff --git a/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js index 2624f0bc9093..837aef94841d 100644 --- a/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js +++ b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js @@ -24,7 +24,7 @@ export default function transformWithoutHelper(loose, path, state) { } // push the rest of the original loop body onto our new body - block.body = block.body.concat(node.body.body); + Array.prototype.push.apply(block.body, node.body.body); t.inherits(loop, node); t.inherits(loop.body, node.body); diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.js b/packages/babel-plugin-transform-modules-systemjs/src/index.js index 4dd75d8146cc..e7fa09c9f6e3 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.js +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.js @@ -295,7 +295,7 @@ export default declare((api, options) => { const exportMap = Object.create(null); const modules = []; - let beforeBody = []; + const beforeBody = []; const setters = []; const sources = []; const variableIds = []; @@ -475,7 +475,7 @@ export default declare((api, options) => { } modules.forEach(function (specifiers) { - let setterBody = []; + const setterBody = []; const target = scope.generateUid(specifiers.key); for (let specifier of specifiers.imports) { @@ -540,7 +540,8 @@ export default declare((api, options) => { } } - setterBody = setterBody.concat( + Array.prototype.push.apply( + setterBody, constructExportCall( path, t.identifier(exportIdent), @@ -589,7 +590,8 @@ export default declare((api, options) => { } if (exportNames.length) { - beforeBody = beforeBody.concat( + Array.prototype.push.apply( + beforeBody, constructExportCall( path, t.identifier(exportIdent), diff --git a/packages/babel-plugin-transform-parameters/src/rest.js b/packages/babel-plugin-transform-parameters/src/rest.js index cfba76ce4ae4..5cf051185d99 100644 --- a/packages/babel-plugin-transform-parameters/src/rest.js +++ b/packages/babel-plugin-transform-parameters/src/rest.js @@ -305,7 +305,8 @@ export default function convertFunctionRest(path) { return true; } - state.references = state.references.concat( + Array.prototype.push.apply( + state.references, state.candidates.map(({ path }) => path), ); diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 4bf873690081..9190351a0373 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -46,7 +46,9 @@ function addCompletionRecords( records: Completion[], context: CompletionContext, ): Completion[] { - if (path) return records.concat(_getCompletionRecords(path, context)); + if (path) { + Array.prototype.push.apply(records, _getCompletionRecords(path, context)); + } return records; } @@ -73,9 +75,9 @@ function completionRecordForSwitch( if (normalCompletions.length) { lastNormalCompletions = normalCompletions; } - records = records.concat(breakCompletions); + Array.prototype.push.apply(records, breakCompletions); } - records = records.concat(lastNormalCompletions); + Array.prototype.push.apply(records, lastNormalCompletions); return records; } @@ -117,7 +119,7 @@ function getStatementListCompletion( paths: NodePath[], context: CompletionContext, ): Completion[] { - let completions = []; + const completions = []; if (context.canHaveBreak) { let lastNormalCompletions = []; for (let i = 0; i < paths.length; i++) { @@ -155,11 +157,11 @@ function getStatementListCompletion( // When we have seen normal completions from the last statement // it is safe to stop populating break and mark normal completions as break normalCompletionToBreak(lastNormalCompletions); - completions = completions.concat(lastNormalCompletions); + Array.prototype.push.apply(completions, lastNormalCompletions); // Declarations have empty completion record, however they can not be nested // directly in return statement, i.e. `return (var a = 1)` is invalid. if (lastNormalCompletions.some(c => c.path.isDeclaration())) { - completions = completions.concat(statementCompletions); + Array.prototype.push.apply(completions, statementCompletions); replaceBreakStatementInBreakCompletion( statementCompletions, /* reachable */ true, @@ -170,7 +172,7 @@ function getStatementListCompletion( /* reachable */ false, ); } else { - completions = completions.concat(statementCompletions); + Array.prototype.push.apply(completions, statementCompletions); if (!context.shouldPopulateBreak) { replaceBreakStatementInBreakCompletion( statementCompletions, @@ -181,9 +183,10 @@ function getStatementListCompletion( break; } if (i === paths.length - 1) { - completions = completions.concat(statementCompletions); + Array.prototype.push.apply(completions, statementCompletions); } else { - completions = completions.concat( + Array.prototype.push.apply( + completions, statementCompletions.filter(c => c.type === BREAK_COMPLETION), ); lastNormalCompletions = statementCompletions.filter( @@ -202,7 +205,7 @@ function getStatementListCompletion( (pathCompletions.length === 1 && !pathCompletions[0].path.isVariableDeclaration()) ) { - completions = completions.concat(pathCompletions); + Array.prototype.push.apply(completions, pathCompletions); break; } } @@ -227,7 +230,8 @@ function _getCompletionRecords( // @ts-expect-error(flow->ts): todo records = addCompletionRecords(path.get("body"), records, context); } else if (path.isProgram() || path.isBlockStatement()) { - records = records.concat( + Array.prototype.push.apply( + records, // @ts-expect-error(flow->ts): todo getStatementListCompletion(path.get("body"), context), ); @@ -241,7 +245,8 @@ function _getCompletionRecords( } else if (path.isSwitchStatement()) { records = completionRecordForSwitch(path.get("cases"), records, context); } else if (path.isSwitchCase()) { - records = records.concat( + Array.prototype.push.apply( + records, getStatementListCompletion(path.get("consequent"), { canHaveBreak: true, shouldPopulateBreak: false, @@ -495,7 +500,7 @@ export function getBindingIdentifierPaths( [x: string]: NodePath; } { const path = this; - let search = [].concat(path); + const search = [path]; const ids = Object.create(null); while (search.length) { @@ -537,8 +542,10 @@ export function getBindingIdentifierPaths( for (let i = 0; i < keys.length; i++) { const key = keys[i]; const child = id.get(key); - if (Array.isArray(child) || child.node) { - search = search.concat(child); + if (Array.isArray(child)) { + Array.prototype.push.apply(search, child); + } else if (child.node) { + search.push(child); } } } diff --git a/packages/babel-traverse/src/path/inference/inferer-reference.ts b/packages/babel-traverse/src/path/inference/inferer-reference.ts index fc745dd14344..71441dbe39c7 100644 --- a/packages/babel-traverse/src/path/inference/inferer-reference.ts +++ b/packages/babel-traverse/src/path/inference/inferer-reference.ts @@ -84,7 +84,7 @@ function getTypeAnnotationBindingConstantViolations(binding, path, name) { }*/ // add back on function constant violations since we can't track calls - constantViolations = constantViolations.concat(functionConstantViolations); + Array.prototype.push.apply(constantViolations, functionConstantViolations); // push on inferred types of violated paths for (const violation of constantViolations) { diff --git a/packages/babel-types/src/comments/addComments.ts b/packages/babel-types/src/comments/addComments.ts index 7aba0779766b..294e3d9a4e58 100644 --- a/packages/babel-types/src/comments/addComments.ts +++ b/packages/babel-types/src/comments/addComments.ts @@ -16,7 +16,7 @@ export default function addComments( if (type === "leading") { node[key] = comments.concat(node[key]); } else { - node[key] = node[key].concat(comments); + Array.prototype.push.apply(node[key], comments); } } else { node[key] = comments; diff --git a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts index dbe07300fa32..ff75c19e7704 100644 --- a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts @@ -48,7 +48,7 @@ export default function removeTypeDuplicates( if (isUnionTypeAnnotation(node)) { if (typeGroups.indexOf(node.types) < 0) { - nodes = nodes.concat(node.types); + Array.prototype.push.apply(nodes, node.types); typeGroups.push(node.types); } continue; diff --git a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts index b418dafc4b42..18bc7334bbe8 100644 --- a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts @@ -41,7 +41,7 @@ export default function removeTypeDuplicates( if (isTSUnionType(node)) { if (typeGroups.indexOf(node.types) < 0) { - nodes = nodes.concat(node.types); + Array.prototype.push.apply(nodes, node.types); typeGroups.push(node.types); } continue; From b6b920ef41ca1ff5f27e27f37c20ad31169f7dfc Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Thu, 29 Jul 2021 02:02:32 +0200 Subject: [PATCH 2/7] Make `tscheck` happy --- packages/babel-traverse/src/path/family.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 9190351a0373..3238ec8d4b66 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -522,7 +522,7 @@ export function getBindingIdentifierPaths( if (id.isExportDeclaration()) { const declaration = id.get("declaration"); - if (declaration.isDeclaration()) { + if (t.isDeclaration(declaration)) { search.push(declaration); } continue; From 7ce7efaa7b30f9c40986c7e2195e1cb55ff806f7 Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Fri, 30 Jul 2021 01:28:18 +0200 Subject: [PATCH 3/7] Address review --- packages/babel-helpers/src/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 59e5c0418d2d..5994fb6826af 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -325,7 +325,7 @@ helpers.objectSpread = helper("7.0.0-beta.0")` var source = (arguments[i] != null) ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { - Array.prototype.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function(sym) { + ownKeys.push.apply(ownKeys, Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } From c3a4d82728b49920ba7efdba13a7837d0115c3b1 Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Thu, 5 Aug 2021 13:28:02 +0200 Subject: [PATCH 4/7] Use spread push --- .../babel-cli/src/babel-external-helpers.ts | 2 +- packages/babel-cli/src/babel/options.ts | 4 +-- packages/babel-helper-define-map/src/index.js | 5 ++- packages/babel-node/src/_babel-node.js | 2 +- packages/babel-node/src/babel-node.js | 2 +- .../src/index.js | 2 +- .../src/transformClass.ts | 13 ++++---- .../src/no-helper-implementation.js | 2 +- .../src/index.js | 10 +++--- .../src/rest.js | 5 +-- packages/babel-traverse/src/path/family.ts | 33 +++++++++---------- .../src/path/inference/inferer-reference.ts | 2 +- .../babel-types/src/comments/addComments.ts | 2 +- .../flow/removeTypeDuplicates.ts | 4 +-- .../typescript/removeTypeDuplicates.ts | 2 +- 15 files changed, 40 insertions(+), 50 deletions(-) diff --git a/packages/babel-cli/src/babel-external-helpers.ts b/packages/babel-cli/src/babel-external-helpers.ts index ca09b8ae0bc7..930cf56717ef 100755 --- a/packages/babel-cli/src/babel-external-helpers.ts +++ b/packages/babel-cli/src/babel-external-helpers.ts @@ -11,7 +11,7 @@ function collect( const values = value.split(","); if (previousValue) { - Array.prototype.push.apply(previousValue, values); + previousValue.push(...values); return previousValue; } return values; diff --git a/packages/babel-cli/src/babel/options.ts b/packages/babel-cli/src/babel/options.ts index 98f67bb0b6d3..da35ca377b5a 100644 --- a/packages/babel-cli/src/babel/options.ts +++ b/packages/babel-cli/src/babel/options.ts @@ -192,7 +192,7 @@ export default function parseArgv(args: Array): CmdOptions | null { let filenames = commander.args.reduce(function (globbed, input) { let files = glob.sync(input); if (!files.length) files = [input]; - Array.prototype.push.apply(globbed, files); + globbed.push(...files); return globbed; }, []); @@ -355,7 +355,7 @@ function collect( const values = value.split(","); if (previousValue) { - Array.prototype.push.apply(previousValue, values); + previousValue.push(...values); return previousValue; } return values; diff --git a/packages/babel-helper-define-map/src/index.js b/packages/babel-helper-define-map/src/index.js index 463026389064..2d90fb6d2675 100644 --- a/packages/babel-helper-define-map/src/index.js +++ b/packages/babel-helper-define-map/src/index.js @@ -42,9 +42,8 @@ export function push( if (node.decorators) { const decorators = (map.decorators = map.decorators || t.arrayExpression([])); - Array.prototype.push.apply( - decorators.elements, - node.decorators.map(dec => dec.expression).reverse(), + decorators.elements.push( + ...node.decorators.map(dec => dec.expression).reverse(), ); } diff --git a/packages/babel-node/src/_babel-node.js b/packages/babel-node/src/_babel-node.js index 52f03b40a932..7331d99943da 100644 --- a/packages/babel-node/src/_babel-node.js +++ b/packages/babel-node/src/_babel-node.js @@ -22,7 +22,7 @@ function collect(value, previousValue): Array { const values = value.split(","); if (previousValue) { - Array.prototype.push.apply(previousValue, values); + previousValue.push(...values); return previousValue; } return values; diff --git a/packages/babel-node/src/babel-node.js b/packages/babel-node/src/babel-node.js index 5fd1885c1b37..909c6bb978aa 100755 --- a/packages/babel-node/src/babel-node.js +++ b/packages/babel-node/src/babel-node.js @@ -69,7 +69,7 @@ getV8Flags(async function (err, v8Flags) { // append arguments passed after -- if (argSeparator > -1) { - Array.prototype.push.apply(args, userArgs); + args.push(...userArgs); } try { diff --git a/packages/babel-plugin-proposal-async-generator-functions/src/index.js b/packages/babel-plugin-proposal-async-generator-functions/src/index.js index 4711f9e2b3fa..0d4d4492faa5 100644 --- a/packages/babel-plugin-proposal-async-generator-functions/src/index.js +++ b/packages/babel-plugin-proposal-async-generator-functions/src/index.js @@ -47,7 +47,7 @@ export default declare(api => { } // push the rest of the original loop body onto our new body - Array.prototype.push.apply(block.body, node.body.body); + block.body.push(...node.body.body); t.inherits(loop, node); t.inherits(loop.body, node.body); diff --git a/packages/babel-plugin-transform-classes/src/transformClass.ts b/packages/babel-plugin-transform-classes/src/transformClass.ts index a7bd7593f952..a23465dbb920 100644 --- a/packages/babel-plugin-transform-classes/src/transformClass.ts +++ b/packages/babel-plugin-transform-classes/src/transformClass.ts @@ -136,10 +136,8 @@ export default function transformClass( if (classState.userConstructor) { const { constructorBody, userConstructor, construct } = classState; - Array.prototype.push.apply( - constructorBody.body, - userConstructor.body.body, - ); + + constructorBody.body.push(...userConstructor.body.body); t.inherits(construct, userConstructor); t.inherits(constructorBody, userConstructor.body); } @@ -713,9 +711,10 @@ export default function transformClass( ); } - Array.prototype.push.apply( - body, - classState.staticPropBody.map(fn => fn(t.cloneNode(classState.classRef))), + body.push( + ...classState.staticPropBody.map(fn => + fn(t.cloneNode(classState.classRef)), + ), ); const isStrict = path.isInStrictMode(); diff --git a/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js index 837aef94841d..c867a5d0960a 100644 --- a/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js +++ b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js @@ -24,7 +24,7 @@ export default function transformWithoutHelper(loose, path, state) { } // push the rest of the original loop body onto our new body - Array.prototype.push.apply(block.body, node.body.body); + block.body.push(...node.body.body); t.inherits(loop, node); t.inherits(loop.body, node.body); diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.js b/packages/babel-plugin-transform-modules-systemjs/src/index.js index e7fa09c9f6e3..b9407d8c1e10 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.js +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.js @@ -540,9 +540,8 @@ export default declare((api, options) => { } } - Array.prototype.push.apply( - setterBody, - constructExportCall( + setterBody.push( + ...constructExportCall( path, t.identifier(exportIdent), exportNames, @@ -590,9 +589,8 @@ export default declare((api, options) => { } if (exportNames.length) { - Array.prototype.push.apply( - beforeBody, - constructExportCall( + beforeBody.push( + ...constructExportCall( path, t.identifier(exportIdent), exportNames, diff --git a/packages/babel-plugin-transform-parameters/src/rest.js b/packages/babel-plugin-transform-parameters/src/rest.js index 5cf051185d99..2d2f422d3c90 100644 --- a/packages/babel-plugin-transform-parameters/src/rest.js +++ b/packages/babel-plugin-transform-parameters/src/rest.js @@ -305,10 +305,7 @@ export default function convertFunctionRest(path) { return true; } - Array.prototype.push.apply( - state.references, - state.candidates.map(({ path }) => path), - ); + state.references.push(...state.candidates.map(({ path }) => path)); const start = t.numericLiteral(paramsCount); const key = scope.generateUidIdentifier("key"); diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 3238ec8d4b66..2d5442312f05 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -47,7 +47,7 @@ function addCompletionRecords( context: CompletionContext, ): Completion[] { if (path) { - Array.prototype.push.apply(records, _getCompletionRecords(path, context)); + records.push(..._getCompletionRecords(path, context)); } return records; } @@ -75,9 +75,9 @@ function completionRecordForSwitch( if (normalCompletions.length) { lastNormalCompletions = normalCompletions; } - Array.prototype.push.apply(records, breakCompletions); + records.push(...breakCompletions); } - Array.prototype.push.apply(records, lastNormalCompletions); + records.push(...lastNormalCompletions); return records; } @@ -157,11 +157,11 @@ function getStatementListCompletion( // When we have seen normal completions from the last statement // it is safe to stop populating break and mark normal completions as break normalCompletionToBreak(lastNormalCompletions); - Array.prototype.push.apply(completions, lastNormalCompletions); + completions.push(...lastNormalCompletions); // Declarations have empty completion record, however they can not be nested // directly in return statement, i.e. `return (var a = 1)` is invalid. if (lastNormalCompletions.some(c => c.path.isDeclaration())) { - Array.prototype.push.apply(completions, statementCompletions); + completions.push(...statementCompletions); replaceBreakStatementInBreakCompletion( statementCompletions, /* reachable */ true, @@ -172,7 +172,7 @@ function getStatementListCompletion( /* reachable */ false, ); } else { - Array.prototype.push.apply(completions, statementCompletions); + completions.push(...statementCompletions); if (!context.shouldPopulateBreak) { replaceBreakStatementInBreakCompletion( statementCompletions, @@ -183,11 +183,10 @@ function getStatementListCompletion( break; } if (i === paths.length - 1) { - Array.prototype.push.apply(completions, statementCompletions); + completions.push(...statementCompletions); } else { - Array.prototype.push.apply( - completions, - statementCompletions.filter(c => c.type === BREAK_COMPLETION), + completions.push( + ...statementCompletions.filter(c => c.type === BREAK_COMPLETION), ); lastNormalCompletions = statementCompletions.filter( c => c.type === NORMAL_COMPLETION, @@ -205,7 +204,7 @@ function getStatementListCompletion( (pathCompletions.length === 1 && !pathCompletions[0].path.isVariableDeclaration()) ) { - Array.prototype.push.apply(completions, pathCompletions); + completions.push(...pathCompletions); break; } } @@ -230,10 +229,9 @@ function _getCompletionRecords( // @ts-expect-error(flow->ts): todo records = addCompletionRecords(path.get("body"), records, context); } else if (path.isProgram() || path.isBlockStatement()) { - Array.prototype.push.apply( - records, + records.push( // @ts-expect-error(flow->ts): todo - getStatementListCompletion(path.get("body"), context), + ...getStatementListCompletion(path.get("body"), context), ); } else if (path.isFunction()) { return _getCompletionRecords(path.get("body"), context); @@ -245,9 +243,8 @@ function _getCompletionRecords( } else if (path.isSwitchStatement()) { records = completionRecordForSwitch(path.get("cases"), records, context); } else if (path.isSwitchCase()) { - Array.prototype.push.apply( - records, - getStatementListCompletion(path.get("consequent"), { + records.push( + ...getStatementListCompletion(path.get("consequent"), { canHaveBreak: true, shouldPopulateBreak: false, inCaseClause: true, @@ -543,7 +540,7 @@ export function getBindingIdentifierPaths( const key = keys[i]; const child = id.get(key); if (Array.isArray(child)) { - Array.prototype.push.apply(search, child); + search.push(...child); } else if (child.node) { search.push(child); } diff --git a/packages/babel-traverse/src/path/inference/inferer-reference.ts b/packages/babel-traverse/src/path/inference/inferer-reference.ts index 71441dbe39c7..a2ef981955ee 100644 --- a/packages/babel-traverse/src/path/inference/inferer-reference.ts +++ b/packages/babel-traverse/src/path/inference/inferer-reference.ts @@ -84,7 +84,7 @@ function getTypeAnnotationBindingConstantViolations(binding, path, name) { }*/ // add back on function constant violations since we can't track calls - Array.prototype.push.apply(constantViolations, functionConstantViolations); + constantViolations.push(...functionConstantViolations); // push on inferred types of violated paths for (const violation of constantViolations) { diff --git a/packages/babel-types/src/comments/addComments.ts b/packages/babel-types/src/comments/addComments.ts index 294e3d9a4e58..a01ce1c42b94 100644 --- a/packages/babel-types/src/comments/addComments.ts +++ b/packages/babel-types/src/comments/addComments.ts @@ -16,7 +16,7 @@ export default function addComments( if (type === "leading") { node[key] = comments.concat(node[key]); } else { - Array.prototype.push.apply(node[key], comments); + node[key].push(...comments); } } else { node[key] = comments; diff --git a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts index ff75c19e7704..90d8ba233a17 100644 --- a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts @@ -17,7 +17,7 @@ function getQualifiedName(node: t.GenericTypeAnnotation["id"]) { * Dedupe type annotations. */ export default function removeTypeDuplicates( - nodes: ReadonlyArray, + nodes: (t.FlowType | false | null | undefined)[], ): t.FlowType[] { const generics = {}; const bases = {}; @@ -48,7 +48,7 @@ export default function removeTypeDuplicates( if (isUnionTypeAnnotation(node)) { if (typeGroups.indexOf(node.types) < 0) { - Array.prototype.push.apply(nodes, node.types); + nodes.push(...node.types); typeGroups.push(node.types); } continue; diff --git a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts index 18bc7334bbe8..0b9f3f30787f 100644 --- a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts @@ -41,7 +41,7 @@ export default function removeTypeDuplicates( if (isTSUnionType(node)) { if (typeGroups.indexOf(node.types) < 0) { - Array.prototype.push.apply(nodes, node.types); + nodes.push(...node.types); typeGroups.push(node.types); } continue; From f14a2d9ad699ccd585d5e658e2939069967f6979 Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Sat, 7 Aug 2021 16:04:19 +0200 Subject: [PATCH 5/7] Minor refactoring --- packages/babel-traverse/src/path/family.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 2d5442312f05..0e38ec28a751 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -185,12 +185,16 @@ function getStatementListCompletion( if (i === paths.length - 1) { completions.push(...statementCompletions); } else { - completions.push( - ...statementCompletions.filter(c => c.type === BREAK_COMPLETION), - ); - lastNormalCompletions = statementCompletions.filter( - c => c.type === NORMAL_COMPLETION, - ); + lastNormalCompletions = []; + for (let i = 0; i < statementCompletions.length; i++) { + const c = statementCompletions[i]; + if (c.type === BREAK_COMPLETION) { + completions.push(c); + } + if (c.type === NORMAL_COMPLETION) { + lastNormalCompletions.push(c); + } + } } } } else if (paths.length) { From b5d80a622309c8c507dd9479f5ebc2609f0416c7 Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Wed, 11 Aug 2021 10:18:25 +0200 Subject: [PATCH 6/7] Code review suggestions --- packages/babel-traverse/src/path/family.ts | 24 ++++++++----------- .../flow/removeTypeDuplicates.ts | 6 +++-- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 0e38ec28a751..6b49758ba489 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -231,29 +231,25 @@ function _getCompletionRecords( path.isLabeledStatement() ) { // @ts-expect-error(flow->ts): todo - records = addCompletionRecords(path.get("body"), records, context); + return addCompletionRecords(path.get("body"), records, context); } else if (path.isProgram() || path.isBlockStatement()) { - records.push( - // @ts-expect-error(flow->ts): todo - ...getStatementListCompletion(path.get("body"), context), - ); + // @ts-expect-error(flow->ts): todo + return getStatementListCompletion(path.get("body"), context); } else if (path.isFunction()) { return _getCompletionRecords(path.get("body"), context); } else if (path.isTryStatement()) { records = addCompletionRecords(path.get("block"), records, context); records = addCompletionRecords(path.get("handler"), records, context); } else if (path.isCatchClause()) { - records = addCompletionRecords(path.get("body"), records, context); + return addCompletionRecords(path.get("body"), records, context); } else if (path.isSwitchStatement()) { - records = completionRecordForSwitch(path.get("cases"), records, context); + return completionRecordForSwitch(path.get("cases"), records, context); } else if (path.isSwitchCase()) { - records.push( - ...getStatementListCompletion(path.get("consequent"), { - canHaveBreak: true, - shouldPopulateBreak: false, - inCaseClause: true, - }), - ); + return getStatementListCompletion(path.get("consequent"), { + canHaveBreak: true, + shouldPopulateBreak: false, + inCaseClause: true, + }); } else if (path.isBreakStatement()) { records.push(BreakCompletion(path)); } else { diff --git a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts index 90d8ba233a17..b57d62e0eec1 100644 --- a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts @@ -17,7 +17,8 @@ function getQualifiedName(node: t.GenericTypeAnnotation["id"]) { * Dedupe type annotations. */ export default function removeTypeDuplicates( - nodes: (t.FlowType | false | null | undefined)[], + // todo(babel-8): change type to Array<...> + nodes: ReadonlyArray, ): t.FlowType[] { const generics = {}; const bases = {}; @@ -48,7 +49,8 @@ export default function removeTypeDuplicates( if (isUnionTypeAnnotation(node)) { if (typeGroups.indexOf(node.types) < 0) { - nodes.push(...node.types); + // todo(babel-8): remove type casting + (nodes as any).push(...node.types); typeGroups.push(node.types); } continue; From 3e5a73124d63d3e8dcfd20ed84bb3dbe16357026 Mon Sep 17 00:00:00 2001 From: Federico Ciardi Date: Sat, 14 Aug 2021 13:29:40 +0200 Subject: [PATCH 7/7] Update removeTypeDuplicates --- .../src/modifications/flow/removeTypeDuplicates.ts | 10 +++++----- .../modifications/typescript/removeTypeDuplicates.ts | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts index b57d62e0eec1..717b993d5a0d 100644 --- a/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/flow/removeTypeDuplicates.ts @@ -24,7 +24,7 @@ export default function removeTypeDuplicates( const bases = {}; // store union type groups to circular references - const typeGroups = []; + const typeGroups = new Set(); const types = []; @@ -48,10 +48,10 @@ export default function removeTypeDuplicates( } if (isUnionTypeAnnotation(node)) { - if (typeGroups.indexOf(node.types) < 0) { - // todo(babel-8): remove type casting - (nodes as any).push(...node.types); - typeGroups.push(node.types); + if (!typeGroups.has(node.types)) { + // todo(babel-8): use .push when nodes is mutable + nodes = nodes.concat(node.types); + typeGroups.add(node.types); } continue; } diff --git a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts index 0b9f3f30787f..da5c565f198f 100644 --- a/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts +++ b/packages/babel-types/src/modifications/typescript/removeTypeDuplicates.ts @@ -15,7 +15,7 @@ export default function removeTypeDuplicates( const bases = {}; // store union type groups to circular references - const typeGroups = []; + const typeGroups = new Set(); const types = []; @@ -40,9 +40,9 @@ export default function removeTypeDuplicates( } if (isTSUnionType(node)) { - if (typeGroups.indexOf(node.types) < 0) { + if (!typeGroups.has(node.types)) { nodes.push(...node.types); - typeGroups.push(node.types); + typeGroups.add(node.types); } continue; }