Convert @babel/traverse to TypeScript (#12488)
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
cd090e9842
commit
d98418efbe
52
Gulpfile.js
52
Gulpfile.js
@ -86,13 +86,12 @@ function rename(fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param {string} generator
|
||||||
* @typedef {("asserts" | "builders" | "constants" | "validators")} HelperKind
|
* @param {string} pkg
|
||||||
* @param {HelperKind} helperKind
|
|
||||||
* @param {string} filename
|
* @param {string} filename
|
||||||
|
* @param {string} message
|
||||||
*/
|
*/
|
||||||
function generateTypeHelpers(helperKind, filename = "index.ts") {
|
function generateHelpers(generator, dest, filename, message) {
|
||||||
const dest = `./packages/babel-types/src/${helperKind}/generated/`;
|
|
||||||
const formatCode = require("./scripts/utils/formatCode");
|
const formatCode = require("./scripts/utils/formatCode");
|
||||||
const stream = gulp
|
const stream = gulp
|
||||||
.src(".", { base: __dirname })
|
.src(".", { base: __dirname })
|
||||||
@ -101,14 +100,9 @@ function generateTypeHelpers(helperKind, filename = "index.ts") {
|
|||||||
through.obj(function (file, enc, callback) {
|
through.obj(function (file, enc, callback) {
|
||||||
file.path = filename;
|
file.path = filename;
|
||||||
file.contents = Buffer.from(
|
file.contents = Buffer.from(
|
||||||
formatCode(
|
formatCode(require(generator)(filename), dest + file.path)
|
||||||
require(`./packages/babel-types/scripts/generators/${helperKind}`)(
|
|
||||||
filename
|
|
||||||
),
|
|
||||||
dest + file.path
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
fancyLog(`${chalk.green("✔")} Generated ${helperKind}`);
|
fancyLog(`${chalk.green("✔")} Generated ${message}`);
|
||||||
callback(null, file);
|
callback(null, file);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -117,6 +111,35 @@ function generateTypeHelpers(helperKind, filename = "index.ts") {
|
|||||||
return finish(stream);
|
return finish(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @typedef {("asserts" | "builders" | "constants" | "validators")} TypesHelperKind
|
||||||
|
* @param {TypesHelperKind} helperKind
|
||||||
|
* @param {string} filename
|
||||||
|
*/
|
||||||
|
async function generateTypeHelpers(helperKind, filename = "index.ts") {
|
||||||
|
return generateHelpers(
|
||||||
|
`./packages/babel-types/scripts/generators/${helperKind}`,
|
||||||
|
`./packages/babel-types/src/${helperKind}/generated/`,
|
||||||
|
filename,
|
||||||
|
`@babel/types -> ${helperKind}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @typedef {("asserts" | "validators" | "virtual-types")} TraverseHelperKind
|
||||||
|
* @param {TraverseHelperKind} helperKind
|
||||||
|
*/
|
||||||
|
async function generateTraverseHelpers(helperKind) {
|
||||||
|
return generateHelpers(
|
||||||
|
`./packages/babel-traverse/scripts/generators/${helperKind}`,
|
||||||
|
`./packages/babel-traverse/src/path/generated/`,
|
||||||
|
`${helperKind}.ts`,
|
||||||
|
`@babel/traverse -> ${helperKind}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function generateStandalone() {
|
function generateStandalone() {
|
||||||
const dest = "./packages/babel-standalone/src/generated/";
|
const dest = "./packages/babel-standalone/src/generated/";
|
||||||
const formatCode = require("./scripts/utils/formatCode");
|
const formatCode = require("./scripts/utils/formatCode");
|
||||||
@ -383,7 +406,7 @@ const standaloneBundle = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
gulp.task("generate-type-helpers", () => {
|
gulp.task("generate-type-helpers", () => {
|
||||||
fancyLog("Generating @babel/types dynamic functions");
|
fancyLog("Generating @babel/types and @babel/traverse dynamic functions");
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
generateTypeHelpers("asserts"),
|
generateTypeHelpers("asserts"),
|
||||||
@ -392,6 +415,9 @@ gulp.task("generate-type-helpers", () => {
|
|||||||
generateTypeHelpers("constants"),
|
generateTypeHelpers("constants"),
|
||||||
generateTypeHelpers("validators"),
|
generateTypeHelpers("validators"),
|
||||||
generateTypeHelpers("ast-types"),
|
generateTypeHelpers("ast-types"),
|
||||||
|
generateTraverseHelpers("asserts"),
|
||||||
|
generateTraverseHelpers("validators"),
|
||||||
|
generateTraverseHelpers("virtual-types"),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -168,3 +168,7 @@ declare module "@babel/helper-function-name" {
|
|||||||
declare module "@babel/helper-split-export-declaration" {
|
declare module "@babel/helper-split-export-declaration" {
|
||||||
declare export default function splitExportDeclaration(exportDeclaration: any): any;
|
declare export default function splitExportDeclaration(exportDeclaration: any): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module "@babel/traverse" {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|||||||
26
packages/babel-traverse/scripts/generators/asserts.js
Normal file
26
packages/babel-traverse/scripts/generators/asserts.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use strict";
|
||||||
|
const t = require("@babel/types");
|
||||||
|
|
||||||
|
module.exports = function generateAsserts() {
|
||||||
|
let output = `/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
import NodePath from "../index";
|
||||||
|
|
||||||
|
|
||||||
|
export interface NodePathAssetions {`;
|
||||||
|
|
||||||
|
for (const type of t.TYPES) {
|
||||||
|
output += `
|
||||||
|
assert${type}(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.${type}>;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
output += `
|
||||||
|
}`;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
37
packages/babel-traverse/scripts/generators/validators.js
Normal file
37
packages/babel-traverse/scripts/generators/validators.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const t = require("@babel/types");
|
||||||
|
const virtualTypes = require("../../lib/path/lib/virtual-types");
|
||||||
|
|
||||||
|
const definitions = require("@babel/types/lib/definitions");
|
||||||
|
|
||||||
|
module.exports = function generateValidators() {
|
||||||
|
let output = `/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
import NodePath from "../index";
|
||||||
|
|
||||||
|
export interface NodePathValidators {
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (const type of t.TYPES) {
|
||||||
|
output += `is${type}(opts?: object): this is NodePath<t.${type}>;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const type of Object.keys(virtualTypes)) {
|
||||||
|
if (type[0] === "_") continue;
|
||||||
|
if (definitions.NODE_FIELDS[type] || definitions.FLIPPED_ALIAS_KEYS[type]) {
|
||||||
|
output += `is${type}(opts?: object): this is NodePath<t.${type}>;`;
|
||||||
|
} else {
|
||||||
|
output += `is${type}(opts?: object): boolean;`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output += `
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
26
packages/babel-traverse/scripts/generators/virtual-types.js
Normal file
26
packages/babel-traverse/scripts/generators/virtual-types.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const virtualTypes = require("../../lib/path/lib/virtual-types");
|
||||||
|
|
||||||
|
module.exports = function generateValidators() {
|
||||||
|
let output = `/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
|
export interface VirtualTypeAliases {
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (const type of Object.keys(virtualTypes)) {
|
||||||
|
output += ` ${type}: ${(virtualTypes[type].types || ["Node"])
|
||||||
|
.map(t => `t.${t}`)
|
||||||
|
.join(" | ")};`;
|
||||||
|
}
|
||||||
|
|
||||||
|
output += `
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import NodePath from "./path";
|
import NodePath from "./path";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type Scope from "./scope";
|
||||||
|
|
||||||
const testing = process.env.NODE_ENV === "test";
|
const testing = process.env.NODE_ENV === "test";
|
||||||
|
|
||||||
@ -12,10 +13,12 @@ export default class TraversalContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare parentPath: NodePath;
|
declare parentPath: NodePath;
|
||||||
declare scope;
|
declare scope: Scope;
|
||||||
declare state;
|
declare state;
|
||||||
declare opts;
|
declare opts;
|
||||||
queue: ?Array<NodePath> = null;
|
queue: Array<NodePath> | null = null;
|
||||||
|
priorityQueue: Array<NodePath> | null = null;
|
||||||
|
declare trap?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method does a simple check to determine whether or not we really need to attempt
|
* This method does a simple check to determine whether or not we really need to attempt
|
||||||
@ -30,7 +33,7 @@ export default class TraversalContext {
|
|||||||
if (opts[node.type]) return true;
|
if (opts[node.type]) return true;
|
||||||
|
|
||||||
// check if we're going to traverse into this node
|
// check if we're going to traverse into this node
|
||||||
const keys: ?Array<string> = t.VISITOR_KEYS[node.type];
|
const keys: Array<string> | undefined = t.VISITOR_KEYS[node.type];
|
||||||
if (!keys?.length) return false;
|
if (!keys?.length) return false;
|
||||||
|
|
||||||
// we need to traverse into this node so ensure that it has children to traverse into!
|
// we need to traverse into this node so ensure that it has children to traverse into!
|
||||||
@ -41,7 +44,7 @@ export default class TraversalContext {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
create(node, obj, key, listKey): NodePath {
|
create(node, obj, key, listKey?): NodePath {
|
||||||
// We don't need to `.setContext()` here, since `.visitQueue()` already
|
// We don't need to `.setContext()` here, since `.visitQueue()` already
|
||||||
// calls `.pushContext`.
|
// calls `.pushContext`.
|
||||||
return NodePath.get({
|
return NodePath.get({
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import type Scope from "./scope";
|
import type Scope from "./scope";
|
||||||
|
|
||||||
export interface HubInterface {
|
export interface HubInterface {
|
||||||
getCode(): ?string;
|
getCode(): string | void;
|
||||||
getScope(): ?Scope;
|
getScope(): Scope | void;
|
||||||
addHelper(name: string): Object;
|
addHelper(name: string): any;
|
||||||
buildError(node: Object, msg: string, Error: Class<Error>): Error;
|
buildError(node: any, msg: string, Error: new () => Error): Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Hub implements HubInterface {
|
export default class Hub implements HubInterface {
|
||||||
@ -2,7 +2,11 @@ import TraversalContext from "./context";
|
|||||||
import * as visitors from "./visitors";
|
import * as visitors from "./visitors";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import * as cache from "./cache";
|
import * as cache from "./cache";
|
||||||
|
import type NodePath from "./path";
|
||||||
|
import type Scope from "./scope";
|
||||||
|
import type { Visitor } from "./types";
|
||||||
|
|
||||||
|
export type { Visitor };
|
||||||
export { default as NodePath } from "./path";
|
export { default as NodePath } from "./path";
|
||||||
export { default as Scope } from "./scope";
|
export { default as Scope } from "./scope";
|
||||||
export { default as Hub } from "./hub";
|
export { default as Hub } from "./hub";
|
||||||
@ -10,15 +14,38 @@ export type { HubInterface } from "./hub";
|
|||||||
|
|
||||||
export { visitors };
|
export { visitors };
|
||||||
|
|
||||||
export default function traverse(
|
export type TraverseOptions<S = t.Node> =
|
||||||
parent: Object | Array<Object>,
|
| {
|
||||||
opts?: Object,
|
scope?: Scope;
|
||||||
scope?: Object,
|
noScope?: boolean;
|
||||||
state: Object,
|
denylist?: string[];
|
||||||
parentPath: Object,
|
}
|
||||||
|
| Visitor<S>;
|
||||||
|
|
||||||
|
function traverse<S>(
|
||||||
|
parent: t.Node,
|
||||||
|
opts: TraverseOptions<S>,
|
||||||
|
scope: Scope | undefined,
|
||||||
|
state: S,
|
||||||
|
parentPath?: NodePath,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
function traverse(
|
||||||
|
parent: t.Node,
|
||||||
|
opts: TraverseOptions,
|
||||||
|
scope?: Scope,
|
||||||
|
state?: any,
|
||||||
|
parentPath?: NodePath,
|
||||||
|
): void;
|
||||||
|
|
||||||
|
function traverse(
|
||||||
|
parent: t.Node,
|
||||||
|
opts: TraverseOptions = {},
|
||||||
|
scope?: Scope,
|
||||||
|
state?: any,
|
||||||
|
parentPath?: NodePath,
|
||||||
) {
|
) {
|
||||||
if (!parent) return;
|
if (!parent) return;
|
||||||
if (!opts) opts = {};
|
|
||||||
|
|
||||||
if (!opts.noScope && !scope) {
|
if (!opts.noScope && !scope) {
|
||||||
if (parent.type !== "Program" && parent.type !== "File") {
|
if (parent.type !== "Program" && parent.type !== "File") {
|
||||||
@ -39,6 +66,8 @@ export default function traverse(
|
|||||||
traverse.node(parent, opts, scope, state, parentPath);
|
traverse.node(parent, opts, scope, state, parentPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default traverse;
|
||||||
|
|
||||||
traverse.visitors = visitors;
|
traverse.visitors = visitors;
|
||||||
traverse.verify = visitors.verify;
|
traverse.verify = visitors.verify;
|
||||||
traverse.explode = visitors.explode;
|
traverse.explode = visitors.explode;
|
||||||
@ -48,14 +77,14 @@ traverse.cheap = function (node, enter) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
traverse.node = function (
|
traverse.node = function (
|
||||||
node: Object,
|
node: t.Node,
|
||||||
opts: Object,
|
opts: TraverseOptions,
|
||||||
scope: Object,
|
scope?: Scope,
|
||||||
state: Object,
|
state?: any,
|
||||||
parentPath: Object,
|
parentPath?: NodePath,
|
||||||
skipKeys?,
|
skipKeys?,
|
||||||
) {
|
) {
|
||||||
const keys: Array = t.VISITOR_KEYS[node.type];
|
const keys = t.VISITOR_KEYS[node.type];
|
||||||
if (!keys) return;
|
if (!keys) return;
|
||||||
|
|
||||||
const context = new TraversalContext(scope, opts, state, parentPath);
|
const context = new TraversalContext(scope, opts, state, parentPath);
|
||||||
@ -65,18 +94,18 @@ traverse.node = function (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
traverse.clearNode = function (node, opts) {
|
traverse.clearNode = function (node: t.Node, opts?) {
|
||||||
t.removeProperties(node, opts);
|
t.removeProperties(node, opts);
|
||||||
|
|
||||||
cache.path.delete(node);
|
cache.path.delete(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
traverse.removeProperties = function (tree, opts) {
|
traverse.removeProperties = function (tree, opts?) {
|
||||||
t.traverseFast(tree, traverse.clearNode, opts);
|
t.traverseFast(tree, traverse.clearNode, opts);
|
||||||
return tree;
|
return tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
function hasDenylistedType(path, state) {
|
function hasDenylistedType(path: NodePath, state) {
|
||||||
if (path.node.type === state.type) {
|
if (path.node.type === state.type) {
|
||||||
state.has = true;
|
state.has = true;
|
||||||
path.stop();
|
path.stop();
|
||||||
@ -84,8 +113,8 @@ function hasDenylistedType(path, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
traverse.hasType = function (
|
traverse.hasType = function (
|
||||||
tree: Object,
|
tree: any,
|
||||||
type: Object,
|
type: any,
|
||||||
denylistTypes?: Array<string>,
|
denylistTypes?: Array<string>,
|
||||||
): boolean {
|
): boolean {
|
||||||
// the node we're searching in is denylisted
|
// the node we're searching in is denylisted
|
||||||
@ -10,7 +10,9 @@ import NodePath from "./index";
|
|||||||
* truthy value.
|
* truthy value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function findParent(callback): ?NodePath {
|
export function findParent(
|
||||||
|
callback: (path: NodePath) => boolean,
|
||||||
|
): NodePath | null {
|
||||||
let path = this;
|
let path = this;
|
||||||
while ((path = path.parentPath)) {
|
while ((path = path.parentPath)) {
|
||||||
if (callback(path)) return path;
|
if (callback(path)) return path;
|
||||||
@ -24,7 +26,10 @@ export function findParent(callback): ?NodePath {
|
|||||||
* or `null` if the `callback` never returns a truthy value.
|
* or `null` if the `callback` never returns a truthy value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function find(callback): ?NodePath {
|
export function find(
|
||||||
|
this: NodePath,
|
||||||
|
callback: (path: NodePath) => boolean,
|
||||||
|
): NodePath | null {
|
||||||
let path = this;
|
let path = this;
|
||||||
do {
|
do {
|
||||||
if (callback(path)) return path;
|
if (callback(path)) return path;
|
||||||
@ -36,15 +41,15 @@ export function find(callback): ?NodePath {
|
|||||||
* Get the parent function of the current path.
|
* Get the parent function of the current path.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getFunctionParent(): ?NodePath {
|
export function getFunctionParent(this: NodePath): NodePath<t.Function> | null {
|
||||||
return this.findParent(p => p.isFunction());
|
return this.findParent(p => p.isFunction()) as NodePath<t.Function> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walk up the tree until we hit a parent node path in a list.
|
* Walk up the tree until we hit a parent node path in a list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getStatementParent(): NodePath {
|
export function getStatementParent(this: NodePath): NodePath<t.Statement> {
|
||||||
let path = this;
|
let path = this;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -64,7 +69,7 @@ export function getStatementParent(): NodePath {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path as NodePath<t.Statement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,6 +81,7 @@ export function getStatementParent(): NodePath {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function getEarliestCommonAncestorFrom(
|
export function getEarliestCommonAncestorFrom(
|
||||||
|
this: NodePath,
|
||||||
paths: Array<NodePath>,
|
paths: Array<NodePath>,
|
||||||
): NodePath {
|
): NodePath {
|
||||||
return this.getDeepestCommonAncestorFrom(
|
return this.getDeepestCommonAncestorFrom(
|
||||||
@ -84,7 +90,7 @@ export function getEarliestCommonAncestorFrom(
|
|||||||
let earliest;
|
let earliest;
|
||||||
const keys = t.VISITOR_KEYS[deepest.type];
|
const keys = t.VISITOR_KEYS[deepest.type];
|
||||||
|
|
||||||
for (const ancestry of (ancestries: Array)) {
|
for (const ancestry of ancestries) {
|
||||||
const path = ancestry[i + 1];
|
const path = ancestry[i + 1];
|
||||||
|
|
||||||
// first path
|
// first path
|
||||||
@ -104,7 +110,7 @@ export function getEarliestCommonAncestorFrom(
|
|||||||
|
|
||||||
// handle keys
|
// handle keys
|
||||||
const earliestKeyIndex = keys.indexOf(earliest.parentKey);
|
const earliestKeyIndex = keys.indexOf(earliest.parentKey);
|
||||||
const currentKeyIndex = keys.indexOf(path.parentKey);
|
const currentKeyIndex = keys.indexOf(path.parentKey as string);
|
||||||
if (earliestKeyIndex > currentKeyIndex) {
|
if (earliestKeyIndex > currentKeyIndex) {
|
||||||
// key appears before so it's earlier
|
// key appears before so it's earlier
|
||||||
earliest = path;
|
earliest = path;
|
||||||
@ -123,8 +129,9 @@ export function getEarliestCommonAncestorFrom(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function getDeepestCommonAncestorFrom(
|
export function getDeepestCommonAncestorFrom(
|
||||||
|
this: NodePath,
|
||||||
paths: Array<NodePath>,
|
paths: Array<NodePath>,
|
||||||
filter?: Function,
|
filter?: (deepest: t.Node, i: number, ancestries: NodePath[][]) => NodePath,
|
||||||
): NodePath {
|
): NodePath {
|
||||||
if (!paths.length) {
|
if (!paths.length) {
|
||||||
return this;
|
return this;
|
||||||
@ -142,7 +149,7 @@ export function getDeepestCommonAncestorFrom(
|
|||||||
|
|
||||||
// get the ancestors of the path, breaking when the parent exceeds ourselves
|
// get the ancestors of the path, breaking when the parent exceeds ourselves
|
||||||
const ancestries = paths.map(path => {
|
const ancestries = paths.map(path => {
|
||||||
const ancestry = [];
|
const ancestry: NodePath[] = [];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ancestry.unshift(path);
|
ancestry.unshift(path);
|
||||||
@ -163,7 +170,7 @@ export function getDeepestCommonAncestorFrom(
|
|||||||
depthLoop: for (let i = 0; i < minDepth; i++) {
|
depthLoop: for (let i = 0; i < minDepth; i++) {
|
||||||
const shouldMatch = first[i];
|
const shouldMatch = first[i];
|
||||||
|
|
||||||
for (const ancestry of (ancestries: Array)) {
|
for (const ancestry of ancestries) {
|
||||||
if (ancestry[i] !== shouldMatch) {
|
if (ancestry[i] !== shouldMatch) {
|
||||||
// we've hit a snag
|
// we've hit a snag
|
||||||
break depthLoop;
|
break depthLoop;
|
||||||
@ -192,7 +199,7 @@ export function getDeepestCommonAncestorFrom(
|
|||||||
* NOTE: The current node path is included in this.
|
* NOTE: The current node path is included in this.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getAncestry(): Array<NodePath> {
|
export function getAncestry(this: NodePath): Array<NodePath> {
|
||||||
let path = this;
|
let path = this;
|
||||||
const paths = [];
|
const paths = [];
|
||||||
do {
|
do {
|
||||||
@ -204,21 +211,21 @@ export function getAncestry(): Array<NodePath> {
|
|||||||
/**
|
/**
|
||||||
* A helper to find if `this` path is an ancestor of @param maybeDescendant
|
* A helper to find if `this` path is an ancestor of @param maybeDescendant
|
||||||
*/
|
*/
|
||||||
export function isAncestor(maybeDescendant: NodePath): boolean {
|
export function isAncestor(this: NodePath, maybeDescendant: NodePath): boolean {
|
||||||
return maybeDescendant.isDescendant(this);
|
return maybeDescendant.isDescendant(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper to find if `this` path is a descendant of @param maybeAncestor
|
* A helper to find if `this` path is a descendant of @param maybeAncestor
|
||||||
*/
|
*/
|
||||||
export function isDescendant(maybeAncestor: NodePath): boolean {
|
export function isDescendant(this: NodePath, maybeAncestor: NodePath): boolean {
|
||||||
return !!this.findParent(parent => parent === maybeAncestor);
|
return !!this.findParent(parent => parent === maybeAncestor);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inType(): boolean {
|
export function inType(this: NodePath, ...candidateTypes: string[]): boolean {
|
||||||
let path = this;
|
let path = this;
|
||||||
while (path) {
|
while (path) {
|
||||||
for (const type of (arguments: Array)) {
|
for (const type of candidateTypes) {
|
||||||
if (path.node.type === type) return true;
|
if (path.node.type === type) return true;
|
||||||
}
|
}
|
||||||
path = path.parentPath;
|
path = path.parentPath;
|
||||||
@ -1,11 +1,12 @@
|
|||||||
// This file contains methods responsible for dealing with comments.
|
// This file contains methods responsible for dealing with comments.
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type NodePath from "./index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share comments amongst siblings.
|
* Share comments amongst siblings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function shareCommentsWithSiblings() {
|
export function shareCommentsWithSiblings(this: NodePath) {
|
||||||
// NOTE: this assumes numbered keys
|
// NOTE: this assumes numbered keys
|
||||||
if (typeof this.key === "string") return;
|
if (typeof this.key === "string") return;
|
||||||
|
|
||||||
@ -27,7 +28,12 @@ export function shareCommentsWithSiblings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addComment(type: string, content: string, line?: boolean) {
|
export function addComment(
|
||||||
|
this: NodePath,
|
||||||
|
type: t.CommentTypeShorthand,
|
||||||
|
content: string,
|
||||||
|
line?: boolean,
|
||||||
|
) {
|
||||||
t.addComment(this.node, type, content, line);
|
t.addComment(this.node, type, content, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +41,10 @@ export function addComment(type: string, content: string, line?: boolean) {
|
|||||||
* Give node `comments` of the specified `type`.
|
* Give node `comments` of the specified `type`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function addComments(type: string, comments: Array) {
|
export function addComments(
|
||||||
|
this: NodePath,
|
||||||
|
type: t.CommentTypeShorthand,
|
||||||
|
comments: readonly t.Comment[],
|
||||||
|
) {
|
||||||
t.addComments(this.node, type, comments);
|
t.addComments(this.node, type, comments);
|
||||||
}
|
}
|
||||||
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
import traverse from "../index";
|
import traverse from "../index";
|
||||||
import { SHOULD_SKIP, SHOULD_STOP } from "./index";
|
import { SHOULD_SKIP, SHOULD_STOP } from "./index";
|
||||||
|
import type TraversalContext from "../context";
|
||||||
|
import type NodePath from "./index";
|
||||||
|
|
||||||
export function call(key): boolean {
|
export function call(this: NodePath, key: string): boolean {
|
||||||
const opts = this.opts;
|
const opts = this.opts;
|
||||||
|
|
||||||
this.debug(key);
|
this.debug(key);
|
||||||
@ -19,7 +21,7 @@ export function call(key): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _call(fns?: Array<Function>): boolean {
|
export function _call(this: NodePath, fns?: Array<Function>): boolean {
|
||||||
if (!fns) return false;
|
if (!fns) return false;
|
||||||
|
|
||||||
for (const fn of fns) {
|
for (const fn of fns) {
|
||||||
@ -51,7 +53,7 @@ export function _call(fns?: Array<Function>): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDenylisted(): boolean {
|
export function isDenylisted(this: NodePath): boolean {
|
||||||
const denylist = this.opts.denylist ?? this.opts.blacklist;
|
const denylist = this.opts.denylist ?? this.opts.blacklist;
|
||||||
return denylist && denylist.indexOf(this.node.type) > -1;
|
return denylist && denylist.indexOf(this.node.type) > -1;
|
||||||
}
|
}
|
||||||
@ -59,7 +61,7 @@ export function isDenylisted(): boolean {
|
|||||||
// TODO: Remove in Babel 8
|
// TODO: Remove in Babel 8
|
||||||
export { isDenylisted as isBlacklisted };
|
export { isDenylisted as isBlacklisted };
|
||||||
|
|
||||||
export function visit(): boolean {
|
export function visit(this: NodePath): boolean {
|
||||||
if (!this.node) {
|
if (!this.node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -97,23 +99,23 @@ export function visit(): boolean {
|
|||||||
return this.shouldStop;
|
return this.shouldStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function skip() {
|
export function skip(this: NodePath) {
|
||||||
this.shouldSkip = true;
|
this.shouldSkip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function skipKey(key) {
|
export function skipKey(this: NodePath, key: string) {
|
||||||
if (this.skipKeys == null) {
|
if (this.skipKeys == null) {
|
||||||
this.skipKeys = {};
|
this.skipKeys = {};
|
||||||
}
|
}
|
||||||
this.skipKeys[key] = true;
|
this.skipKeys[key] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stop() {
|
export function stop(this: NodePath) {
|
||||||
// this.shouldSkip = true; this.shouldStop = true;
|
// this.shouldSkip = true; this.shouldStop = true;
|
||||||
this._traverseFlags |= SHOULD_SKIP | SHOULD_STOP;
|
this._traverseFlags |= SHOULD_SKIP | SHOULD_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setScope() {
|
export function setScope(this: NodePath) {
|
||||||
if (this.opts && this.opts.noScope) return;
|
if (this.opts && this.opts.noScope) return;
|
||||||
|
|
||||||
let path = this.parentPath;
|
let path = this.parentPath;
|
||||||
@ -129,7 +131,7 @@ export function setScope() {
|
|||||||
if (this.scope) this.scope.init();
|
if (this.scope) this.scope.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setContext(context) {
|
export function setContext(this: NodePath, context?: TraversalContext) {
|
||||||
if (this.skipKeys != null) {
|
if (this.skipKeys != null) {
|
||||||
this.skipKeys = {};
|
this.skipKeys = {};
|
||||||
}
|
}
|
||||||
@ -153,7 +155,7 @@ export function setContext(context) {
|
|||||||
* for the new values.
|
* for the new values.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function resync() {
|
export function resync(this: NodePath) {
|
||||||
if (this.removed) return;
|
if (this.removed) return;
|
||||||
|
|
||||||
this._resyncParent();
|
this._resyncParent();
|
||||||
@ -162,13 +164,13 @@ export function resync() {
|
|||||||
//this._resyncRemoved();
|
//this._resyncRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _resyncParent() {
|
export function _resyncParent(this: NodePath) {
|
||||||
if (this.parentPath) {
|
if (this.parentPath) {
|
||||||
this.parent = this.parentPath.node;
|
this.parent = this.parentPath.node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _resyncKey() {
|
export function _resyncKey(this: NodePath) {
|
||||||
if (!this.container) return;
|
if (!this.container) return;
|
||||||
|
|
||||||
if (this.node === this.container[this.key]) return;
|
if (this.node === this.container[this.key]) return;
|
||||||
@ -194,7 +196,7 @@ export function _resyncKey() {
|
|||||||
this.key = null;
|
this.key = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _resyncList() {
|
export function _resyncList(this: NodePath) {
|
||||||
if (!this.parent || !this.inList) return;
|
if (!this.parent || !this.inList) return;
|
||||||
|
|
||||||
const newContainer = this.parent[this.listKey];
|
const newContainer = this.parent[this.listKey];
|
||||||
@ -204,7 +206,7 @@ export function _resyncList() {
|
|||||||
this.container = newContainer || null;
|
this.container = newContainer || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _resyncRemoved() {
|
export function _resyncRemoved(this: NodePath) {
|
||||||
if (
|
if (
|
||||||
this.key == null ||
|
this.key == null ||
|
||||||
!this.container ||
|
!this.container ||
|
||||||
@ -214,7 +216,7 @@ export function _resyncRemoved() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function popContext() {
|
export function popContext(this: NodePath) {
|
||||||
this.contexts.pop();
|
this.contexts.pop();
|
||||||
if (this.contexts.length > 0) {
|
if (this.contexts.length > 0) {
|
||||||
this.setContext(this.contexts[this.contexts.length - 1]);
|
this.setContext(this.contexts[this.contexts.length - 1]);
|
||||||
@ -223,12 +225,12 @@ export function popContext() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pushContext(context) {
|
export function pushContext(this: NodePath, context: TraversalContext) {
|
||||||
this.contexts.push(context);
|
this.contexts.push(context);
|
||||||
this.setContext(context);
|
this.setContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setup(parentPath, container, listKey, key) {
|
export function setup(this: NodePath, parentPath, container, listKey, key) {
|
||||||
this.listKey = listKey;
|
this.listKey = listKey;
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
@ -236,13 +238,13 @@ export function setup(parentPath, container, listKey, key) {
|
|||||||
this.setKey(key);
|
this.setKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setKey(key) {
|
export function setKey(this: NodePath, key) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.node = this.container[this.key];
|
this.node = this.container[this.key];
|
||||||
this.type = this.node?.type;
|
this.type = this.node?.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requeue(pathToQueue = this) {
|
export function requeue(this: NodePath, pathToQueue = this) {
|
||||||
if (pathToQueue.removed) return;
|
if (pathToQueue.removed) return;
|
||||||
|
|
||||||
// TODO: Uncomment in Babel 8. If a path is skipped, and then replaced with a
|
// TODO: Uncomment in Babel 8. If a path is skipped, and then replaced with a
|
||||||
@ -263,7 +265,7 @@ export function requeue(pathToQueue = this) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _getQueueContexts() {
|
export function _getQueueContexts(this: NodePath) {
|
||||||
let path = this;
|
let path = this;
|
||||||
let contexts = this.contexts;
|
let contexts = this.contexts;
|
||||||
while (!contexts.length) {
|
while (!contexts.length) {
|
||||||
@ -2,27 +2,31 @@
|
|||||||
|
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import nameFunction from "@babel/helper-function-name";
|
import nameFunction from "@babel/helper-function-name";
|
||||||
|
import type NodePath from "./index";
|
||||||
|
|
||||||
export function toComputedKey(): Object {
|
export function toComputedKey(this: NodePath) {
|
||||||
const node = this.node;
|
|
||||||
|
|
||||||
let key;
|
let key;
|
||||||
if (this.isMemberExpression()) {
|
if (this.isMemberExpression()) {
|
||||||
key = node.property;
|
key = this.node.property;
|
||||||
} else if (this.isProperty() || this.isMethod()) {
|
} else if (this.isProperty() || this.isMethod()) {
|
||||||
key = node.key;
|
key = this.node.key;
|
||||||
} else {
|
} else {
|
||||||
throw new ReferenceError("todo");
|
throw new ReferenceError("todo");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node.computed) {
|
// @ts-expect-error todo(flow->ts) computed does not exist in ClassPrivateProperty
|
||||||
|
if (!this.node.computed) {
|
||||||
if (t.isIdentifier(key)) key = t.stringLiteral(key.name);
|
if (t.isIdentifier(key)) key = t.stringLiteral(key.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ensureBlock() {
|
export function ensureBlock(
|
||||||
|
this: NodePath<
|
||||||
|
t.Loop | t.WithStatement | t.Function | t.LabeledStatement | t.CatchClause
|
||||||
|
>,
|
||||||
|
) {
|
||||||
const body = this.get("body");
|
const body = this.get("body");
|
||||||
const bodyNode = body.node;
|
const bodyNode = body.node;
|
||||||
|
|
||||||
@ -37,7 +41,7 @@ export function ensureBlock() {
|
|||||||
return bodyNode;
|
return bodyNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const statements = [];
|
const statements: Array<t.Statement> = [];
|
||||||
|
|
||||||
let stringPath = "body";
|
let stringPath = "body";
|
||||||
let key;
|
let key;
|
||||||
@ -50,15 +54,15 @@ export function ensureBlock() {
|
|||||||
stringPath += ".body.0";
|
stringPath += ".body.0";
|
||||||
if (this.isFunction()) {
|
if (this.isFunction()) {
|
||||||
key = "argument";
|
key = "argument";
|
||||||
statements.push(t.returnStatement(body.node));
|
statements.push(t.returnStatement(body.node as t.Expression));
|
||||||
} else {
|
} else {
|
||||||
key = "expression";
|
key = "expression";
|
||||||
statements.push(t.expressionStatement(body.node));
|
statements.push(t.expressionStatement(body.node as t.Expression));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.node.body = t.blockStatement(statements);
|
this.node.body = t.blockStatement(statements);
|
||||||
const parentPath = this.get(stringPath);
|
const parentPath = this.get(stringPath) as NodePath;
|
||||||
body.setup(
|
body.setup(
|
||||||
parentPath,
|
parentPath,
|
||||||
listKey ? parentPath.node[listKey] : parentPath.node,
|
listKey ? parentPath.node[listKey] : parentPath.node,
|
||||||
@ -72,7 +76,7 @@ export function ensureBlock() {
|
|||||||
/**
|
/**
|
||||||
* Keeping this for backward-compatibility. You should use arrowFunctionToExpression() for >=7.x.
|
* Keeping this for backward-compatibility. You should use arrowFunctionToExpression() for >=7.x.
|
||||||
*/
|
*/
|
||||||
export function arrowFunctionToShadowed() {
|
export function arrowFunctionToShadowed(this: NodePath) {
|
||||||
if (!this.isArrowFunctionExpression()) return;
|
if (!this.isArrowFunctionExpression()) return;
|
||||||
|
|
||||||
this.arrowFunctionToExpression();
|
this.arrowFunctionToExpression();
|
||||||
@ -84,7 +88,7 @@ export function arrowFunctionToShadowed() {
|
|||||||
* you have wrapped some set of items in an IIFE or other function, but want "this", "arguments", and super"
|
* you have wrapped some set of items in an IIFE or other function, but want "this", "arguments", and super"
|
||||||
* to continue behaving as expected.
|
* to continue behaving as expected.
|
||||||
*/
|
*/
|
||||||
export function unwrapFunctionEnvironment() {
|
export function unwrapFunctionEnvironment(this: NodePath) {
|
||||||
if (
|
if (
|
||||||
!this.isArrowFunctionExpression() &&
|
!this.isArrowFunctionExpression() &&
|
||||||
!this.isFunctionExpression() &&
|
!this.isFunctionExpression() &&
|
||||||
@ -101,10 +105,10 @@ export function unwrapFunctionEnvironment() {
|
|||||||
/**
|
/**
|
||||||
* Convert a given arrow function into a normal ES5 function expression.
|
* Convert a given arrow function into a normal ES5 function expression.
|
||||||
*/
|
*/
|
||||||
export function arrowFunctionToExpression({
|
export function arrowFunctionToExpression(
|
||||||
allowInsertArrow = true,
|
this: NodePath,
|
||||||
specCompliant = false,
|
{ allowInsertArrow = true, specCompliant = false } = {},
|
||||||
} = {}) {
|
) {
|
||||||
if (!this.isArrowFunctionExpression()) {
|
if (!this.isArrowFunctionExpression()) {
|
||||||
throw this.buildCodeFrameError(
|
throw this.buildCodeFrameError(
|
||||||
"Cannot convert non-arrow function to a function expression.",
|
"Cannot convert non-arrow function to a function expression.",
|
||||||
@ -118,6 +122,7 @@ export function arrowFunctionToExpression({
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.ensureBlock();
|
this.ensureBlock();
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutating nodes
|
||||||
this.node.type = "FunctionExpression";
|
this.node.type = "FunctionExpression";
|
||||||
if (specCompliant) {
|
if (specCompliant) {
|
||||||
const checkBinding = thisBinding
|
const checkBinding = thisBinding
|
||||||
@ -392,7 +397,7 @@ function standardizeSuperProperty(superProp) {
|
|||||||
? superProp.scope.generateDeclaredUidIdentifier("prop")
|
? superProp.scope.generateDeclaredUidIdentifier("prop")
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const parts = [
|
const parts: t.Expression[] = [
|
||||||
t.assignmentExpression(
|
t.assignmentExpression(
|
||||||
"=",
|
"=",
|
||||||
tmp,
|
tmp,
|
||||||
@ -23,7 +23,7 @@ const INVALID_METHODS = ["random"];
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function evaluateTruthy(): boolean {
|
export function evaluateTruthy(this: NodePath): boolean {
|
||||||
const res = this.evaluate();
|
const res = this.evaluate();
|
||||||
if (res.confident) return !!res.value;
|
if (res.confident) return !!res.value;
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ function deopt(path, state) {
|
|||||||
* var g = a ? 1 : 2,
|
* var g = a ? 1 : 2,
|
||||||
* a = g * this.foo
|
* a = g * this.foo
|
||||||
*/
|
*/
|
||||||
function evaluateCached(path, state) {
|
function evaluateCached(path: NodePath, state) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
const { seen } = state;
|
const { seen } = state;
|
||||||
|
|
||||||
@ -58,7 +58,8 @@ function evaluateCached(path, state) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const item = { resolved: false };
|
// todo: create type annotation for state instead
|
||||||
|
const item: { resolved: boolean; value?: any } = { resolved: false };
|
||||||
seen.set(node, item);
|
seen.set(node, item);
|
||||||
|
|
||||||
const val = _evaluate(path, state);
|
const val = _evaluate(path, state);
|
||||||
@ -70,11 +71,9 @@ function evaluateCached(path, state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _evaluate(path, state) {
|
function _evaluate(path: NodePath, state) {
|
||||||
if (!state.confident) return;
|
if (!state.confident) return;
|
||||||
|
|
||||||
const { node } = path;
|
|
||||||
|
|
||||||
if (path.isSequenceExpression()) {
|
if (path.isSequenceExpression()) {
|
||||||
const exprs = path.get("expressions");
|
const exprs = path.get("expressions");
|
||||||
return evaluateCached(exprs[exprs.length - 1], state);
|
return evaluateCached(exprs[exprs.length - 1], state);
|
||||||
@ -85,7 +84,7 @@ function _evaluate(path, state) {
|
|||||||
path.isNumericLiteral() ||
|
path.isNumericLiteral() ||
|
||||||
path.isBooleanLiteral()
|
path.isBooleanLiteral()
|
||||||
) {
|
) {
|
||||||
return node.value;
|
return path.node.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.isNullLiteral()) {
|
if (path.isNullLiteral()) {
|
||||||
@ -93,27 +92,30 @@ function _evaluate(path, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (path.isTemplateLiteral()) {
|
if (path.isTemplateLiteral()) {
|
||||||
return evaluateQuasis(path, node.quasis, state);
|
return evaluateQuasis(path, path.node.quasis, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
path.isTaggedTemplateExpression() &&
|
path.isTaggedTemplateExpression() &&
|
||||||
path.get("tag").isMemberExpression()
|
path.get("tag").isMemberExpression()
|
||||||
) {
|
) {
|
||||||
const object = path.get("tag.object");
|
const object = path.get("tag.object") as NodePath;
|
||||||
const {
|
const {
|
||||||
|
// @ts-expect-error todo(flow->ts): possible bug, object is can be any expression and so name might be undefined
|
||||||
node: { name },
|
node: { name },
|
||||||
} = object;
|
} = object;
|
||||||
const property = path.get("tag.property");
|
const property = path.get("tag.property") as NodePath;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
object.isIdentifier() &&
|
object.isIdentifier() &&
|
||||||
name === "String" &&
|
name === "String" &&
|
||||||
!path.scope.getBinding(name, true) &&
|
// todo(flow->ts): was changed from getBinding(name, true)
|
||||||
property.isIdentifier &&
|
// should this be hasBinding(name, true) as the binding is never used later?
|
||||||
|
!path.scope.getBinding(name) &&
|
||||||
|
property.isIdentifier() &&
|
||||||
property.node.name === "raw"
|
property.node.name === "raw"
|
||||||
) {
|
) {
|
||||||
return evaluateQuasis(path, node.quasi.quasis, state, true);
|
return evaluateQuasis(path, path.node.quasi.quasis, state, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,12 +137,13 @@ function _evaluate(path, state) {
|
|||||||
// "foo".length
|
// "foo".length
|
||||||
if (
|
if (
|
||||||
path.isMemberExpression() &&
|
path.isMemberExpression() &&
|
||||||
!path.parentPath.isCallExpression({ callee: node })
|
!path.parentPath.isCallExpression({ callee: path.node })
|
||||||
) {
|
) {
|
||||||
const property = path.get("property");
|
const property = path.get("property") as NodePath;
|
||||||
const object = path.get("object");
|
const object = path.get("object") as NodePath;
|
||||||
|
|
||||||
if (object.isLiteral() && property.isIdentifier()) {
|
if (object.isLiteral() && property.isIdentifier()) {
|
||||||
|
// @ts-expect-error todo(flow->ts): instead of typeof - would it be better to check type of ast node?
|
||||||
const value = object.node.value;
|
const value = object.node.value;
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
if (type === "number" || type === "string") {
|
if (type === "number" || type === "string") {
|
||||||
@ -150,7 +153,8 @@ function _evaluate(path, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (path.isReferencedIdentifier()) {
|
if (path.isReferencedIdentifier()) {
|
||||||
const binding = path.scope.getBinding(node.name);
|
// @ts-expect-error todo(flow->ts): consider separating type refinement and check for reference
|
||||||
|
const binding = path.scope.getBinding(path.node.name);
|
||||||
|
|
||||||
if (binding && binding.constantViolations.length > 0) {
|
if (binding && binding.constantViolations.length > 0) {
|
||||||
return deopt(binding.path, state);
|
return deopt(binding.path, state);
|
||||||
@ -163,11 +167,14 @@ function _evaluate(path, state) {
|
|||||||
if (binding?.hasValue) {
|
if (binding?.hasValue) {
|
||||||
return binding.value;
|
return binding.value;
|
||||||
} else {
|
} else {
|
||||||
if (node.name === "undefined") {
|
// @ts-expect-error todo(flow->ts): consider separating type refinement and check for reference
|
||||||
|
if (path.node.name === "undefined") {
|
||||||
return binding ? deopt(binding.path, state) : undefined;
|
return binding ? deopt(binding.path, state) : undefined;
|
||||||
} else if (node.name === "Infinity") {
|
// @ts-expect-error todo(flow->ts): consider separating type refinement and check for reference
|
||||||
|
} else if (path.node.name === "Infinity") {
|
||||||
return binding ? deopt(binding.path, state) : Infinity;
|
return binding ? deopt(binding.path, state) : Infinity;
|
||||||
} else if (node.name === "NaN") {
|
// @ts-expect-error todo(flow->ts): consider separating type refinement and check for reference
|
||||||
|
} else if (path.node.name === "NaN") {
|
||||||
return binding ? deopt(binding.path, state) : NaN;
|
return binding ? deopt(binding.path, state) : NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,14 +188,14 @@ function _evaluate(path, state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (path.isUnaryExpression({ prefix: true })) {
|
if (path.isUnaryExpression({ prefix: true })) {
|
||||||
if (node.operator === "void") {
|
if (path.node.operator === "void") {
|
||||||
// we don't need to evaluate the argument to know what this will return
|
// we don't need to evaluate the argument to know what this will return
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const argument = path.get("argument");
|
const argument = path.get("argument");
|
||||||
if (
|
if (
|
||||||
node.operator === "typeof" &&
|
path.node.operator === "typeof" &&
|
||||||
(argument.isFunction() || argument.isClass())
|
(argument.isFunction() || argument.isClass())
|
||||||
) {
|
) {
|
||||||
return "function";
|
return "function";
|
||||||
@ -196,7 +203,7 @@ function _evaluate(path, state) {
|
|||||||
|
|
||||||
const arg = evaluateCached(argument, state);
|
const arg = evaluateCached(argument, state);
|
||||||
if (!state.confident) return;
|
if (!state.confident) return;
|
||||||
switch (node.operator) {
|
switch (path.node.operator) {
|
||||||
case "!":
|
case "!":
|
||||||
return !arg;
|
return !arg;
|
||||||
case "+":
|
case "+":
|
||||||
@ -227,13 +234,14 @@ function _evaluate(path, state) {
|
|||||||
|
|
||||||
if (path.isObjectExpression()) {
|
if (path.isObjectExpression()) {
|
||||||
const obj = {};
|
const obj = {};
|
||||||
const props: Array<NodePath> = path.get("properties");
|
const props = path.get("properties");
|
||||||
for (const prop of props) {
|
for (const prop of props) {
|
||||||
if (prop.isObjectMethod() || prop.isSpreadElement()) {
|
if (prop.isObjectMethod() || prop.isSpreadElement()) {
|
||||||
return deopt(prop, state);
|
return deopt(prop, state);
|
||||||
}
|
}
|
||||||
const keyPath = prop.get("key");
|
const keyPath: any = prop.get("key");
|
||||||
let key = keyPath;
|
let key = keyPath;
|
||||||
|
// @ts-expect-error todo(flow->ts): type refinement issues ObjectMethod and SpreadElement somehow not excluded
|
||||||
if (prop.node.computed) {
|
if (prop.node.computed) {
|
||||||
key = key.evaluate();
|
key = key.evaluate();
|
||||||
if (!key.confident) {
|
if (!key.confident) {
|
||||||
@ -245,7 +253,8 @@ function _evaluate(path, state) {
|
|||||||
} else {
|
} else {
|
||||||
key = key.node.value;
|
key = key.node.value;
|
||||||
}
|
}
|
||||||
const valuePath = prop.get("value");
|
// todo(flow->ts): remove typecast
|
||||||
|
const valuePath = prop.get("value") as NodePath;
|
||||||
let value = valuePath.evaluate();
|
let value = valuePath.evaluate();
|
||||||
if (!value.confident) {
|
if (!value.confident) {
|
||||||
return deopt(value.deopt, state);
|
return deopt(value.deopt, state);
|
||||||
@ -266,7 +275,7 @@ function _evaluate(path, state) {
|
|||||||
const right = evaluateCached(path.get("right"), state);
|
const right = evaluateCached(path.get("right"), state);
|
||||||
const rightConfident = state.confident;
|
const rightConfident = state.confident;
|
||||||
|
|
||||||
switch (node.operator) {
|
switch (path.node.operator) {
|
||||||
case "||":
|
case "||":
|
||||||
// TODO consider having a "truthy type" that doesn't bail on
|
// TODO consider having a "truthy type" that doesn't bail on
|
||||||
// left uncertainty but can still evaluate to truthy.
|
// left uncertainty but can still evaluate to truthy.
|
||||||
@ -288,7 +297,7 @@ function _evaluate(path, state) {
|
|||||||
const right = evaluateCached(path.get("right"), state);
|
const right = evaluateCached(path.get("right"), state);
|
||||||
if (!state.confident) return;
|
if (!state.confident) return;
|
||||||
|
|
||||||
switch (node.operator) {
|
switch (path.node.operator) {
|
||||||
case "-":
|
case "-":
|
||||||
return left - right;
|
return left - right;
|
||||||
case "+":
|
case "+":
|
||||||
@ -340,15 +349,16 @@ function _evaluate(path, state) {
|
|||||||
// Number(1);
|
// Number(1);
|
||||||
if (
|
if (
|
||||||
callee.isIdentifier() &&
|
callee.isIdentifier() &&
|
||||||
!path.scope.getBinding(callee.node.name, true) &&
|
!path.scope.getBinding(callee.node.name) &&
|
||||||
VALID_CALLEES.indexOf(callee.node.name) >= 0
|
VALID_CALLEES.indexOf(callee.node.name) >= 0
|
||||||
) {
|
) {
|
||||||
func = global[node.callee.name];
|
func = global[callee.node.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callee.isMemberExpression()) {
|
if (callee.isMemberExpression()) {
|
||||||
const object = callee.get("object");
|
const object = callee.get("object");
|
||||||
const property = callee.get("property");
|
// todo: improve babel-types
|
||||||
|
const property = callee.get("property") as NodePath;
|
||||||
|
|
||||||
// Math.min(1, 2)
|
// Math.min(1, 2)
|
||||||
if (
|
if (
|
||||||
@ -363,8 +373,10 @@ function _evaluate(path, state) {
|
|||||||
|
|
||||||
// "abc".charCodeAt(4)
|
// "abc".charCodeAt(4)
|
||||||
if (object.isLiteral() && property.isIdentifier()) {
|
if (object.isLiteral() && property.isIdentifier()) {
|
||||||
|
// @ts-expect-error todo(flow->ts): consider checking ast node type instead of value type (StringLiteral and NumberLiteral)
|
||||||
const type = typeof object.node.value;
|
const type = typeof object.node.value;
|
||||||
if (type === "string" || type === "number") {
|
if (type === "string" || type === "number") {
|
||||||
|
// @ts-expect-error todo(flow->ts): consider checking ast node type instead of value type
|
||||||
context = object.node.value;
|
context = object.node.value;
|
||||||
func = context[property.node.name];
|
func = context[property.node.name];
|
||||||
}
|
}
|
||||||
@ -382,7 +394,7 @@ function _evaluate(path, state) {
|
|||||||
deopt(path, state);
|
deopt(path, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateQuasis(path, quasis: Array<Object>, state, raw = false) {
|
function evaluateQuasis(path, quasis: Array<any>, state, raw = false) {
|
||||||
let str = "";
|
let str = "";
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -420,10 +432,12 @@ function evaluateQuasis(path, quasis: Array<Object>, state, raw = false) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function evaluate(): {
|
export function evaluate(
|
||||||
confident: boolean,
|
this: NodePath,
|
||||||
value: any,
|
): {
|
||||||
deopt?: NodePath,
|
confident: boolean;
|
||||||
|
value: any;
|
||||||
|
deopt?: NodePath;
|
||||||
} {
|
} {
|
||||||
const state = {
|
const state = {
|
||||||
confident: true,
|
confident: true,
|
||||||
@ -1,24 +1,27 @@
|
|||||||
// @flow
|
|
||||||
// This file contains methods responsible for dealing with/retrieving children or siblings.
|
// This file contains methods responsible for dealing with/retrieving children or siblings.
|
||||||
|
|
||||||
import type TraversalContext from "../index";
|
import type TraversalContext from "../context";
|
||||||
import NodePath from "./index";
|
import NodePath from "./index";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
export function getOpposite(): ?NodePath {
|
export function getOpposite(this: NodePath): NodePath | null {
|
||||||
if (this.key === "left") {
|
if (this.key === "left") {
|
||||||
return this.getSibling("right");
|
return this.getSibling("right");
|
||||||
} else if (this.key === "right") {
|
} else if (this.key === "right") {
|
||||||
return this.getSibling("left");
|
return this.getSibling("left");
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCompletionRecords(path, paths) {
|
function addCompletionRecords(
|
||||||
|
path: NodePath | null | undefined,
|
||||||
|
paths: NodePath[],
|
||||||
|
): NodePath[] {
|
||||||
if (path) return paths.concat(path.getCompletionRecords());
|
if (path) return paths.concat(path.getCompletionRecords());
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findBreak(statements): ?NodePath {
|
function findBreak(statements): NodePath | null {
|
||||||
let breakStatement;
|
let breakStatement;
|
||||||
if (!Array.isArray(statements)) {
|
if (!Array.isArray(statements)) {
|
||||||
statements = [statements];
|
statements = [statements];
|
||||||
@ -94,15 +97,17 @@ function completionRecordForSwitch(cases, paths) {
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCompletionRecords(): NodePath[] {
|
export function getCompletionRecords(this: NodePath): NodePath[] {
|
||||||
let paths = [];
|
let paths = [];
|
||||||
|
|
||||||
if (this.isIfStatement()) {
|
if (this.isIfStatement()) {
|
||||||
paths = addCompletionRecords(this.get("consequent"), paths);
|
paths = addCompletionRecords(this.get("consequent"), paths);
|
||||||
paths = addCompletionRecords(this.get("alternate"), paths);
|
paths = addCompletionRecords(this.get("alternate"), paths);
|
||||||
} else if (this.isDoExpression() || this.isFor() || this.isWhile()) {
|
} else if (this.isDoExpression() || this.isFor() || this.isWhile()) {
|
||||||
|
// @ts-expect-error(flow->ts): todo
|
||||||
paths = addCompletionRecords(this.get("body"), paths);
|
paths = addCompletionRecords(this.get("body"), paths);
|
||||||
} else if (this.isProgram() || this.isBlockStatement()) {
|
} else if (this.isProgram() || this.isBlockStatement()) {
|
||||||
|
// @ts-expect-error(flow->ts): todo
|
||||||
paths = addCompletionRecords(this.get("body").pop(), paths);
|
paths = addCompletionRecords(this.get("body").pop(), paths);
|
||||||
} else if (this.isFunction()) {
|
} else if (this.isFunction()) {
|
||||||
return this.get("body").getCompletionRecords();
|
return this.get("body").getCompletionRecords();
|
||||||
@ -120,7 +125,7 @@ export function getCompletionRecords(): NodePath[] {
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSibling(key: string): NodePath {
|
export function getSibling(this: NodePath, key: string | number): NodePath {
|
||||||
return NodePath.get({
|
return NodePath.get({
|
||||||
parentPath: this.parentPath,
|
parentPath: this.parentPath,
|
||||||
parent: this.parent,
|
parent: this.parent,
|
||||||
@ -130,16 +135,19 @@ export function getSibling(key: string): NodePath {
|
|||||||
}).setContext(this.context);
|
}).setContext(this.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPrevSibling(): NodePath {
|
export function getPrevSibling(this: NodePath): NodePath {
|
||||||
|
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||||
return this.getSibling(this.key - 1);
|
return this.getSibling(this.key - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNextSibling(): NodePath {
|
export function getNextSibling(this: NodePath): NodePath {
|
||||||
|
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||||
return this.getSibling(this.key + 1);
|
return this.getSibling(this.key + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllNextSiblings(): NodePath[] {
|
export function getAllNextSiblings(this: NodePath): NodePath[] {
|
||||||
let _key = this.key;
|
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||||
|
let _key: number = this.key;
|
||||||
let sibling = this.getSibling(++_key);
|
let sibling = this.getSibling(++_key);
|
||||||
const siblings = [];
|
const siblings = [];
|
||||||
while (sibling.node) {
|
while (sibling.node) {
|
||||||
@ -149,8 +157,9 @@ export function getAllNextSiblings(): NodePath[] {
|
|||||||
return siblings;
|
return siblings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllPrevSiblings(): NodePath[] {
|
export function getAllPrevSiblings(this: NodePath): NodePath[] {
|
||||||
let _key = this.key;
|
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||||
|
let _key: number = this.key;
|
||||||
let sibling = this.getSibling(--_key);
|
let sibling = this.getSibling(--_key);
|
||||||
const siblings = [];
|
const siblings = [];
|
||||||
while (sibling.node) {
|
while (sibling.node) {
|
||||||
@ -160,9 +169,26 @@ export function getAllPrevSiblings(): NodePath[] {
|
|||||||
return siblings;
|
return siblings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get(
|
function get<T extends t.Node, K extends keyof T>(
|
||||||
|
this: NodePath<T>,
|
||||||
|
key: K,
|
||||||
|
context?: boolean | TraversalContext,
|
||||||
|
): T[K] extends Array<t.Node | null | undefined>
|
||||||
|
? Array<NodePath<T[K][number]>>
|
||||||
|
: T[K] extends t.Node | null | undefined
|
||||||
|
? NodePath<T[K]>
|
||||||
|
: never;
|
||||||
|
|
||||||
|
function get<T extends t.Node>(
|
||||||
|
this: NodePath<T>,
|
||||||
key: string,
|
key: string,
|
||||||
context?: boolean | TraversalContext = true,
|
context?: true | TraversalContext,
|
||||||
|
): NodePath | NodePath[];
|
||||||
|
|
||||||
|
function get<T extends t.Node>(
|
||||||
|
this: NodePath<T>,
|
||||||
|
key: string,
|
||||||
|
context: true | TraversalContext = true,
|
||||||
): NodePath | NodePath[] {
|
): NodePath | NodePath[] {
|
||||||
if (context === true) context = this.context;
|
if (context === true) context = this.context;
|
||||||
const parts = key.split(".");
|
const parts = key.split(".");
|
||||||
@ -175,7 +201,10 @@ export function get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _getKey(
|
export { get };
|
||||||
|
|
||||||
|
export function _getKey<T extends t.Node>(
|
||||||
|
this: NodePath<T>,
|
||||||
key: string,
|
key: string,
|
||||||
context?: TraversalContext,
|
context?: TraversalContext,
|
||||||
): NodePath | NodePath[] {
|
): NodePath | NodePath[] {
|
||||||
@ -204,12 +233,14 @@ export function _getKey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function _getPattern(
|
export function _getPattern(
|
||||||
|
this: NodePath,
|
||||||
parts: string[],
|
parts: string[],
|
||||||
context?: TraversalContext,
|
context?: TraversalContext,
|
||||||
): NodePath | NodePath[] {
|
): NodePath | NodePath[] {
|
||||||
let path = this;
|
let path: NodePath | NodePath[] = this;
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
if (part === ".") {
|
if (part === ".") {
|
||||||
|
// @ts-expect-error todo(flow-ts): Can path be an array here?
|
||||||
path = path.parentPath;
|
path = path.parentPath;
|
||||||
} else {
|
} else {
|
||||||
if (Array.isArray(path)) {
|
if (Array.isArray(path)) {
|
||||||
@ -222,21 +253,52 @@ export function _getPattern(
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBindingIdentifiers(duplicates?: boolean): Object {
|
function getBindingIdentifiers(
|
||||||
|
duplicates: true,
|
||||||
|
): Record<string, t.Identifier[]>;
|
||||||
|
function getBindingIdentifiers(
|
||||||
|
duplicates?: false,
|
||||||
|
): Record<string, t.Identifier>;
|
||||||
|
function getBindingIdentifiers(
|
||||||
|
duplicates: boolean,
|
||||||
|
): Record<string, t.Identifier[] | t.Identifier>;
|
||||||
|
|
||||||
|
function getBindingIdentifiers(
|
||||||
|
duplicates?: boolean,
|
||||||
|
): Record<string, t.Identifier[] | t.Identifier> {
|
||||||
return t.getBindingIdentifiers(this.node, duplicates);
|
return t.getBindingIdentifiers(this.node, duplicates);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOuterBindingIdentifiers(duplicates?: boolean): Object {
|
export { getBindingIdentifiers };
|
||||||
|
|
||||||
|
function getOuterBindingIdentifiers(
|
||||||
|
duplicates: true,
|
||||||
|
): Record<string, t.Identifier[]>;
|
||||||
|
function getOuterBindingIdentifiers(
|
||||||
|
duplicates?: false,
|
||||||
|
): Record<string, t.Identifier>;
|
||||||
|
function getOuterBindingIdentifiers(
|
||||||
|
duplicates: boolean,
|
||||||
|
): Record<string, t.Identifier[] | t.Identifier>;
|
||||||
|
|
||||||
|
function getOuterBindingIdentifiers(
|
||||||
|
duplicates?: boolean,
|
||||||
|
): Record<string, t.Identifier[] | t.Identifier> {
|
||||||
return t.getOuterBindingIdentifiers(this.node, duplicates);
|
return t.getOuterBindingIdentifiers(this.node, duplicates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { getOuterBindingIdentifiers };
|
||||||
|
|
||||||
// original source - https://github.com/babel/babel/blob/main/packages/babel-types/src/retrievers/getBindingIdentifiers.js
|
// original source - https://github.com/babel/babel/blob/main/packages/babel-types/src/retrievers/getBindingIdentifiers.js
|
||||||
// path.getBindingIdentifiers returns nodes where the following re-implementation
|
// path.getBindingIdentifiers returns nodes where the following re-implementation
|
||||||
// returns paths
|
// returns paths
|
||||||
export function getBindingIdentifierPaths(
|
export function getBindingIdentifierPaths(
|
||||||
duplicates?: boolean = false,
|
this: NodePath,
|
||||||
outerOnly?: boolean = false,
|
duplicates: boolean = false,
|
||||||
): { [string]: NodePath } {
|
outerOnly: boolean = false,
|
||||||
|
): {
|
||||||
|
[x: string]: NodePath;
|
||||||
|
} {
|
||||||
const path = this;
|
const path = this;
|
||||||
let search = [].concat(path);
|
let search = [].concat(path);
|
||||||
const ids = Object.create(null);
|
const ids = Object.create(null);
|
||||||
@ -292,7 +354,10 @@ export function getBindingIdentifierPaths(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getOuterBindingIdentifierPaths(
|
export function getOuterBindingIdentifierPaths(
|
||||||
|
this: NodePath,
|
||||||
duplicates?: boolean,
|
duplicates?: boolean,
|
||||||
): { [string]: NodePath } {
|
): {
|
||||||
|
[x: string]: NodePath;
|
||||||
|
} {
|
||||||
return this.getBindingIdentifierPaths(duplicates, true);
|
return this.getBindingIdentifierPaths(duplicates, true);
|
||||||
}
|
}
|
||||||
688
packages/babel-traverse/src/path/generated/asserts.ts
Executable file
688
packages/babel-traverse/src/path/generated/asserts.ts
Executable file
@ -0,0 +1,688 @@
|
|||||||
|
/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
import NodePath from "../index";
|
||||||
|
|
||||||
|
export interface NodePathAssetions {
|
||||||
|
assertAnyTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.AnyTypeAnnotation>;
|
||||||
|
assertArgumentPlaceholder(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ArgumentPlaceholder>;
|
||||||
|
assertArrayExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ArrayExpression>;
|
||||||
|
assertArrayPattern(opts?: object): asserts this is NodePath<t.ArrayPattern>;
|
||||||
|
assertArrayTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ArrayTypeAnnotation>;
|
||||||
|
assertArrowFunctionExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ArrowFunctionExpression>;
|
||||||
|
assertAssignmentExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.AssignmentExpression>;
|
||||||
|
assertAssignmentPattern(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.AssignmentPattern>;
|
||||||
|
assertAwaitExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.AwaitExpression>;
|
||||||
|
assertBigIntLiteral(opts?: object): asserts this is NodePath<t.BigIntLiteral>;
|
||||||
|
assertBinary(opts?: object): asserts this is NodePath<t.Binary>;
|
||||||
|
assertBinaryExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BinaryExpression>;
|
||||||
|
assertBindExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BindExpression>;
|
||||||
|
assertBlock(opts?: object): asserts this is NodePath<t.Block>;
|
||||||
|
assertBlockParent(opts?: object): asserts this is NodePath<t.BlockParent>;
|
||||||
|
assertBlockStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BlockStatement>;
|
||||||
|
assertBooleanLiteral(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BooleanLiteral>;
|
||||||
|
assertBooleanLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BooleanLiteralTypeAnnotation>;
|
||||||
|
assertBooleanTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BooleanTypeAnnotation>;
|
||||||
|
assertBreakStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.BreakStatement>;
|
||||||
|
assertCallExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.CallExpression>;
|
||||||
|
assertCatchClause(opts?: object): asserts this is NodePath<t.CatchClause>;
|
||||||
|
assertClass(opts?: object): asserts this is NodePath<t.Class>;
|
||||||
|
assertClassBody(opts?: object): asserts this is NodePath<t.ClassBody>;
|
||||||
|
assertClassDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ClassDeclaration>;
|
||||||
|
assertClassExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ClassExpression>;
|
||||||
|
assertClassImplements(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ClassImplements>;
|
||||||
|
assertClassMethod(opts?: object): asserts this is NodePath<t.ClassMethod>;
|
||||||
|
assertClassPrivateMethod(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ClassPrivateMethod>;
|
||||||
|
assertClassPrivateProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ClassPrivateProperty>;
|
||||||
|
assertClassProperty(opts?: object): asserts this is NodePath<t.ClassProperty>;
|
||||||
|
assertCompletionStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.CompletionStatement>;
|
||||||
|
assertConditional(opts?: object): asserts this is NodePath<t.Conditional>;
|
||||||
|
assertConditionalExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ConditionalExpression>;
|
||||||
|
assertContinueStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ContinueStatement>;
|
||||||
|
assertDebuggerStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DebuggerStatement>;
|
||||||
|
assertDecimalLiteral(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DecimalLiteral>;
|
||||||
|
assertDeclaration(opts?: object): asserts this is NodePath<t.Declaration>;
|
||||||
|
assertDeclareClass(opts?: object): asserts this is NodePath<t.DeclareClass>;
|
||||||
|
assertDeclareExportAllDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareExportAllDeclaration>;
|
||||||
|
assertDeclareExportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareExportDeclaration>;
|
||||||
|
assertDeclareFunction(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareFunction>;
|
||||||
|
assertDeclareInterface(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareInterface>;
|
||||||
|
assertDeclareModule(opts?: object): asserts this is NodePath<t.DeclareModule>;
|
||||||
|
assertDeclareModuleExports(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareModuleExports>;
|
||||||
|
assertDeclareOpaqueType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareOpaqueType>;
|
||||||
|
assertDeclareTypeAlias(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareTypeAlias>;
|
||||||
|
assertDeclareVariable(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclareVariable>;
|
||||||
|
assertDeclaredPredicate(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DeclaredPredicate>;
|
||||||
|
assertDecorator(opts?: object): asserts this is NodePath<t.Decorator>;
|
||||||
|
assertDirective(opts?: object): asserts this is NodePath<t.Directive>;
|
||||||
|
assertDirectiveLiteral(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DirectiveLiteral>;
|
||||||
|
assertDoExpression(opts?: object): asserts this is NodePath<t.DoExpression>;
|
||||||
|
assertDoWhileStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.DoWhileStatement>;
|
||||||
|
assertEmptyStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EmptyStatement>;
|
||||||
|
assertEmptyTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EmptyTypeAnnotation>;
|
||||||
|
assertEnumBody(opts?: object): asserts this is NodePath<t.EnumBody>;
|
||||||
|
assertEnumBooleanBody(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumBooleanBody>;
|
||||||
|
assertEnumBooleanMember(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumBooleanMember>;
|
||||||
|
assertEnumDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumDeclaration>;
|
||||||
|
assertEnumDefaultedMember(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumDefaultedMember>;
|
||||||
|
assertEnumMember(opts?: object): asserts this is NodePath<t.EnumMember>;
|
||||||
|
assertEnumNumberBody(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumNumberBody>;
|
||||||
|
assertEnumNumberMember(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumNumberMember>;
|
||||||
|
assertEnumStringBody(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumStringBody>;
|
||||||
|
assertEnumStringMember(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumStringMember>;
|
||||||
|
assertEnumSymbolBody(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.EnumSymbolBody>;
|
||||||
|
assertExistsTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExistsTypeAnnotation>;
|
||||||
|
assertExportAllDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportAllDeclaration>;
|
||||||
|
assertExportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportDeclaration>;
|
||||||
|
assertExportDefaultDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportDefaultDeclaration>;
|
||||||
|
assertExportDefaultSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportDefaultSpecifier>;
|
||||||
|
assertExportNamedDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportNamedDeclaration>;
|
||||||
|
assertExportNamespaceSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportNamespaceSpecifier>;
|
||||||
|
assertExportSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExportSpecifier>;
|
||||||
|
assertExpression(opts?: object): asserts this is NodePath<t.Expression>;
|
||||||
|
assertExpressionStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExpressionStatement>;
|
||||||
|
assertExpressionWrapper(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ExpressionWrapper>;
|
||||||
|
assertFile(opts?: object): asserts this is NodePath<t.File>;
|
||||||
|
assertFlow(opts?: object): asserts this is NodePath<t.Flow>;
|
||||||
|
assertFlowBaseAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FlowBaseAnnotation>;
|
||||||
|
assertFlowDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FlowDeclaration>;
|
||||||
|
assertFlowPredicate(opts?: object): asserts this is NodePath<t.FlowPredicate>;
|
||||||
|
assertFlowType(opts?: object): asserts this is NodePath<t.FlowType>;
|
||||||
|
assertFor(opts?: object): asserts this is NodePath<t.For>;
|
||||||
|
assertForInStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ForInStatement>;
|
||||||
|
assertForOfStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ForOfStatement>;
|
||||||
|
assertForStatement(opts?: object): asserts this is NodePath<t.ForStatement>;
|
||||||
|
assertForXStatement(opts?: object): asserts this is NodePath<t.ForXStatement>;
|
||||||
|
assertFunction(opts?: object): asserts this is NodePath<t.Function>;
|
||||||
|
assertFunctionDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FunctionDeclaration>;
|
||||||
|
assertFunctionExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FunctionExpression>;
|
||||||
|
assertFunctionParent(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FunctionParent>;
|
||||||
|
assertFunctionTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FunctionTypeAnnotation>;
|
||||||
|
assertFunctionTypeParam(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.FunctionTypeParam>;
|
||||||
|
assertGenericTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.GenericTypeAnnotation>;
|
||||||
|
assertIdentifier(opts?: object): asserts this is NodePath<t.Identifier>;
|
||||||
|
assertIfStatement(opts?: object): asserts this is NodePath<t.IfStatement>;
|
||||||
|
assertImmutable(opts?: object): asserts this is NodePath<t.Immutable>;
|
||||||
|
assertImport(opts?: object): asserts this is NodePath<t.Import>;
|
||||||
|
assertImportAttribute(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ImportAttribute>;
|
||||||
|
assertImportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ImportDeclaration>;
|
||||||
|
assertImportDefaultSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ImportDefaultSpecifier>;
|
||||||
|
assertImportNamespaceSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ImportNamespaceSpecifier>;
|
||||||
|
assertImportSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ImportSpecifier>;
|
||||||
|
assertInferredPredicate(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.InferredPredicate>;
|
||||||
|
assertInterfaceDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.InterfaceDeclaration>;
|
||||||
|
assertInterfaceExtends(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.InterfaceExtends>;
|
||||||
|
assertInterfaceTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.InterfaceTypeAnnotation>;
|
||||||
|
assertInterpreterDirective(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.InterpreterDirective>;
|
||||||
|
assertIntersectionTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.IntersectionTypeAnnotation>;
|
||||||
|
assertJSX(opts?: object): asserts this is NodePath<t.JSX>;
|
||||||
|
assertJSXAttribute(opts?: object): asserts this is NodePath<t.JSXAttribute>;
|
||||||
|
assertJSXClosingElement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXClosingElement>;
|
||||||
|
assertJSXClosingFragment(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXClosingFragment>;
|
||||||
|
assertJSXElement(opts?: object): asserts this is NodePath<t.JSXElement>;
|
||||||
|
assertJSXEmptyExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXEmptyExpression>;
|
||||||
|
assertJSXExpressionContainer(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXExpressionContainer>;
|
||||||
|
assertJSXFragment(opts?: object): asserts this is NodePath<t.JSXFragment>;
|
||||||
|
assertJSXIdentifier(opts?: object): asserts this is NodePath<t.JSXIdentifier>;
|
||||||
|
assertJSXMemberExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXMemberExpression>;
|
||||||
|
assertJSXNamespacedName(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXNamespacedName>;
|
||||||
|
assertJSXOpeningElement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXOpeningElement>;
|
||||||
|
assertJSXOpeningFragment(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXOpeningFragment>;
|
||||||
|
assertJSXSpreadAttribute(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXSpreadAttribute>;
|
||||||
|
assertJSXSpreadChild(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.JSXSpreadChild>;
|
||||||
|
assertJSXText(opts?: object): asserts this is NodePath<t.JSXText>;
|
||||||
|
assertLVal(opts?: object): asserts this is NodePath<t.LVal>;
|
||||||
|
assertLabeledStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.LabeledStatement>;
|
||||||
|
assertLiteral(opts?: object): asserts this is NodePath<t.Literal>;
|
||||||
|
assertLogicalExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.LogicalExpression>;
|
||||||
|
assertLoop(opts?: object): asserts this is NodePath<t.Loop>;
|
||||||
|
assertMemberExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.MemberExpression>;
|
||||||
|
assertMetaProperty(opts?: object): asserts this is NodePath<t.MetaProperty>;
|
||||||
|
assertMethod(opts?: object): asserts this is NodePath<t.Method>;
|
||||||
|
assertMixedTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.MixedTypeAnnotation>;
|
||||||
|
assertModuleDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ModuleDeclaration>;
|
||||||
|
assertModuleSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ModuleSpecifier>;
|
||||||
|
assertNewExpression(opts?: object): asserts this is NodePath<t.NewExpression>;
|
||||||
|
assertNoop(opts?: object): asserts this is NodePath<t.Noop>;
|
||||||
|
assertNullLiteral(opts?: object): asserts this is NodePath<t.NullLiteral>;
|
||||||
|
assertNullLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.NullLiteralTypeAnnotation>;
|
||||||
|
assertNullableTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.NullableTypeAnnotation>;
|
||||||
|
assertNumberLiteral(opts?: object): asserts this is NodePath<t.NumberLiteral>;
|
||||||
|
assertNumberLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.NumberLiteralTypeAnnotation>;
|
||||||
|
assertNumberTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.NumberTypeAnnotation>;
|
||||||
|
assertNumericLiteral(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.NumericLiteral>;
|
||||||
|
assertObjectExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectExpression>;
|
||||||
|
assertObjectMember(opts?: object): asserts this is NodePath<t.ObjectMember>;
|
||||||
|
assertObjectMethod(opts?: object): asserts this is NodePath<t.ObjectMethod>;
|
||||||
|
assertObjectPattern(opts?: object): asserts this is NodePath<t.ObjectPattern>;
|
||||||
|
assertObjectProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectProperty>;
|
||||||
|
assertObjectTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeAnnotation>;
|
||||||
|
assertObjectTypeCallProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeCallProperty>;
|
||||||
|
assertObjectTypeIndexer(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeIndexer>;
|
||||||
|
assertObjectTypeInternalSlot(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeInternalSlot>;
|
||||||
|
assertObjectTypeProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeProperty>;
|
||||||
|
assertObjectTypeSpreadProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ObjectTypeSpreadProperty>;
|
||||||
|
assertOpaqueType(opts?: object): asserts this is NodePath<t.OpaqueType>;
|
||||||
|
assertOptionalCallExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.OptionalCallExpression>;
|
||||||
|
assertOptionalMemberExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.OptionalMemberExpression>;
|
||||||
|
assertParenthesizedExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ParenthesizedExpression>;
|
||||||
|
assertPattern(opts?: object): asserts this is NodePath<t.Pattern>;
|
||||||
|
assertPatternLike(opts?: object): asserts this is NodePath<t.PatternLike>;
|
||||||
|
assertPipelineBareFunction(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.PipelineBareFunction>;
|
||||||
|
assertPipelinePrimaryTopicReference(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.PipelinePrimaryTopicReference>;
|
||||||
|
assertPipelineTopicExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.PipelineTopicExpression>;
|
||||||
|
assertPlaceholder(opts?: object): asserts this is NodePath<t.Placeholder>;
|
||||||
|
assertPrivate(opts?: object): asserts this is NodePath<t.Private>;
|
||||||
|
assertPrivateName(opts?: object): asserts this is NodePath<t.PrivateName>;
|
||||||
|
assertProgram(opts?: object): asserts this is NodePath<t.Program>;
|
||||||
|
assertProperty(opts?: object): asserts this is NodePath<t.Property>;
|
||||||
|
assertPureish(opts?: object): asserts this is NodePath<t.Pureish>;
|
||||||
|
assertQualifiedTypeIdentifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.QualifiedTypeIdentifier>;
|
||||||
|
assertRecordExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.RecordExpression>;
|
||||||
|
assertRegExpLiteral(opts?: object): asserts this is NodePath<t.RegExpLiteral>;
|
||||||
|
assertRegexLiteral(opts?: object): asserts this is NodePath<t.RegexLiteral>;
|
||||||
|
assertRestElement(opts?: object): asserts this is NodePath<t.RestElement>;
|
||||||
|
assertRestProperty(opts?: object): asserts this is NodePath<t.RestProperty>;
|
||||||
|
assertReturnStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ReturnStatement>;
|
||||||
|
assertScopable(opts?: object): asserts this is NodePath<t.Scopable>;
|
||||||
|
assertSequenceExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.SequenceExpression>;
|
||||||
|
assertSpreadElement(opts?: object): asserts this is NodePath<t.SpreadElement>;
|
||||||
|
assertSpreadProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.SpreadProperty>;
|
||||||
|
assertStatement(opts?: object): asserts this is NodePath<t.Statement>;
|
||||||
|
assertStaticBlock(opts?: object): asserts this is NodePath<t.StaticBlock>;
|
||||||
|
assertStringLiteral(opts?: object): asserts this is NodePath<t.StringLiteral>;
|
||||||
|
assertStringLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.StringLiteralTypeAnnotation>;
|
||||||
|
assertStringTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.StringTypeAnnotation>;
|
||||||
|
assertSuper(opts?: object): asserts this is NodePath<t.Super>;
|
||||||
|
assertSwitchCase(opts?: object): asserts this is NodePath<t.SwitchCase>;
|
||||||
|
assertSwitchStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.SwitchStatement>;
|
||||||
|
assertSymbolTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.SymbolTypeAnnotation>;
|
||||||
|
assertTSAnyKeyword(opts?: object): asserts this is NodePath<t.TSAnyKeyword>;
|
||||||
|
assertTSArrayType(opts?: object): asserts this is NodePath<t.TSArrayType>;
|
||||||
|
assertTSAsExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSAsExpression>;
|
||||||
|
assertTSBaseType(opts?: object): asserts this is NodePath<t.TSBaseType>;
|
||||||
|
assertTSBigIntKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSBigIntKeyword>;
|
||||||
|
assertTSBooleanKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSBooleanKeyword>;
|
||||||
|
assertTSCallSignatureDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSCallSignatureDeclaration>;
|
||||||
|
assertTSConditionalType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSConditionalType>;
|
||||||
|
assertTSConstructSignatureDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSConstructSignatureDeclaration>;
|
||||||
|
assertTSConstructorType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSConstructorType>;
|
||||||
|
assertTSDeclareFunction(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSDeclareFunction>;
|
||||||
|
assertTSDeclareMethod(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSDeclareMethod>;
|
||||||
|
assertTSEntityName(opts?: object): asserts this is NodePath<t.TSEntityName>;
|
||||||
|
assertTSEnumDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSEnumDeclaration>;
|
||||||
|
assertTSEnumMember(opts?: object): asserts this is NodePath<t.TSEnumMember>;
|
||||||
|
assertTSExportAssignment(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSExportAssignment>;
|
||||||
|
assertTSExpressionWithTypeArguments(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSExpressionWithTypeArguments>;
|
||||||
|
assertTSExternalModuleReference(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSExternalModuleReference>;
|
||||||
|
assertTSFunctionType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSFunctionType>;
|
||||||
|
assertTSImportEqualsDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSImportEqualsDeclaration>;
|
||||||
|
assertTSImportType(opts?: object): asserts this is NodePath<t.TSImportType>;
|
||||||
|
assertTSIndexSignature(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSIndexSignature>;
|
||||||
|
assertTSIndexedAccessType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSIndexedAccessType>;
|
||||||
|
assertTSInferType(opts?: object): asserts this is NodePath<t.TSInferType>;
|
||||||
|
assertTSInterfaceBody(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSInterfaceBody>;
|
||||||
|
assertTSInterfaceDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSInterfaceDeclaration>;
|
||||||
|
assertTSIntersectionType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSIntersectionType>;
|
||||||
|
assertTSIntrinsicKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSIntrinsicKeyword>;
|
||||||
|
assertTSLiteralType(opts?: object): asserts this is NodePath<t.TSLiteralType>;
|
||||||
|
assertTSMappedType(opts?: object): asserts this is NodePath<t.TSMappedType>;
|
||||||
|
assertTSMethodSignature(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSMethodSignature>;
|
||||||
|
assertTSModuleBlock(opts?: object): asserts this is NodePath<t.TSModuleBlock>;
|
||||||
|
assertTSModuleDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSModuleDeclaration>;
|
||||||
|
assertTSNamedTupleMember(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSNamedTupleMember>;
|
||||||
|
assertTSNamespaceExportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSNamespaceExportDeclaration>;
|
||||||
|
assertTSNeverKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSNeverKeyword>;
|
||||||
|
assertTSNonNullExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSNonNullExpression>;
|
||||||
|
assertTSNullKeyword(opts?: object): asserts this is NodePath<t.TSNullKeyword>;
|
||||||
|
assertTSNumberKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSNumberKeyword>;
|
||||||
|
assertTSObjectKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSObjectKeyword>;
|
||||||
|
assertTSOptionalType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSOptionalType>;
|
||||||
|
assertTSParameterProperty(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSParameterProperty>;
|
||||||
|
assertTSParenthesizedType(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSParenthesizedType>;
|
||||||
|
assertTSPropertySignature(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSPropertySignature>;
|
||||||
|
assertTSQualifiedName(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSQualifiedName>;
|
||||||
|
assertTSRestType(opts?: object): asserts this is NodePath<t.TSRestType>;
|
||||||
|
assertTSStringKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSStringKeyword>;
|
||||||
|
assertTSSymbolKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSSymbolKeyword>;
|
||||||
|
assertTSThisType(opts?: object): asserts this is NodePath<t.TSThisType>;
|
||||||
|
assertTSTupleType(opts?: object): asserts this is NodePath<t.TSTupleType>;
|
||||||
|
assertTSType(opts?: object): asserts this is NodePath<t.TSType>;
|
||||||
|
assertTSTypeAliasDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeAliasDeclaration>;
|
||||||
|
assertTSTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeAnnotation>;
|
||||||
|
assertTSTypeAssertion(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeAssertion>;
|
||||||
|
assertTSTypeElement(opts?: object): asserts this is NodePath<t.TSTypeElement>;
|
||||||
|
assertTSTypeLiteral(opts?: object): asserts this is NodePath<t.TSTypeLiteral>;
|
||||||
|
assertTSTypeOperator(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeOperator>;
|
||||||
|
assertTSTypeParameter(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeParameter>;
|
||||||
|
assertTSTypeParameterDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeParameterDeclaration>;
|
||||||
|
assertTSTypeParameterInstantiation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeParameterInstantiation>;
|
||||||
|
assertTSTypePredicate(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypePredicate>;
|
||||||
|
assertTSTypeQuery(opts?: object): asserts this is NodePath<t.TSTypeQuery>;
|
||||||
|
assertTSTypeReference(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSTypeReference>;
|
||||||
|
assertTSUndefinedKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSUndefinedKeyword>;
|
||||||
|
assertTSUnionType(opts?: object): asserts this is NodePath<t.TSUnionType>;
|
||||||
|
assertTSUnknownKeyword(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TSUnknownKeyword>;
|
||||||
|
assertTSVoidKeyword(opts?: object): asserts this is NodePath<t.TSVoidKeyword>;
|
||||||
|
assertTaggedTemplateExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TaggedTemplateExpression>;
|
||||||
|
assertTemplateElement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TemplateElement>;
|
||||||
|
assertTemplateLiteral(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TemplateLiteral>;
|
||||||
|
assertTerminatorless(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.Terminatorless>;
|
||||||
|
assertThisExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ThisExpression>;
|
||||||
|
assertThisTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ThisTypeAnnotation>;
|
||||||
|
assertThrowStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.ThrowStatement>;
|
||||||
|
assertTryStatement(opts?: object): asserts this is NodePath<t.TryStatement>;
|
||||||
|
assertTupleExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TupleExpression>;
|
||||||
|
assertTupleTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TupleTypeAnnotation>;
|
||||||
|
assertTypeAlias(opts?: object): asserts this is NodePath<t.TypeAlias>;
|
||||||
|
assertTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TypeAnnotation>;
|
||||||
|
assertTypeCastExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TypeCastExpression>;
|
||||||
|
assertTypeParameter(opts?: object): asserts this is NodePath<t.TypeParameter>;
|
||||||
|
assertTypeParameterDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TypeParameterDeclaration>;
|
||||||
|
assertTypeParameterInstantiation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TypeParameterInstantiation>;
|
||||||
|
assertTypeofTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.TypeofTypeAnnotation>;
|
||||||
|
assertUnaryExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.UnaryExpression>;
|
||||||
|
assertUnaryLike(opts?: object): asserts this is NodePath<t.UnaryLike>;
|
||||||
|
assertUnionTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.UnionTypeAnnotation>;
|
||||||
|
assertUpdateExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.UpdateExpression>;
|
||||||
|
assertUserWhitespacable(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.UserWhitespacable>;
|
||||||
|
assertV8IntrinsicIdentifier(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.V8IntrinsicIdentifier>;
|
||||||
|
assertVariableDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.VariableDeclaration>;
|
||||||
|
assertVariableDeclarator(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.VariableDeclarator>;
|
||||||
|
assertVariance(opts?: object): asserts this is NodePath<t.Variance>;
|
||||||
|
assertVoidTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.VoidTypeAnnotation>;
|
||||||
|
assertWhile(opts?: object): asserts this is NodePath<t.While>;
|
||||||
|
assertWhileStatement(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.WhileStatement>;
|
||||||
|
assertWithStatement(opts?: object): asserts this is NodePath<t.WithStatement>;
|
||||||
|
assertYieldExpression(
|
||||||
|
opts?: object,
|
||||||
|
): asserts this is NodePath<t.YieldExpression>;
|
||||||
|
}
|
||||||
432
packages/babel-traverse/src/path/generated/validators.ts
Executable file
432
packages/babel-traverse/src/path/generated/validators.ts
Executable file
@ -0,0 +1,432 @@
|
|||||||
|
/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
import NodePath from "../index";
|
||||||
|
|
||||||
|
export interface NodePathValidators {
|
||||||
|
isAnyTypeAnnotation(opts?: object): this is NodePath<t.AnyTypeAnnotation>;
|
||||||
|
isArgumentPlaceholder(opts?: object): this is NodePath<t.ArgumentPlaceholder>;
|
||||||
|
isArrayExpression(opts?: object): this is NodePath<t.ArrayExpression>;
|
||||||
|
isArrayPattern(opts?: object): this is NodePath<t.ArrayPattern>;
|
||||||
|
isArrayTypeAnnotation(opts?: object): this is NodePath<t.ArrayTypeAnnotation>;
|
||||||
|
isArrowFunctionExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ArrowFunctionExpression>;
|
||||||
|
isAssignmentExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.AssignmentExpression>;
|
||||||
|
isAssignmentPattern(opts?: object): this is NodePath<t.AssignmentPattern>;
|
||||||
|
isAwaitExpression(opts?: object): this is NodePath<t.AwaitExpression>;
|
||||||
|
isBigIntLiteral(opts?: object): this is NodePath<t.BigIntLiteral>;
|
||||||
|
isBinary(opts?: object): this is NodePath<t.Binary>;
|
||||||
|
isBinaryExpression(opts?: object): this is NodePath<t.BinaryExpression>;
|
||||||
|
isBindExpression(opts?: object): this is NodePath<t.BindExpression>;
|
||||||
|
isBlock(opts?: object): this is NodePath<t.Block>;
|
||||||
|
isBlockParent(opts?: object): this is NodePath<t.BlockParent>;
|
||||||
|
isBlockStatement(opts?: object): this is NodePath<t.BlockStatement>;
|
||||||
|
isBooleanLiteral(opts?: object): this is NodePath<t.BooleanLiteral>;
|
||||||
|
isBooleanLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.BooleanLiteralTypeAnnotation>;
|
||||||
|
isBooleanTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.BooleanTypeAnnotation>;
|
||||||
|
isBreakStatement(opts?: object): this is NodePath<t.BreakStatement>;
|
||||||
|
isCallExpression(opts?: object): this is NodePath<t.CallExpression>;
|
||||||
|
isCatchClause(opts?: object): this is NodePath<t.CatchClause>;
|
||||||
|
isClass(opts?: object): this is NodePath<t.Class>;
|
||||||
|
isClassBody(opts?: object): this is NodePath<t.ClassBody>;
|
||||||
|
isClassDeclaration(opts?: object): this is NodePath<t.ClassDeclaration>;
|
||||||
|
isClassExpression(opts?: object): this is NodePath<t.ClassExpression>;
|
||||||
|
isClassImplements(opts?: object): this is NodePath<t.ClassImplements>;
|
||||||
|
isClassMethod(opts?: object): this is NodePath<t.ClassMethod>;
|
||||||
|
isClassPrivateMethod(opts?: object): this is NodePath<t.ClassPrivateMethod>;
|
||||||
|
isClassPrivateProperty(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ClassPrivateProperty>;
|
||||||
|
isClassProperty(opts?: object): this is NodePath<t.ClassProperty>;
|
||||||
|
isCompletionStatement(opts?: object): this is NodePath<t.CompletionStatement>;
|
||||||
|
isConditional(opts?: object): this is NodePath<t.Conditional>;
|
||||||
|
isConditionalExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ConditionalExpression>;
|
||||||
|
isContinueStatement(opts?: object): this is NodePath<t.ContinueStatement>;
|
||||||
|
isDebuggerStatement(opts?: object): this is NodePath<t.DebuggerStatement>;
|
||||||
|
isDecimalLiteral(opts?: object): this is NodePath<t.DecimalLiteral>;
|
||||||
|
isDeclaration(opts?: object): this is NodePath<t.Declaration>;
|
||||||
|
isDeclareClass(opts?: object): this is NodePath<t.DeclareClass>;
|
||||||
|
isDeclareExportAllDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.DeclareExportAllDeclaration>;
|
||||||
|
isDeclareExportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.DeclareExportDeclaration>;
|
||||||
|
isDeclareFunction(opts?: object): this is NodePath<t.DeclareFunction>;
|
||||||
|
isDeclareInterface(opts?: object): this is NodePath<t.DeclareInterface>;
|
||||||
|
isDeclareModule(opts?: object): this is NodePath<t.DeclareModule>;
|
||||||
|
isDeclareModuleExports(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.DeclareModuleExports>;
|
||||||
|
isDeclareOpaqueType(opts?: object): this is NodePath<t.DeclareOpaqueType>;
|
||||||
|
isDeclareTypeAlias(opts?: object): this is NodePath<t.DeclareTypeAlias>;
|
||||||
|
isDeclareVariable(opts?: object): this is NodePath<t.DeclareVariable>;
|
||||||
|
isDeclaredPredicate(opts?: object): this is NodePath<t.DeclaredPredicate>;
|
||||||
|
isDecorator(opts?: object): this is NodePath<t.Decorator>;
|
||||||
|
isDirective(opts?: object): this is NodePath<t.Directive>;
|
||||||
|
isDirectiveLiteral(opts?: object): this is NodePath<t.DirectiveLiteral>;
|
||||||
|
isDoExpression(opts?: object): this is NodePath<t.DoExpression>;
|
||||||
|
isDoWhileStatement(opts?: object): this is NodePath<t.DoWhileStatement>;
|
||||||
|
isEmptyStatement(opts?: object): this is NodePath<t.EmptyStatement>;
|
||||||
|
isEmptyTypeAnnotation(opts?: object): this is NodePath<t.EmptyTypeAnnotation>;
|
||||||
|
isEnumBody(opts?: object): this is NodePath<t.EnumBody>;
|
||||||
|
isEnumBooleanBody(opts?: object): this is NodePath<t.EnumBooleanBody>;
|
||||||
|
isEnumBooleanMember(opts?: object): this is NodePath<t.EnumBooleanMember>;
|
||||||
|
isEnumDeclaration(opts?: object): this is NodePath<t.EnumDeclaration>;
|
||||||
|
isEnumDefaultedMember(opts?: object): this is NodePath<t.EnumDefaultedMember>;
|
||||||
|
isEnumMember(opts?: object): this is NodePath<t.EnumMember>;
|
||||||
|
isEnumNumberBody(opts?: object): this is NodePath<t.EnumNumberBody>;
|
||||||
|
isEnumNumberMember(opts?: object): this is NodePath<t.EnumNumberMember>;
|
||||||
|
isEnumStringBody(opts?: object): this is NodePath<t.EnumStringBody>;
|
||||||
|
isEnumStringMember(opts?: object): this is NodePath<t.EnumStringMember>;
|
||||||
|
isEnumSymbolBody(opts?: object): this is NodePath<t.EnumSymbolBody>;
|
||||||
|
isExistsTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExistsTypeAnnotation>;
|
||||||
|
isExportAllDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExportAllDeclaration>;
|
||||||
|
isExportDeclaration(opts?: object): this is NodePath<t.ExportDeclaration>;
|
||||||
|
isExportDefaultDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExportDefaultDeclaration>;
|
||||||
|
isExportDefaultSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExportDefaultSpecifier>;
|
||||||
|
isExportNamedDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExportNamedDeclaration>;
|
||||||
|
isExportNamespaceSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ExportNamespaceSpecifier>;
|
||||||
|
isExportSpecifier(opts?: object): this is NodePath<t.ExportSpecifier>;
|
||||||
|
isExpression(opts?: object): this is NodePath<t.Expression>;
|
||||||
|
isExpressionStatement(opts?: object): this is NodePath<t.ExpressionStatement>;
|
||||||
|
isExpressionWrapper(opts?: object): this is NodePath<t.ExpressionWrapper>;
|
||||||
|
isFile(opts?: object): this is NodePath<t.File>;
|
||||||
|
isFlow(opts?: object): this is NodePath<t.Flow>;
|
||||||
|
isFlowBaseAnnotation(opts?: object): this is NodePath<t.FlowBaseAnnotation>;
|
||||||
|
isFlowDeclaration(opts?: object): this is NodePath<t.FlowDeclaration>;
|
||||||
|
isFlowPredicate(opts?: object): this is NodePath<t.FlowPredicate>;
|
||||||
|
isFlowType(opts?: object): this is NodePath<t.FlowType>;
|
||||||
|
isFor(opts?: object): this is NodePath<t.For>;
|
||||||
|
isForInStatement(opts?: object): this is NodePath<t.ForInStatement>;
|
||||||
|
isForOfStatement(opts?: object): this is NodePath<t.ForOfStatement>;
|
||||||
|
isForStatement(opts?: object): this is NodePath<t.ForStatement>;
|
||||||
|
isForXStatement(opts?: object): this is NodePath<t.ForXStatement>;
|
||||||
|
isFunction(opts?: object): this is NodePath<t.Function>;
|
||||||
|
isFunctionDeclaration(opts?: object): this is NodePath<t.FunctionDeclaration>;
|
||||||
|
isFunctionExpression(opts?: object): this is NodePath<t.FunctionExpression>;
|
||||||
|
isFunctionParent(opts?: object): this is NodePath<t.FunctionParent>;
|
||||||
|
isFunctionTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.FunctionTypeAnnotation>;
|
||||||
|
isFunctionTypeParam(opts?: object): this is NodePath<t.FunctionTypeParam>;
|
||||||
|
isGenericTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.GenericTypeAnnotation>;
|
||||||
|
isIdentifier(opts?: object): this is NodePath<t.Identifier>;
|
||||||
|
isIfStatement(opts?: object): this is NodePath<t.IfStatement>;
|
||||||
|
isImmutable(opts?: object): this is NodePath<t.Immutable>;
|
||||||
|
isImport(opts?: object): this is NodePath<t.Import>;
|
||||||
|
isImportAttribute(opts?: object): this is NodePath<t.ImportAttribute>;
|
||||||
|
isImportDeclaration(opts?: object): this is NodePath<t.ImportDeclaration>;
|
||||||
|
isImportDefaultSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ImportDefaultSpecifier>;
|
||||||
|
isImportNamespaceSpecifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ImportNamespaceSpecifier>;
|
||||||
|
isImportSpecifier(opts?: object): this is NodePath<t.ImportSpecifier>;
|
||||||
|
isInferredPredicate(opts?: object): this is NodePath<t.InferredPredicate>;
|
||||||
|
isInterfaceDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.InterfaceDeclaration>;
|
||||||
|
isInterfaceExtends(opts?: object): this is NodePath<t.InterfaceExtends>;
|
||||||
|
isInterfaceTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.InterfaceTypeAnnotation>;
|
||||||
|
isInterpreterDirective(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.InterpreterDirective>;
|
||||||
|
isIntersectionTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.IntersectionTypeAnnotation>;
|
||||||
|
isJSX(opts?: object): this is NodePath<t.JSX>;
|
||||||
|
isJSXAttribute(opts?: object): this is NodePath<t.JSXAttribute>;
|
||||||
|
isJSXClosingElement(opts?: object): this is NodePath<t.JSXClosingElement>;
|
||||||
|
isJSXClosingFragment(opts?: object): this is NodePath<t.JSXClosingFragment>;
|
||||||
|
isJSXElement(opts?: object): this is NodePath<t.JSXElement>;
|
||||||
|
isJSXEmptyExpression(opts?: object): this is NodePath<t.JSXEmptyExpression>;
|
||||||
|
isJSXExpressionContainer(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.JSXExpressionContainer>;
|
||||||
|
isJSXFragment(opts?: object): this is NodePath<t.JSXFragment>;
|
||||||
|
isJSXIdentifier(opts?: object): this is NodePath<t.JSXIdentifier>;
|
||||||
|
isJSXMemberExpression(opts?: object): this is NodePath<t.JSXMemberExpression>;
|
||||||
|
isJSXNamespacedName(opts?: object): this is NodePath<t.JSXNamespacedName>;
|
||||||
|
isJSXOpeningElement(opts?: object): this is NodePath<t.JSXOpeningElement>;
|
||||||
|
isJSXOpeningFragment(opts?: object): this is NodePath<t.JSXOpeningFragment>;
|
||||||
|
isJSXSpreadAttribute(opts?: object): this is NodePath<t.JSXSpreadAttribute>;
|
||||||
|
isJSXSpreadChild(opts?: object): this is NodePath<t.JSXSpreadChild>;
|
||||||
|
isJSXText(opts?: object): this is NodePath<t.JSXText>;
|
||||||
|
isLVal(opts?: object): this is NodePath<t.LVal>;
|
||||||
|
isLabeledStatement(opts?: object): this is NodePath<t.LabeledStatement>;
|
||||||
|
isLiteral(opts?: object): this is NodePath<t.Literal>;
|
||||||
|
isLogicalExpression(opts?: object): this is NodePath<t.LogicalExpression>;
|
||||||
|
isLoop(opts?: object): this is NodePath<t.Loop>;
|
||||||
|
isMemberExpression(opts?: object): this is NodePath<t.MemberExpression>;
|
||||||
|
isMetaProperty(opts?: object): this is NodePath<t.MetaProperty>;
|
||||||
|
isMethod(opts?: object): this is NodePath<t.Method>;
|
||||||
|
isMixedTypeAnnotation(opts?: object): this is NodePath<t.MixedTypeAnnotation>;
|
||||||
|
isModuleDeclaration(opts?: object): this is NodePath<t.ModuleDeclaration>;
|
||||||
|
isModuleSpecifier(opts?: object): this is NodePath<t.ModuleSpecifier>;
|
||||||
|
isNewExpression(opts?: object): this is NodePath<t.NewExpression>;
|
||||||
|
isNoop(opts?: object): this is NodePath<t.Noop>;
|
||||||
|
isNullLiteral(opts?: object): this is NodePath<t.NullLiteral>;
|
||||||
|
isNullLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.NullLiteralTypeAnnotation>;
|
||||||
|
isNullableTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.NullableTypeAnnotation>;
|
||||||
|
isNumberLiteral(opts?: object): this is NodePath<t.NumberLiteral>;
|
||||||
|
isNumberLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.NumberLiteralTypeAnnotation>;
|
||||||
|
isNumberTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.NumberTypeAnnotation>;
|
||||||
|
isNumericLiteral(opts?: object): this is NodePath<t.NumericLiteral>;
|
||||||
|
isObjectExpression(opts?: object): this is NodePath<t.ObjectExpression>;
|
||||||
|
isObjectMember(opts?: object): this is NodePath<t.ObjectMember>;
|
||||||
|
isObjectMethod(opts?: object): this is NodePath<t.ObjectMethod>;
|
||||||
|
isObjectPattern(opts?: object): this is NodePath<t.ObjectPattern>;
|
||||||
|
isObjectProperty(opts?: object): this is NodePath<t.ObjectProperty>;
|
||||||
|
isObjectTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ObjectTypeAnnotation>;
|
||||||
|
isObjectTypeCallProperty(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ObjectTypeCallProperty>;
|
||||||
|
isObjectTypeIndexer(opts?: object): this is NodePath<t.ObjectTypeIndexer>;
|
||||||
|
isObjectTypeInternalSlot(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ObjectTypeInternalSlot>;
|
||||||
|
isObjectTypeProperty(opts?: object): this is NodePath<t.ObjectTypeProperty>;
|
||||||
|
isObjectTypeSpreadProperty(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ObjectTypeSpreadProperty>;
|
||||||
|
isOpaqueType(opts?: object): this is NodePath<t.OpaqueType>;
|
||||||
|
isOptionalCallExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.OptionalCallExpression>;
|
||||||
|
isOptionalMemberExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.OptionalMemberExpression>;
|
||||||
|
isParenthesizedExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.ParenthesizedExpression>;
|
||||||
|
isPattern(opts?: object): this is NodePath<t.Pattern>;
|
||||||
|
isPatternLike(opts?: object): this is NodePath<t.PatternLike>;
|
||||||
|
isPipelineBareFunction(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.PipelineBareFunction>;
|
||||||
|
isPipelinePrimaryTopicReference(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.PipelinePrimaryTopicReference>;
|
||||||
|
isPipelineTopicExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.PipelineTopicExpression>;
|
||||||
|
isPlaceholder(opts?: object): this is NodePath<t.Placeholder>;
|
||||||
|
isPrivate(opts?: object): this is NodePath<t.Private>;
|
||||||
|
isPrivateName(opts?: object): this is NodePath<t.PrivateName>;
|
||||||
|
isProgram(opts?: object): this is NodePath<t.Program>;
|
||||||
|
isProperty(opts?: object): this is NodePath<t.Property>;
|
||||||
|
isPureish(opts?: object): this is NodePath<t.Pureish>;
|
||||||
|
isQualifiedTypeIdentifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.QualifiedTypeIdentifier>;
|
||||||
|
isRecordExpression(opts?: object): this is NodePath<t.RecordExpression>;
|
||||||
|
isRegExpLiteral(opts?: object): this is NodePath<t.RegExpLiteral>;
|
||||||
|
isRegexLiteral(opts?: object): this is NodePath<t.RegexLiteral>;
|
||||||
|
isRestElement(opts?: object): this is NodePath<t.RestElement>;
|
||||||
|
isRestProperty(opts?: object): this is NodePath<t.RestProperty>;
|
||||||
|
isReturnStatement(opts?: object): this is NodePath<t.ReturnStatement>;
|
||||||
|
isScopable(opts?: object): this is NodePath<t.Scopable>;
|
||||||
|
isSequenceExpression(opts?: object): this is NodePath<t.SequenceExpression>;
|
||||||
|
isSpreadElement(opts?: object): this is NodePath<t.SpreadElement>;
|
||||||
|
isSpreadProperty(opts?: object): this is NodePath<t.SpreadProperty>;
|
||||||
|
isStatement(opts?: object): this is NodePath<t.Statement>;
|
||||||
|
isStaticBlock(opts?: object): this is NodePath<t.StaticBlock>;
|
||||||
|
isStringLiteral(opts?: object): this is NodePath<t.StringLiteral>;
|
||||||
|
isStringLiteralTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.StringLiteralTypeAnnotation>;
|
||||||
|
isStringTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.StringTypeAnnotation>;
|
||||||
|
isSuper(opts?: object): this is NodePath<t.Super>;
|
||||||
|
isSwitchCase(opts?: object): this is NodePath<t.SwitchCase>;
|
||||||
|
isSwitchStatement(opts?: object): this is NodePath<t.SwitchStatement>;
|
||||||
|
isSymbolTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.SymbolTypeAnnotation>;
|
||||||
|
isTSAnyKeyword(opts?: object): this is NodePath<t.TSAnyKeyword>;
|
||||||
|
isTSArrayType(opts?: object): this is NodePath<t.TSArrayType>;
|
||||||
|
isTSAsExpression(opts?: object): this is NodePath<t.TSAsExpression>;
|
||||||
|
isTSBaseType(opts?: object): this is NodePath<t.TSBaseType>;
|
||||||
|
isTSBigIntKeyword(opts?: object): this is NodePath<t.TSBigIntKeyword>;
|
||||||
|
isTSBooleanKeyword(opts?: object): this is NodePath<t.TSBooleanKeyword>;
|
||||||
|
isTSCallSignatureDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSCallSignatureDeclaration>;
|
||||||
|
isTSConditionalType(opts?: object): this is NodePath<t.TSConditionalType>;
|
||||||
|
isTSConstructSignatureDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSConstructSignatureDeclaration>;
|
||||||
|
isTSConstructorType(opts?: object): this is NodePath<t.TSConstructorType>;
|
||||||
|
isTSDeclareFunction(opts?: object): this is NodePath<t.TSDeclareFunction>;
|
||||||
|
isTSDeclareMethod(opts?: object): this is NodePath<t.TSDeclareMethod>;
|
||||||
|
isTSEntityName(opts?: object): this is NodePath<t.TSEntityName>;
|
||||||
|
isTSEnumDeclaration(opts?: object): this is NodePath<t.TSEnumDeclaration>;
|
||||||
|
isTSEnumMember(opts?: object): this is NodePath<t.TSEnumMember>;
|
||||||
|
isTSExportAssignment(opts?: object): this is NodePath<t.TSExportAssignment>;
|
||||||
|
isTSExpressionWithTypeArguments(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSExpressionWithTypeArguments>;
|
||||||
|
isTSExternalModuleReference(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSExternalModuleReference>;
|
||||||
|
isTSFunctionType(opts?: object): this is NodePath<t.TSFunctionType>;
|
||||||
|
isTSImportEqualsDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSImportEqualsDeclaration>;
|
||||||
|
isTSImportType(opts?: object): this is NodePath<t.TSImportType>;
|
||||||
|
isTSIndexSignature(opts?: object): this is NodePath<t.TSIndexSignature>;
|
||||||
|
isTSIndexedAccessType(opts?: object): this is NodePath<t.TSIndexedAccessType>;
|
||||||
|
isTSInferType(opts?: object): this is NodePath<t.TSInferType>;
|
||||||
|
isTSInterfaceBody(opts?: object): this is NodePath<t.TSInterfaceBody>;
|
||||||
|
isTSInterfaceDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSInterfaceDeclaration>;
|
||||||
|
isTSIntersectionType(opts?: object): this is NodePath<t.TSIntersectionType>;
|
||||||
|
isTSIntrinsicKeyword(opts?: object): this is NodePath<t.TSIntrinsicKeyword>;
|
||||||
|
isTSLiteralType(opts?: object): this is NodePath<t.TSLiteralType>;
|
||||||
|
isTSMappedType(opts?: object): this is NodePath<t.TSMappedType>;
|
||||||
|
isTSMethodSignature(opts?: object): this is NodePath<t.TSMethodSignature>;
|
||||||
|
isTSModuleBlock(opts?: object): this is NodePath<t.TSModuleBlock>;
|
||||||
|
isTSModuleDeclaration(opts?: object): this is NodePath<t.TSModuleDeclaration>;
|
||||||
|
isTSNamedTupleMember(opts?: object): this is NodePath<t.TSNamedTupleMember>;
|
||||||
|
isTSNamespaceExportDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSNamespaceExportDeclaration>;
|
||||||
|
isTSNeverKeyword(opts?: object): this is NodePath<t.TSNeverKeyword>;
|
||||||
|
isTSNonNullExpression(opts?: object): this is NodePath<t.TSNonNullExpression>;
|
||||||
|
isTSNullKeyword(opts?: object): this is NodePath<t.TSNullKeyword>;
|
||||||
|
isTSNumberKeyword(opts?: object): this is NodePath<t.TSNumberKeyword>;
|
||||||
|
isTSObjectKeyword(opts?: object): this is NodePath<t.TSObjectKeyword>;
|
||||||
|
isTSOptionalType(opts?: object): this is NodePath<t.TSOptionalType>;
|
||||||
|
isTSParameterProperty(opts?: object): this is NodePath<t.TSParameterProperty>;
|
||||||
|
isTSParenthesizedType(opts?: object): this is NodePath<t.TSParenthesizedType>;
|
||||||
|
isTSPropertySignature(opts?: object): this is NodePath<t.TSPropertySignature>;
|
||||||
|
isTSQualifiedName(opts?: object): this is NodePath<t.TSQualifiedName>;
|
||||||
|
isTSRestType(opts?: object): this is NodePath<t.TSRestType>;
|
||||||
|
isTSStringKeyword(opts?: object): this is NodePath<t.TSStringKeyword>;
|
||||||
|
isTSSymbolKeyword(opts?: object): this is NodePath<t.TSSymbolKeyword>;
|
||||||
|
isTSThisType(opts?: object): this is NodePath<t.TSThisType>;
|
||||||
|
isTSTupleType(opts?: object): this is NodePath<t.TSTupleType>;
|
||||||
|
isTSType(opts?: object): this is NodePath<t.TSType>;
|
||||||
|
isTSTypeAliasDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSTypeAliasDeclaration>;
|
||||||
|
isTSTypeAnnotation(opts?: object): this is NodePath<t.TSTypeAnnotation>;
|
||||||
|
isTSTypeAssertion(opts?: object): this is NodePath<t.TSTypeAssertion>;
|
||||||
|
isTSTypeElement(opts?: object): this is NodePath<t.TSTypeElement>;
|
||||||
|
isTSTypeLiteral(opts?: object): this is NodePath<t.TSTypeLiteral>;
|
||||||
|
isTSTypeOperator(opts?: object): this is NodePath<t.TSTypeOperator>;
|
||||||
|
isTSTypeParameter(opts?: object): this is NodePath<t.TSTypeParameter>;
|
||||||
|
isTSTypeParameterDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSTypeParameterDeclaration>;
|
||||||
|
isTSTypeParameterInstantiation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TSTypeParameterInstantiation>;
|
||||||
|
isTSTypePredicate(opts?: object): this is NodePath<t.TSTypePredicate>;
|
||||||
|
isTSTypeQuery(opts?: object): this is NodePath<t.TSTypeQuery>;
|
||||||
|
isTSTypeReference(opts?: object): this is NodePath<t.TSTypeReference>;
|
||||||
|
isTSUndefinedKeyword(opts?: object): this is NodePath<t.TSUndefinedKeyword>;
|
||||||
|
isTSUnionType(opts?: object): this is NodePath<t.TSUnionType>;
|
||||||
|
isTSUnknownKeyword(opts?: object): this is NodePath<t.TSUnknownKeyword>;
|
||||||
|
isTSVoidKeyword(opts?: object): this is NodePath<t.TSVoidKeyword>;
|
||||||
|
isTaggedTemplateExpression(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TaggedTemplateExpression>;
|
||||||
|
isTemplateElement(opts?: object): this is NodePath<t.TemplateElement>;
|
||||||
|
isTemplateLiteral(opts?: object): this is NodePath<t.TemplateLiteral>;
|
||||||
|
isTerminatorless(opts?: object): this is NodePath<t.Terminatorless>;
|
||||||
|
isThisExpression(opts?: object): this is NodePath<t.ThisExpression>;
|
||||||
|
isThisTypeAnnotation(opts?: object): this is NodePath<t.ThisTypeAnnotation>;
|
||||||
|
isThrowStatement(opts?: object): this is NodePath<t.ThrowStatement>;
|
||||||
|
isTryStatement(opts?: object): this is NodePath<t.TryStatement>;
|
||||||
|
isTupleExpression(opts?: object): this is NodePath<t.TupleExpression>;
|
||||||
|
isTupleTypeAnnotation(opts?: object): this is NodePath<t.TupleTypeAnnotation>;
|
||||||
|
isTypeAlias(opts?: object): this is NodePath<t.TypeAlias>;
|
||||||
|
isTypeAnnotation(opts?: object): this is NodePath<t.TypeAnnotation>;
|
||||||
|
isTypeCastExpression(opts?: object): this is NodePath<t.TypeCastExpression>;
|
||||||
|
isTypeParameter(opts?: object): this is NodePath<t.TypeParameter>;
|
||||||
|
isTypeParameterDeclaration(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TypeParameterDeclaration>;
|
||||||
|
isTypeParameterInstantiation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TypeParameterInstantiation>;
|
||||||
|
isTypeofTypeAnnotation(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.TypeofTypeAnnotation>;
|
||||||
|
isUnaryExpression(opts?: object): this is NodePath<t.UnaryExpression>;
|
||||||
|
isUnaryLike(opts?: object): this is NodePath<t.UnaryLike>;
|
||||||
|
isUnionTypeAnnotation(opts?: object): this is NodePath<t.UnionTypeAnnotation>;
|
||||||
|
isUpdateExpression(opts?: object): this is NodePath<t.UpdateExpression>;
|
||||||
|
isUserWhitespacable(opts?: object): this is NodePath<t.UserWhitespacable>;
|
||||||
|
isV8IntrinsicIdentifier(
|
||||||
|
opts?: object,
|
||||||
|
): this is NodePath<t.V8IntrinsicIdentifier>;
|
||||||
|
isVariableDeclaration(opts?: object): this is NodePath<t.VariableDeclaration>;
|
||||||
|
isVariableDeclarator(opts?: object): this is NodePath<t.VariableDeclarator>;
|
||||||
|
isVariance(opts?: object): this is NodePath<t.Variance>;
|
||||||
|
isVoidTypeAnnotation(opts?: object): this is NodePath<t.VoidTypeAnnotation>;
|
||||||
|
isWhile(opts?: object): this is NodePath<t.While>;
|
||||||
|
isWhileStatement(opts?: object): this is NodePath<t.WhileStatement>;
|
||||||
|
isWithStatement(opts?: object): this is NodePath<t.WithStatement>;
|
||||||
|
isYieldExpression(opts?: object): this is NodePath<t.YieldExpression>;
|
||||||
|
isReferencedIdentifier(opts?: object): boolean;
|
||||||
|
isReferencedMemberExpression(opts?: object): boolean;
|
||||||
|
isBindingIdentifier(opts?: object): boolean;
|
||||||
|
isStatement(opts?: object): this is NodePath<t.Statement>;
|
||||||
|
isExpression(opts?: object): this is NodePath<t.Expression>;
|
||||||
|
isScope(opts?: object): boolean;
|
||||||
|
isReferenced(opts?: object): boolean;
|
||||||
|
isBlockScoped(opts?: object): boolean;
|
||||||
|
isVar(opts?: object): boolean;
|
||||||
|
isUser(opts?: object): boolean;
|
||||||
|
isGenerated(opts?: object): boolean;
|
||||||
|
isPure(opts?: object): boolean;
|
||||||
|
isFlow(opts?: object): this is NodePath<t.Flow>;
|
||||||
|
isRestProperty(opts?: object): boolean;
|
||||||
|
isSpreadProperty(opts?: object): boolean;
|
||||||
|
isExistentialTypeParam(opts?: object): boolean;
|
||||||
|
isNumericLiteralTypeAnnotation(opts?: object): boolean;
|
||||||
|
isForAwaitStatement(opts?: object): boolean;
|
||||||
|
}
|
||||||
26
packages/babel-traverse/src/path/generated/virtual-types.ts
Executable file
26
packages/babel-traverse/src/path/generated/virtual-types.ts
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This file is auto-generated! Do not modify it directly.
|
||||||
|
* To re-generate run 'make build'
|
||||||
|
*/
|
||||||
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
|
export interface VirtualTypeAliases {
|
||||||
|
ReferencedIdentifier: t.Identifier | t.JSXIdentifier;
|
||||||
|
ReferencedMemberExpression: t.MemberExpression;
|
||||||
|
BindingIdentifier: t.Identifier;
|
||||||
|
Statement: t.Statement;
|
||||||
|
Expression: t.Expression;
|
||||||
|
Scope: t.Scopable | t.Pattern;
|
||||||
|
Referenced: t.Node;
|
||||||
|
BlockScoped: t.Node;
|
||||||
|
Var: t.VariableDeclaration;
|
||||||
|
User: t.Node;
|
||||||
|
Generated: t.Node;
|
||||||
|
Pure: t.Node;
|
||||||
|
Flow: t.Flow | t.ImportDeclaration | t.ExportDeclaration | t.ImportSpecifier;
|
||||||
|
RestProperty: t.RestElement;
|
||||||
|
SpreadProperty: t.RestElement;
|
||||||
|
ExistentialTypeParam: t.ExistsTypeAnnotation;
|
||||||
|
NumericLiteralTypeAnnotation: t.NumberLiteralTypeAnnotation;
|
||||||
|
ForAwaitStatement: t.ForOfStatement;
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ import type TraversalContext from "../context";
|
|||||||
import * as virtualTypes from "./lib/virtual-types";
|
import * as virtualTypes from "./lib/virtual-types";
|
||||||
import buildDebug from "debug";
|
import buildDebug from "debug";
|
||||||
import traverse from "../index";
|
import traverse from "../index";
|
||||||
|
import type { Visitor } from "../types";
|
||||||
import Scope from "../scope";
|
import Scope from "../scope";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import { path as pathCache } from "../cache";
|
import { path as pathCache } from "../cache";
|
||||||
@ -20,6 +21,8 @@ import * as NodePath_removal from "./removal";
|
|||||||
import * as NodePath_modification from "./modification";
|
import * as NodePath_modification from "./modification";
|
||||||
import * as NodePath_family from "./family";
|
import * as NodePath_family from "./family";
|
||||||
import * as NodePath_comments from "./comments";
|
import * as NodePath_comments from "./comments";
|
||||||
|
import type { NodePathAssetions } from "./generated/asserts";
|
||||||
|
import type { NodePathValidators } from "./generated/validators";
|
||||||
|
|
||||||
const debug = buildDebug("babel");
|
const debug = buildDebug("babel");
|
||||||
|
|
||||||
@ -27,8 +30,8 @@ export const REMOVED = 1 << 0;
|
|||||||
export const SHOULD_STOP = 1 << 1;
|
export const SHOULD_STOP = 1 << 1;
|
||||||
export const SHOULD_SKIP = 1 << 2;
|
export const SHOULD_SKIP = 1 << 2;
|
||||||
|
|
||||||
export default class NodePath {
|
class NodePath<T extends t.Node = t.Node> {
|
||||||
constructor(hub: HubInterface, parent: Object) {
|
constructor(hub: HubInterface, parent: t.Node) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.hub = hub;
|
this.hub = hub;
|
||||||
this.data = null;
|
this.data = null;
|
||||||
@ -37,26 +40,40 @@ export default class NodePath {
|
|||||||
this.scope = null;
|
this.scope = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare parent: Object;
|
declare parent: t.Node;
|
||||||
declare hub: HubInterface;
|
declare hub: HubInterface;
|
||||||
declare data: Object;
|
declare data: object;
|
||||||
declare context: TraversalContext;
|
declare context: TraversalContext;
|
||||||
declare scope: Scope;
|
declare scope: Scope;
|
||||||
|
|
||||||
contexts: Array<TraversalContext> = [];
|
contexts: Array<TraversalContext> = [];
|
||||||
state: any = null;
|
state: any = null;
|
||||||
opts: ?Object = null;
|
opts: any = null;
|
||||||
// this.shouldSkip = false; this.shouldStop = false; this.removed = false;
|
// this.shouldSkip = false; this.shouldStop = false; this.removed = false;
|
||||||
_traverseFlags: number = 0;
|
_traverseFlags: number = 0;
|
||||||
skipKeys: ?Object = null;
|
skipKeys: any = null;
|
||||||
parentPath: ?NodePath = null;
|
parentPath: NodePath | null = null;
|
||||||
container: ?Object | Array<Object> = null;
|
container: object | null | Array<any> = null;
|
||||||
listKey: ?string = null;
|
listKey: string | null = null;
|
||||||
key: ?string = null;
|
key: string | number | null = null;
|
||||||
node: ?Object = null;
|
node: T = null;
|
||||||
type: ?string = null;
|
type: string | null = null;
|
||||||
|
|
||||||
static get({ hub, parentPath, parent, container, listKey, key }): NodePath {
|
static get({
|
||||||
|
hub,
|
||||||
|
parentPath,
|
||||||
|
parent,
|
||||||
|
container,
|
||||||
|
listKey,
|
||||||
|
key,
|
||||||
|
}: {
|
||||||
|
hub?;
|
||||||
|
parentPath;
|
||||||
|
parent;
|
||||||
|
container;
|
||||||
|
listKey?;
|
||||||
|
key;
|
||||||
|
}): NodePath {
|
||||||
if (!hub && parentPath) {
|
if (!hub && parentPath) {
|
||||||
hub = parentPath.hub;
|
hub = parentPath.hub;
|
||||||
}
|
}
|
||||||
@ -104,22 +121,27 @@ export default class NodePath {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCodeFrameError(msg: string, Error: typeof Error = SyntaxError): Error {
|
buildCodeFrameError(
|
||||||
|
msg: string,
|
||||||
|
Error: new () => Error = SyntaxError,
|
||||||
|
): Error {
|
||||||
return this.hub.buildError(this.node, msg, Error);
|
return this.hub.buildError(this.node, msg, Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
traverse(visitor: Object, state?: any) {
|
traverse<T>(visitor: Visitor<T>, state: T): void;
|
||||||
|
traverse(visitor: Visitor): void;
|
||||||
|
traverse(visitor: any, state?: any) {
|
||||||
traverse(this.node, visitor, this.scope, state, this);
|
traverse(this.node, visitor, this.scope, state, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key: string, node: Object) {
|
set(key: string, node: any) {
|
||||||
t.validate(this.node, key, node);
|
t.validate(this.node, key, node);
|
||||||
this.node[key] = node;
|
this.node[key] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPathLocation(): string {
|
getPathLocation(): string {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
let path = this;
|
let path: NodePath = this;
|
||||||
do {
|
do {
|
||||||
let key = path.key;
|
let key = path.key;
|
||||||
if (path.inList) key = `${path.listKey}[${key}]`;
|
if (path.inList) key = `${path.listKey}[${key}]`;
|
||||||
@ -203,7 +225,7 @@ Object.assign(
|
|||||||
NodePath_comments,
|
NodePath_comments,
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const type of (t.TYPES: Array<string>)) {
|
for (const type of t.TYPES) {
|
||||||
const typeKey = `is${type}`;
|
const typeKey = `is${type}`;
|
||||||
const fn = t[typeKey];
|
const fn = t[typeKey];
|
||||||
NodePath.prototype[typeKey] = function (opts) {
|
NodePath.prototype[typeKey] = function (opts) {
|
||||||
@ -227,3 +249,23 @@ for (const type of Object.keys(virtualTypes)) {
|
|||||||
return virtualType.checkPath(this, opts);
|
return virtualType.checkPath(this, opts);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NodePathMixins = typeof NodePath_ancestry &
|
||||||
|
typeof NodePath_inference &
|
||||||
|
typeof NodePath_replacement &
|
||||||
|
typeof NodePath_evaluation &
|
||||||
|
typeof NodePath_conversion &
|
||||||
|
typeof NodePath_introspection &
|
||||||
|
typeof NodePath_context &
|
||||||
|
typeof NodePath_removal &
|
||||||
|
typeof NodePath_modification &
|
||||||
|
typeof NodePath_family &
|
||||||
|
typeof NodePath_comments;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface NodePath<T>
|
||||||
|
extends NodePathAssetions,
|
||||||
|
NodePathValidators,
|
||||||
|
NodePathMixins {}
|
||||||
|
|
||||||
|
export default NodePath;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import type NodePath from "./index";
|
import type NodePath from "../index";
|
||||||
import * as inferers from "./inferers";
|
import * as inferers from "./inferers";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ import * as t from "@babel/types";
|
|||||||
* Infer the type of the current `NodePath`.
|
* Infer the type of the current `NodePath`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getTypeAnnotation(): Object {
|
export function getTypeAnnotation(): t.FlowType {
|
||||||
if (this.typeAnnotation) return this.typeAnnotation;
|
if (this.typeAnnotation) return this.typeAnnotation;
|
||||||
|
|
||||||
let type = this._getTypeAnnotation() || t.anyTypeAnnotation();
|
let type = this._getTypeAnnotation() || t.anyTypeAnnotation();
|
||||||
@ -23,7 +23,7 @@ const typeAnnotationInferringNodes = new WeakSet();
|
|||||||
* todo: split up this method
|
* todo: split up this method
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function _getTypeAnnotation(): ?Object {
|
export function _getTypeAnnotation(): any {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@ -106,7 +106,7 @@ export function couldBeBaseType(name: string): boolean {
|
|||||||
if (t.isAnyTypeAnnotation(type)) return true;
|
if (t.isAnyTypeAnnotation(type)) return true;
|
||||||
|
|
||||||
if (t.isUnionTypeAnnotation(type)) {
|
if (t.isUnionTypeAnnotation(type)) {
|
||||||
for (const type2 of (type.types: Array<Object>)) {
|
for (const type2 of type.types) {
|
||||||
if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
|
if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -117,13 +117,14 @@ export function couldBeBaseType(name: string): boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function baseTypeStrictlyMatches(right: NodePath) {
|
export function baseTypeStrictlyMatches(rightArg: NodePath): boolean {
|
||||||
const left = this.getTypeAnnotation();
|
const left = this.getTypeAnnotation();
|
||||||
right = right.getTypeAnnotation();
|
const right = rightArg.getTypeAnnotation();
|
||||||
|
|
||||||
if (!t.isAnyTypeAnnotation(left) && t.isFlowBaseAnnotation(left)) {
|
if (!t.isAnyTypeAnnotation(left) && t.isFlowBaseAnnotation(left)) {
|
||||||
return right.type === left.type;
|
return right.type === left.type;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isGenericType(genericName: string): boolean {
|
export function isGenericType(genericName: string): boolean {
|
||||||
@ -1,7 +1,8 @@
|
|||||||
import type NodePath from "../index";
|
import type NodePath from "../index";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type Binding from "../../scope/binding";
|
||||||
|
|
||||||
export default function (node: Object) {
|
export default function (node: any) {
|
||||||
if (!this.isReferenced()) return;
|
if (!this.isReferenced()) return;
|
||||||
|
|
||||||
// check if a binding exists of this value and if so then return a union type of all
|
// check if a binding exists of this value and if so then return a union type of all
|
||||||
@ -86,7 +87,7 @@ function getTypeAnnotationBindingConstantViolations(binding, path, name) {
|
|||||||
constantViolations = constantViolations.concat(functionConstantViolations);
|
constantViolations = constantViolations.concat(functionConstantViolations);
|
||||||
|
|
||||||
// push on inferred types of violated paths
|
// push on inferred types of violated paths
|
||||||
for (const violation of (constantViolations: Array<NodePath>)) {
|
for (const violation of constantViolations) {
|
||||||
types.push(violation.getTypeAnnotation());
|
types.push(violation.getTypeAnnotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +107,7 @@ function getTypeAnnotationBindingConstantViolations(binding, path, name) {
|
|||||||
return t.createUnionTypeAnnotation(types);
|
return t.createUnionTypeAnnotation(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConstantViolationsBefore(binding, path, functions) {
|
function getConstantViolationsBefore(binding: Binding, path, functions?) {
|
||||||
const violations = binding.constantViolations.slice();
|
const violations = binding.constantViolations.slice();
|
||||||
violations.unshift(binding.path);
|
violations.unshift(binding.path);
|
||||||
return violations.filter(violation => {
|
return violations.filter(violation => {
|
||||||
@ -117,7 +118,10 @@ function getConstantViolationsBefore(binding, path, functions) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function inferAnnotationFromBinaryExpression(name, path) {
|
function inferAnnotationFromBinaryExpression(
|
||||||
|
name: string,
|
||||||
|
path: NodePath<t.BinaryExpression>,
|
||||||
|
) {
|
||||||
const operator = path.node.operator;
|
const operator = path.node.operator;
|
||||||
|
|
||||||
const right = path.get("right").resolve();
|
const right = path.get("right").resolve();
|
||||||
@ -144,14 +148,14 @@ function inferAnnotationFromBinaryExpression(name, path) {
|
|||||||
if (operator !== "===" && operator !== "==") return;
|
if (operator !== "===" && operator !== "==") return;
|
||||||
|
|
||||||
//
|
//
|
||||||
let typeofPath;
|
let typeofPath: NodePath<t.UnaryExpression>;
|
||||||
let typePath;
|
let typePath: NodePath<t.Expression>;
|
||||||
if (left.isUnaryExpression({ operator: "typeof" })) {
|
if (left.isUnaryExpression({ operator: "typeof" })) {
|
||||||
typeofPath = left;
|
typeofPath = left;
|
||||||
typePath = right;
|
typePath = right as NodePath<t.Expression>;
|
||||||
} else if (right.isUnaryExpression({ operator: "typeof" })) {
|
} else if (right.isUnaryExpression({ operator: "typeof" })) {
|
||||||
typeofPath = right;
|
typeofPath = right;
|
||||||
typePath = left;
|
typePath = left as NodePath<t.Expression>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!typeofPath) return;
|
if (!typeofPath) return;
|
||||||
@ -159,14 +163,16 @@ function inferAnnotationFromBinaryExpression(name, path) {
|
|||||||
if (!typeofPath.get("argument").isIdentifier({ name })) return;
|
if (!typeofPath.get("argument").isIdentifier({ name })) return;
|
||||||
|
|
||||||
// ensure that the type path is a Literal
|
// ensure that the type path is a Literal
|
||||||
typePath = typePath.resolve();
|
typePath = typePath.resolve() as NodePath<t.Expression>;
|
||||||
if (!typePath.isLiteral()) return;
|
if (!typePath.isLiteral()) return;
|
||||||
|
|
||||||
// and that it's a string so we can infer it
|
// and that it's a string so we can infer it
|
||||||
|
// @ts-expect-error todo(flow->ts): value is not defined for NullLiteral and some other
|
||||||
const typeValue = typePath.node.value;
|
const typeValue = typePath.node.value;
|
||||||
if (typeof typeValue !== "string") return;
|
if (typeof typeValue !== "string") return;
|
||||||
|
|
||||||
// turn type value into a type annotation
|
// turn type value into a type annotation
|
||||||
|
// @ts-expect-error todo(flow->ts): move validation from helper or relax type constraint to just a string
|
||||||
return t.createTypeAnnotationBasedOnTypeof(typeValue);
|
return t.createTypeAnnotationBasedOnTypeof(typeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +194,11 @@ function getParentConditionalPath(binding, path, name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConditionalAnnotation(binding, path, name) {
|
function getConditionalAnnotation<T extends t.Node>(
|
||||||
|
binding: Binding,
|
||||||
|
path: NodePath<T>,
|
||||||
|
name?,
|
||||||
|
) {
|
||||||
const ifStatement = getParentConditionalPath(binding, path, name);
|
const ifStatement = getParentConditionalPath(binding, path, name);
|
||||||
if (!ifStatement) return;
|
if (!ifStatement) return;
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ import * as t from "@babel/types";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function matchesPattern(
|
export function matchesPattern(
|
||||||
|
this: NodePath,
|
||||||
pattern: string,
|
pattern: string,
|
||||||
allowPartial?: boolean,
|
allowPartial?: boolean,
|
||||||
): boolean {
|
): boolean {
|
||||||
@ -22,7 +23,7 @@ export function matchesPattern(
|
|||||||
* if the array has any items, otherwise we just check if it's falsy.
|
* if the array has any items, otherwise we just check if it's falsy.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function has(key): boolean {
|
export function has(this: NodePath, key: string): boolean {
|
||||||
const val = this.node && this.node[key];
|
const val = this.node && this.node[key];
|
||||||
if (val && Array.isArray(val)) {
|
if (val && Array.isArray(val)) {
|
||||||
return !!val.length;
|
return !!val.length;
|
||||||
@ -35,7 +36,7 @@ export function has(key): boolean {
|
|||||||
* Description
|
* Description
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isStatic() {
|
export function isStatic(this: NodePath): boolean {
|
||||||
return this.scope.isStatic(this.node);
|
return this.scope.isStatic(this.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ export const is = has;
|
|||||||
* Opposite of `has`.
|
* Opposite of `has`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isnt(key): boolean {
|
export function isnt(this: NodePath, key: string): boolean {
|
||||||
return !this.has(key);
|
return !this.has(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ export function isnt(key): boolean {
|
|||||||
* Check whether the path node `key` strict equals `value`.
|
* Check whether the path node `key` strict equals `value`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function equals(key, value): boolean {
|
export function equals(this: NodePath, key: string, value): boolean {
|
||||||
return this.node[key] === value;
|
return this.node[key] === value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ export function equals(key, value): boolean {
|
|||||||
* been removed yet we still internally know the type and need it to calculate node replacement.
|
* been removed yet we still internally know the type and need it to calculate node replacement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isNodeType(type: string): boolean {
|
export function isNodeType(this: NodePath, type: string): boolean {
|
||||||
return t.isType(this.type, type);
|
return t.isType(this.type, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ export function isNodeType(type: string): boolean {
|
|||||||
* to tell the path replacement that it's ok to replace this with an expression.
|
* to tell the path replacement that it's ok to replace this with an expression.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function canHaveVariableDeclarationOrExpression() {
|
export function canHaveVariableDeclarationOrExpression(this: NodePath) {
|
||||||
return (
|
return (
|
||||||
(this.key === "init" || this.key === "left") && this.parentPath.isFor()
|
(this.key === "init" || this.key === "left") && this.parentPath.isFor()
|
||||||
);
|
);
|
||||||
@ -94,7 +95,10 @@ export function canHaveVariableDeclarationOrExpression() {
|
|||||||
* is the same as containing a block statement.
|
* is the same as containing a block statement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function canSwapBetweenExpressionAndStatement(replacement) {
|
export function canSwapBetweenExpressionAndStatement(
|
||||||
|
this: NodePath,
|
||||||
|
replacement: t.Node,
|
||||||
|
): boolean {
|
||||||
if (this.key !== "body" || !this.parentPath.isArrowFunctionExpression()) {
|
if (this.key !== "body" || !this.parentPath.isArrowFunctionExpression()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -112,7 +116,10 @@ export function canSwapBetweenExpressionAndStatement(replacement) {
|
|||||||
* Check whether the current path references a completion record
|
* Check whether the current path references a completion record
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isCompletionRecord(allowInsideFunction?) {
|
export function isCompletionRecord(
|
||||||
|
this: NodePath,
|
||||||
|
allowInsideFunction?: boolean,
|
||||||
|
): boolean {
|
||||||
let path = this;
|
let path = this;
|
||||||
let first = true;
|
let first = true;
|
||||||
|
|
||||||
@ -141,14 +148,14 @@ export function isCompletionRecord(allowInsideFunction?) {
|
|||||||
* so we can explode it if necessary.
|
* so we can explode it if necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isStatementOrBlock() {
|
export function isStatementOrBlock(this: NodePath): boolean {
|
||||||
if (
|
if (
|
||||||
this.parentPath.isLabeledStatement() ||
|
this.parentPath.isLabeledStatement() ||
|
||||||
t.isBlockStatement(this.container)
|
t.isBlockStatement(this.container)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return t.STATEMENT_OR_BLOCK_KEYS.includes(this.key);
|
return t.STATEMENT_OR_BLOCK_KEYS.includes(this.key as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +163,11 @@ export function isStatementOrBlock() {
|
|||||||
* Check if the currently assigned path references the `importName` of `moduleSource`.
|
* Check if the currently assigned path references the `importName` of `moduleSource`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function referencesImport(moduleSource, importName) {
|
export function referencesImport(
|
||||||
|
this: NodePath<t.Identifier>,
|
||||||
|
moduleSource: string,
|
||||||
|
importName: string,
|
||||||
|
): boolean {
|
||||||
if (!this.isReferencedIdentifier()) return false;
|
if (!this.isReferencedIdentifier()) return false;
|
||||||
|
|
||||||
const binding = this.scope.getBinding(this.node.name);
|
const binding = this.scope.getBinding(this.node.name);
|
||||||
@ -181,7 +192,10 @@ export function referencesImport(moduleSource, importName) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.isImportSpecifier() && path.node.imported.name === importName) {
|
if (
|
||||||
|
path.isImportSpecifier() &&
|
||||||
|
t.isIdentifier(path.node.imported, { name: importName })
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +206,7 @@ export function referencesImport(moduleSource, importName) {
|
|||||||
* Get the source code associated with this node.
|
* Get the source code associated with this node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getSource() {
|
export function getSource(this: NodePath): string {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
if (node.end) {
|
if (node.end) {
|
||||||
const code = this.hub.getCode();
|
const code = this.hub.getCode();
|
||||||
@ -201,7 +215,7 @@ export function getSource() {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function willIMaybeExecuteBefore(target) {
|
export function willIMaybeExecuteBefore(this: NodePath, target): boolean {
|
||||||
return this._guessExecutionStatusRelativeTo(target) !== "after";
|
return this._guessExecutionStatusRelativeTo(target) !== "after";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +296,7 @@ type RelativeExecutionStatus = "before" | "after" | "unknown";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function _guessExecutionStatusRelativeTo(
|
export function _guessExecutionStatusRelativeTo(
|
||||||
|
this: NodePath,
|
||||||
target: NodePath,
|
target: NodePath,
|
||||||
): RelativeExecutionStatus {
|
): RelativeExecutionStatus {
|
||||||
// check if the two paths are in different functions, we can't track execution of these
|
// check if the two paths are in different functions, we can't track execution of these
|
||||||
@ -354,8 +369,8 @@ export function _guessExecutionStatusRelativeTo(
|
|||||||
// otherwise we're associated by a parent node, check which key comes before the other
|
// otherwise we're associated by a parent node, check which key comes before the other
|
||||||
const keys = t.VISITOR_KEYS[commonPath.type];
|
const keys = t.VISITOR_KEYS[commonPath.type];
|
||||||
const keyPosition = {
|
const keyPosition = {
|
||||||
this: keys.indexOf(divergence.this.parentKey),
|
this: keys.indexOf(divergence.this.parentKey as string),
|
||||||
target: keys.indexOf(divergence.target.parentKey),
|
target: keys.indexOf(divergence.target.parentKey as string),
|
||||||
};
|
};
|
||||||
return keyPosition.target > keyPosition.this ? "before" : "after";
|
return keyPosition.target > keyPosition.this ? "before" : "after";
|
||||||
}
|
}
|
||||||
@ -367,6 +382,7 @@ export function _guessExecutionStatusRelativeTo(
|
|||||||
const executionOrderCheckedNodes = new WeakSet();
|
const executionOrderCheckedNodes = new WeakSet();
|
||||||
|
|
||||||
export function _guessExecutionStatusRelativeToDifferentFunctions(
|
export function _guessExecutionStatusRelativeToDifferentFunctions(
|
||||||
|
this: NodePath,
|
||||||
target: NodePath,
|
target: NodePath,
|
||||||
): RelativeExecutionStatus {
|
): RelativeExecutionStatus {
|
||||||
if (
|
if (
|
||||||
@ -423,12 +439,15 @@ export function _guessExecutionStatusRelativeToDifferentFunctions(
|
|||||||
/**
|
/**
|
||||||
* Resolve a "pointer" `NodePath` to it's absolute path.
|
* Resolve a "pointer" `NodePath` to it's absolute path.
|
||||||
*/
|
*/
|
||||||
|
export function resolve(this: NodePath, dangerous?, resolved?) {
|
||||||
export function resolve(dangerous, resolved) {
|
|
||||||
return this._resolve(dangerous, resolved) || this;
|
return this._resolve(dangerous, resolved) || this;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _resolve(dangerous?, resolved?): ?NodePath {
|
export function _resolve(
|
||||||
|
this: NodePath,
|
||||||
|
dangerous?,
|
||||||
|
resolved?,
|
||||||
|
): NodePath | undefined | null {
|
||||||
// detect infinite recursion
|
// detect infinite recursion
|
||||||
// todo: possibly have a max length on this just to be safe
|
// todo: possibly have a max length on this just to be safe
|
||||||
if (resolved && resolved.indexOf(this) >= 0) return;
|
if (resolved && resolved.indexOf(this) >= 0) return;
|
||||||
@ -444,6 +463,7 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
|
|||||||
// otherwise it's a request for a pattern and that's a bit more tricky
|
// otherwise it's a request for a pattern and that's a bit more tricky
|
||||||
}
|
}
|
||||||
} else if (this.isReferencedIdentifier()) {
|
} else if (this.isReferencedIdentifier()) {
|
||||||
|
// @ts-expect-error todo(flow->ts): think about options to improve type refinements
|
||||||
const binding = this.scope.getBinding(this.node.name);
|
const binding = this.scope.getBinding(this.node.name);
|
||||||
if (!binding) return;
|
if (!binding) return;
|
||||||
|
|
||||||
@ -460,6 +480,7 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else if (this.isTypeCastExpression()) {
|
} else if (this.isTypeCastExpression()) {
|
||||||
|
// @ ts-ignore todo: babel-types
|
||||||
return this.get("expression").resolve(dangerous, resolved);
|
return this.get("expression").resolve(dangerous, resolved);
|
||||||
} else if (dangerous && this.isMemberExpression()) {
|
} else if (dangerous && this.isMemberExpression()) {
|
||||||
// this is dangerous, as non-direct target assignments will mutate it's state
|
// this is dangerous, as non-direct target assignments will mutate it's state
|
||||||
@ -468,13 +489,14 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
|
|||||||
const targetKey = this.toComputedKey();
|
const targetKey = this.toComputedKey();
|
||||||
if (!t.isLiteral(targetKey)) return;
|
if (!t.isLiteral(targetKey)) return;
|
||||||
|
|
||||||
|
// @ts-expect-error todo(flow->ts): NullLiteral
|
||||||
const targetName = targetKey.value;
|
const targetName = targetKey.value;
|
||||||
|
|
||||||
const target = this.get("object").resolve(dangerous, resolved);
|
const target = this.get("object").resolve(dangerous, resolved);
|
||||||
|
|
||||||
if (target.isObjectExpression()) {
|
if (target.isObjectExpression()) {
|
||||||
const props = target.get("properties");
|
const props = target.get("properties");
|
||||||
for (const prop of (props: Array)) {
|
for (const prop of props as any[]) {
|
||||||
if (!prop.isProperty()) continue;
|
if (!prop.isProperty()) continue;
|
||||||
|
|
||||||
const key = prop.get("key");
|
const key = prop.get("key");
|
||||||
@ -496,7 +518,7 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isConstantExpression() {
|
export function isConstantExpression(this: NodePath) {
|
||||||
if (this.isIdentifier()) {
|
if (this.isIdentifier()) {
|
||||||
const binding = this.scope.getBinding(this.node.name);
|
const binding = this.scope.getBinding(this.node.name);
|
||||||
if (!binding) return false;
|
if (!binding) return false;
|
||||||
@ -518,7 +540,7 @@ export function isConstantExpression() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isUnaryExpression()) {
|
if (this.isUnaryExpression()) {
|
||||||
if (this.get("operator").node !== "void") {
|
if (this.node.operator !== "void") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +557,7 @@ export function isConstantExpression() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isInStrictMode() {
|
export function isInStrictMode(this: NodePath) {
|
||||||
const start = this.isProgram() ? this : this.parentPath;
|
const start = this.isProgram() ? this : this.parentPath;
|
||||||
|
|
||||||
const strictParent = start.find(path => {
|
const strictParent = start.find(path => {
|
||||||
@ -552,10 +574,11 @@ export function isInStrictMode() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { node } = path;
|
const body: t.BlockStatement | t.Program = path.isFunction()
|
||||||
if (path.isFunction()) node = node.body;
|
? (path.node.body as t.BlockStatement)
|
||||||
|
: (path.node as t.Program);
|
||||||
|
|
||||||
for (const directive of node.directives) {
|
for (const directive of body.directives) {
|
||||||
if (directive.value.value === "use strict") {
|
if (directive.value.value === "use strict") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1,7 +1,11 @@
|
|||||||
import { react } from "@babel/types";
|
import { react } from "@babel/types";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type Scope from "../../scope";
|
||||||
|
import type NodePath from "../index";
|
||||||
|
import type Binding from "../../scope/binding";
|
||||||
|
import type { Visitor } from "../../types";
|
||||||
|
|
||||||
const referenceVisitor = {
|
const referenceVisitor: Visitor<PathHoister> = {
|
||||||
// This visitor looks for bindings to establish a topmost scope for hoisting.
|
// This visitor looks for bindings to establish a topmost scope for hoisting.
|
||||||
ReferencedIdentifier(path, state) {
|
ReferencedIdentifier(path, state) {
|
||||||
// Don't hoist regular JSX identifiers ('div', 'span', etc).
|
// Don't hoist regular JSX identifiers ('div', 'span', etc).
|
||||||
@ -49,8 +53,16 @@ const referenceVisitor = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class PathHoister {
|
export default class PathHoister<T extends t.Node = t.Node> {
|
||||||
constructor(path, scope) {
|
breakOnScopePaths: NodePath[];
|
||||||
|
bindings: { [k: string]: Binding };
|
||||||
|
mutableBinding: boolean;
|
||||||
|
private scopes: Scope[];
|
||||||
|
scope: Scope;
|
||||||
|
private path: NodePath<T>;
|
||||||
|
private attachAfter: boolean;
|
||||||
|
|
||||||
|
constructor(path: NodePath<T>, scope: Scope) {
|
||||||
// Storage for scopes we can't hoist above.
|
// Storage for scopes we can't hoist above.
|
||||||
this.breakOnScopePaths = [];
|
this.breakOnScopePaths = [];
|
||||||
// Storage for bindings that may affect what path we can hoist to.
|
// Storage for bindings that may affect what path we can hoist to.
|
||||||
@ -131,7 +143,7 @@ export default class PathHoister {
|
|||||||
path = binding.path;
|
path = binding.path;
|
||||||
|
|
||||||
// We also move past any constant violations.
|
// We also move past any constant violations.
|
||||||
for (const violationPath of (binding.constantViolations: Array)) {
|
for (const violationPath of binding.constantViolations) {
|
||||||
if (this.getAttachmentParentForPath(violationPath).key > path.key) {
|
if (this.getAttachmentParentForPath(violationPath).key > path.key) {
|
||||||
path = violationPath;
|
path = violationPath;
|
||||||
}
|
}
|
||||||
@ -156,10 +168,11 @@ export default class PathHoister {
|
|||||||
if (this.scope === scope) return;
|
if (this.scope === scope) return;
|
||||||
|
|
||||||
// needs to be attached to the body
|
// needs to be attached to the body
|
||||||
const bodies = scope.path.get("body").get("body");
|
const bodies = scope.path.get("body").get("body") as NodePath[];
|
||||||
for (let i = 0; i < bodies.length; i++) {
|
for (let i = 0; i < bodies.length; i++) {
|
||||||
// Don't attach to something that's going to get hoisted,
|
// Don't attach to something that's going to get hoisted,
|
||||||
// like a default parameter
|
// like a default parameter
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid mutating the node, introducing new fields
|
||||||
if (bodies[i].node._blockHoist) continue;
|
if (bodies[i].node._blockHoist) continue;
|
||||||
return bodies[i];
|
return bodies[i];
|
||||||
}
|
}
|
||||||
@ -221,6 +234,7 @@ export default class PathHoister {
|
|||||||
// generate declaration and insert it to our point
|
// generate declaration and insert it to our point
|
||||||
let uid = attachTo.scope.generateUidIdentifier("ref");
|
let uid = attachTo.scope.generateUidIdentifier("ref");
|
||||||
|
|
||||||
|
// @ts-expect-error todo(flow->ts): more specific type for this.path
|
||||||
const declarator = t.variableDeclarator(uid, this.path.node);
|
const declarator = t.variableDeclarator(uid, this.path.node);
|
||||||
|
|
||||||
const insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
|
const insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
|
||||||
@ -234,7 +248,7 @@ export default class PathHoister {
|
|||||||
if (parent.isJSXElement() && this.path.container === parent.node.children) {
|
if (parent.isJSXElement() && this.path.container === parent.node.children) {
|
||||||
// turning the `span` in `<div><span /></div>` to an expression so we need to wrap it with
|
// turning the `span` in `<div><span /></div>` to an expression so we need to wrap it with
|
||||||
// an expression container
|
// an expression container
|
||||||
uid = t.JSXExpressionContainer(uid);
|
uid = t.jsxExpressionContainer(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.path.replaceWith(t.cloneNode(uid));
|
this.path.replaceWith(t.cloneNode(uid));
|
||||||
@ -4,7 +4,7 @@ import * as t from "@babel/types";
|
|||||||
|
|
||||||
export const ReferencedIdentifier = {
|
export const ReferencedIdentifier = {
|
||||||
types: ["Identifier", "JSXIdentifier"],
|
types: ["Identifier", "JSXIdentifier"],
|
||||||
checkPath(path: NodePath, opts?: Object): boolean {
|
checkPath(path: NodePath, opts?: any): boolean {
|
||||||
const { node, parent } = path;
|
const { node, parent } = path;
|
||||||
if (!t.isIdentifier(node, opts) && !t.isJSXMemberExpression(parent, opts)) {
|
if (!t.isIdentifier(node, opts) && !t.isJSXMemberExpression(parent, opts)) {
|
||||||
if (t.isJSXIdentifier(node, opts)) {
|
if (t.isJSXIdentifier(node, opts)) {
|
||||||
@ -116,6 +116,7 @@ export const Flow = {
|
|||||||
} else if (t.isImportDeclaration(node)) {
|
} else if (t.isImportDeclaration(node)) {
|
||||||
return node.importKind === "type" || node.importKind === "typeof";
|
return node.importKind === "type" || node.importKind === "typeof";
|
||||||
} else if (t.isExportDeclaration(node)) {
|
} else if (t.isExportDeclaration(node)) {
|
||||||
|
// @ts-expect-error todo(flow->ts) `exportKind` does not exist on ExportAllDeclaration
|
||||||
return node.exportKind === "type";
|
return node.exportKind === "type";
|
||||||
} else if (t.isImportSpecifier(node)) {
|
} else if (t.isImportSpecifier(node)) {
|
||||||
return node.importKind === "type" || node.importKind === "typeof";
|
return node.importKind === "type" || node.importKind === "typeof";
|
||||||
@ -150,7 +151,7 @@ export const NumericLiteralTypeAnnotation = {
|
|||||||
|
|
||||||
export const ForAwaitStatement = {
|
export const ForAwaitStatement = {
|
||||||
types: ["ForOfStatement"],
|
types: ["ForOfStatement"],
|
||||||
checkPath({ node }: NodePath): boolean {
|
checkPath({ node }: NodePath<t.ForOfStatement>): boolean {
|
||||||
return node.await === true;
|
return node.await === true;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -4,15 +4,16 @@ import { path as pathCache } from "../cache";
|
|||||||
import PathHoister from "./lib/hoister";
|
import PathHoister from "./lib/hoister";
|
||||||
import NodePath from "./index";
|
import NodePath from "./index";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type Scope from "../scope";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the provided nodes before the current one.
|
* Insert the provided nodes before the current one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function insertBefore(nodes) {
|
export function insertBefore(this: NodePath, nodes_: t.Node | t.Node[]) {
|
||||||
this._assertUnremoved();
|
this._assertUnremoved();
|
||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
const nodes = this._verifyNodeList(nodes_);
|
||||||
|
|
||||||
const { parentPath } = this;
|
const { parentPath } = this;
|
||||||
|
|
||||||
@ -28,17 +29,18 @@ export function insertBefore(nodes) {
|
|||||||
(parentPath.isForStatement() && this.key === "init")
|
(parentPath.isForStatement() && this.key === "init")
|
||||||
) {
|
) {
|
||||||
if (this.node) nodes.push(this.node);
|
if (this.node) nodes.push(this.node);
|
||||||
|
// @ts-expect-error todo(flow->ts): check that nodes is an array of statements
|
||||||
return this.replaceExpressionWithStatements(nodes);
|
return this.replaceExpressionWithStatements(nodes);
|
||||||
} else if (Array.isArray(this.container)) {
|
} else if (Array.isArray(this.container)) {
|
||||||
return this._containerInsertBefore(nodes);
|
return this._containerInsertBefore(nodes);
|
||||||
} else if (this.isStatementOrBlock()) {
|
} else if (this.isStatementOrBlock()) {
|
||||||
|
const node = this.node as t.Statement;
|
||||||
const shouldInsertCurrentNode =
|
const shouldInsertCurrentNode =
|
||||||
this.node &&
|
node &&
|
||||||
(!this.isExpressionStatement() || this.node.expression != null);
|
(!this.isExpressionStatement() ||
|
||||||
|
(node as t.ExpressionStatement).expression != null);
|
||||||
|
|
||||||
this.replaceWith(
|
this.replaceWith(t.blockStatement(shouldInsertCurrentNode ? [node] : []));
|
||||||
t.blockStatement(shouldInsertCurrentNode ? [this.node] : []),
|
|
||||||
);
|
|
||||||
return this.unshiftContainer("body", nodes);
|
return this.unshiftContainer("body", nodes);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -48,11 +50,12 @@ export function insertBefore(nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _containerInsert(from, nodes) {
|
export function _containerInsert(this: NodePath, from, nodes) {
|
||||||
this.updateSiblingKeys(from, nodes.length);
|
this.updateSiblingKeys(from, nodes.length);
|
||||||
|
|
||||||
const paths = [];
|
const paths = [];
|
||||||
|
|
||||||
|
// @ts-expect-error todo(flow->ts): this.container could be a NodePath
|
||||||
this.container.splice(from, 0, ...nodes);
|
this.container.splice(from, 0, ...nodes);
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
const to = from + i;
|
const to = from + i;
|
||||||
@ -78,11 +81,12 @@ export function _containerInsert(from, nodes) {
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _containerInsertBefore(nodes) {
|
export function _containerInsertBefore(this: NodePath, nodes) {
|
||||||
return this._containerInsert(this.key, nodes);
|
return this._containerInsert(this.key, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _containerInsertAfter(nodes) {
|
export function _containerInsertAfter(this: NodePath, nodes) {
|
||||||
|
// @ts-expect-error todo(flow->ts): this.key could be a string
|
||||||
return this._containerInsert(this.key + 1, nodes);
|
return this._containerInsert(this.key + 1, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,10 +95,10 @@ export function _containerInsertAfter(nodes) {
|
|||||||
* expression, ensure that the completion record is correct by pushing the current node.
|
* expression, ensure that the completion record is correct by pushing the current node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function insertAfter(nodes) {
|
export function insertAfter(this: NodePath, nodes_: t.Node | t.Node[]) {
|
||||||
this._assertUnremoved();
|
this._assertUnremoved();
|
||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
const nodes = this._verifyNodeList(nodes_);
|
||||||
|
|
||||||
const { parentPath } = this;
|
const { parentPath } = this;
|
||||||
if (
|
if (
|
||||||
@ -121,31 +125,36 @@ export function insertAfter(nodes) {
|
|||||||
(parentPath.isForStatement() && this.key === "init")
|
(parentPath.isForStatement() && this.key === "init")
|
||||||
) {
|
) {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
|
const node = this.node as t.Expression | t.VariableDeclaration;
|
||||||
let { scope } = this;
|
let { scope } = this;
|
||||||
// Inserting after the computed key of a method should insert the
|
// Inserting after the computed key of a method should insert the
|
||||||
// temporary binding in the method's parent's scope.
|
// temporary binding in the method's parent's scope.
|
||||||
if (parentPath.isMethod({ computed: true, key: this.node })) {
|
if (parentPath.isMethod({ computed: true, key: node })) {
|
||||||
scope = scope.parent;
|
scope = scope.parent;
|
||||||
}
|
}
|
||||||
const temp = scope.generateDeclaredUidIdentifier();
|
const temp = scope.generateDeclaredUidIdentifier();
|
||||||
nodes.unshift(
|
nodes.unshift(
|
||||||
t.expressionStatement(
|
t.expressionStatement(
|
||||||
t.assignmentExpression("=", t.cloneNode(temp), this.node),
|
// @ts-expect-error todo(flow->ts): This can be a variable
|
||||||
|
// declaraion in the "init" of a for statement, but that's
|
||||||
|
// invalid here.
|
||||||
|
t.assignmentExpression("=", t.cloneNode(temp), node),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
nodes.push(t.expressionStatement(t.cloneNode(temp)));
|
nodes.push(t.expressionStatement(t.cloneNode(temp)));
|
||||||
}
|
}
|
||||||
|
// @ts-expect-error todo(flow->ts): check that nodes is an array of statements
|
||||||
return this.replaceExpressionWithStatements(nodes);
|
return this.replaceExpressionWithStatements(nodes);
|
||||||
} else if (Array.isArray(this.container)) {
|
} else if (Array.isArray(this.container)) {
|
||||||
return this._containerInsertAfter(nodes);
|
return this._containerInsertAfter(nodes);
|
||||||
} else if (this.isStatementOrBlock()) {
|
} else if (this.isStatementOrBlock()) {
|
||||||
|
const node = this.node as t.Statement;
|
||||||
const shouldInsertCurrentNode =
|
const shouldInsertCurrentNode =
|
||||||
this.node &&
|
node &&
|
||||||
(!this.isExpressionStatement() || this.node.expression != null);
|
(!this.isExpressionStatement() ||
|
||||||
|
(node as t.ExpressionStatement).expression != null);
|
||||||
|
|
||||||
this.replaceWith(
|
this.replaceWith(t.blockStatement(shouldInsertCurrentNode ? [node] : []));
|
||||||
t.blockStatement(shouldInsertCurrentNode ? [this.node] : []),
|
|
||||||
);
|
|
||||||
return this.pushContainer("body", nodes);
|
return this.pushContainer("body", nodes);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -159,7 +168,11 @@ export function insertAfter(nodes) {
|
|||||||
* Update all sibling node paths after `fromIndex` by `incrementBy`.
|
* Update all sibling node paths after `fromIndex` by `incrementBy`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function updateSiblingKeys(fromIndex, incrementBy) {
|
export function updateSiblingKeys(
|
||||||
|
this: NodePath,
|
||||||
|
fromIndex: number,
|
||||||
|
incrementBy: number,
|
||||||
|
) {
|
||||||
if (!this.parent) return;
|
if (!this.parent) return;
|
||||||
|
|
||||||
const paths = pathCache.get(this.parent);
|
const paths = pathCache.get(this.parent);
|
||||||
@ -170,12 +183,15 @@ export function updateSiblingKeys(fromIndex, incrementBy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _verifyNodeList(nodes) {
|
export function _verifyNodeList(
|
||||||
|
this: NodePath,
|
||||||
|
nodes: t.Node | t.Node[],
|
||||||
|
): t.Node[] {
|
||||||
if (!nodes) {
|
if (!nodes) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodes.constructor !== Array) {
|
if (!Array.isArray(nodes)) {
|
||||||
nodes = [nodes];
|
nodes = [nodes];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +220,11 @@ export function _verifyNodeList(nodes) {
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unshiftContainer(listKey, nodes) {
|
export function unshiftContainer<Nodes extends t.Node | t.Node[]>(
|
||||||
|
listKey: string,
|
||||||
|
nodes: Nodes,
|
||||||
|
): NodePath[] {
|
||||||
|
// todo: NodePaths<Nodes>
|
||||||
this._assertUnremoved();
|
this._assertUnremoved();
|
||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
nodes = this._verifyNodeList(nodes);
|
||||||
@ -222,10 +242,14 @@ export function unshiftContainer(listKey, nodes) {
|
|||||||
return path._containerInsertBefore(nodes);
|
return path._containerInsertBefore(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pushContainer(listKey, nodes) {
|
export function pushContainer(
|
||||||
|
this: NodePath,
|
||||||
|
listKey: string,
|
||||||
|
nodes: t.Node | t.Node[],
|
||||||
|
) {
|
||||||
this._assertUnremoved();
|
this._assertUnremoved();
|
||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
const verifiedNodes = this._verifyNodeList(nodes);
|
||||||
|
|
||||||
// get an invisible path that represents the last node + 1 and replace it with our
|
// get an invisible path that represents the last node + 1 and replace it with our
|
||||||
// nodes, effectively inlining it
|
// nodes, effectively inlining it
|
||||||
@ -239,15 +263,17 @@ export function pushContainer(listKey, nodes) {
|
|||||||
key: container.length,
|
key: container.length,
|
||||||
}).setContext(this.context);
|
}).setContext(this.context);
|
||||||
|
|
||||||
return path.replaceWithMultiple(nodes);
|
return path.replaceWithMultiple(verifiedNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hoist the current node to the highest scope possible and return a UID
|
* Hoist the current node to the highest scope possible and return a UID
|
||||||
* referencing it.
|
* referencing it.
|
||||||
*/
|
*/
|
||||||
|
export function hoist<T extends t.Node>(
|
||||||
export function hoist(scope = this.scope) {
|
this: NodePath<T>,
|
||||||
const hoister = new PathHoister(this, scope);
|
scope: Scope = this.scope,
|
||||||
|
) {
|
||||||
|
const hoister = new PathHoister<T>(this, scope);
|
||||||
return hoister.run();
|
return hoister.run();
|
||||||
}
|
}
|
||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
import { hooks } from "./lib/removal-hooks";
|
import { hooks } from "./lib/removal-hooks";
|
||||||
import { path as pathCache } from "../cache";
|
import { path as pathCache } from "../cache";
|
||||||
import { REMOVED, SHOULD_SKIP } from "./index";
|
import NodePath, { REMOVED, SHOULD_SKIP } from "./index";
|
||||||
|
|
||||||
export function remove() {
|
export function remove(this: NodePath) {
|
||||||
this._assertUnremoved();
|
this._assertUnremoved();
|
||||||
|
|
||||||
this.resync();
|
this.resync();
|
||||||
@ -22,34 +22,34 @@ export function remove() {
|
|||||||
this._markRemoved();
|
this._markRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _removeFromScope() {
|
export function _removeFromScope(this: NodePath) {
|
||||||
const bindings = this.getBindingIdentifiers();
|
const bindings = this.getBindingIdentifiers();
|
||||||
Object.keys(bindings).forEach(name => this.scope.removeBinding(name));
|
Object.keys(bindings).forEach(name => this.scope.removeBinding(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _callRemovalHooks() {
|
export function _callRemovalHooks(this: NodePath) {
|
||||||
for (const fn of (hooks: Array<Function>)) {
|
for (const fn of hooks) {
|
||||||
if (fn(this, this.parentPath)) return true;
|
if (fn(this, this.parentPath)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _remove() {
|
export function _remove(this: NodePath) {
|
||||||
if (Array.isArray(this.container)) {
|
if (Array.isArray(this.container)) {
|
||||||
this.container.splice(this.key, 1);
|
this.container.splice(this.key as number, 1);
|
||||||
this.updateSiblingKeys(this.key, -1);
|
this.updateSiblingKeys(this.key as number, -1);
|
||||||
} else {
|
} else {
|
||||||
this._replaceWith(null);
|
this._replaceWith(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _markRemoved() {
|
export function _markRemoved(this: NodePath) {
|
||||||
// this.shouldSkip = true; this.removed = true;
|
// this.shouldSkip = true; this.removed = true;
|
||||||
this._traverseFlags |= SHOULD_SKIP | REMOVED;
|
this._traverseFlags |= SHOULD_SKIP | REMOVED;
|
||||||
if (this.parent) pathCache.get(this.parent).delete(this.node);
|
if (this.parent) pathCache.get(this.parent).delete(this.node);
|
||||||
this.node = null;
|
this.node = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _assertUnremoved() {
|
export function _assertUnremoved(this: NodePath) {
|
||||||
if (this.removed) {
|
if (this.removed) {
|
||||||
throw this.buildCodeFrameError(
|
throw this.buildCodeFrameError(
|
||||||
"NodePath has been removed so is read-only.",
|
"NodePath has been removed so is read-only.",
|
||||||
@ -22,7 +22,7 @@ const hoistVariablesVisitor = {
|
|||||||
|
|
||||||
const exprs = [];
|
const exprs = [];
|
||||||
|
|
||||||
for (const declar of (path.node.declarations: Array<Object>)) {
|
for (const declar of path.node.declarations as Array<any>) {
|
||||||
if (declar.init) {
|
if (declar.init) {
|
||||||
exprs.push(
|
exprs.push(
|
||||||
t.expressionStatement(
|
t.expressionStatement(
|
||||||
@ -44,7 +44,10 @@ const hoistVariablesVisitor = {
|
|||||||
* - Remove the current node.
|
* - Remove the current node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function replaceWithMultiple(nodes: Array<Object>) {
|
export function replaceWithMultiple<Nodes extends Array<t.Node>>(
|
||||||
|
nodes: Nodes,
|
||||||
|
): NodePath[] {
|
||||||
|
// todo NodePaths
|
||||||
this.resync();
|
this.resync();
|
||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
nodes = this._verifyNodeList(nodes);
|
||||||
@ -70,7 +73,7 @@ export function replaceWithMultiple(nodes: Array<Object>) {
|
|||||||
* easier to use, your transforms will be extremely brittle.
|
* easier to use, your transforms will be extremely brittle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function replaceWithSourceString(replacement) {
|
export function replaceWithSourceString(this: NodePath, replacement) {
|
||||||
this.resync();
|
this.resync();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -101,7 +104,7 @@ export function replaceWithSourceString(replacement) {
|
|||||||
* Replace the current node with another.
|
* Replace the current node with another.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function replaceWith(replacement) {
|
export function replaceWith(this: NodePath, replacement: t.Node | NodePath) {
|
||||||
this.resync();
|
this.resync();
|
||||||
|
|
||||||
if (this.removed) {
|
if (this.removed) {
|
||||||
@ -187,15 +190,16 @@ export function replaceWith(replacement) {
|
|||||||
* Description
|
* Description
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function _replaceWith(node) {
|
export function _replaceWith(this: NodePath, node) {
|
||||||
if (!this.container) {
|
if (!this.container) {
|
||||||
throw new ReferenceError("Container is falsy");
|
throw new ReferenceError("Container is falsy");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.inList) {
|
if (this.inList) {
|
||||||
|
// @ts-expect-error todo(flow->ts): check if t.validate accepts a numeric key
|
||||||
t.validate(this.parent, this.key, [node]);
|
t.validate(this.parent, this.key, [node]);
|
||||||
} else {
|
} else {
|
||||||
t.validate(this.parent, this.key, node);
|
t.validate(this.parent, this.key as string, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.debug(`Replace with ${node?.type}`);
|
this.debug(`Replace with ${node?.type}`);
|
||||||
@ -210,7 +214,10 @@ export function _replaceWith(node) {
|
|||||||
* extremely important to retain original semantics.
|
* extremely important to retain original semantics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
export function replaceExpressionWithStatements(
|
||||||
|
this: NodePath,
|
||||||
|
nodes: Array<t.Statement>,
|
||||||
|
) {
|
||||||
this.resync();
|
this.resync();
|
||||||
|
|
||||||
const toSequenceExpression = t.toSequenceExpression(nodes, this.scope);
|
const toSequenceExpression = t.toSequenceExpression(nodes, this.scope);
|
||||||
@ -225,12 +232,17 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
|||||||
const container = t.arrowFunctionExpression([], t.blockStatement(nodes));
|
const container = t.arrowFunctionExpression([], t.blockStatement(nodes));
|
||||||
|
|
||||||
this.replaceWith(t.callExpression(container, []));
|
this.replaceWith(t.callExpression(container, []));
|
||||||
|
// replaceWith changes the type of "this", but it isn't trackable by TS
|
||||||
|
type ThisType = NodePath<
|
||||||
|
t.CallExpression & { callee: t.ArrowFunctionExpression }
|
||||||
|
>;
|
||||||
|
|
||||||
this.traverse(hoistVariablesVisitor);
|
this.traverse(hoistVariablesVisitor);
|
||||||
|
|
||||||
// add implicit returns to all ending expression statements
|
// add implicit returns to all ending expression statements
|
||||||
const completionRecords: Array<NodePath> = this.get(
|
const completionRecords: Array<NodePath> = (this as ThisType)
|
||||||
"callee",
|
.get("callee")
|
||||||
).getCompletionRecords();
|
.getCompletionRecords();
|
||||||
for (const path of completionRecords) {
|
for (const path of completionRecords) {
|
||||||
if (!path.isExpressionStatement()) continue;
|
if (!path.isExpressionStatement()) continue;
|
||||||
|
|
||||||
@ -239,7 +251,7 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
|||||||
let uid = loop.getData("expressionReplacementReturnUid");
|
let uid = loop.getData("expressionReplacementReturnUid");
|
||||||
|
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
const callee = this.get("callee");
|
const callee = (this as ThisType).get("callee");
|
||||||
uid = callee.scope.generateDeclaredUidIdentifier("ret");
|
uid = callee.scope.generateDeclaredUidIdentifier("ret");
|
||||||
callee
|
callee
|
||||||
.get("body")
|
.get("body")
|
||||||
@ -259,26 +271,26 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const callee = this.get("callee");
|
const callee = this.get("callee") as NodePath<t.FunctionExpression>;
|
||||||
callee.arrowFunctionToExpression();
|
callee.arrowFunctionToExpression();
|
||||||
|
|
||||||
// (() => await xxx)() -> await (async () => await xxx)();
|
// (() => await xxx)() -> await (async () => await xxx)();
|
||||||
if (
|
if (
|
||||||
isParentAsync &&
|
isParentAsync &&
|
||||||
traverse.hasType(
|
traverse.hasType(
|
||||||
this.get("callee.body").node,
|
(this.get("callee.body") as NodePath<t.BlockStatement>).node,
|
||||||
"AwaitExpression",
|
"AwaitExpression",
|
||||||
t.FUNCTION_TYPES,
|
t.FUNCTION_TYPES,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
callee.set("async", true);
|
callee.set("async", true);
|
||||||
this.replaceWith(t.awaitExpression(this.node));
|
this.replaceWith(t.awaitExpression((this as ThisType).node));
|
||||||
}
|
}
|
||||||
|
|
||||||
return callee.get("body.body");
|
return callee.get("body.body");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function replaceInline(nodes: Object | Array<Object>) {
|
export function replaceInline(this: NodePath, nodes: t.Node | Array<t.Node>) {
|
||||||
this.resync();
|
this.resync();
|
||||||
|
|
||||||
if (Array.isArray(nodes)) {
|
if (Array.isArray(nodes)) {
|
||||||
@ -1,5 +1,16 @@
|
|||||||
import type NodePath from "../path";
|
import type NodePath from "../path";
|
||||||
|
import type * as t from "@babel/types";
|
||||||
|
import type Scope from "./index";
|
||||||
|
|
||||||
|
type BindingKind =
|
||||||
|
| "var"
|
||||||
|
| "let"
|
||||||
|
| "const"
|
||||||
|
| "module"
|
||||||
|
| "hoisted"
|
||||||
|
| "param"
|
||||||
|
| "local"
|
||||||
|
| "unknown";
|
||||||
/**
|
/**
|
||||||
* This class is responsible for a binding inside of a scope.
|
* This class is responsible for a binding inside of a scope.
|
||||||
*
|
*
|
||||||
@ -12,7 +23,22 @@ import type NodePath from "../path";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export default class Binding {
|
export default class Binding {
|
||||||
constructor({ identifier, scope, path, kind }) {
|
identifier: t.Identifier;
|
||||||
|
scope: Scope;
|
||||||
|
path: NodePath;
|
||||||
|
kind: BindingKind;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
identifier,
|
||||||
|
scope,
|
||||||
|
path,
|
||||||
|
kind,
|
||||||
|
}: {
|
||||||
|
identifier: t.Identifier;
|
||||||
|
scope: Scope;
|
||||||
|
path: NodePath;
|
||||||
|
kind: BindingKind;
|
||||||
|
}) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
@ -53,7 +79,7 @@ export default class Binding {
|
|||||||
* Register a constant violation with the provided `path`.
|
* Register a constant violation with the provided `path`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
reassign(path: Object) {
|
reassign(path: any) {
|
||||||
this.constant = false;
|
this.constant = false;
|
||||||
if (this.constantViolations.indexOf(path) !== -1) {
|
if (this.constantViolations.indexOf(path) !== -1) {
|
||||||
return;
|
return;
|
||||||
@ -1,26 +1,57 @@
|
|||||||
import Renamer from "./lib/renamer";
|
import Renamer from "./lib/renamer";
|
||||||
import type NodePath from "../path";
|
import type NodePath from "../path";
|
||||||
import traverse from "../index";
|
import traverse from "../index";
|
||||||
|
import type { TraverseOptions } from "../index";
|
||||||
import Binding from "./binding";
|
import Binding from "./binding";
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import { scope as scopeCache } from "../cache";
|
import { scope as scopeCache } from "../cache";
|
||||||
|
import type { Visitor } from "../types";
|
||||||
|
|
||||||
// Recursively gathers the identifying names of a node.
|
// Recursively gathers the identifying names of a node.
|
||||||
function gatherNodeParts(node: Object, parts: Array) {
|
function gatherNodeParts(node: t.Node, parts: any[]) {
|
||||||
switch (node?.type) {
|
switch (node?.type) {
|
||||||
default:
|
default:
|
||||||
if (t.isModuleDeclaration(node)) {
|
if (t.isModuleDeclaration(node)) {
|
||||||
if (node.source) {
|
if (
|
||||||
|
(t.isExportAllDeclaration(node) ||
|
||||||
|
t.isExportNamedDeclaration(node) ||
|
||||||
|
t.isImportDeclaration(node)) &&
|
||||||
|
node.source
|
||||||
|
) {
|
||||||
gatherNodeParts(node.source, parts);
|
gatherNodeParts(node.source, parts);
|
||||||
} else if (node.specifiers && node.specifiers.length) {
|
} else if (
|
||||||
|
(t.isExportNamedDeclaration(node) || t.isImportDeclaration(node)) &&
|
||||||
|
node.specifiers &&
|
||||||
|
node.specifiers.length
|
||||||
|
) {
|
||||||
for (const e of node.specifiers) gatherNodeParts(e, parts);
|
for (const e of node.specifiers) gatherNodeParts(e, parts);
|
||||||
} else if (node.declaration) {
|
} else if (
|
||||||
|
(t.isExportDefaultDeclaration(node) ||
|
||||||
|
t.isExportNamedDeclaration(node)) &&
|
||||||
|
node.declaration
|
||||||
|
) {
|
||||||
gatherNodeParts(node.declaration, parts);
|
gatherNodeParts(node.declaration, parts);
|
||||||
}
|
}
|
||||||
} else if (t.isModuleSpecifier(node)) {
|
} else if (t.isModuleSpecifier(node)) {
|
||||||
|
// todo(flow->ts): should condition instead be:
|
||||||
|
// ```
|
||||||
|
// t.isExportSpecifier(node) ||
|
||||||
|
// t.isImportDefaultSpecifier(node) ||
|
||||||
|
// t.isImportNamespaceSpecifier(node) ||
|
||||||
|
// t.isImportSpecifier(node)
|
||||||
|
// ```
|
||||||
|
// allowing only nodes with `.local`?
|
||||||
|
// @ts-expect-error todo(flow->ts)
|
||||||
gatherNodeParts(node.local, parts);
|
gatherNodeParts(node.local, parts);
|
||||||
} else if (t.isLiteral(node)) {
|
} else if (t.isLiteral(node)) {
|
||||||
|
// todo(flow->ts): should condition be stricter to ensure value is there
|
||||||
|
// ```
|
||||||
|
// !t.isNullLiteral(node) &&
|
||||||
|
// !t.isRegExpLiteral(node) &&
|
||||||
|
// !t.isTemplateLiteral(node)
|
||||||
|
// ```
|
||||||
|
// @ts-expect-error todo(flow->ts)
|
||||||
parts.push(node.value);
|
parts.push(node.value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -147,11 +178,17 @@ function gatherNodeParts(node: Object, parts: Array) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
interface CollectVisitorState {
|
||||||
|
assignments: NodePath<t.AssignmentExpression>[];
|
||||||
|
references: NodePath<t.Identifier | t.JSXIdentifier>[];
|
||||||
|
constantViolations: NodePath[];
|
||||||
|
}
|
||||||
|
|
||||||
const collectorVisitor = {
|
const collectorVisitor: Visitor<CollectVisitorState> = {
|
||||||
For(path) {
|
For(path) {
|
||||||
for (const key of (t.FOR_INIT_KEYS: Array)) {
|
for (const key of t.FOR_INIT_KEYS) {
|
||||||
const declar = path.get(key);
|
// todo: might be not needed with improvement to babel-types
|
||||||
|
const declar = path.get(key) as NodePath;
|
||||||
// delegate block scope handling to the `BlockScoped` method
|
// delegate block scope handling to the `BlockScoped` method
|
||||||
if (declar.isVar()) {
|
if (declar.isVar()) {
|
||||||
const parentScope =
|
const parentScope =
|
||||||
@ -166,6 +203,7 @@ const collectorVisitor = {
|
|||||||
if (path.isBlockScoped()) return;
|
if (path.isBlockScoped()) return;
|
||||||
|
|
||||||
// this will be hit again once we traverse into it after this iteration
|
// this will be hit again once we traverse into it after this iteration
|
||||||
|
// @ts-expect-error todo(flow->ts): might be not correct for export all declaration
|
||||||
if (path.isExportDeclaration() && path.get("declaration").isDeclaration()) {
|
if (path.isExportDeclaration() && path.get("declaration").isDeclaration()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -190,6 +228,7 @@ const collectorVisitor = {
|
|||||||
ExportDeclaration: {
|
ExportDeclaration: {
|
||||||
exit(path) {
|
exit(path) {
|
||||||
const { node, scope } = path;
|
const { node, scope } = path;
|
||||||
|
// @ts-expect-error todo(flow->ts) declaration is not present on ExportAllDeclaration
|
||||||
const declar = node.declaration;
|
const declar = node.declaration;
|
||||||
if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar)) {
|
if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar)) {
|
||||||
const id = declar.id;
|
const id = declar.id;
|
||||||
@ -198,7 +237,7 @@ const collectorVisitor = {
|
|||||||
const binding = scope.getBinding(id.name);
|
const binding = scope.getBinding(id.name);
|
||||||
if (binding) binding.reference(path);
|
if (binding) binding.reference(path);
|
||||||
} else if (t.isVariableDeclaration(declar)) {
|
} else if (t.isVariableDeclaration(declar)) {
|
||||||
for (const decl of (declar.declarations: Array<Object>)) {
|
for (const decl of declar.declarations) {
|
||||||
for (const name of Object.keys(t.getBindingIdentifiers(decl))) {
|
for (const name of Object.keys(t.getBindingIdentifiers(decl))) {
|
||||||
const binding = scope.getBinding(name);
|
const binding = scope.getBinding(name);
|
||||||
if (binding) binding.reference(path);
|
if (binding) binding.reference(path);
|
||||||
@ -209,6 +248,7 @@ const collectorVisitor = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
LabeledStatement(path) {
|
LabeledStatement(path) {
|
||||||
|
// @ts-expect-error todo(flow->ts): possible bug - statement might not have name and so should not be added as global
|
||||||
path.scope.getProgramParent().addGlobal(path.node);
|
path.scope.getProgramParent().addGlobal(path.node);
|
||||||
path.scope.getBlockParent().registerDeclaration(path);
|
path.scope.getBlockParent().registerDeclaration(path);
|
||||||
},
|
},
|
||||||
@ -245,7 +285,7 @@ const collectorVisitor = {
|
|||||||
|
|
||||||
Block(path) {
|
Block(path) {
|
||||||
const paths = path.get("body");
|
const paths = path.get("body");
|
||||||
for (const bodyPath of (paths: Array)) {
|
for (const bodyPath of paths) {
|
||||||
if (bodyPath.isFunctionDeclaration()) {
|
if (bodyPath.isFunctionDeclaration()) {
|
||||||
path.scope.getBlockParent().registerDeclaration(bodyPath);
|
path.scope.getBlockParent().registerDeclaration(bodyPath);
|
||||||
}
|
}
|
||||||
@ -281,11 +321,25 @@ const collectorVisitor = {
|
|||||||
let uid = 0;
|
let uid = 0;
|
||||||
|
|
||||||
export default class Scope {
|
export default class Scope {
|
||||||
|
uid;
|
||||||
|
|
||||||
|
path: NodePath;
|
||||||
|
block: t.Node;
|
||||||
|
|
||||||
|
labels;
|
||||||
|
inited;
|
||||||
|
|
||||||
|
bindings: { [name: string]: Binding };
|
||||||
|
references: object;
|
||||||
|
globals: object;
|
||||||
|
uids: object;
|
||||||
|
data: object;
|
||||||
|
crawling: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This searches the current "scope" and collects all references/bindings
|
* This searches the current "scope" and collects all references/bindings
|
||||||
* within.
|
* within.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constructor(path: NodePath) {
|
constructor(path: NodePath) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
const cached = scopeCache.get(node);
|
const cached = scopeCache.get(node);
|
||||||
@ -330,11 +384,16 @@ export default class Scope {
|
|||||||
return this.path.hub;
|
return this.path.hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traverse<S>(
|
||||||
|
node: t.Node | t.Node[],
|
||||||
|
opts: TraverseOptions<S>,
|
||||||
|
state: S,
|
||||||
|
): void;
|
||||||
|
traverse(node: t.Node | t.Node[], opts?: TraverseOptions, state?: any): void;
|
||||||
/**
|
/**
|
||||||
* Traverse node with current scope and path.
|
* Traverse node with current scope and path.
|
||||||
*/
|
*/
|
||||||
|
traverse(node: any, opts: any, state?) {
|
||||||
traverse(node: Object, opts: Object, state?) {
|
|
||||||
traverse(node, opts, this, state, this.path);
|
traverse(node, opts, this, state, this.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +419,7 @@ export default class Scope {
|
|||||||
* Generate a unique `_id1` binding.
|
* Generate a unique `_id1` binding.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
generateUid(name: string = "temp") {
|
generateUid(name: string = "temp"): string {
|
||||||
name = t
|
name = t
|
||||||
.toIdentifier(name)
|
.toIdentifier(name)
|
||||||
.replace(/^_+/, "")
|
.replace(/^_+/, "")
|
||||||
@ -395,7 +454,7 @@ export default class Scope {
|
|||||||
return `_${id}`;
|
return `_${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateUidBasedOnNode(node: Object, defaultName?: String) {
|
generateUidBasedOnNode(node: t.Node, defaultName?: string) {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
gatherNodeParts(node, parts);
|
gatherNodeParts(node, parts);
|
||||||
|
|
||||||
@ -409,7 +468,7 @@ export default class Scope {
|
|||||||
* Generate a unique identifier based on a node.
|
* Generate a unique identifier based on a node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
generateUidIdentifierBasedOnNode(node: Object, defaultName?: String): Object {
|
generateUidIdentifierBasedOnNode(node: t.Node, defaultName?: string) {
|
||||||
return t.identifier(this.generateUidBasedOnNode(node, defaultName));
|
return t.identifier(this.generateUidBasedOnNode(node, defaultName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +482,7 @@ export default class Scope {
|
|||||||
* - Bound identifiers
|
* - Bound identifiers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isStatic(node: Object): boolean {
|
isStatic(node: t.Node): boolean {
|
||||||
if (t.isThisExpression(node) || t.isSuper(node)) {
|
if (t.isThisExpression(node) || t.isSuper(node)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -444,7 +503,7 @@ export default class Scope {
|
|||||||
* Possibly generate a memoised identifier if it is not static and has consequences.
|
* Possibly generate a memoised identifier if it is not static and has consequences.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maybeGenerateMemoised(node: Object, dontPush?: boolean): ?Object {
|
maybeGenerateMemoised(node: t.Node, dontPush?: boolean) {
|
||||||
if (this.isStatic(node)) {
|
if (this.isStatic(node)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -457,7 +516,12 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkBlockScopedCollisions(local, kind: string, name: string, id: Object) {
|
checkBlockScopedCollisions(
|
||||||
|
local: Binding,
|
||||||
|
kind: string,
|
||||||
|
name: string,
|
||||||
|
id: any,
|
||||||
|
) {
|
||||||
// ignore parameters
|
// ignore parameters
|
||||||
if (kind === "param") return;
|
if (kind === "param") return;
|
||||||
|
|
||||||
@ -483,7 +547,7 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rename(oldName: string, newName: string, block?) {
|
rename(oldName: string, newName?: string, block?: t.Node) {
|
||||||
const binding = this.getBinding(oldName);
|
const binding = this.getBinding(oldName);
|
||||||
if (binding) {
|
if (binding) {
|
||||||
newName = newName || this.generateUidIdentifier(oldName).name;
|
newName = newName || this.generateUidIdentifier(oldName).name;
|
||||||
@ -501,7 +565,7 @@ export default class Scope {
|
|||||||
dump() {
|
dump() {
|
||||||
const sep = "-".repeat(60);
|
const sep = "-".repeat(60);
|
||||||
console.log(sep);
|
console.log(sep);
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
console.log("#", scope.block.type);
|
console.log("#", scope.block.type);
|
||||||
for (const name of Object.keys(scope.bindings)) {
|
for (const name of Object.keys(scope.bindings)) {
|
||||||
@ -518,7 +582,7 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: (Babel 8) Split i in two parameters, and use an object of flags
|
// TODO: (Babel 8) Split i in two parameters, and use an object of flags
|
||||||
toArray(node: Object, i?: number | boolean, allowArrayLike?: boolean) {
|
toArray(node: t.Node, i?: number | boolean, allowArrayLike?: boolean) {
|
||||||
if (t.isIdentifier(node)) {
|
if (t.isIdentifier(node)) {
|
||||||
const binding = this.getBinding(node.name);
|
const binding = this.getBinding(node.name);
|
||||||
if (binding?.constant && binding.path.isGenericType("Array")) {
|
if (binding?.constant && binding.path.isGenericType("Array")) {
|
||||||
@ -567,6 +631,7 @@ export default class Scope {
|
|||||||
helperName = "maybeArrayLike";
|
helperName = "maybeArrayLike";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error todo(flow->ts): t.Node is not valid to use in args, function argument typeneeds to be clarified
|
||||||
return t.callExpression(this.hub.addHelper(helperName), args);
|
return t.callExpression(this.hub.addHelper(helperName), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +643,7 @@ export default class Scope {
|
|||||||
return this.labels.get(name);
|
return this.labels.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLabel(path: NodePath) {
|
registerLabel(path: NodePath<t.LabeledStatement>) {
|
||||||
this.labels.set(path.node.label.name, path);
|
this.labels.set(path.node.label.name, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,18 +654,19 @@ export default class Scope {
|
|||||||
this.registerBinding("hoisted", path.get("id"), path);
|
this.registerBinding("hoisted", path.get("id"), path);
|
||||||
} else if (path.isVariableDeclaration()) {
|
} else if (path.isVariableDeclaration()) {
|
||||||
const declarations = path.get("declarations");
|
const declarations = path.get("declarations");
|
||||||
for (const declar of (declarations: Array)) {
|
for (const declar of declarations) {
|
||||||
this.registerBinding(path.node.kind, declar);
|
this.registerBinding(path.node.kind, declar);
|
||||||
}
|
}
|
||||||
} else if (path.isClassDeclaration()) {
|
} else if (path.isClassDeclaration()) {
|
||||||
this.registerBinding("let", path);
|
this.registerBinding("let", path);
|
||||||
} else if (path.isImportDeclaration()) {
|
} else if (path.isImportDeclaration()) {
|
||||||
const specifiers = path.get("specifiers");
|
const specifiers = path.get("specifiers");
|
||||||
for (const specifier of (specifiers: Array)) {
|
for (const specifier of specifiers) {
|
||||||
this.registerBinding("module", specifier);
|
this.registerBinding("module", specifier);
|
||||||
}
|
}
|
||||||
} else if (path.isExportDeclaration()) {
|
} else if (path.isExportDeclaration()) {
|
||||||
const declar = path.get("declaration");
|
// todo: improve babel-types
|
||||||
|
const declar = path.get("declaration") as NodePath;
|
||||||
if (
|
if (
|
||||||
declar.isClassDeclaration() ||
|
declar.isClassDeclaration() ||
|
||||||
declar.isFunctionDeclaration() ||
|
declar.isFunctionDeclaration() ||
|
||||||
@ -625,7 +691,11 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerBinding(kind: string, path: NodePath, bindingPath = path) {
|
registerBinding(
|
||||||
|
kind: Binding["kind"],
|
||||||
|
path: NodePath,
|
||||||
|
bindingPath: NodePath = path,
|
||||||
|
) {
|
||||||
if (!kind) throw new ReferenceError("no `kind`");
|
if (!kind) throw new ReferenceError("no `kind`");
|
||||||
|
|
||||||
if (path.isVariableDeclaration()) {
|
if (path.isVariableDeclaration()) {
|
||||||
@ -642,7 +712,7 @@ export default class Scope {
|
|||||||
for (const name of Object.keys(ids)) {
|
for (const name of Object.keys(ids)) {
|
||||||
parent.references[name] = true;
|
parent.references[name] = true;
|
||||||
|
|
||||||
for (const id of (ids[name]: Array<Object>)) {
|
for (const id of ids[name]) {
|
||||||
const local = this.getOwnBinding(name);
|
const local = this.getOwnBinding(name);
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
@ -668,12 +738,13 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addGlobal(node: Object) {
|
// todo: flow->ts maybe add more specific type
|
||||||
|
addGlobal(node: Extract<t.Node, { name: string }>) {
|
||||||
this.globals[node.name] = node;
|
this.globals[node.name] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasUid(name): boolean {
|
hasUid(name: string): boolean {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (scope.uids[name]) return true;
|
if (scope.uids[name]) return true;
|
||||||
@ -683,7 +754,7 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasGlobal(name: string): boolean {
|
hasGlobal(name: string): boolean {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (scope.globals[name]) return true;
|
if (scope.globals[name]) return true;
|
||||||
@ -696,7 +767,7 @@ export default class Scope {
|
|||||||
return !!this.getProgramParent().references[name];
|
return !!this.getProgramParent().references[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
isPure(node, constantsOnly?: boolean) {
|
isPure(node: t.Node, constantsOnly?: boolean) {
|
||||||
if (t.isIdentifier(node)) {
|
if (t.isIdentifier(node)) {
|
||||||
const binding = this.getBinding(node.name);
|
const binding = this.getBinding(node.name);
|
||||||
if (!binding) return false;
|
if (!binding) return false;
|
||||||
@ -718,12 +789,12 @@ export default class Scope {
|
|||||||
this.isPure(node.right, constantsOnly)
|
this.isPure(node.right, constantsOnly)
|
||||||
);
|
);
|
||||||
} else if (t.isArrayExpression(node)) {
|
} else if (t.isArrayExpression(node)) {
|
||||||
for (const elem of (node.elements: Array<Object>)) {
|
for (const elem of node.elements) {
|
||||||
if (!this.isPure(elem, constantsOnly)) return false;
|
if (!this.isPure(elem, constantsOnly)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (t.isObjectExpression(node)) {
|
} else if (t.isObjectExpression(node)) {
|
||||||
for (const prop of (node.properties: Array<Object>)) {
|
for (const prop of node.properties) {
|
||||||
if (!this.isPure(prop, constantsOnly)) return false;
|
if (!this.isPure(prop, constantsOnly)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -732,6 +803,7 @@ export default class Scope {
|
|||||||
if (node.kind === "get" || node.kind === "set") return false;
|
if (node.kind === "get" || node.kind === "set") return false;
|
||||||
return true;
|
return true;
|
||||||
} else if (t.isProperty(node)) {
|
} else if (t.isProperty(node)) {
|
||||||
|
// @ts-expect-error todo(flow->ts): computed in not present on private properties
|
||||||
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
||||||
return this.isPure(node.value, constantsOnly);
|
return this.isPure(node.value, constantsOnly);
|
||||||
} else if (t.isUnaryExpression(node)) {
|
} else if (t.isUnaryExpression(node)) {
|
||||||
@ -743,7 +815,7 @@ export default class Scope {
|
|||||||
this.isPure(node.quasi, constantsOnly)
|
this.isPure(node.quasi, constantsOnly)
|
||||||
);
|
);
|
||||||
} else if (t.isTemplateLiteral(node)) {
|
} else if (t.isTemplateLiteral(node)) {
|
||||||
for (const expression of (node.expressions: Array<Object>)) {
|
for (const expression of node.expressions) {
|
||||||
if (!this.isPure(expression, constantsOnly)) return false;
|
if (!this.isPure(expression, constantsOnly)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -756,7 +828,7 @@ export default class Scope {
|
|||||||
* Set some arbitrary data on the current scope.
|
* Set some arbitrary data on the current scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setData(key, val) {
|
setData(key: string, val: any) {
|
||||||
return (this.data[key] = val);
|
return (this.data[key] = val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,8 +836,8 @@ export default class Scope {
|
|||||||
* Recursively walk up scope tree looking for the data `key`.
|
* Recursively walk up scope tree looking for the data `key`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
getData(key) {
|
getData(key: string): any {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
const data = scope.data[key];
|
const data = scope.data[key];
|
||||||
if (data != null) return data;
|
if (data != null) return data;
|
||||||
@ -777,8 +849,8 @@ export default class Scope {
|
|||||||
* remove it.
|
* remove it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
removeData(key) {
|
removeData(key: string) {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
const data = scope.data[key];
|
const data = scope.data[key];
|
||||||
if (data != null) scope.data[key] = null;
|
if (data != null) scope.data[key] = null;
|
||||||
@ -820,7 +892,7 @@ export default class Scope {
|
|||||||
const programParent = this.getProgramParent();
|
const programParent = this.getProgramParent();
|
||||||
if (programParent.crawling) return;
|
if (programParent.crawling) return;
|
||||||
|
|
||||||
const state = {
|
const state: CollectVisitorState = {
|
||||||
references: [],
|
references: [],
|
||||||
constantViolations: [],
|
constantViolations: [],
|
||||||
assignments: [],
|
assignments: [],
|
||||||
@ -860,11 +932,11 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(opts: {
|
push(opts: {
|
||||||
id: Object,
|
id: t.LVal;
|
||||||
init: ?Object,
|
init?: t.Expression;
|
||||||
unique: ?boolean,
|
unique?: boolean;
|
||||||
_blockHoist: ?number,
|
_blockHoist?: number | undefined;
|
||||||
kind: "var" | "let",
|
kind?: "var" | "let";
|
||||||
}) {
|
}) {
|
||||||
let path = this.path;
|
let path = this.path;
|
||||||
|
|
||||||
@ -878,6 +950,7 @@ export default class Scope {
|
|||||||
|
|
||||||
if (path.isLoop() || path.isCatchClause() || path.isFunction()) {
|
if (path.isLoop() || path.isCatchClause() || path.isFunction()) {
|
||||||
path.ensureBlock();
|
path.ensureBlock();
|
||||||
|
// @ts-expect-error todo(flow->ts): improve types
|
||||||
path = path.get("body");
|
path = path.get("body");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,6 +963,7 @@ export default class Scope {
|
|||||||
|
|
||||||
if (!declarPath) {
|
if (!declarPath) {
|
||||||
const declar = t.variableDeclaration(kind, []);
|
const declar = t.variableDeclaration(kind, []);
|
||||||
|
// @ts-expect-error todo(flow->ts): avoid modifying nodes
|
||||||
declar._blockHoist = blockHoist;
|
declar._blockHoist = blockHoist;
|
||||||
|
|
||||||
[declarPath] = path.unshiftContainer("body", [declar]);
|
[declarPath] = path.unshiftContainer("body", [declar]);
|
||||||
@ -906,7 +980,7 @@ export default class Scope {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
getProgramParent() {
|
getProgramParent() {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
if (scope.path.isProgram()) {
|
if (scope.path.isProgram()) {
|
||||||
return scope;
|
return scope;
|
||||||
@ -919,8 +993,8 @@ export default class Scope {
|
|||||||
* Walk up the scope tree until we hit either a Function or return null.
|
* Walk up the scope tree until we hit either a Function or return null.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
getFunctionParent() {
|
getFunctionParent(): Scope | null {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
if (scope.path.isFunctionParent()) {
|
if (scope.path.isFunctionParent()) {
|
||||||
return scope;
|
return scope;
|
||||||
@ -935,7 +1009,7 @@ export default class Scope {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
getBlockParent() {
|
getBlockParent() {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
if (scope.path.isBlockParent()) {
|
if (scope.path.isBlockParent()) {
|
||||||
return scope;
|
return scope;
|
||||||
@ -950,10 +1024,10 @@ export default class Scope {
|
|||||||
* Walks the scope tree and gathers **all** bindings.
|
* Walks the scope tree and gathers **all** bindings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
getAllBindings(): Object {
|
getAllBindings(): any {
|
||||||
const ids = Object.create(null);
|
const ids = Object.create(null);
|
||||||
|
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
for (const key of Object.keys(scope.bindings)) {
|
for (const key of Object.keys(scope.bindings)) {
|
||||||
if (key in ids === false) {
|
if (key in ids === false) {
|
||||||
@ -970,11 +1044,11 @@ export default class Scope {
|
|||||||
* Walks the scope tree and gathers all declarations of `kind`.
|
* Walks the scope tree and gathers all declarations of `kind`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
getAllBindingsOfKind(): Object {
|
getAllBindingsOfKind(...kinds: string[]): any {
|
||||||
const ids = Object.create(null);
|
const ids = Object.create(null);
|
||||||
|
|
||||||
for (const kind of (arguments: Array)) {
|
for (const kind of kinds) {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
for (const name of Object.keys(scope.bindings)) {
|
for (const name of Object.keys(scope.bindings)) {
|
||||||
const binding = scope.bindings[name];
|
const binding = scope.bindings[name];
|
||||||
@ -987,12 +1061,12 @@ export default class Scope {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
bindingIdentifierEquals(name: string, node: Object): boolean {
|
bindingIdentifierEquals(name: string, node: t.Node): boolean {
|
||||||
return this.getBindingIdentifier(name) === node;
|
return this.getBindingIdentifier(name) === node;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBinding(name: string) {
|
getBinding(name: string): Binding | undefined {
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
let previousPath;
|
let previousPath;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -1016,15 +1090,17 @@ export default class Scope {
|
|||||||
} while ((scope = scope.parent));
|
} while ((scope = scope.parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
getOwnBinding(name: string) {
|
getOwnBinding(name: string): Binding | undefined {
|
||||||
return this.bindings[name];
|
return this.bindings[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
getBindingIdentifier(name: string) {
|
// todo: return probably can be undefined…
|
||||||
|
getBindingIdentifier(name: string): t.Identifier {
|
||||||
return this.getBinding(name)?.identifier;
|
return this.getBinding(name)?.identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
getOwnBindingIdentifier(name: string) {
|
// todo: flow->ts return probably can be undefined
|
||||||
|
getOwnBindingIdentifier(name: string): t.Identifier {
|
||||||
const binding = this.bindings[name];
|
const binding = this.bindings[name];
|
||||||
return binding?.identifier;
|
return binding?.identifier;
|
||||||
}
|
}
|
||||||
@ -1051,7 +1127,7 @@ export default class Scope {
|
|||||||
* Move a binding of `name` to another `scope`.
|
* Move a binding of `name` to another `scope`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
moveBindingTo(name, scope) {
|
moveBindingTo(name: string, scope: Scope) {
|
||||||
const info = this.getBinding(name);
|
const info = this.getBinding(name);
|
||||||
if (info) {
|
if (info) {
|
||||||
info.scope.removeOwnBinding(name);
|
info.scope.removeOwnBinding(name);
|
||||||
@ -1069,7 +1145,7 @@ export default class Scope {
|
|||||||
this.getBinding(name)?.scope.removeOwnBinding(name);
|
this.getBinding(name)?.scope.removeOwnBinding(name);
|
||||||
|
|
||||||
// clear uids with this name - https://github.com/babel/babel/issues/2101
|
// clear uids with this name - https://github.com/babel/babel/issues/2101
|
||||||
let scope = this;
|
let scope: Scope = this;
|
||||||
do {
|
do {
|
||||||
if (scope.uids[name]) {
|
if (scope.uids[name]) {
|
||||||
scope.uids[name] = false;
|
scope.uids[name] = false;
|
||||||
@ -1,8 +1,9 @@
|
|||||||
import Binding from "../binding";
|
import Binding from "../binding";
|
||||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
import type { Visitor } from "../../types";
|
||||||
|
|
||||||
const renameVisitor = {
|
const renameVisitor: Visitor<Renamer> = {
|
||||||
ReferencedIdentifier({ node }, state) {
|
ReferencedIdentifier({ node }, state) {
|
||||||
if (node.name === state.oldName) {
|
if (node.name === state.oldName) {
|
||||||
node.name = state.newName;
|
node.name = state.newName;
|
||||||
@ -135,11 +136,6 @@ export default class Renamer {
|
|||||||
this.binding.identifier.name = newName;
|
this.binding.identifier.name = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding.type === "hoisted") {
|
|
||||||
// https://github.com/babel/babel/issues/2435
|
|
||||||
// todo: hoist and convert function to a let
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentDeclar) {
|
if (parentDeclar) {
|
||||||
this.maybeConvertFromClassFunctionDeclaration(parentDeclar);
|
this.maybeConvertFromClassFunctionDeclaration(parentDeclar);
|
||||||
this.maybeConvertFromClassFunctionExpression(parentDeclar);
|
this.maybeConvertFromClassFunctionExpression(parentDeclar);
|
||||||
31
packages/babel-traverse/src/types.ts
Normal file
31
packages/babel-traverse/src/types.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import * as t from "@babel/types";
|
||||||
|
import { NodePath } from "./index";
|
||||||
|
import { VirtualTypeAliases } from "./path/generated/virtual-types";
|
||||||
|
|
||||||
|
export type Visitor<S = {}> = VisitNodeObject<S, t.Node> &
|
||||||
|
{
|
||||||
|
[Type in t.Node["type"]]?: VisitNode<S, Extract<t.Node, { type: Type }>>;
|
||||||
|
} &
|
||||||
|
{
|
||||||
|
[K in keyof t.Aliases]?: VisitNode<S, t.Aliases[K]>;
|
||||||
|
} &
|
||||||
|
{
|
||||||
|
[K in keyof VirtualTypeAliases]?: VisitNode<S, VirtualTypeAliases[K]>;
|
||||||
|
} & {
|
||||||
|
[k: string]: VisitNode<S, t.Node>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type VisitNode<S, P extends t.Node> =
|
||||||
|
| VisitNodeFunction<S, P>
|
||||||
|
| VisitNodeObject<S, P>;
|
||||||
|
|
||||||
|
export type VisitNodeFunction<S, P extends t.Node> = (
|
||||||
|
this: S,
|
||||||
|
path: NodePath<P>,
|
||||||
|
state: S,
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export interface VisitNodeObject<S, P extends t.Node> {
|
||||||
|
enter?: VisitNodeFunction<S, P>;
|
||||||
|
exit?: VisitNodeFunction<S, P>;
|
||||||
|
}
|
||||||
@ -50,7 +50,7 @@ export function explode(visitor) {
|
|||||||
ensureCallbackArrays(visitor);
|
ensureCallbackArrays(visitor);
|
||||||
|
|
||||||
// add type wrappers
|
// add type wrappers
|
||||||
for (const nodeType of (Object.keys(visitor): Array)) {
|
for (const nodeType of Object.keys(visitor)) {
|
||||||
if (shouldIgnoreKey(nodeType)) continue;
|
if (shouldIgnoreKey(nodeType)) continue;
|
||||||
|
|
||||||
const wrapper = virtualTypes[nodeType];
|
const wrapper = virtualTypes[nodeType];
|
||||||
@ -66,7 +66,7 @@ export function explode(visitor) {
|
|||||||
delete visitor[nodeType];
|
delete visitor[nodeType];
|
||||||
|
|
||||||
if (wrapper.types) {
|
if (wrapper.types) {
|
||||||
for (const type of (wrapper.types: Array<string>)) {
|
for (const type of wrapper.types) {
|
||||||
// merge the visitor if necessary or just put it back in
|
// merge the visitor if necessary or just put it back in
|
||||||
if (visitor[type]) {
|
if (visitor[type]) {
|
||||||
mergePair(visitor[type], fns);
|
mergePair(visitor[type], fns);
|
||||||
@ -85,7 +85,7 @@ export function explode(visitor) {
|
|||||||
|
|
||||||
const fns = visitor[nodeType];
|
const fns = visitor[nodeType];
|
||||||
|
|
||||||
let aliases: ?Array<string> = t.FLIPPED_ALIAS_KEYS[nodeType];
|
let aliases: Array<string> | undefined = t.FLIPPED_ALIAS_KEYS[nodeType];
|
||||||
|
|
||||||
const deprecratedKey = t.DEPRECATED_KEYS[nodeType];
|
const deprecratedKey = t.DEPRECATED_KEYS[nodeType];
|
||||||
if (deprecratedKey) {
|
if (deprecratedKey) {
|
||||||
@ -176,9 +176,9 @@ function validateVisitorMethods(path, val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function merge(
|
export function merge(
|
||||||
visitors: Array,
|
visitors: any[],
|
||||||
states: Array = [],
|
states: any[] = [],
|
||||||
wrapper?: ?Function,
|
wrapper?: Function | null,
|
||||||
) {
|
) {
|
||||||
const rootVisitor = {};
|
const rootVisitor = {};
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ export function merge(
|
|||||||
return rootVisitor;
|
return rootVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapWithStateOrWrapper(oldVisitor, state, wrapper: ?Function) {
|
function wrapWithStateOrWrapper(oldVisitor, state, wrapper?: Function | null) {
|
||||||
const newVisitor = {};
|
const newVisitor = {};
|
||||||
|
|
||||||
for (const key of Object.keys(oldVisitor)) {
|
for (const key of Object.keys(oldVisitor)) {
|
||||||
@ -182,9 +182,9 @@ describe("modification", function () {
|
|||||||
const tagName = path.node.openingElement.name.name;
|
const tagName = path.node.openingElement.name.name;
|
||||||
if (tagName !== "span") return;
|
if (tagName !== "span") return;
|
||||||
path.insertBefore(
|
path.insertBefore(
|
||||||
t.JSXElement(
|
t.jsxElement(
|
||||||
t.JSXOpeningElement(t.JSXIdentifier("div"), [], false),
|
t.jsxOpeningElement(t.jsxIdentifier("div"), [], false),
|
||||||
t.JSXClosingElement(t.JSXIdentifier("div")),
|
t.jsxClosingElement(t.jsxIdentifier("div")),
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -292,9 +292,9 @@ describe("modification", function () {
|
|||||||
const tagName = path.node.openingElement.name.name;
|
const tagName = path.node.openingElement.name.name;
|
||||||
if (tagName !== "span") return;
|
if (tagName !== "span") return;
|
||||||
path.insertAfter(
|
path.insertAfter(
|
||||||
t.JSXElement(
|
t.jsxElement(
|
||||||
t.JSXOpeningElement(t.JSXIdentifier("div"), [], false),
|
t.jsxOpeningElement(t.jsxIdentifier("div"), [], false),
|
||||||
t.JSXClosingElement(t.JSXIdentifier("div")),
|
t.jsxClosingElement(t.jsxIdentifier("div")),
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -40,9 +40,9 @@ export default function traverse<T>(
|
|||||||
|
|
||||||
function traverseSimpleImpl<T>(
|
function traverseSimpleImpl<T>(
|
||||||
node: any,
|
node: any,
|
||||||
enter: Function | undefined | null,
|
enter: Function | undefined,
|
||||||
exit: Function | undefined | null,
|
exit: Function | undefined,
|
||||||
state: T | undefined | null,
|
state: T | undefined,
|
||||||
ancestors: TraversalAncestors,
|
ancestors: TraversalAncestors,
|
||||||
) {
|
) {
|
||||||
const keys = VISITOR_KEYS[node.type];
|
const keys = VISITOR_KEYS[node.type];
|
||||||
|
|||||||
@ -14,10 +14,7 @@ export default function isType(
|
|||||||
/**
|
/**
|
||||||
* Test if a `nodeType` is a `targetType` or if `targetType` is an alias of `nodeType`.
|
* Test if a `nodeType` is a `targetType` or if `targetType` is an alias of `nodeType`.
|
||||||
*/
|
*/
|
||||||
export default function isType(
|
export default function isType(nodeType: string, targetType: string): boolean {
|
||||||
nodeType: string | undefined | null,
|
|
||||||
targetType: string,
|
|
||||||
): boolean {
|
|
||||||
if (nodeType === targetType) return true;
|
if (nodeType === targetType) return true;
|
||||||
|
|
||||||
// This is a fast-path. If the test above failed, but an alias key is found, then the
|
// This is a fast-path. If the test above failed, but an alias key is found, then the
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user