Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ccf0428

Browse files
committed
improve babel@8 compatibility, test both - babel@{ 7, 8 }
1 parent 9d33aec commit ccf0428

166 files changed

Lines changed: 2502 additions & 110 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ jobs:
101101
node-version: ${{ matrix.node }}
102102
cache: npm
103103
- run: npm run prepare-monorepo
104-
- run: npx run-s bundle test-unit-node test-entries test-compat-data test-compat-tools test-builder test-polyfill-provider test-babel-plugin test-babel-plugin-unit test-unplugin test-unplugin-unit test-transpiler-integration
104+
- run: npx run-s bundle test-unit-node test-entries test-compat-data test-compat-tools test-builder test-transpiling

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"lint": "run-s prepare lint-raw",
4343
"lint-raw": "run-s build-types test-eslint bundle-package test-publint",
4444
"test": "run-s prepare test-raw",
45-
"test-raw": "run-s lint-raw types-coverage bundle-tests test-unit test-promises test-type-definitions-smoke test-builder test-polyfill-provider test-babel-plugin test-babel-plugin-unit test-unplugin test-unplugin-unit test-transpiler-integration test-entries test-compat-data test-compat-tools check",
45+
"test-raw": "run-s lint-raw types-coverage bundle-tests test-unit test-promises test-type-definitions-smoke test-builder test-transpiling test-entries test-compat-data test-compat-tools check",
4646
"test-eslint": "npm run zxi time tests/eslint/runner.mjs",
4747
"test-publint": "npm run zxi time tests/publint/runner.mjs",
4848
"test-unit": "run-s test-unit-karma test-unit-node test-unit-bun",
@@ -53,10 +53,13 @@
5353
"test-entries": "npm run zxi tests/entries/index.mjs",
5454
"test-babel-plugin": "npm run zxi time cd tests/babel-plugin/index.mjs",
5555
"test-babel-plugin-unit": "npm run zxi time cd tests/babel-plugin/unit.mjs",
56+
"test-babel-plugin-unit-v8": "BABEL_REQUIRE_FROM=../babel-plugin-v8 npm run zxi time cd tests/babel-plugin-v8/unit.mjs",
57+
"test-babel-plugin-v8": "BABEL_REQUIRE_FROM=../babel-plugin-v8 BABEL_SKIP=../babel-plugin-v8/skip.mjs BABEL_VARIANT=babel-v8 npm run zxi time cd tests/babel-plugin-v8/runner.mjs",
5658
"test-polyfill-provider": "npm run zxi time cd tests/polyfill-provider/index.mjs",
5759
"test-unplugin": "npm run zxi time cd tests/unplugin/index.mjs",
5860
"test-unplugin-unit": "npm run zxi time cd tests/unplugin/unit.mjs",
5961
"test-transpiler-integration": "npm run zxi time cd tests/transpiler-integration/runner.mjs",
62+
"test-transpiling": "run-s test-polyfill-provider test-babel-plugin test-babel-plugin-unit test-babel-plugin-v8 test-babel-plugin-unit-v8 test-unplugin test-unplugin-unit test-transpiler-integration",
6063
"test-builder": "npm run zxi tests/builder/builder.mjs",
6164
"test-compat-data": "npm run zxi tests/compat-data/index.mjs",
6265
"test-compat-tools": "npm run zxi tests/compat-tools/index.mjs",

