Skip to content

Commit 9fad3a8

Browse files
authored
Fix: do not report global variables as injected binding (#14827)
* test: update regression/10162 * fix: global variables must not be global types * refactor: let GLOBAL_TYPES be a map<scope, set> * log warning messages to test fixtures
1 parent ba802fe commit 9fad3a8

17 files changed

Lines changed: 78 additions & 33 deletions

File tree

packages/babel-plugin-transform-typescript/src/index.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { declare } from "@babel/helper-plugin-utils";
22
import syntaxTypeScript from "@babel/plugin-syntax-typescript";
33
import { types as t, template } from "@babel/core";
44
import { injectInitialization } from "@babel/helper-create-class-features-plugin";
5-
import type { Binding, NodePath } from "@babel/traverse";
5+
import type { Binding, NodePath, Scope } from "@babel/traverse";
66
import type { Options as SyntaxOptions } from "@babel/plugin-syntax-typescript";
77

88
import transpileConstEnum from "./const-enum";
@@ -27,17 +27,16 @@ function isInType(path: NodePath) {
2727
}
2828
}
2929

30-
const GLOBAL_TYPES = new WeakMap();
30+
const GLOBAL_TYPES = new WeakMap<Scope, Set<string>>();
3131
// Track programs which contain imports/exports of values, so that we can include
3232
// empty exports for programs that do not, but were parsed as modules. This allows
3333
// tools to infer unamibiguously that results are ESM.
3434
const NEEDS_EXPLICIT_ESM = new WeakMap();
3535
const PARSED_PARAMS = new WeakSet();
3636

37-
function isGlobalType(path: NodePath, name: string) {
38-
const program = path.find(path => path.isProgram()).node;
39-
if (path.scope.hasOwnBinding(name)) return false;
40-
if (GLOBAL_TYPES.get(program).has(name)) return true;
37+
function isGlobalType({ scope }: NodePath, name: string) {
38+
if (scope.hasBinding(name)) return false;
39+
if (GLOBAL_TYPES.get(scope).has(name)) return true;
4140

4241
console.warn(
4342
`The exported identifier "${name}" is not declared in Babel's scope tracker\n` +
@@ -52,8 +51,8 @@ function isGlobalType(path: NodePath, name: string) {
5251
return false;
5352
}
5453

55-
function registerGlobalType(programNode: t.Program, name: string) {
56-
GLOBAL_TYPES.get(programNode).add(name);
54+
function registerGlobalType(programScope: Scope, name: string) {
55+
GLOBAL_TYPES.get(programScope).add(name);
5756
}
5857
export interface Options extends SyntaxOptions {
5958
/** @default true */
@@ -213,10 +212,10 @@ export default declare((api, opts: Options) => {
213212
const { file } = state;
214213
let fileJsxPragma = null;
215214
let fileJsxPragmaFrag = null;
216-
const programNode = path.node;
215+
const programScope = path.scope;
217216

218-
if (!GLOBAL_TYPES.has(programNode)) {
219-
GLOBAL_TYPES.set(programNode, new Set());
217+
if (!GLOBAL_TYPES.has(programScope)) {
218+
GLOBAL_TYPES.set(programScope, new Set());
220219
}
221220

222221
if (file.ast.comments) {
@@ -252,7 +251,7 @@ export default declare((api, opts: Options) => {
252251

253252
if (stmt.node.importKind === "type") {
254253
for (const specifier of stmt.node.specifiers) {
255-
registerGlobalType(programNode, specifier.local.name);
254+
registerGlobalType(programScope, specifier.local.name);
256255
}
257256
stmt.remove();
258257
continue;
@@ -269,7 +268,7 @@ export default declare((api, opts: Options) => {
269268
specifier.type === "ImportSpecifier" &&
270269
specifier.importKind === "type"
271270
) {
272-
registerGlobalType(programNode, specifier.local.name);
271+
registerGlobalType(programScope, specifier.local.name);
273272
const binding = stmt.scope.getBinding(specifier.local.name);
274273
if (binding) {
275274
importsToRemove.add(binding.path);
@@ -332,7 +331,7 @@ export default declare((api, opts: Options) => {
332331

333332
if (stmt.isVariableDeclaration({ declare: true })) {
334333
for (const name of Object.keys(stmt.getBindingIdentifiers())) {
335-
registerGlobalType(programNode, name);
334+
registerGlobalType(programScope, name);
336335
}
337336
} else if (
338337
stmt.isTSTypeAliasDeclaration() ||
@@ -344,7 +343,7 @@ export default declare((api, opts: Options) => {
344343
stmt.get("id").isIdentifier())
345344
) {
346345
registerGlobalType(
347-
programNode,
346+
programScope,
348347
//@ts-expect-error
349348
stmt.node.id.name,
350349
);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const enum None {};
2+
export type { None };
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"plugins": ["transform-typescript"],
3+
"sourceType": "module",
4+
"validateLogs": true
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
var None;
2+
3+
(function (None) {})(None || (None = {}));
4+
5+
;
6+
export {};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default undefined;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"plugins": ["transform-typescript"],
3+
"sourceType": "module",
4+
"validateLogs": true
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default undefined;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default Math;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"plugins": ["transform-typescript"],
3+
"sourceType": "module",
4+
"validateLogs": true
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default Math;

0 commit comments

Comments
 (0)