convert @babel/helper-module-transforms to typescript (#12928)
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
e5e37b94a5
commit
6ac07a1647
@ -208,3 +208,7 @@ declare module "@babel/highlight" {
|
|||||||
declare module "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" {
|
declare module "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" {
|
||||||
declare module.exports: any;
|
declare module.exports: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module "@babel/helper-module-transforms" {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
export default function getModuleName(
|
export default function getModuleName(
|
||||||
rootOpts: Object,
|
rootOpts: any,
|
||||||
pluginOpts: Object,
|
pluginOpts: any,
|
||||||
): ?string {
|
): string | undefined | null {
|
||||||
const {
|
const {
|
||||||
filename,
|
filename,
|
||||||
filenameRelative = filename,
|
filenameRelative = filename,
|
||||||
@ -9,9 +9,13 @@ import rewriteLiveReferences from "./rewrite-live-references";
|
|||||||
import normalizeAndLoadModuleMetadata, {
|
import normalizeAndLoadModuleMetadata, {
|
||||||
hasExports,
|
hasExports,
|
||||||
isSideEffectImport,
|
isSideEffectImport,
|
||||||
type ModuleMetadata,
|
|
||||||
type SourceModuleMetadata,
|
|
||||||
} from "./normalize-and-load-metadata";
|
} from "./normalize-and-load-metadata";
|
||||||
|
import type {
|
||||||
|
InteropType,
|
||||||
|
ModuleMetadata,
|
||||||
|
SourceModuleMetadata,
|
||||||
|
} from "./normalize-and-load-metadata";
|
||||||
|
import type { NodePath } from "@babel/traverse";
|
||||||
|
|
||||||
export { default as getModuleName } from "./get-module-name";
|
export { default as getModuleName } from "./get-module-name";
|
||||||
|
|
||||||
@ -24,7 +28,7 @@ export { hasExports, isSideEffectImport, isModule, rewriteThis };
|
|||||||
* and returns a list of statements for use when initializing the module.
|
* and returns a list of statements for use when initializing the module.
|
||||||
*/
|
*/
|
||||||
export function rewriteModuleStatementsAndPrepareHeader(
|
export function rewriteModuleStatementsAndPrepareHeader(
|
||||||
path: NodePath,
|
path: NodePath<t.Program>,
|
||||||
{
|
{
|
||||||
// TODO(Babel 8): Remove this
|
// TODO(Babel 8): Remove this
|
||||||
loose,
|
loose,
|
||||||
@ -39,6 +43,17 @@ export function rewriteModuleStatementsAndPrepareHeader(
|
|||||||
|
|
||||||
constantReexports = loose,
|
constantReexports = loose,
|
||||||
enumerableModuleMeta = loose,
|
enumerableModuleMeta = loose,
|
||||||
|
}: {
|
||||||
|
exportName?;
|
||||||
|
strict;
|
||||||
|
allowTopLevelThis?;
|
||||||
|
strictMode;
|
||||||
|
loose?;
|
||||||
|
noInterop?;
|
||||||
|
lazy?;
|
||||||
|
esNamespaceOnly?;
|
||||||
|
constantReexports?;
|
||||||
|
enumerableModuleMeta?;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
assert(isModule(path), "Cannot process module statements in a script");
|
assert(isModule(path), "Cannot process module statements in a script");
|
||||||
@ -106,9 +121,9 @@ export function ensureStatementsHoisted(statements) {
|
|||||||
*/
|
*/
|
||||||
export function wrapInterop(
|
export function wrapInterop(
|
||||||
programPath: NodePath,
|
programPath: NodePath,
|
||||||
expr: Node,
|
expr: t.Expression,
|
||||||
type: InteropType,
|
type: InteropType,
|
||||||
): Node {
|
): t.CallExpression {
|
||||||
if (type === "none") {
|
if (type === "none") {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -138,7 +153,7 @@ export function buildNamespaceInitStatements(
|
|||||||
) {
|
) {
|
||||||
const statements = [];
|
const statements = [];
|
||||||
|
|
||||||
let srcNamespace = t.identifier(sourceMetadata.name);
|
let srcNamespace: t.Node = t.identifier(sourceMetadata.name);
|
||||||
if (sourceMetadata.lazy) srcNamespace = t.callExpression(srcNamespace, []);
|
if (sourceMetadata.lazy) srcNamespace = t.callExpression(srcNamespace, []);
|
||||||
|
|
||||||
for (const localName of sourceMetadata.importsNamespace) {
|
for (const localName of sourceMetadata.importsNamespace) {
|
||||||
@ -329,7 +344,7 @@ function buildExportNameListDeclaration(
|
|||||||
exportedVars[exportName] = true;
|
exportedVars[exportName] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasReexport = hasReexport || data.reexportAll;
|
hasReexport = hasReexport || !!data.reexportAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasReexport || Object.keys(exportedVars).length === 0) return null;
|
if (!hasReexport || Object.keys(exportedVars).length === 0) return null;
|
||||||
@ -1,61 +1,52 @@
|
|||||||
import { basename, extname } from "path";
|
import { basename, extname } from "path";
|
||||||
|
import type * as t from "@babel/types";
|
||||||
|
|
||||||
import { isIdentifierName } from "@babel/helper-validator-identifier";
|
import { isIdentifierName } from "@babel/helper-validator-identifier";
|
||||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
|
import type { NodePath } from "@babel/traverse";
|
||||||
|
|
||||||
export type ModuleMetadata = {
|
export interface ModuleMetadata {
|
||||||
exportName: string,
|
exportName: string;
|
||||||
|
|
||||||
// The name of the variable that will reference an object containing export names.
|
// The name of the variable that will reference an object containing export names.
|
||||||
exportNameListName: null | string,
|
exportNameListName: null | string;
|
||||||
|
hasExports: boolean;
|
||||||
hasExports: boolean,
|
|
||||||
|
|
||||||
// Lookup from local binding to export information.
|
// Lookup from local binding to export information.
|
||||||
local: Map<string, LocalExportMetadata>,
|
local: Map<string, LocalExportMetadata>;
|
||||||
|
|
||||||
// Lookup of source file to source file metadata.
|
// Lookup of source file to source file metadata.
|
||||||
source: Map<string, SourceModuleMetadata>,
|
source: Map<string, SourceModuleMetadata>;
|
||||||
|
|
||||||
// List of names that should only be printed as string literals.
|
// List of names that should only be printed as string literals.
|
||||||
// i.e. `import { "any unicode" as foo } from "some-module"`
|
// i.e. `import { "any unicode" as foo } from "some-module"`
|
||||||
// `stringSpecifiers` is Set(1) ["any unicode"]
|
// `stringSpecifiers` is Set(1) ["any unicode"]
|
||||||
// In most cases `stringSpecifiers` is an empty Set
|
// In most cases `stringSpecifiers` is an empty Set
|
||||||
stringSpecifiers: Set<string>,
|
stringSpecifiers: Set<string>;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type InteropType = "default" | "namespace" | "none";
|
export type InteropType = "default" | "namespace" | "none";
|
||||||
|
|
||||||
export type SourceModuleMetadata = {
|
export interface SourceModuleMetadata {
|
||||||
// A unique variable name to use for this namespace object. Centralized for simplicity.
|
// A unique variable name to use for this namespace object. Centralized for simplicity.
|
||||||
name: string,
|
name: string;
|
||||||
|
loc: t.SourceLocation | undefined | null;
|
||||||
loc: ?BabelNodeSourceLocation,
|
interop: InteropType;
|
||||||
|
|
||||||
interop: InteropType,
|
|
||||||
|
|
||||||
// Local binding to reference from this source namespace. Key: Local name, value: Import name
|
// Local binding to reference from this source namespace. Key: Local name, value: Import name
|
||||||
imports: Map<string, string>,
|
imports: Map<string, string>;
|
||||||
|
|
||||||
// Local names that reference namespace object.
|
// Local names that reference namespace object.
|
||||||
importsNamespace: Set<string>,
|
importsNamespace: Set<string>;
|
||||||
|
|
||||||
// Reexports to create for namespace. Key: Export name, value: Import name
|
// Reexports to create for namespace. Key: Export name, value: Import name
|
||||||
reexports: Map<string, string>,
|
reexports: Map<string, string>;
|
||||||
|
|
||||||
// List of names to re-export namespace as.
|
// List of names to re-export namespace as.
|
||||||
reexportNamespace: Set<string>,
|
reexportNamespace: Set<string>;
|
||||||
|
|
||||||
// Tracks if the source should be re-exported.
|
// Tracks if the source should be re-exported.
|
||||||
reexportAll: null | {
|
reexportAll: null | {
|
||||||
loc: ?BabelNodeSourceLocation,
|
loc: t.SourceLocation | undefined | null;
|
||||||
},
|
};
|
||||||
};
|
lazy?;
|
||||||
|
}
|
||||||
|
|
||||||
export type LocalExportMetadata = {
|
export interface LocalExportMetadata {
|
||||||
name: Array<string>, // names of exports
|
names: Array<string>; // names of exports,
|
||||||
kind: "import" | "hoisted" | "block" | "var",
|
kind: "import" | "hoisted" | "block" | "var";
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the module has any exports that need handling.
|
* Check if the module has any exports that need handling.
|
||||||
@ -82,7 +73,7 @@ export function isSideEffectImport(source: SourceModuleMetadata) {
|
|||||||
* needed to reconstruct the module's behavior.
|
* needed to reconstruct the module's behavior.
|
||||||
*/
|
*/
|
||||||
export default function normalizeModuleAndLoadMetadata(
|
export default function normalizeModuleAndLoadMetadata(
|
||||||
programPath: NodePath,
|
programPath: NodePath<t.Program>,
|
||||||
exportName?: string,
|
exportName?: string,
|
||||||
{
|
{
|
||||||
noInterop = false,
|
noInterop = false,
|
||||||
@ -94,7 +85,7 @@ export default function normalizeModuleAndLoadMetadata(
|
|||||||
if (!exportName) {
|
if (!exportName) {
|
||||||
exportName = programPath.scope.generateUidIdentifier("exports").name;
|
exportName = programPath.scope.generateUidIdentifier("exports").name;
|
||||||
}
|
}
|
||||||
const stringSpecifiers = new Set();
|
const stringSpecifiers = new Set<string>();
|
||||||
|
|
||||||
nameAnonymousExports(programPath);
|
nameAnonymousExports(programPath);
|
||||||
|
|
||||||
@ -166,11 +157,15 @@ function getExportSpecifierName(
|
|||||||
* Get metadata about the imports and exports present in this module.
|
* Get metadata about the imports and exports present in this module.
|
||||||
*/
|
*/
|
||||||
function getModuleMetadata(
|
function getModuleMetadata(
|
||||||
programPath: NodePath,
|
programPath: NodePath<t.Program>,
|
||||||
{
|
{
|
||||||
lazy,
|
lazy,
|
||||||
initializeReexports,
|
initializeReexports,
|
||||||
}: { lazy: boolean, initializeReexports: boolean },
|
}: {
|
||||||
|
// todo(flow-ts) changed from boolean, to match expected usage inside the function
|
||||||
|
lazy: boolean | string[] | Function;
|
||||||
|
initializeReexports: boolean;
|
||||||
|
},
|
||||||
stringSpecifiers: Set<string>,
|
stringSpecifiers: Set<string>,
|
||||||
) {
|
) {
|
||||||
const localData = getLocalExportMetadata(
|
const localData = getLocalExportMetadata(
|
||||||
@ -289,7 +284,9 @@ function getModuleMetadata(
|
|||||||
data.reexports.set(exportName, importName);
|
data.reexports.set(exportName, importName);
|
||||||
|
|
||||||
if (exportName === "__esModule") {
|
if (exportName === "__esModule") {
|
||||||
throw exportName.buildCodeFrameError('Illegal export "__esModule".');
|
throw spec
|
||||||
|
.get("exported")
|
||||||
|
.buildCodeFrameError('Illegal export "__esModule".');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
@ -360,13 +357,13 @@ function getModuleMetadata(
|
|||||||
* Get metadata about local variables that are exported.
|
* Get metadata about local variables that are exported.
|
||||||
*/
|
*/
|
||||||
function getLocalExportMetadata(
|
function getLocalExportMetadata(
|
||||||
programPath: NodePath,
|
programPath: NodePath<t.Program>,
|
||||||
initializeReexports: boolean,
|
initializeReexports: boolean,
|
||||||
stringSpecifiers: Set<string>,
|
stringSpecifiers: Set<string>,
|
||||||
): Map<string, LocalExportMetadata> {
|
): Map<string, LocalExportMetadata> {
|
||||||
const bindingKindLookup = new Map();
|
const bindingKindLookup = new Map();
|
||||||
|
|
||||||
programPath.get("body").forEach(child => {
|
programPath.get("body").forEach((child: any) => {
|
||||||
let kind;
|
let kind;
|
||||||
if (child.isImportDeclaration()) {
|
if (child.isImportDeclaration()) {
|
||||||
kind = "import";
|
kind = "import";
|
||||||
@ -434,7 +431,8 @@ function getLocalExportMetadata(
|
|||||||
(initializeReexports || !child.node.source)
|
(initializeReexports || !child.node.source)
|
||||||
) {
|
) {
|
||||||
if (child.node.declaration) {
|
if (child.node.declaration) {
|
||||||
const declaration = child.get("declaration");
|
// todo: flow->ts babel-types node field types
|
||||||
|
const declaration = child.get("declaration") as NodePath;
|
||||||
const ids = declaration.getOuterBindingIdentifierPaths();
|
const ids = declaration.getOuterBindingIdentifierPaths();
|
||||||
Object.keys(ids).forEach(name => {
|
Object.keys(ids).forEach(name => {
|
||||||
if (name === "__esModule") {
|
if (name === "__esModule") {
|
||||||
@ -463,6 +461,7 @@ function getLocalExportMetadata(
|
|||||||
declaration.isFunctionDeclaration() ||
|
declaration.isFunctionDeclaration() ||
|
||||||
declaration.isClassDeclaration()
|
declaration.isClassDeclaration()
|
||||||
) {
|
) {
|
||||||
|
// @ts-expect-error todo(flow->ts): improve babel-types
|
||||||
getLocalMetadata(declaration.get("id")).names.push("default");
|
getLocalMetadata(declaration.get("id")).names.push("default");
|
||||||
} else {
|
} else {
|
||||||
// These should have been removed by the nameAnonymousExports() call.
|
// These should have been removed by the nameAnonymousExports() call.
|
||||||
@ -478,7 +477,7 @@ function getLocalExportMetadata(
|
|||||||
/**
|
/**
|
||||||
* Ensure that all exported values have local binding names.
|
* Ensure that all exported values have local binding names.
|
||||||
*/
|
*/
|
||||||
function nameAnonymousExports(programPath: NodePath) {
|
function nameAnonymousExports(programPath: NodePath<t.Program>) {
|
||||||
// Name anonymous exported locals.
|
// Name anonymous exported locals.
|
||||||
programPath.get("body").forEach(child => {
|
programPath.get("body").forEach(child => {
|
||||||
if (!child.isExportDefaultDeclaration()) return;
|
if (!child.isExportDefaultDeclaration()) return;
|
||||||
@ -486,12 +485,13 @@ function nameAnonymousExports(programPath: NodePath) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeModuleDeclarations(programPath: NodePath) {
|
function removeModuleDeclarations(programPath: NodePath<t.Program>) {
|
||||||
programPath.get("body").forEach(child => {
|
programPath.get("body").forEach(child => {
|
||||||
if (child.isImportDeclaration()) {
|
if (child.isImportDeclaration()) {
|
||||||
child.remove();
|
child.remove();
|
||||||
} else if (child.isExportNamedDeclaration()) {
|
} else if (child.isExportNamedDeclaration()) {
|
||||||
if (child.node.declaration) {
|
if (child.node.declaration) {
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutations
|
||||||
child.node.declaration._blockHoist = child.node._blockHoist;
|
child.node.declaration._blockHoist = child.node._blockHoist;
|
||||||
child.replaceWith(child.node.declaration);
|
child.replaceWith(child.node.declaration);
|
||||||
} else {
|
} else {
|
||||||
@ -504,6 +504,7 @@ function removeModuleDeclarations(programPath: NodePath) {
|
|||||||
declaration.isFunctionDeclaration() ||
|
declaration.isFunctionDeclaration() ||
|
||||||
declaration.isClassDeclaration()
|
declaration.isClassDeclaration()
|
||||||
) {
|
) {
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutations
|
||||||
declaration._blockHoist = child.node._blockHoist;
|
declaration._blockHoist = child.node._blockHoist;
|
||||||
child.replaceWith(declaration);
|
child.replaceWith(declaration);
|
||||||
} else {
|
} else {
|
||||||
@ -1,12 +1,33 @@
|
|||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import template from "@babel/template";
|
import template from "@babel/template";
|
||||||
|
import type { NodePath, Visitor, Scope } from "@babel/traverse";
|
||||||
import simplifyAccess from "@babel/helper-simple-access";
|
import simplifyAccess from "@babel/helper-simple-access";
|
||||||
|
|
||||||
import type { ModuleMetadata } from "./normalize-and-load-metadata";
|
import type { ModuleMetadata } from "./normalize-and-load-metadata";
|
||||||
|
|
||||||
|
interface RewriteReferencesVisitorState {
|
||||||
|
exported: Map<any, any>;
|
||||||
|
metadata: ModuleMetadata;
|
||||||
|
requeueInParent: (path) => void;
|
||||||
|
scope: Scope;
|
||||||
|
imported: Map<any, any>;
|
||||||
|
buildImportReference: (
|
||||||
|
[source, importName, localName]: readonly [any, any, any],
|
||||||
|
identNode,
|
||||||
|
) => any;
|
||||||
|
seen: WeakSet<object>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RewriteBindingInitVisitorState {
|
||||||
|
exported: Map<any, any>;
|
||||||
|
metadata: ModuleMetadata;
|
||||||
|
requeueInParent: (path) => void;
|
||||||
|
scope: Scope;
|
||||||
|
}
|
||||||
|
|
||||||
export default function rewriteLiveReferences(
|
export default function rewriteLiveReferences(
|
||||||
programPath: NodePath,
|
programPath: NodePath<t.Program>,
|
||||||
metadata: ModuleMetadata,
|
metadata: ModuleMetadata,
|
||||||
) {
|
) {
|
||||||
const imported = new Map();
|
const imported = new Map();
|
||||||
@ -39,12 +60,16 @@ export default function rewriteLiveReferences(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite initialization of bindings to update exports.
|
// Rewrite initialization of bindings to update exports.
|
||||||
programPath.traverse(rewriteBindingInitVisitor, {
|
const rewriteBindingInitVisitorState: RewriteBindingInitVisitorState = {
|
||||||
metadata,
|
metadata,
|
||||||
requeueInParent,
|
requeueInParent,
|
||||||
scope: programPath.scope,
|
scope: programPath.scope,
|
||||||
exported, // local name => exported name list
|
exported, // local name => exported name list
|
||||||
});
|
};
|
||||||
|
programPath.traverse(
|
||||||
|
rewriteBindingInitVisitor,
|
||||||
|
rewriteBindingInitVisitorState,
|
||||||
|
);
|
||||||
|
|
||||||
simplifyAccess(
|
simplifyAccess(
|
||||||
programPath,
|
programPath,
|
||||||
@ -53,7 +78,7 @@ export default function rewriteLiveReferences(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Rewrite reads/writes from imports and exports to have the correct behavior.
|
// Rewrite reads/writes from imports and exports to have the correct behavior.
|
||||||
programPath.traverse(rewriteReferencesVisitor, {
|
const rewriteReferencesVisitorState: RewriteReferencesVisitorState = {
|
||||||
seen: new WeakSet(),
|
seen: new WeakSet(),
|
||||||
metadata,
|
metadata,
|
||||||
requeueInParent,
|
requeueInParent,
|
||||||
@ -68,7 +93,7 @@ export default function rewriteLiveReferences(
|
|||||||
return identNode;
|
return identNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
let namespace = t.identifier(meta.name);
|
let namespace: t.Expression = t.identifier(meta.name);
|
||||||
if (meta.lazy) namespace = t.callExpression(namespace, []);
|
if (meta.lazy) namespace = t.callExpression(namespace, []);
|
||||||
|
|
||||||
const computed = metadata.stringSpecifiers.has(importName);
|
const computed = metadata.stringSpecifiers.has(importName);
|
||||||
@ -79,13 +104,14 @@ export default function rewriteLiveReferences(
|
|||||||
computed,
|
computed,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
programPath.traverse(rewriteReferencesVisitor, rewriteReferencesVisitorState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to inject export update statements during binding initialization.
|
* A visitor to inject export update statements during binding initialization.
|
||||||
*/
|
*/
|
||||||
const rewriteBindingInitVisitor = {
|
const rewriteBindingInitVisitor: Visitor<RewriteBindingInitVisitorState> = {
|
||||||
Scope(path) {
|
Scope(path) {
|
||||||
path.skip();
|
path.skip();
|
||||||
},
|
},
|
||||||
@ -105,6 +131,7 @@ const rewriteBindingInitVisitor = {
|
|||||||
t.identifier(localName),
|
t.identifier(localName),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutations
|
||||||
statement._blockHoist = path.node._blockHoist;
|
statement._blockHoist = path.node._blockHoist;
|
||||||
|
|
||||||
requeueInParent(path.insertAfter(statement)[0]);
|
requeueInParent(path.insertAfter(statement)[0]);
|
||||||
@ -124,6 +151,7 @@ const rewriteBindingInitVisitor = {
|
|||||||
t.identifier(localName),
|
t.identifier(localName),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutations
|
||||||
statement._blockHoist = path.node._blockHoist;
|
statement._blockHoist = path.node._blockHoist;
|
||||||
|
|
||||||
requeueInParent(path.insertAfter(statement)[0]);
|
requeueInParent(path.insertAfter(statement)[0]);
|
||||||
@ -163,7 +191,7 @@ const buildImportThrow = localName => {
|
|||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rewriteReferencesVisitor = {
|
const rewriteReferencesVisitor: Visitor<RewriteReferencesVisitorState> = {
|
||||||
ReferencedIdentifier(path) {
|
ReferencedIdentifier(path) {
|
||||||
const {
|
const {
|
||||||
seen,
|
seen,
|
||||||
@ -200,9 +228,11 @@ const rewriteReferencesVisitor = {
|
|||||||
} else if (path.isJSXIdentifier() && t.isMemberExpression(ref)) {
|
} else if (path.isJSXIdentifier() && t.isMemberExpression(ref)) {
|
||||||
const { object, property } = ref;
|
const { object, property } = ref;
|
||||||
path.replaceWith(
|
path.replaceWith(
|
||||||
t.JSXMemberExpression(
|
t.jsxMemberExpression(
|
||||||
t.JSXIdentifier(object.name),
|
// @ts-expect-error todo(flow->ts): possible bug `object` might not have a name
|
||||||
t.JSXIdentifier(property.name),
|
t.jsxIdentifier(object.name),
|
||||||
|
// @ts-expect-error todo(flow->ts): possible bug `property` might not have a name
|
||||||
|
t.jsxIdentifier(property.name),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -303,9 +333,10 @@ const rewriteReferencesVisitor = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
let node = t.sequenceExpression(items);
|
let node: t.Node = t.sequenceExpression(items);
|
||||||
if (path.parentPath.isExpressionStatement()) {
|
if (path.parentPath.isExpressionStatement()) {
|
||||||
node = t.expressionStatement(node);
|
node = t.expressionStatement(node);
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutations
|
||||||
node._blockHoist = path.parentPath.node._blockHoist;
|
node._blockHoist = path.parentPath.node._blockHoist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +346,9 @@ const rewriteReferencesVisitor = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ForOfStatement|ForInStatement"(path) {
|
"ForOfStatement|ForInStatement"(
|
||||||
|
path: NodePath<t.ForOfStatement | t.ForInStatement>,
|
||||||
|
) {
|
||||||
const { scope, node } = path;
|
const { scope, node } = path;
|
||||||
const { left } = node;
|
const { left } = node;
|
||||||
const { exported, scope: programScope } = this;
|
const { exported, scope: programScope } = this;
|
||||||
@ -2,6 +2,7 @@ import { environmentVisitor } from "@babel/helper-replace-supers";
|
|||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
|
import type { NodePath, Visitor } from "@babel/traverse";
|
||||||
export default function rewriteThis(programPath: NodePath) {
|
export default function rewriteThis(programPath: NodePath) {
|
||||||
// Rewrite "this" to be "undefined".
|
// Rewrite "this" to be "undefined".
|
||||||
traverse(programPath.node, { ...rewriteThisVisitor, noScope: true });
|
traverse(programPath.node, { ...rewriteThisVisitor, noScope: true });
|
||||||
@ -11,10 +12,10 @@ export default function rewriteThis(programPath: NodePath) {
|
|||||||
* A visitor to walk the tree, rewriting all `this` references in the top-level scope to be
|
* A visitor to walk the tree, rewriting all `this` references in the top-level scope to be
|
||||||
* `void 0` (undefined).
|
* `void 0` (undefined).
|
||||||
*/
|
*/
|
||||||
const rewriteThisVisitor = traverse.visitors.merge([
|
const rewriteThisVisitor: Visitor = traverse.visitors.merge([
|
||||||
environmentVisitor,
|
environmentVisitor,
|
||||||
{
|
{
|
||||||
ThisExpression(path) {
|
ThisExpression(path: NodePath<t.ThisExpression>) {
|
||||||
path.replaceWith(t.unaryExpression("void", t.numericLiteral(0), true));
|
path.replaceWith(t.unaryExpression("void", t.numericLiteral(0), true));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Loading…
x
Reference in New Issue
Block a user