packages/core-js-babel-plugin/internals/destructure-emitter.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -707,10 +707,9 @@ export default function createDestructureEmitter({
707707
// position around the consumed slot. pre-siblings run before the lifted SE, post-siblings
708708
// after the extracted target. earlier collapsed-trailing emission silently reordered
709709
// pre-sibling initializers past the SE expression, observable when both sides carry effects
710-
function wrapBodylessWithSideEffect({ declaration, initNode, parentDeclarator, extractedDeclaration }) {
710+
function wrapBodylessWithSideEffect({ declaration, initNode, parentDeclarator, extractedDeclaration, kind }) {
711711
const decls = declaration.node.declarations;
712712
const idx = decls.indexOf(parentDeclarator);
713-
const { kind } = declaration.node;
714713
const stmts = [];
715714
if (idx > 0) stmts.push(t.variableDeclaration(kind, decls.slice(0, idx)));
716715
stmts.push(t.expressionStatement(t.cloneDeep(initNode)), extractedDeclaration);
@@ -869,15 +868,37 @@ export default function createDestructureEmitter({
869868
};
870869
}
871870

871+
// @babel/traverse@8 stale-path fixup: an earlier emit in the same handleObjectPropertyResult
872+
// chain (cascade extraction) may have wrapped a bodyless VariableDeclaration in BlockStatement
873+
// and `parent.parentPath` now points at the wrapper. raw `parent.parent` is still the real
874+
// VariableDeclaration - scan the wrapper's children for the matching path. babel@7's tracker
875+
// kept paths in sync so this is a no-op there
876+
function resolveDeclarationPath(declaratorPath) {
877+
const declaration = declaratorPath.parentPath;
878+
if (declaration.isBlockStatement() && declaratorPath.parent?.type === 'VariableDeclaration') {
879+
const rebound = declaration.get('body').find(p => p.node === declaratorPath.parent);
880+
if (rebound) return rebound;
881+
}
882+
return declaration;
883+
}
884+
885+
// kind snapshot resilient to downstream path-orphaning. fall through declaration -> statement
886+
// parent -> `var` (the only kind valid inside bodyless control hosts where wrap fires).
887+
// @babel/types@7 silently accepted undefined in variableDeclaration builders; v8 throws
888+
function snapshotDeclarationKind(declaration) {
889+
return declaration.node.kind ?? findStatementParent(declaration).node?.kind ?? 'var';
890+
}
891+
872892
// VariableDeclarator branch executor. classifies the host shape, asks the planner
873893
// for a strategy, then dispatches to the matching AST mutation
874894
function emitVariableDeclaratorDestructure({ prop, parent, localBinding, value, isStaticValue, isEmpty }) {
875-
const declaration = parent.parentPath;
895+
const declaration = resolveDeclarationPath(parent);
876896
// save original index before first insertBefore shifts it
877897
if (!originalDeclKeys.has(declaration.node)) {
878898
originalDeclKeys.set(declaration.node, findStatementParent(declaration).key);
879899
}
880-
const extractedDeclaration = t.variableDeclaration(declaration.node.kind, [
900+
const kind = snapshotDeclarationKind(declaration);
901+
const extractedDeclaration = t.variableDeclaration(kind, [
881902
t.variableDeclarator(localBinding, value),
882903
]);
883904
const ctx = classifyVariableDeclaratorSite({ declaration, parent, isStaticValue, isEmpty });
@@ -889,6 +910,7 @@ export default function createDestructureEmitter({
889910
initNode: parent.node.init,
890911
parentDeclarator: parent.node,
891912
extractedDeclaration,
913+
kind,
892914
});
893915
case STRATEGIES.FOR_INIT_SE_STATIC:
894916
case STRATEGIES.FOR_INIT_SE_INSTANCE:

packages/core-js-babel-plugin/internals/detect-usage.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,13 @@ export function createSyntaxVisitors({ injectModulesForModeEntry, injectModulesF
436436
injectModulesForModeEntry, injectModulesForEntry, isDisabled, isWebpack,
437437
});
438438
return {
439+
// CallExpression path covers @babel/parser@7 where `import('mod')` is
440+
// CallExpression { callee: { type: 'Import' } }. @babel/parser@8 parses the same
441+
// source as a top-level ImportExpression node - hence the second visitor below
439442
CallExpression(path) {
440443
if (path.get('callee').isImport()) rules.onImportExpression(path.node);
441444
},
445+
ImportExpression(path) { rules.onImportExpression(path.node); },
442446
Function(path) { rules.onFunction(path.node); },
443447
'ForOfStatement|ArrayPattern'(path) {
444448
if (path.isForOfStatement()) rules.onForOfStatement(path.node);

packages/core-js-babel-plugin/internals/import-injector.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@ import { resolveImportPath } from '@core-js/polyfill-provider/helpers/path-norma
22
import ImportInjectorState from '@core-js/polyfill-provider/injector-base';
33
import { polyfillOrderComparator, sortByPolyfillOrder } from '@core-js/polyfill-provider/plugin-options/inject';
44

5+
// babel@7 exposes `scope.references` / `scope.uids` as object maps; babel@8 replaced them
6+
// with `scope.referencesSet` / `scope.uidsSet` (real Sets) and throws on the legacy
7+
// accessors. one probe of any scope at injector construction commits the bag to a single
8+
// path - no runtime checks on subsequent calls. the API surface is invariant across all
9+
// scopes of a given babel install, so probing once is sufficient
10+
function makeScopeBag(probeScope, setKey, mapKey) {
11+
if (probeScope[setKey]) return {
12+
has: (scope, name) => scope[setKey].has(name),
13+
add: (scope, name) => scope[setKey].add(name),
14+
list: scope => scope[setKey],
15+
};
16+
return {
17+
has: (scope, name) => !!scope[mapKey]?.[name],
18+
add(scope, name) { (scope[mapKey] ??= {})[name] = true; },
19+
list: scope => Object.keys(scope[mapKey] ?? {}),
20+
};
21+
}
22+
523
export default class ImportInjector extends ImportInjectorState {
624
#t;
725
#programPath;
@@ -31,11 +49,17 @@ export default class ImportInjector extends ImportInjectorState {
3149
// sibling imports. flag set by `reorderImportRegion`, asserted by
3250
// `reorderRefsAfterImports` so caller-order violations surface as a clear error
3351
#importRegionSorted = false;
52+
// scope-bag accessors specialised once per injector to the babel version's API
53+
#scopeReferences;
54+
#scopeUids;
3455

3556
constructor({ t, programPath, pkg, packages = null, mode, importStyle, absoluteImports = false }) {
3657
super({ absoluteImports, mode, pkg, importStyle, packages });
3758
this.#t = t;
3859
this.#programPath = programPath;
60+
const program = programPath.scope.getProgramParent();
61+
this.#scopeReferences = makeScopeBag(program, 'referencesSet', 'references');
62+
this.#scopeUids = makeScopeBag(program, 'uidsSet', 'uids');
3963
}
4064

4165
// post-hook safety-net needs to know whether any import has already been written so
@@ -53,7 +77,7 @@ export default class ImportInjector extends ImportInjectorState {
5377
// land here. without it, UID generator would pick `_Map` and collide with a user's
5478
// accidental `_Map = ...` sloppy global (reassigning our const import throws at runtime)
5579
return scope.hasBinding(name) || !!program.globals[name]
56-
|| !!program.references[name] || !!program.uids[name];
80+
|| this.#scopeReferences.has(program, name) || this.#scopeUids.has(program, name);
5781
}
5882

5983
// publish every allocated UID into program.references/.uids so sibling transforms
@@ -66,8 +90,8 @@ export default class ImportInjector extends ImportInjectorState {
6690
uniqueName(prefix, extraCheck) {
6791
const name = super.uniqueName(prefix, extraCheck);
6892
const program = this.#programPath.scope.getProgramParent();
69-
program.references[name] = true;
70-
program.uids[name] = true;
93+
this.#scopeReferences.add(program, name);
94+
this.#scopeUids.add(program, name);
7195
return name;
7296
}
7397

@@ -197,8 +221,8 @@ export default class ImportInjector extends ImportInjectorState {
197221
this.#forEachScopeBinding(([name]) => taken.add(name));
198222
const program = this.#programPath.scope.getProgramParent();
199223
for (const n of Object.keys(program.globals ?? {})) taken.add(n);
200-
for (const n of Object.keys(program.references ?? {})) taken.add(n);
201-
for (const n of Object.keys(program.uids ?? {})) taken.add(n);
224+
for (const n of this.#scopeReferences.list(program)) taken.add(n);
225+
for (const n of this.#scopeUids.list(program)) taken.add(n);
202226
return taken;
203227
}
204228

packages/core-js-polyfill-provider/resolve-node-type/name-resolution.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ import {
2525
import { collectQualifiedSegments, isInterfaceDeclaration, isTypeAlias } from './ast-shapes.js';
2626
import { unwrapExportedDeclaration } from '../helpers/ast-patterns.js';
2727

28+
// `declare global { ... }` opens a program-scope augmentation block. @babel/parser@7 flags it
29+
// with a boolean `decl.global`; @babel/parser@8 dropped that field and only sets `kind: 'global'`
30+
function isGlobalAugmentation(decl) {
31+
return decl.global || decl.kind === 'global';
32+
}
33+
2834
// TS `declare class X` is parsed as ClassDeclaration { declare: true }, not DeclareClass.
2935
// module-level functions so `ambientDeclCache` keys by identity stay stable across calls
3036
export function isAmbientFunctionNode(node) {
@@ -196,10 +202,10 @@ export function createNameResolution({ t }) {
196202
if (decl.type !== 'TSModuleDeclaration') continue;
197203
const moduleSegs = moduleNameSegments(decl.id);
198204
if (!moduleSegs) continue;
199-
// `declare global { ... }` augments program scope - its body's bindings are visible
200-
// at every depth. descend regardless of segment count so both `Box` (bare) and
201-
// `NS.Foo` (qualified via `declare global { namespace NS {} }`) resolve through it
202-
if (decl.global) {
205+
// `declare global { ... }` body bindings are visible at every depth - descend regardless
206+
// of segment count so both `Box` (bare) and `NS.Foo` (qualified via `declare global {
207+
// namespace NS {} }`) resolve through it
208+
if (isGlobalAugmentation(decl)) {
203209
const inner = walkStatementsForDecl({ segments, statements: moduleStatements(decl), collect, leafMatch });
204210
if (inner && !collect) return inner;
205211
continue;
@@ -452,10 +458,9 @@ export function createNameResolution({ t }) {
452458
// own body on every bare segment query, doubling work on deep TSModuleDeclaration trees
453459
if (rest.length === 0) continue;
454460
if (decl.type !== 'TSModuleDeclaration') continue;
455-
// `declare global { ... }` augments program scope: descend its body for any segment
456-
// depth, mirrors `walkStatementsForDecl`. without this branch the NodePath-walking
457-
// variant misses globally-augmented decls that the node-walking variant finds
458-
if (decl.global) {
461+
// NodePath-walking mirror of `walkStatementsForDecl`'s global-augmentation branch -
462+
// without this the path variant misses globally-augmented decls that the node variant finds
463+
if (isGlobalAugmentation(decl)) {
459464
const bodyPath = declPath.get('body');
460465
const innerPaths = bodyPath?.node?.type === 'TSModuleDeclaration'
461466
? [bodyPath]

0 commit comments

Comments
 (0)