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) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @typedef {("asserts" | "builders" | "constants" | "validators")} HelperKind
|
||||
* @param {HelperKind} helperKind
|
||||
* @param {string} generator
|
||||
* @param {string} pkg
|
||||
* @param {string} filename
|
||||
* @param {string} message
|
||||
*/
|
||||
function generateTypeHelpers(helperKind, filename = "index.ts") {
|
||||
const dest = `./packages/babel-types/src/${helperKind}/generated/`;
|
||||
function generateHelpers(generator, dest, filename, message) {
|
||||
const formatCode = require("./scripts/utils/formatCode");
|
||||
const stream = gulp
|
||||
.src(".", { base: __dirname })
|
||||
@ -101,14 +100,9 @@ function generateTypeHelpers(helperKind, filename = "index.ts") {
|
||||
through.obj(function (file, enc, callback) {
|
||||
file.path = filename;
|
||||
file.contents = Buffer.from(
|
||||
formatCode(
|
||||
require(`./packages/babel-types/scripts/generators/${helperKind}`)(
|
||||
filename
|
||||
),
|
||||
dest + file.path
|
||||
)
|
||||
formatCode(require(generator)(filename), dest + file.path)
|
||||
);
|
||||
fancyLog(`${chalk.green("✔")} Generated ${helperKind}`);
|
||||
fancyLog(`${chalk.green("✔")} Generated ${message}`);
|
||||
callback(null, file);
|
||||
})
|
||||
)
|
||||
@ -117,6 +111,35 @@ function generateTypeHelpers(helperKind, filename = "index.ts") {
|
||||
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() {
|
||||
const dest = "./packages/babel-standalone/src/generated/";
|
||||
const formatCode = require("./scripts/utils/formatCode");
|
||||
@ -383,7 +406,7 @@ const standaloneBundle = [
|
||||
];
|
||||
|
||||
gulp.task("generate-type-helpers", () => {
|
||||
fancyLog("Generating @babel/types dynamic functions");
|
||||
fancyLog("Generating @babel/types and @babel/traverse dynamic functions");
|
||||
|
||||
return Promise.all([
|
||||
generateTypeHelpers("asserts"),
|
||||
@ -392,6 +415,9 @@ gulp.task("generate-type-helpers", () => {
|
||||
generateTypeHelpers("constants"),
|
||||
generateTypeHelpers("validators"),
|
||||
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 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 * as t from "@babel/types";
|
||||
import type Scope from "./scope";
|
||||
|
||||
const testing = process.env.NODE_ENV === "test";
|
||||
|
||||
@ -12,10 +13,12 @@ export default class TraversalContext {
|
||||
}
|
||||
|
||||
declare parentPath: NodePath;
|
||||
declare scope;
|
||||
declare scope: Scope;
|
||||
declare state;
|
||||
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
|
||||
@ -30,7 +33,7 @@ export default class TraversalContext {
|
||||
if (opts[node.type]) return true;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
create(node, obj, key, listKey): NodePath {
|
||||
create(node, obj, key, listKey?): NodePath {
|
||||
// We don't need to `.setContext()` here, since `.visitQueue()` already
|
||||
// calls `.pushContext`.
|
||||
return NodePath.get({
|
||||
@ -1,10 +1,10 @@
|
||||
import type Scope from "./scope";
|
||||
|
||||
export interface HubInterface {
|
||||
getCode(): ?string;
|
||||
getScope(): ?Scope;
|
||||
addHelper(name: string): Object;
|
||||
buildError(node: Object, msg: string, Error: Class<Error>): Error;
|
||||
getCode(): string | void;
|
||||
getScope(): Scope | void;
|
||||
addHelper(name: string): any;
|
||||
buildError(node: any, msg: string, Error: new () => Error): Error;
|
||||
}
|
||||
|
||||
export default class Hub implements HubInterface {
|
||||
@ -2,7 +2,11 @@ import TraversalContext from "./context";
|
||||
import * as visitors from "./visitors";
|
||||
import * as t from "@babel/types";
|
||||
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 Scope } from "./scope";
|
||||
export { default as Hub } from "./hub";
|
||||
@ -10,15 +14,38 @@ export type { HubInterface } from "./hub";
|
||||
|
||||
export { visitors };
|
||||
|
||||
export default function traverse(
|
||||
parent: Object | Array<Object>,
|
||||
opts?: Object,
|
||||
scope?: Object,
|
||||
state: Object,
|
||||
parentPath: Object,
|
||||
export type TraverseOptions<S = t.Node> =
|
||||
| {
|
||||
scope?: Scope;
|
||||
noScope?: boolean;
|
||||
denylist?: string[];
|
||||
}
|
||||
| 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 (!opts) opts = {};
|
||||
|
||||
if (!opts.noScope && !scope) {
|
||||
if (parent.type !== "Program" && parent.type !== "File") {
|
||||
@ -39,6 +66,8 @@ export default function traverse(
|
||||
traverse.node(parent, opts, scope, state, parentPath);
|
||||
}
|
||||
|
||||
export default traverse;
|
||||
|
||||
traverse.visitors = visitors;
|
||||
traverse.verify = visitors.verify;
|
||||
traverse.explode = visitors.explode;
|
||||
@ -48,14 +77,14 @@ traverse.cheap = function (node, enter) {
|
||||
};
|
||||
|
||||
traverse.node = function (
|
||||
node: Object,
|
||||
opts: Object,
|
||||
scope: Object,
|
||||
state: Object,
|
||||
parentPath: Object,
|
||||
node: t.Node,
|
||||
opts: TraverseOptions,
|
||||
scope?: Scope,
|
||||
state?: any,
|
||||
parentPath?: NodePath,
|
||||
skipKeys?,
|
||||
) {
|
||||
const keys: Array = t.VISITOR_KEYS[node.type];
|
||||
const keys = t.VISITOR_KEYS[node.type];
|
||||
if (!keys) return;
|
||||
|
||||
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);
|
||||
|
||||
cache.path.delete(node);
|
||||
};
|
||||
|
||||
traverse.removeProperties = function (tree, opts) {
|
||||
traverse.removeProperties = function (tree, opts?) {
|
||||
t.traverseFast(tree, traverse.clearNode, opts);
|
||||
return tree;
|
||||
};
|
||||
|
||||
function hasDenylistedType(path, state) {
|
||||
function hasDenylistedType(path: NodePath, state) {
|
||||
if (path.node.type === state.type) {
|
||||
state.has = true;
|
||||
path.stop();
|
||||
@ -84,8 +113,8 @@ function hasDenylistedType(path, state) {
|
||||
}
|
||||
|
||||
traverse.hasType = function (
|
||||
tree: Object,
|
||||
type: Object,
|
||||
tree: any,
|
||||
type: any,
|
||||
denylistTypes?: Array<string>,
|
||||
): boolean {
|
||||
// the node we're searching in is denylisted
|
||||
@ -10,7 +10,9 @@ import NodePath from "./index";
|
||||
* truthy value.
|
||||
*/
|
||||
|
||||
export function findParent(callback): ?NodePath {
|
||||
export function findParent(
|
||||
callback: (path: NodePath) => boolean,
|
||||
): NodePath | null {
|
||||
let path = this;
|
||||
while ((path = path.parentPath)) {
|
||||
if (callback(path)) return path;
|
||||
@ -24,7 +26,10 @@ export function findParent(callback): ?NodePath {
|
||||
* 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;
|
||||
do {
|
||||
if (callback(path)) return path;
|
||||
@ -36,15 +41,15 @@ export function find(callback): ?NodePath {
|
||||
* Get the parent function of the current path.
|
||||
*/
|
||||
|
||||
export function getFunctionParent(): ?NodePath {
|
||||
return this.findParent(p => p.isFunction());
|
||||
export function getFunctionParent(this: NodePath): NodePath<t.Function> | null {
|
||||
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.
|
||||
*/
|
||||
|
||||
export function getStatementParent(): NodePath {
|
||||
export function getStatementParent(this: NodePath): NodePath<t.Statement> {
|
||||
let path = this;
|
||||
|
||||
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(
|
||||
this: NodePath,
|
||||
paths: Array<NodePath>,
|
||||
): NodePath {
|
||||
return this.getDeepestCommonAncestorFrom(
|
||||
@ -84,7 +90,7 @@ export function getEarliestCommonAncestorFrom(
|
||||
let earliest;
|
||||
const keys = t.VISITOR_KEYS[deepest.type];
|
||||
|
||||
for (const ancestry of (ancestries: Array)) {
|
||||
for (const ancestry of ancestries) {
|
||||
const path = ancestry[i + 1];
|
||||
|
||||
// first path
|
||||
@ -104,7 +110,7 @@ export function getEarliestCommonAncestorFrom(
|
||||
|
||||
// handle keys
|
||||
const earliestKeyIndex = keys.indexOf(earliest.parentKey);
|
||||
const currentKeyIndex = keys.indexOf(path.parentKey);
|
||||
const currentKeyIndex = keys.indexOf(path.parentKey as string);
|
||||
if (earliestKeyIndex > currentKeyIndex) {
|
||||
// key appears before so it's earlier
|
||||
earliest = path;
|
||||
@ -123,8 +129,9 @@ export function getEarliestCommonAncestorFrom(
|
||||
*/
|
||||
|
||||
export function getDeepestCommonAncestorFrom(
|
||||
this: NodePath,
|
||||
paths: Array<NodePath>,
|
||||
filter?: Function,
|
||||
filter?: (deepest: t.Node, i: number, ancestries: NodePath[][]) => NodePath,
|
||||
): NodePath {
|
||||
if (!paths.length) {
|
||||
return this;
|
||||
@ -142,7 +149,7 @@ export function getDeepestCommonAncestorFrom(
|
||||
|
||||
// get the ancestors of the path, breaking when the parent exceeds ourselves
|
||||
const ancestries = paths.map(path => {
|
||||
const ancestry = [];
|
||||
const ancestry: NodePath[] = [];
|
||||
|
||||
do {
|
||||
ancestry.unshift(path);
|
||||
@ -163,7 +170,7 @@ export function getDeepestCommonAncestorFrom(
|
||||
depthLoop: for (let i = 0; i < minDepth; i++) {
|
||||
const shouldMatch = first[i];
|
||||
|
||||
for (const ancestry of (ancestries: Array)) {
|
||||
for (const ancestry of ancestries) {
|
||||
if (ancestry[i] !== shouldMatch) {
|
||||
// we've hit a snag
|
||||
break depthLoop;
|
||||
@ -192,7 +199,7 @@ export function getDeepestCommonAncestorFrom(
|
||||
* NOTE: The current node path is included in this.
|
||||
*/
|
||||
|
||||
export function getAncestry(): Array<NodePath> {
|
||||
export function getAncestry(this: NodePath): Array<NodePath> {
|
||||
let path = this;
|
||||
const paths = [];
|
||||
do {
|
||||
@ -204,21 +211,21 @@ export function getAncestry(): Array<NodePath> {
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
export function inType(): boolean {
|
||||
export function inType(this: NodePath, ...candidateTypes: string[]): boolean {
|
||||
let path = this;
|
||||
while (path) {
|
||||
for (const type of (arguments: Array)) {
|
||||
for (const type of candidateTypes) {
|
||||
if (path.node.type === type) return true;
|
||||
}
|
||||
path = path.parentPath;
|
||||
@ -1,11 +1,12 @@
|
||||
// This file contains methods responsible for dealing with comments.
|
||||
import * as t from "@babel/types";
|
||||
import type NodePath from "./index";
|
||||
|
||||
/**
|
||||
* Share comments amongst siblings.
|
||||
*/
|
||||
|
||||
export function shareCommentsWithSiblings() {
|
||||
export function shareCommentsWithSiblings(this: NodePath) {
|
||||
// NOTE: this assumes numbered keys
|
||||
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);
|
||||
}
|
||||
|
||||
@ -35,6 +41,10 @@ export function addComment(type: string, content: string, line?: boolean) {
|
||||
* 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);
|
||||
}
|
||||
@ -2,8 +2,10 @@
|
||||
|
||||
import traverse 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;
|
||||
|
||||
this.debug(key);
|
||||
@ -19,7 +21,7 @@ export function call(key): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function _call(fns?: Array<Function>): boolean {
|
||||
export function _call(this: NodePath, fns?: Array<Function>): boolean {
|
||||
if (!fns) return false;
|
||||
|
||||
for (const fn of fns) {
|
||||
@ -51,7 +53,7 @@ export function _call(fns?: Array<Function>): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isDenylisted(): boolean {
|
||||
export function isDenylisted(this: NodePath): boolean {
|
||||
const denylist = this.opts.denylist ?? this.opts.blacklist;
|
||||
return denylist && denylist.indexOf(this.node.type) > -1;
|
||||
}
|
||||
@ -59,7 +61,7 @@ export function isDenylisted(): boolean {
|
||||
// TODO: Remove in Babel 8
|
||||
export { isDenylisted as isBlacklisted };
|
||||
|
||||
export function visit(): boolean {
|
||||
export function visit(this: NodePath): boolean {
|
||||
if (!this.node) {
|
||||
return false;
|
||||
}
|
||||
@ -97,23 +99,23 @@ export function visit(): boolean {
|
||||
return this.shouldStop;
|
||||
}
|
||||
|
||||
export function skip() {
|
||||
export function skip(this: NodePath) {
|
||||
this.shouldSkip = true;
|
||||
}
|
||||
|
||||
export function skipKey(key) {
|
||||
export function skipKey(this: NodePath, key: string) {
|
||||
if (this.skipKeys == null) {
|
||||
this.skipKeys = {};
|
||||
}
|
||||
this.skipKeys[key] = true;
|
||||
}
|
||||
|
||||
export function stop() {
|
||||
export function stop(this: NodePath) {
|
||||
// this.shouldSkip = true; this.shouldStop = true;
|
||||
this._traverseFlags |= SHOULD_SKIP | SHOULD_STOP;
|
||||
}
|
||||
|
||||
export function setScope() {
|
||||
export function setScope(this: NodePath) {
|
||||
if (this.opts && this.opts.noScope) return;
|
||||
|
||||
let path = this.parentPath;
|
||||
@ -129,7 +131,7 @@ export function setScope() {
|
||||
if (this.scope) this.scope.init();
|
||||
}
|
||||
|
||||
export function setContext(context) {
|
||||
export function setContext(this: NodePath, context?: TraversalContext) {
|
||||
if (this.skipKeys != null) {
|
||||
this.skipKeys = {};
|
||||
}
|
||||
@ -153,7 +155,7 @@ export function setContext(context) {
|
||||
* for the new values.
|
||||
*/
|
||||
|
||||
export function resync() {
|
||||
export function resync(this: NodePath) {
|
||||
if (this.removed) return;
|
||||
|
||||
this._resyncParent();
|
||||
@ -162,13 +164,13 @@ export function resync() {
|
||||
//this._resyncRemoved();
|
||||
}
|
||||
|
||||
export function _resyncParent() {
|
||||
export function _resyncParent(this: NodePath) {
|
||||
if (this.parentPath) {
|
||||
this.parent = this.parentPath.node;
|
||||
}
|
||||
}
|
||||
|
||||
export function _resyncKey() {
|
||||
export function _resyncKey(this: NodePath) {
|
||||
if (!this.container) return;
|
||||
|
||||
if (this.node === this.container[this.key]) return;
|
||||
@ -194,7 +196,7 @@ export function _resyncKey() {
|
||||
this.key = null;
|
||||
}
|
||||
|
||||
export function _resyncList() {
|
||||
export function _resyncList(this: NodePath) {
|
||||
if (!this.parent || !this.inList) return;
|
||||
|
||||
const newContainer = this.parent[this.listKey];
|
||||
@ -204,7 +206,7 @@ export function _resyncList() {
|
||||
this.container = newContainer || null;
|
||||
}
|
||||
|
||||
export function _resyncRemoved() {
|
||||
export function _resyncRemoved(this: NodePath) {
|
||||
if (
|
||||
this.key == null ||
|
||||
!this.container ||
|
||||
@ -214,7 +216,7 @@ export function _resyncRemoved() {
|
||||
}
|
||||
}
|
||||
|
||||
export function popContext() {
|
||||
export function popContext(this: NodePath) {
|
||||
this.contexts.pop();
|
||||
if (this.contexts.length > 0) {
|
||||
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.setContext(context);
|
||||
}
|
||||
|
||||
export function setup(parentPath, container, listKey, key) {
|
||||
export function setup(this: NodePath, parentPath, container, listKey, key) {
|
||||
this.listKey = listKey;
|
||||
this.container = container;
|
||||
|
||||
@ -236,13 +238,13 @@ export function setup(parentPath, container, listKey, key) {
|
||||
this.setKey(key);
|
||||
}
|
||||
|
||||
export function setKey(key) {
|
||||
export function setKey(this: NodePath, key) {
|
||||
this.key = key;
|
||||
this.node = this.container[this.key];
|
||||
this.type = this.node?.type;
|
||||
}
|
||||
|
||||
export function requeue(pathToQueue = this) {
|
||||
export function requeue(this: NodePath, pathToQueue = this) {
|
||||
if (pathToQueue.removed) return;
|
||||
|
||||
// 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 contexts = this.contexts;
|
||||
while (!contexts.length) {
|
||||
@ -2,27 +2,31 @@
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import nameFunction from "@babel/helper-function-name";
|
||||
import type NodePath from "./index";
|
||||
|
||||
export function toComputedKey(): Object {
|
||||
const node = this.node;
|
||||
|
||||
export function toComputedKey(this: NodePath) {
|
||||
let key;
|
||||
if (this.isMemberExpression()) {
|
||||
key = node.property;
|
||||
key = this.node.property;
|
||||
} else if (this.isProperty() || this.isMethod()) {
|
||||
key = node.key;
|
||||
key = this.node.key;
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
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 bodyNode = body.node;
|
||||
|
||||
@ -37,7 +41,7 @@ export function ensureBlock() {
|
||||
return bodyNode;
|
||||
}
|
||||
|
||||
const statements = [];
|
||||
const statements: Array<t.Statement> = [];
|
||||
|
||||
let stringPath = "body";
|
||||
let key;
|
||||
@ -50,15 +54,15 @@ export function ensureBlock() {
|
||||
stringPath += ".body.0";
|
||||
if (this.isFunction()) {
|
||||
key = "argument";
|
||||
statements.push(t.returnStatement(body.node));
|
||||
statements.push(t.returnStatement(body.node as t.Expression));
|
||||
} else {
|
||||
key = "expression";
|
||||
statements.push(t.expressionStatement(body.node));
|
||||
statements.push(t.expressionStatement(body.node as t.Expression));
|
||||
}
|
||||
}
|
||||
|
||||
this.node.body = t.blockStatement(statements);
|
||||
const parentPath = this.get(stringPath);
|
||||
const parentPath = this.get(stringPath) as NodePath;
|
||||
body.setup(
|
||||
parentPath,
|
||||
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.
|
||||
*/
|
||||
export function arrowFunctionToShadowed() {
|
||||
export function arrowFunctionToShadowed(this: NodePath) {
|
||||
if (!this.isArrowFunctionExpression()) return;
|
||||
|
||||
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"
|
||||
* to continue behaving as expected.
|
||||
*/
|
||||
export function unwrapFunctionEnvironment() {
|
||||
export function unwrapFunctionEnvironment(this: NodePath) {
|
||||
if (
|
||||
!this.isArrowFunctionExpression() &&
|
||||
!this.isFunctionExpression() &&
|
||||
@ -101,10 +105,10 @@ export function unwrapFunctionEnvironment() {
|
||||
/**
|
||||
* Convert a given arrow function into a normal ES5 function expression.
|
||||
*/
|
||||
export function arrowFunctionToExpression({
|
||||
allowInsertArrow = true,
|
||||
specCompliant = false,
|
||||
} = {}) {
|
||||
export function arrowFunctionToExpression(
|
||||
this: NodePath,
|
||||
{ allowInsertArrow = true, specCompliant = false } = {},
|
||||
) {
|
||||
if (!this.isArrowFunctionExpression()) {
|
||||
throw this.buildCodeFrameError(
|
||||
"Cannot convert non-arrow function to a function expression.",
|
||||
@ -118,6 +122,7 @@ export function arrowFunctionToExpression({
|
||||
);
|
||||
|
||||
this.ensureBlock();
|
||||
// @ts-expect-error todo(flow->ts): avoid mutating nodes
|
||||
this.node.type = "FunctionExpression";
|
||||
if (specCompliant) {
|
||||
const checkBinding = thisBinding
|
||||
@ -392,7 +397,7 @@ function standardizeSuperProperty(superProp) {
|
||||
? superProp.scope.generateDeclaredUidIdentifier("prop")
|
||||
: null;
|
||||
|
||||
const parts = [
|
||||
const parts: t.Expression[] = [
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
tmp,
|
||||
@ -23,7 +23,7 @@ const INVALID_METHODS = ["random"];
|
||||
*
|
||||
*/
|
||||
|
||||
export function evaluateTruthy(): boolean {
|
||||
export function evaluateTruthy(this: NodePath): boolean {
|
||||
const res = this.evaluate();
|
||||
if (res.confident) return !!res.value;
|
||||
}
|
||||
@ -45,7 +45,7 @@ function deopt(path, state) {
|
||||
* var g = a ? 1 : 2,
|
||||
* a = g * this.foo
|
||||
*/
|
||||
function evaluateCached(path, state) {
|
||||
function evaluateCached(path: NodePath, state) {
|
||||
const { node } = path;
|
||||
const { seen } = state;
|
||||
|
||||
@ -58,7 +58,8 @@ function evaluateCached(path, state) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const item = { resolved: false };
|
||||
// todo: create type annotation for state instead
|
||||
const item: { resolved: boolean; value?: any } = { resolved: false };
|
||||
seen.set(node, item);
|
||||
|
||||
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;
|
||||
|
||||
const { node } = path;
|
||||
|
||||
if (path.isSequenceExpression()) {
|
||||
const exprs = path.get("expressions");
|
||||
return evaluateCached(exprs[exprs.length - 1], state);
|
||||
@ -85,7 +84,7 @@ function _evaluate(path, state) {
|
||||
path.isNumericLiteral() ||
|
||||
path.isBooleanLiteral()
|
||||
) {
|
||||
return node.value;
|
||||
return path.node.value;
|
||||
}
|
||||
|
||||
if (path.isNullLiteral()) {
|
||||
@ -93,27 +92,30 @@ function _evaluate(path, state) {
|
||||
}
|
||||
|
||||
if (path.isTemplateLiteral()) {
|
||||
return evaluateQuasis(path, node.quasis, state);
|
||||
return evaluateQuasis(path, path.node.quasis, state);
|
||||
}
|
||||
|
||||
if (
|
||||
path.isTaggedTemplateExpression() &&
|
||||
path.get("tag").isMemberExpression()
|
||||
) {
|
||||
const object = path.get("tag.object");
|
||||
const object = path.get("tag.object") as NodePath;
|
||||
const {
|
||||
// @ts-expect-error todo(flow->ts): possible bug, object is can be any expression and so name might be undefined
|
||||
node: { name },
|
||||
} = object;
|
||||
const property = path.get("tag.property");
|
||||
const property = path.get("tag.property") as NodePath;
|
||||
|
||||
if (
|
||||
object.isIdentifier() &&
|
||||
name === "String" &&
|
||||
!path.scope.getBinding(name, true) &&
|
||||
property.isIdentifier &&
|
||||
// todo(flow->ts): was changed from getBinding(name, true)
|
||||
// should this be hasBinding(name, true) as the binding is never used later?
|
||||
!path.scope.getBinding(name) &&
|
||||
property.isIdentifier() &&
|
||||
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
|
||||
if (
|
||||
path.isMemberExpression() &&
|
||||
!path.parentPath.isCallExpression({ callee: node })
|
||||
!path.parentPath.isCallExpression({ callee: path.node })
|
||||
) {
|
||||
const property = path.get("property");
|
||||
const object = path.get("object");
|
||||
const property = path.get("property") as NodePath;
|
||||
const object = path.get("object") as NodePath;
|
||||
|
||||
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 type = typeof value;
|
||||
if (type === "number" || type === "string") {
|
||||
@ -150,7 +153,8 @@ function _evaluate(path, state) {
|
||||
}
|
||||
|
||||
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) {
|
||||
return deopt(binding.path, state);
|
||||
@ -163,11 +167,14 @@ function _evaluate(path, state) {
|
||||
if (binding?.hasValue) {
|
||||
return binding.value;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -181,14 +188,14 @@ function _evaluate(path, state) {
|
||||
}
|
||||
|
||||
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
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const argument = path.get("argument");
|
||||
if (
|
||||
node.operator === "typeof" &&
|
||||
path.node.operator === "typeof" &&
|
||||
(argument.isFunction() || argument.isClass())
|
||||
) {
|
||||
return "function";
|
||||
@ -196,7 +203,7 @@ function _evaluate(path, state) {
|
||||
|
||||
const arg = evaluateCached(argument, state);
|
||||
if (!state.confident) return;
|
||||
switch (node.operator) {
|
||||
switch (path.node.operator) {
|
||||
case "!":
|
||||
return !arg;
|
||||
case "+":
|
||||
@ -227,13 +234,14 @@ function _evaluate(path, state) {
|
||||
|
||||
if (path.isObjectExpression()) {
|
||||
const obj = {};
|
||||
const props: Array<NodePath> = path.get("properties");
|
||||
const props = path.get("properties");
|
||||
for (const prop of props) {
|
||||
if (prop.isObjectMethod() || prop.isSpreadElement()) {
|
||||
return deopt(prop, state);
|
||||
}
|
||||
const keyPath = prop.get("key");
|
||||
const keyPath: any = prop.get("key");
|
||||
let key = keyPath;
|
||||
// @ts-expect-error todo(flow->ts): type refinement issues ObjectMethod and SpreadElement somehow not excluded
|
||||
if (prop.node.computed) {
|
||||
key = key.evaluate();
|
||||
if (!key.confident) {
|
||||
@ -245,7 +253,8 @@ function _evaluate(path, state) {
|
||||
} else {
|
||||
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();
|
||||
if (!value.confident) {
|
||||
return deopt(value.deopt, state);
|
||||
@ -266,7 +275,7 @@ function _evaluate(path, state) {
|
||||
const right = evaluateCached(path.get("right"), state);
|
||||
const rightConfident = state.confident;
|
||||
|
||||
switch (node.operator) {
|
||||
switch (path.node.operator) {
|
||||
case "||":
|
||||
// TODO consider having a "truthy type" that doesn't bail on
|
||||
// left uncertainty but can still evaluate to truthy.
|
||||
@ -288,7 +297,7 @@ function _evaluate(path, state) {
|
||||
const right = evaluateCached(path.get("right"), state);
|
||||
if (!state.confident) return;
|
||||
|
||||
switch (node.operator) {
|
||||
switch (path.node.operator) {
|
||||
case "-":
|
||||
return left - right;
|
||||
case "+":
|
||||
@ -340,15 +349,16 @@ function _evaluate(path, state) {
|
||||
// Number(1);
|
||||
if (
|
||||
callee.isIdentifier() &&
|
||||
!path.scope.getBinding(callee.node.name, true) &&
|
||||
!path.scope.getBinding(callee.node.name) &&
|
||||
VALID_CALLEES.indexOf(callee.node.name) >= 0
|
||||
) {
|
||||
func = global[node.callee.name];
|
||||
func = global[callee.node.name];
|
||||
}
|
||||
|
||||
if (callee.isMemberExpression()) {
|
||||
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)
|
||||
if (
|
||||
@ -363,8 +373,10 @@ function _evaluate(path, state) {
|
||||
|
||||
// "abc".charCodeAt(4)
|
||||
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;
|
||||
if (type === "string" || type === "number") {
|
||||
// @ts-expect-error todo(flow->ts): consider checking ast node type instead of value type
|
||||
context = object.node.value;
|
||||
func = context[property.node.name];
|
||||
}
|
||||
@ -382,7 +394,7 @@ function _evaluate(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 i = 0;
|
||||
@ -420,10 +432,12 @@ function evaluateQuasis(path, quasis: Array<Object>, state, raw = false) {
|
||||
*
|
||||
*/
|
||||
|
||||
export function evaluate(): {
|
||||
confident: boolean,
|
||||
value: any,
|
||||
deopt?: NodePath,
|
||||
export function evaluate(
|
||||
this: NodePath,
|
||||
): {
|
||||
confident: boolean;
|
||||
value: any;
|
||||
deopt?: NodePath;
|
||||
} {
|
||||
const state = {
|
||||
confident: true,
|
||||
@ -1,24 +1,27 @@
|
||||
// @flow
|
||||
// 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 * as t from "@babel/types";
|
||||
|
||||
export function getOpposite(): ?NodePath {
|
||||
export function getOpposite(this: NodePath): NodePath | null {
|
||||
if (this.key === "left") {
|
||||
return this.getSibling("right");
|
||||
} else if (this.key === "right") {
|
||||
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());
|
||||
return paths;
|
||||
}
|
||||
|
||||
function findBreak(statements): ?NodePath {
|
||||
function findBreak(statements): NodePath | null {
|
||||
let breakStatement;
|
||||
if (!Array.isArray(statements)) {
|
||||
statements = [statements];
|
||||
@ -94,15 +97,17 @@ function completionRecordForSwitch(cases, paths) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
export function getCompletionRecords(): NodePath[] {
|
||||
export function getCompletionRecords(this: NodePath): NodePath[] {
|
||||
let paths = [];
|
||||
|
||||
if (this.isIfStatement()) {
|
||||
paths = addCompletionRecords(this.get("consequent"), paths);
|
||||
paths = addCompletionRecords(this.get("alternate"), paths);
|
||||
} else if (this.isDoExpression() || this.isFor() || this.isWhile()) {
|
||||
// @ts-expect-error(flow->ts): todo
|
||||
paths = addCompletionRecords(this.get("body"), paths);
|
||||
} else if (this.isProgram() || this.isBlockStatement()) {
|
||||
// @ts-expect-error(flow->ts): todo
|
||||
paths = addCompletionRecords(this.get("body").pop(), paths);
|
||||
} else if (this.isFunction()) {
|
||||
return this.get("body").getCompletionRecords();
|
||||
@ -120,7 +125,7 @@ export function getCompletionRecords(): NodePath[] {
|
||||
return paths;
|
||||
}
|
||||
|
||||
export function getSibling(key: string): NodePath {
|
||||
export function getSibling(this: NodePath, key: string | number): NodePath {
|
||||
return NodePath.get({
|
||||
parentPath: this.parentPath,
|
||||
parent: this.parent,
|
||||
@ -130,16 +135,19 @@ export function getSibling(key: string): NodePath {
|
||||
}).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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
export function getAllNextSiblings(): NodePath[] {
|
||||
let _key = this.key;
|
||||
export function getAllNextSiblings(this: NodePath): NodePath[] {
|
||||
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||
let _key: number = this.key;
|
||||
let sibling = this.getSibling(++_key);
|
||||
const siblings = [];
|
||||
while (sibling.node) {
|
||||
@ -149,8 +157,9 @@ export function getAllNextSiblings(): NodePath[] {
|
||||
return siblings;
|
||||
}
|
||||
|
||||
export function getAllPrevSiblings(): NodePath[] {
|
||||
let _key = this.key;
|
||||
export function getAllPrevSiblings(this: NodePath): NodePath[] {
|
||||
// @ts-expect-error todo(flow->ts) this.key could be a string
|
||||
let _key: number = this.key;
|
||||
let sibling = this.getSibling(--_key);
|
||||
const siblings = [];
|
||||
while (sibling.node) {
|
||||
@ -160,9 +169,26 @@ export function getAllPrevSiblings(): NodePath[] {
|
||||
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,
|
||||
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[] {
|
||||
if (context === true) context = this.context;
|
||||
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,
|
||||
context?: TraversalContext,
|
||||
): NodePath | NodePath[] {
|
||||
@ -204,12 +233,14 @@ export function _getKey(
|
||||
}
|
||||
|
||||
export function _getPattern(
|
||||
this: NodePath,
|
||||
parts: string[],
|
||||
context?: TraversalContext,
|
||||
): NodePath | NodePath[] {
|
||||
let path = this;
|
||||
let path: NodePath | NodePath[] = this;
|
||||
for (const part of parts) {
|
||||
if (part === ".") {
|
||||
// @ts-expect-error todo(flow-ts): Can path be an array here?
|
||||
path = path.parentPath;
|
||||
} else {
|
||||
if (Array.isArray(path)) {
|
||||
@ -222,21 +253,52 @@ export function _getPattern(
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
export { getOuterBindingIdentifiers };
|
||||
|
||||
// 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
|
||||
// returns paths
|
||||
export function getBindingIdentifierPaths(
|
||||
duplicates?: boolean = false,
|
||||
outerOnly?: boolean = false,
|
||||
): { [string]: NodePath } {
|
||||
this: NodePath,
|
||||
duplicates: boolean = false,
|
||||
outerOnly: boolean = false,
|
||||
): {
|
||||
[x: string]: NodePath;
|
||||
} {
|
||||
const path = this;
|
||||
let search = [].concat(path);
|
||||
const ids = Object.create(null);
|
||||
@ -292,7 +354,10 @@ export function getBindingIdentifierPaths(
|
||||
}
|
||||
|
||||
export function getOuterBindingIdentifierPaths(
|
||||
this: NodePath,
|
||||
duplicates?: boolean,
|
||||
): { [string]: NodePath } {
|
||||
): {
|
||||
[x: string]: NodePath;
|
||||
} {
|
||||
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 buildDebug from "debug";
|
||||
import traverse from "../index";
|
||||
import type { Visitor } from "../types";
|
||||
import Scope from "../scope";
|
||||
import * as t from "@babel/types";
|
||||
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_family from "./family";
|
||||
import * as NodePath_comments from "./comments";
|
||||
import type { NodePathAssetions } from "./generated/asserts";
|
||||
import type { NodePathValidators } from "./generated/validators";
|
||||
|
||||
const debug = buildDebug("babel");
|
||||
|
||||
@ -27,8 +30,8 @@ export const REMOVED = 1 << 0;
|
||||
export const SHOULD_STOP = 1 << 1;
|
||||
export const SHOULD_SKIP = 1 << 2;
|
||||
|
||||
export default class NodePath {
|
||||
constructor(hub: HubInterface, parent: Object) {
|
||||
class NodePath<T extends t.Node = t.Node> {
|
||||
constructor(hub: HubInterface, parent: t.Node) {
|
||||
this.parent = parent;
|
||||
this.hub = hub;
|
||||
this.data = null;
|
||||
@ -37,26 +40,40 @@ export default class NodePath {
|
||||
this.scope = null;
|
||||
}
|
||||
|
||||
declare parent: Object;
|
||||
declare parent: t.Node;
|
||||
declare hub: HubInterface;
|
||||
declare data: Object;
|
||||
declare data: object;
|
||||
declare context: TraversalContext;
|
||||
declare scope: Scope;
|
||||
|
||||
contexts: Array<TraversalContext> = [];
|
||||
state: any = null;
|
||||
opts: ?Object = null;
|
||||
opts: any = null;
|
||||
// this.shouldSkip = false; this.shouldStop = false; this.removed = false;
|
||||
_traverseFlags: number = 0;
|
||||
skipKeys: ?Object = null;
|
||||
parentPath: ?NodePath = null;
|
||||
container: ?Object | Array<Object> = null;
|
||||
listKey: ?string = null;
|
||||
key: ?string = null;
|
||||
node: ?Object = null;
|
||||
type: ?string = null;
|
||||
skipKeys: any = null;
|
||||
parentPath: NodePath | null = null;
|
||||
container: object | null | Array<any> = null;
|
||||
listKey: string | null = null;
|
||||
key: string | number | null = null;
|
||||
node: T = 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) {
|
||||
hub = parentPath.hub;
|
||||
}
|
||||
@ -104,22 +121,27 @@ export default class NodePath {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
set(key: string, node: Object) {
|
||||
set(key: string, node: any) {
|
||||
t.validate(this.node, key, node);
|
||||
this.node[key] = node;
|
||||
}
|
||||
|
||||
getPathLocation(): string {
|
||||
const parts = [];
|
||||
let path = this;
|
||||
let path: NodePath = this;
|
||||
do {
|
||||
let key = path.key;
|
||||
if (path.inList) key = `${path.listKey}[${key}]`;
|
||||
@ -203,7 +225,7 @@ Object.assign(
|
||||
NodePath_comments,
|
||||
);
|
||||
|
||||
for (const type of (t.TYPES: Array<string>)) {
|
||||
for (const type of t.TYPES) {
|
||||
const typeKey = `is${type}`;
|
||||
const fn = t[typeKey];
|
||||
NodePath.prototype[typeKey] = function (opts) {
|
||||
@ -227,3 +249,23 @@ for (const type of Object.keys(virtualTypes)) {
|
||||
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 t from "@babel/types";
|
||||
|
||||
@ -6,7 +6,7 @@ import * as t from "@babel/types";
|
||||
* Infer the type of the current `NodePath`.
|
||||
*/
|
||||
|
||||
export function getTypeAnnotation(): Object {
|
||||
export function getTypeAnnotation(): t.FlowType {
|
||||
if (this.typeAnnotation) return this.typeAnnotation;
|
||||
|
||||
let type = this._getTypeAnnotation() || t.anyTypeAnnotation();
|
||||
@ -23,7 +23,7 @@ const typeAnnotationInferringNodes = new WeakSet();
|
||||
* todo: split up this method
|
||||
*/
|
||||
|
||||
export function _getTypeAnnotation(): ?Object {
|
||||
export function _getTypeAnnotation(): any {
|
||||
const node = this.node;
|
||||
|
||||
if (!node) {
|
||||
@ -106,7 +106,7 @@ export function couldBeBaseType(name: string): boolean {
|
||||
if (t.isAnyTypeAnnotation(type)) return true;
|
||||
|
||||
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)) {
|
||||
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();
|
||||
right = right.getTypeAnnotation();
|
||||
const right = rightArg.getTypeAnnotation();
|
||||
|
||||
if (!t.isAnyTypeAnnotation(left) && t.isFlowBaseAnnotation(left)) {
|
||||
return right.type === left.type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isGenericType(genericName: string): boolean {
|
||||
@ -1,7 +1,8 @@
|
||||
import type NodePath from "../index";
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
// push on inferred types of violated paths
|
||||
for (const violation of (constantViolations: Array<NodePath>)) {
|
||||
for (const violation of constantViolations) {
|
||||
types.push(violation.getTypeAnnotation());
|
||||
}
|
||||
}
|
||||
@ -106,7 +107,7 @@ function getTypeAnnotationBindingConstantViolations(binding, path, name) {
|
||||
return t.createUnionTypeAnnotation(types);
|
||||
}
|
||||
|
||||
function getConstantViolationsBefore(binding, path, functions) {
|
||||
function getConstantViolationsBefore(binding: Binding, path, functions?) {
|
||||
const violations = binding.constantViolations.slice();
|
||||
violations.unshift(binding.path);
|
||||
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 right = path.get("right").resolve();
|
||||
@ -144,14 +148,14 @@ function inferAnnotationFromBinaryExpression(name, path) {
|
||||
if (operator !== "===" && operator !== "==") return;
|
||||
|
||||
//
|
||||
let typeofPath;
|
||||
let typePath;
|
||||
let typeofPath: NodePath<t.UnaryExpression>;
|
||||
let typePath: NodePath<t.Expression>;
|
||||
if (left.isUnaryExpression({ operator: "typeof" })) {
|
||||
typeofPath = left;
|
||||
typePath = right;
|
||||
typePath = right as NodePath<t.Expression>;
|
||||
} else if (right.isUnaryExpression({ operator: "typeof" })) {
|
||||
typeofPath = right;
|
||||
typePath = left;
|
||||
typePath = left as NodePath<t.Expression>;
|
||||
}
|
||||
|
||||
if (!typeofPath) return;
|
||||
@ -159,14 +163,16 @@ function inferAnnotationFromBinaryExpression(name, path) {
|
||||
if (!typeofPath.get("argument").isIdentifier({ name })) return;
|
||||
|
||||
// ensure that the type path is a Literal
|
||||
typePath = typePath.resolve();
|
||||
typePath = typePath.resolve() as NodePath<t.Expression>;
|
||||
if (!typePath.isLiteral()) return;
|
||||
|
||||
// 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;
|
||||
if (typeof typeValue !== "string") return;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
if (!ifStatement) return;
|
||||
|
||||
@ -11,6 +11,7 @@ import * as t from "@babel/types";
|
||||
*/
|
||||
|
||||
export function matchesPattern(
|
||||
this: NodePath,
|
||||
pattern: string,
|
||||
allowPartial?: boolean,
|
||||
): boolean {
|
||||
@ -22,7 +23,7 @@ export function matchesPattern(
|
||||
* 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];
|
||||
if (val && Array.isArray(val)) {
|
||||
return !!val.length;
|
||||
@ -35,7 +36,7 @@ export function has(key): boolean {
|
||||
* Description
|
||||
*/
|
||||
|
||||
export function isStatic() {
|
||||
export function isStatic(this: NodePath): boolean {
|
||||
return this.scope.isStatic(this.node);
|
||||
}
|
||||
|
||||
@ -49,7 +50,7 @@ export const is = has;
|
||||
* Opposite of `has`.
|
||||
*/
|
||||
|
||||
export function isnt(key): boolean {
|
||||
export function isnt(this: NodePath, key: string): boolean {
|
||||
return !this.has(key);
|
||||
}
|
||||
|
||||
@ -57,7 +58,7 @@ export function isnt(key): boolean {
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
export function isNodeType(type: string): boolean {
|
||||
export function isNodeType(this: NodePath, type: string): boolean {
|
||||
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.
|
||||
*/
|
||||
|
||||
export function canHaveVariableDeclarationOrExpression() {
|
||||
export function canHaveVariableDeclarationOrExpression(this: NodePath) {
|
||||
return (
|
||||
(this.key === "init" || this.key === "left") && this.parentPath.isFor()
|
||||
);
|
||||
@ -94,7 +95,10 @@ export function canHaveVariableDeclarationOrExpression() {
|
||||
* 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()) {
|
||||
return false;
|
||||
}
|
||||
@ -112,7 +116,10 @@ export function canSwapBetweenExpressionAndStatement(replacement) {
|
||||
* 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 first = true;
|
||||
|
||||
@ -141,14 +148,14 @@ export function isCompletionRecord(allowInsideFunction?) {
|
||||
* so we can explode it if necessary.
|
||||
*/
|
||||
|
||||
export function isStatementOrBlock() {
|
||||
export function isStatementOrBlock(this: NodePath): boolean {
|
||||
if (
|
||||
this.parentPath.isLabeledStatement() ||
|
||||
t.isBlockStatement(this.container)
|
||||
) {
|
||||
return false;
|
||||
} 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`.
|
||||
*/
|
||||
|
||||
export function referencesImport(moduleSource, importName) {
|
||||
export function referencesImport(
|
||||
this: NodePath<t.Identifier>,
|
||||
moduleSource: string,
|
||||
importName: string,
|
||||
): boolean {
|
||||
if (!this.isReferencedIdentifier()) return false;
|
||||
|
||||
const binding = this.scope.getBinding(this.node.name);
|
||||
@ -181,7 +192,10 @@ export function referencesImport(moduleSource, importName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path.isImportSpecifier() && path.node.imported.name === importName) {
|
||||
if (
|
||||
path.isImportSpecifier() &&
|
||||
t.isIdentifier(path.node.imported, { name: importName })
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -192,7 +206,7 @@ export function referencesImport(moduleSource, importName) {
|
||||
* Get the source code associated with this node.
|
||||
*/
|
||||
|
||||
export function getSource() {
|
||||
export function getSource(this: NodePath): string {
|
||||
const node = this.node;
|
||||
if (node.end) {
|
||||
const code = this.hub.getCode();
|
||||
@ -201,7 +215,7 @@ export function getSource() {
|
||||
return "";
|
||||
}
|
||||
|
||||
export function willIMaybeExecuteBefore(target) {
|
||||
export function willIMaybeExecuteBefore(this: NodePath, target): boolean {
|
||||
return this._guessExecutionStatusRelativeTo(target) !== "after";
|
||||
}
|
||||
|
||||
@ -282,6 +296,7 @@ type RelativeExecutionStatus = "before" | "after" | "unknown";
|
||||
*/
|
||||
|
||||
export function _guessExecutionStatusRelativeTo(
|
||||
this: NodePath,
|
||||
target: NodePath,
|
||||
): RelativeExecutionStatus {
|
||||
// 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
|
||||
const keys = t.VISITOR_KEYS[commonPath.type];
|
||||
const keyPosition = {
|
||||
this: keys.indexOf(divergence.this.parentKey),
|
||||
target: keys.indexOf(divergence.target.parentKey),
|
||||
this: keys.indexOf(divergence.this.parentKey as string),
|
||||
target: keys.indexOf(divergence.target.parentKey as string),
|
||||
};
|
||||
return keyPosition.target > keyPosition.this ? "before" : "after";
|
||||
}
|
||||
@ -367,6 +382,7 @@ export function _guessExecutionStatusRelativeTo(
|
||||
const executionOrderCheckedNodes = new WeakSet();
|
||||
|
||||
export function _guessExecutionStatusRelativeToDifferentFunctions(
|
||||
this: NodePath,
|
||||
target: NodePath,
|
||||
): RelativeExecutionStatus {
|
||||
if (
|
||||
@ -423,12 +439,15 @@ export function _guessExecutionStatusRelativeToDifferentFunctions(
|
||||
/**
|
||||
* Resolve a "pointer" `NodePath` to it's absolute path.
|
||||
*/
|
||||
|
||||
export function resolve(dangerous, resolved) {
|
||||
export function resolve(this: NodePath, dangerous?, resolved?) {
|
||||
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
|
||||
// todo: possibly have a max length on this just to be safe
|
||||
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
|
||||
}
|
||||
} 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);
|
||||
if (!binding) return;
|
||||
|
||||
@ -460,6 +480,7 @@ export function _resolve(dangerous?, resolved?): ?NodePath {
|
||||
return ret;
|
||||
}
|
||||
} else if (this.isTypeCastExpression()) {
|
||||
// @ ts-ignore todo: babel-types
|
||||
return this.get("expression").resolve(dangerous, resolved);
|
||||
} else if (dangerous && this.isMemberExpression()) {
|
||||
// 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();
|
||||
if (!t.isLiteral(targetKey)) return;
|
||||
|
||||
// @ts-expect-error todo(flow->ts): NullLiteral
|
||||
const targetName = targetKey.value;
|
||||
|
||||
const target = this.get("object").resolve(dangerous, resolved);
|
||||
|
||||
if (target.isObjectExpression()) {
|
||||
const props = target.get("properties");
|
||||
for (const prop of (props: Array)) {
|
||||
for (const prop of props as any[]) {
|
||||
if (!prop.isProperty()) continue;
|
||||
|
||||
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()) {
|
||||
const binding = this.scope.getBinding(this.node.name);
|
||||
if (!binding) return false;
|
||||
@ -518,7 +540,7 @@ export function isConstantExpression() {
|
||||
}
|
||||
|
||||
if (this.isUnaryExpression()) {
|
||||
if (this.get("operator").node !== "void") {
|
||||
if (this.node.operator !== "void") {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -535,7 +557,7 @@ export function isConstantExpression() {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isInStrictMode() {
|
||||
export function isInStrictMode(this: NodePath) {
|
||||
const start = this.isProgram() ? this : this.parentPath;
|
||||
|
||||
const strictParent = start.find(path => {
|
||||
@ -552,10 +574,11 @@ export function isInStrictMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let { node } = path;
|
||||
if (path.isFunction()) node = node.body;
|
||||
const body: t.BlockStatement | t.Program = path.isFunction()
|
||||
? (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") {
|
||||
return true;
|
||||
}
|
||||
@ -1,7 +1,11 @@
|
||||
import { react } 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.
|
||||
ReferencedIdentifier(path, state) {
|
||||
// Don't hoist regular JSX identifiers ('div', 'span', etc).
|
||||
@ -49,8 +53,16 @@ const referenceVisitor = {
|
||||
},
|
||||
};
|
||||
|
||||
export default class PathHoister {
|
||||
constructor(path, scope) {
|
||||
export default class PathHoister<T extends t.Node = t.Node> {
|
||||
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.
|
||||
this.breakOnScopePaths = [];
|
||||
// Storage for bindings that may affect what path we can hoist to.
|
||||
@ -131,7 +143,7 @@ export default class PathHoister {
|
||||
path = binding.path;
|
||||
|
||||
// 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) {
|
||||
path = violationPath;
|
||||
}
|
||||
@ -156,10 +168,11 @@ export default class PathHoister {
|
||||
if (this.scope === scope) return;
|
||||
|
||||
// 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++) {
|
||||
// Don't attach to something that's going to get hoisted,
|
||||
// like a default parameter
|
||||
// @ts-expect-error todo(flow->ts): avoid mutating the node, introducing new fields
|
||||
if (bodies[i].node._blockHoist) continue;
|
||||
return bodies[i];
|
||||
}
|
||||
@ -221,6 +234,7 @@ export default class PathHoister {
|
||||
// generate declaration and insert it to our point
|
||||
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 insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
|
||||
@ -234,7 +248,7 @@ export default class PathHoister {
|
||||
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
|
||||
// an expression container
|
||||
uid = t.JSXExpressionContainer(uid);
|
||||
uid = t.jsxExpressionContainer(uid);
|
||||
}
|
||||
|
||||
this.path.replaceWith(t.cloneNode(uid));
|
||||
@ -4,7 +4,7 @@ import * as t from "@babel/types";
|
||||
|
||||
export const ReferencedIdentifier = {
|
||||
types: ["Identifier", "JSXIdentifier"],
|
||||
checkPath(path: NodePath, opts?: Object): boolean {
|
||||
checkPath(path: NodePath, opts?: any): boolean {
|
||||
const { node, parent } = path;
|
||||
if (!t.isIdentifier(node, opts) && !t.isJSXMemberExpression(parent, opts)) {
|
||||
if (t.isJSXIdentifier(node, opts)) {
|
||||
@ -116,6 +116,7 @@ export const Flow = {
|
||||
} else if (t.isImportDeclaration(node)) {
|
||||
return node.importKind === "type" || node.importKind === "typeof";
|
||||
} else if (t.isExportDeclaration(node)) {
|
||||
// @ts-expect-error todo(flow->ts) `exportKind` does not exist on ExportAllDeclaration
|
||||
return node.exportKind === "type";
|
||||
} else if (t.isImportSpecifier(node)) {
|
||||
return node.importKind === "type" || node.importKind === "typeof";
|
||||
@ -150,7 +151,7 @@ export const NumericLiteralTypeAnnotation = {
|
||||
|
||||
export const ForAwaitStatement = {
|
||||
types: ["ForOfStatement"],
|
||||
checkPath({ node }: NodePath): boolean {
|
||||
checkPath({ node }: NodePath<t.ForOfStatement>): boolean {
|
||||
return node.await === true;
|
||||
},
|
||||
};
|
||||
@ -4,15 +4,16 @@ import { path as pathCache } from "../cache";
|
||||
import PathHoister from "./lib/hoister";
|
||||
import NodePath from "./index";
|
||||
import * as t from "@babel/types";
|
||||
import type Scope from "../scope";
|
||||
|
||||
/**
|
||||
* Insert the provided nodes before the current one.
|
||||
*/
|
||||
|
||||
export function insertBefore(nodes) {
|
||||
export function insertBefore(this: NodePath, nodes_: t.Node | t.Node[]) {
|
||||
this._assertUnremoved();
|
||||
|
||||
nodes = this._verifyNodeList(nodes);
|
||||
const nodes = this._verifyNodeList(nodes_);
|
||||
|
||||
const { parentPath } = this;
|
||||
|
||||
@ -28,17 +29,18 @@ export function insertBefore(nodes) {
|
||||
(parentPath.isForStatement() && this.key === "init")
|
||||
) {
|
||||
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);
|
||||
} else if (Array.isArray(this.container)) {
|
||||
return this._containerInsertBefore(nodes);
|
||||
} else if (this.isStatementOrBlock()) {
|
||||
const node = this.node as t.Statement;
|
||||
const shouldInsertCurrentNode =
|
||||
this.node &&
|
||||
(!this.isExpressionStatement() || this.node.expression != null);
|
||||
node &&
|
||||
(!this.isExpressionStatement() ||
|
||||
(node as t.ExpressionStatement).expression != null);
|
||||
|
||||
this.replaceWith(
|
||||
t.blockStatement(shouldInsertCurrentNode ? [this.node] : []),
|
||||
);
|
||||
this.replaceWith(t.blockStatement(shouldInsertCurrentNode ? [node] : []));
|
||||
return this.unshiftContainer("body", nodes);
|
||||
} else {
|
||||
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);
|
||||
|
||||
const paths = [];
|
||||
|
||||
// @ts-expect-error todo(flow->ts): this.container could be a NodePath
|
||||
this.container.splice(from, 0, ...nodes);
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const to = from + i;
|
||||
@ -78,11 +81,12 @@ export function _containerInsert(from, nodes) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
export function _containerInsertBefore(nodes) {
|
||||
export function _containerInsertBefore(this: NodePath, 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);
|
||||
}
|
||||
|
||||
@ -91,10 +95,10 @@ export function _containerInsertAfter(nodes) {
|
||||
* 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();
|
||||
|
||||
nodes = this._verifyNodeList(nodes);
|
||||
const nodes = this._verifyNodeList(nodes_);
|
||||
|
||||
const { parentPath } = this;
|
||||
if (
|
||||
@ -121,31 +125,36 @@ export function insertAfter(nodes) {
|
||||
(parentPath.isForStatement() && this.key === "init")
|
||||
) {
|
||||
if (this.node) {
|
||||
const node = this.node as t.Expression | t.VariableDeclaration;
|
||||
let { scope } = this;
|
||||
// Inserting after the computed key of a method should insert the
|
||||
// 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;
|
||||
}
|
||||
const temp = scope.generateDeclaredUidIdentifier();
|
||||
nodes.unshift(
|
||||
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)));
|
||||
}
|
||||
// @ts-expect-error todo(flow->ts): check that nodes is an array of statements
|
||||
return this.replaceExpressionWithStatements(nodes);
|
||||
} else if (Array.isArray(this.container)) {
|
||||
return this._containerInsertAfter(nodes);
|
||||
} else if (this.isStatementOrBlock()) {
|
||||
const node = this.node as t.Statement;
|
||||
const shouldInsertCurrentNode =
|
||||
this.node &&
|
||||
(!this.isExpressionStatement() || this.node.expression != null);
|
||||
node &&
|
||||
(!this.isExpressionStatement() ||
|
||||
(node as t.ExpressionStatement).expression != null);
|
||||
|
||||
this.replaceWith(
|
||||
t.blockStatement(shouldInsertCurrentNode ? [this.node] : []),
|
||||
);
|
||||
this.replaceWith(t.blockStatement(shouldInsertCurrentNode ? [node] : []));
|
||||
return this.pushContainer("body", nodes);
|
||||
} else {
|
||||
throw new Error(
|
||||
@ -159,7 +168,11 @@ export function insertAfter(nodes) {
|
||||
* 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;
|
||||
|
||||
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) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (nodes.constructor !== Array) {
|
||||
if (!Array.isArray(nodes)) {
|
||||
nodes = [nodes];
|
||||
}
|
||||
|
||||
@ -204,7 +220,11 @@ export function _verifyNodeList(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();
|
||||
|
||||
nodes = this._verifyNodeList(nodes);
|
||||
@ -222,10 +242,14 @@ export function unshiftContainer(listKey, nodes) {
|
||||
return path._containerInsertBefore(nodes);
|
||||
}
|
||||
|
||||
export function pushContainer(listKey, nodes) {
|
||||
export function pushContainer(
|
||||
this: NodePath,
|
||||
listKey: string,
|
||||
nodes: t.Node | t.Node[],
|
||||
) {
|
||||
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
|
||||
// nodes, effectively inlining it
|
||||
@ -239,15 +263,17 @@ export function pushContainer(listKey, nodes) {
|
||||
key: container.length,
|
||||
}).setContext(this.context);
|
||||
|
||||
return path.replaceWithMultiple(nodes);
|
||||
return path.replaceWithMultiple(verifiedNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hoist the current node to the highest scope possible and return a UID
|
||||
* referencing it.
|
||||
*/
|
||||
|
||||
export function hoist(scope = this.scope) {
|
||||
const hoister = new PathHoister(this, scope);
|
||||
export function hoist<T extends t.Node>(
|
||||
this: NodePath<T>,
|
||||
scope: Scope = this.scope,
|
||||
) {
|
||||
const hoister = new PathHoister<T>(this, scope);
|
||||
return hoister.run();
|
||||
}
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
import { hooks } from "./lib/removal-hooks";
|
||||
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.resync();
|
||||
@ -22,34 +22,34 @@ export function remove() {
|
||||
this._markRemoved();
|
||||
}
|
||||
|
||||
export function _removeFromScope() {
|
||||
export function _removeFromScope(this: NodePath) {
|
||||
const bindings = this.getBindingIdentifiers();
|
||||
Object.keys(bindings).forEach(name => this.scope.removeBinding(name));
|
||||
}
|
||||
|
||||
export function _callRemovalHooks() {
|
||||
for (const fn of (hooks: Array<Function>)) {
|
||||
export function _callRemovalHooks(this: NodePath) {
|
||||
for (const fn of hooks) {
|
||||
if (fn(this, this.parentPath)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
export function _remove() {
|
||||
export function _remove(this: NodePath) {
|
||||
if (Array.isArray(this.container)) {
|
||||
this.container.splice(this.key, 1);
|
||||
this.updateSiblingKeys(this.key, -1);
|
||||
this.container.splice(this.key as number, 1);
|
||||
this.updateSiblingKeys(this.key as number, -1);
|
||||
} else {
|
||||
this._replaceWith(null);
|
||||
}
|
||||
}
|
||||
|
||||
export function _markRemoved() {
|
||||
export function _markRemoved(this: NodePath) {
|
||||
// this.shouldSkip = true; this.removed = true;
|
||||
this._traverseFlags |= SHOULD_SKIP | REMOVED;
|
||||
if (this.parent) pathCache.get(this.parent).delete(this.node);
|
||||
this.node = null;
|
||||
}
|
||||
|
||||
export function _assertUnremoved() {
|
||||
export function _assertUnremoved(this: NodePath) {
|
||||
if (this.removed) {
|
||||
throw this.buildCodeFrameError(
|
||||
"NodePath has been removed so is read-only.",
|
||||
@ -22,7 +22,7 @@ const hoistVariablesVisitor = {
|
||||
|
||||
const exprs = [];
|
||||
|
||||
for (const declar of (path.node.declarations: Array<Object>)) {
|
||||
for (const declar of path.node.declarations as Array<any>) {
|
||||
if (declar.init) {
|
||||
exprs.push(
|
||||
t.expressionStatement(
|
||||
@ -44,7 +44,10 @@ const hoistVariablesVisitor = {
|
||||
* - 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();
|
||||
|
||||
nodes = this._verifyNodeList(nodes);
|
||||
@ -70,7 +73,7 @@ export function replaceWithMultiple(nodes: Array<Object>) {
|
||||
* easier to use, your transforms will be extremely brittle.
|
||||
*/
|
||||
|
||||
export function replaceWithSourceString(replacement) {
|
||||
export function replaceWithSourceString(this: NodePath, replacement) {
|
||||
this.resync();
|
||||
|
||||
try {
|
||||
@ -101,7 +104,7 @@ export function replaceWithSourceString(replacement) {
|
||||
* Replace the current node with another.
|
||||
*/
|
||||
|
||||
export function replaceWith(replacement) {
|
||||
export function replaceWith(this: NodePath, replacement: t.Node | NodePath) {
|
||||
this.resync();
|
||||
|
||||
if (this.removed) {
|
||||
@ -187,15 +190,16 @@ export function replaceWith(replacement) {
|
||||
* Description
|
||||
*/
|
||||
|
||||
export function _replaceWith(node) {
|
||||
export function _replaceWith(this: NodePath, node) {
|
||||
if (!this.container) {
|
||||
throw new ReferenceError("Container is falsy");
|
||||
}
|
||||
|
||||
if (this.inList) {
|
||||
// @ts-expect-error todo(flow->ts): check if t.validate accepts a numeric key
|
||||
t.validate(this.parent, this.key, [node]);
|
||||
} else {
|
||||
t.validate(this.parent, this.key, node);
|
||||
t.validate(this.parent, this.key as string, node);
|
||||
}
|
||||
|
||||
this.debug(`Replace with ${node?.type}`);
|
||||
@ -210,7 +214,10 @@ export function _replaceWith(node) {
|
||||
* extremely important to retain original semantics.
|
||||
*/
|
||||
|
||||
export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
||||
export function replaceExpressionWithStatements(
|
||||
this: NodePath,
|
||||
nodes: Array<t.Statement>,
|
||||
) {
|
||||
this.resync();
|
||||
|
||||
const toSequenceExpression = t.toSequenceExpression(nodes, this.scope);
|
||||
@ -225,12 +232,17 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
||||
const container = t.arrowFunctionExpression([], t.blockStatement(nodes));
|
||||
|
||||
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);
|
||||
|
||||
// add implicit returns to all ending expression statements
|
||||
const completionRecords: Array<NodePath> = this.get(
|
||||
"callee",
|
||||
).getCompletionRecords();
|
||||
const completionRecords: Array<NodePath> = (this as ThisType)
|
||||
.get("callee")
|
||||
.getCompletionRecords();
|
||||
for (const path of completionRecords) {
|
||||
if (!path.isExpressionStatement()) continue;
|
||||
|
||||
@ -239,7 +251,7 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
|
||||
let uid = loop.getData("expressionReplacementReturnUid");
|
||||
|
||||
if (!uid) {
|
||||
const callee = this.get("callee");
|
||||
const callee = (this as ThisType).get("callee");
|
||||
uid = callee.scope.generateDeclaredUidIdentifier("ret");
|
||||
callee
|
||||
.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();
|
||||
|
||||
// (() => await xxx)() -> await (async () => await xxx)();
|
||||
if (
|
||||
isParentAsync &&
|
||||
traverse.hasType(
|
||||
this.get("callee.body").node,
|
||||
(this.get("callee.body") as NodePath<t.BlockStatement>).node,
|
||||
"AwaitExpression",
|
||||
t.FUNCTION_TYPES,
|
||||
)
|
||||
) {
|
||||
callee.set("async", true);
|
||||
this.replaceWith(t.awaitExpression(this.node));
|
||||
this.replaceWith(t.awaitExpression((this as ThisType).node));
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (Array.isArray(nodes)) {
|
||||
@ -1,5 +1,16 @@
|
||||
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.
|
||||
*
|
||||
@ -12,7 +23,22 @@ import type NodePath from "../path";
|
||||
*/
|
||||
|
||||
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.scope = scope;
|
||||
this.path = path;
|
||||
@ -53,7 +79,7 @@ export default class Binding {
|
||||
* Register a constant violation with the provided `path`.
|
||||
*/
|
||||
|
||||
reassign(path: Object) {
|
||||
reassign(path: any) {
|
||||
this.constant = false;
|
||||
if (this.constantViolations.indexOf(path) !== -1) {
|
||||
return;
|
||||
@ -1,26 +1,57 @@
|
||||
import Renamer from "./lib/renamer";
|
||||
import type NodePath from "../path";
|
||||
import traverse from "../index";
|
||||
import type { TraverseOptions } from "../index";
|
||||
import Binding from "./binding";
|
||||
import globals from "globals";
|
||||
import * as t from "@babel/types";
|
||||
import { scope as scopeCache } from "../cache";
|
||||
import type { Visitor } from "../types";
|
||||
|
||||
// Recursively gathers the identifying names of a node.
|
||||
function gatherNodeParts(node: Object, parts: Array) {
|
||||
function gatherNodeParts(node: t.Node, parts: any[]) {
|
||||
switch (node?.type) {
|
||||
default:
|
||||
if (t.isModuleDeclaration(node)) {
|
||||
if (node.source) {
|
||||
if (
|
||||
(t.isExportAllDeclaration(node) ||
|
||||
t.isExportNamedDeclaration(node) ||
|
||||
t.isImportDeclaration(node)) &&
|
||||
node.source
|
||||
) {
|
||||
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);
|
||||
} else if (node.declaration) {
|
||||
} else if (
|
||||
(t.isExportDefaultDeclaration(node) ||
|
||||
t.isExportNamedDeclaration(node)) &&
|
||||
node.declaration
|
||||
) {
|
||||
gatherNodeParts(node.declaration, parts);
|
||||
}
|
||||
} 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);
|
||||
} 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);
|
||||
}
|
||||
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 (const key of (t.FOR_INIT_KEYS: Array)) {
|
||||
const declar = path.get(key);
|
||||
for (const key of t.FOR_INIT_KEYS) {
|
||||
// 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
|
||||
if (declar.isVar()) {
|
||||
const parentScope =
|
||||
@ -166,6 +203,7 @@ const collectorVisitor = {
|
||||
if (path.isBlockScoped()) return;
|
||||
|
||||
// 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()) {
|
||||
return;
|
||||
}
|
||||
@ -190,6 +228,7 @@ const collectorVisitor = {
|
||||
ExportDeclaration: {
|
||||
exit(path) {
|
||||
const { node, scope } = path;
|
||||
// @ts-expect-error todo(flow->ts) declaration is not present on ExportAllDeclaration
|
||||
const declar = node.declaration;
|
||||
if (t.isClassDeclaration(declar) || t.isFunctionDeclaration(declar)) {
|
||||
const id = declar.id;
|
||||
@ -198,7 +237,7 @@ const collectorVisitor = {
|
||||
const binding = scope.getBinding(id.name);
|
||||
if (binding) binding.reference(path);
|
||||
} 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))) {
|
||||
const binding = scope.getBinding(name);
|
||||
if (binding) binding.reference(path);
|
||||
@ -209,6 +248,7 @@ const collectorVisitor = {
|
||||
},
|
||||
|
||||
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.getBlockParent().registerDeclaration(path);
|
||||
},
|
||||
@ -245,7 +285,7 @@ const collectorVisitor = {
|
||||
|
||||
Block(path) {
|
||||
const paths = path.get("body");
|
||||
for (const bodyPath of (paths: Array)) {
|
||||
for (const bodyPath of paths) {
|
||||
if (bodyPath.isFunctionDeclaration()) {
|
||||
path.scope.getBlockParent().registerDeclaration(bodyPath);
|
||||
}
|
||||
@ -281,11 +321,25 @@ const collectorVisitor = {
|
||||
let uid = 0;
|
||||
|
||||
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
|
||||
* within.
|
||||
*/
|
||||
|
||||
constructor(path: NodePath) {
|
||||
const { node } = path;
|
||||
const cached = scopeCache.get(node);
|
||||
@ -330,11 +384,16 @@ export default class Scope {
|
||||
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: Object, opts: Object, state?) {
|
||||
traverse(node: any, opts: any, state?) {
|
||||
traverse(node, opts, this, state, this.path);
|
||||
}
|
||||
|
||||
@ -360,7 +419,7 @@ export default class Scope {
|
||||
* Generate a unique `_id1` binding.
|
||||
*/
|
||||
|
||||
generateUid(name: string = "temp") {
|
||||
generateUid(name: string = "temp"): string {
|
||||
name = t
|
||||
.toIdentifier(name)
|
||||
.replace(/^_+/, "")
|
||||
@ -395,7 +454,7 @@ export default class Scope {
|
||||
return `_${id}`;
|
||||
}
|
||||
|
||||
generateUidBasedOnNode(node: Object, defaultName?: String) {
|
||||
generateUidBasedOnNode(node: t.Node, defaultName?: string) {
|
||||
const parts = [];
|
||||
gatherNodeParts(node, parts);
|
||||
|
||||
@ -409,7 +468,7 @@ export default class Scope {
|
||||
* 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));
|
||||
}
|
||||
|
||||
@ -423,7 +482,7 @@ export default class Scope {
|
||||
* - Bound identifiers
|
||||
*/
|
||||
|
||||
isStatic(node: Object): boolean {
|
||||
isStatic(node: t.Node): boolean {
|
||||
if (t.isThisExpression(node) || t.isSuper(node)) {
|
||||
return true;
|
||||
}
|
||||
@ -444,7 +503,7 @@ export default class Scope {
|
||||
* 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)) {
|
||||
return null;
|
||||
} 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
|
||||
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);
|
||||
if (binding) {
|
||||
newName = newName || this.generateUidIdentifier(oldName).name;
|
||||
@ -501,7 +565,7 @@ export default class Scope {
|
||||
dump() {
|
||||
const sep = "-".repeat(60);
|
||||
console.log(sep);
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
console.log("#", scope.block.type);
|
||||
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
|
||||
toArray(node: Object, i?: number | boolean, allowArrayLike?: boolean) {
|
||||
toArray(node: t.Node, i?: number | boolean, allowArrayLike?: boolean) {
|
||||
if (t.isIdentifier(node)) {
|
||||
const binding = this.getBinding(node.name);
|
||||
if (binding?.constant && binding.path.isGenericType("Array")) {
|
||||
@ -567,6 +631,7 @@ export default class Scope {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -578,7 +643,7 @@ export default class Scope {
|
||||
return this.labels.get(name);
|
||||
}
|
||||
|
||||
registerLabel(path: NodePath) {
|
||||
registerLabel(path: NodePath<t.LabeledStatement>) {
|
||||
this.labels.set(path.node.label.name, path);
|
||||
}
|
||||
|
||||
@ -589,18 +654,19 @@ export default class Scope {
|
||||
this.registerBinding("hoisted", path.get("id"), path);
|
||||
} else if (path.isVariableDeclaration()) {
|
||||
const declarations = path.get("declarations");
|
||||
for (const declar of (declarations: Array)) {
|
||||
for (const declar of declarations) {
|
||||
this.registerBinding(path.node.kind, declar);
|
||||
}
|
||||
} else if (path.isClassDeclaration()) {
|
||||
this.registerBinding("let", path);
|
||||
} else if (path.isImportDeclaration()) {
|
||||
const specifiers = path.get("specifiers");
|
||||
for (const specifier of (specifiers: Array)) {
|
||||
for (const specifier of specifiers) {
|
||||
this.registerBinding("module", specifier);
|
||||
}
|
||||
} else if (path.isExportDeclaration()) {
|
||||
const declar = path.get("declaration");
|
||||
// todo: improve babel-types
|
||||
const declar = path.get("declaration") as NodePath;
|
||||
if (
|
||||
declar.isClassDeclaration() ||
|
||||
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 (path.isVariableDeclaration()) {
|
||||
@ -642,7 +712,7 @@ export default class Scope {
|
||||
for (const name of Object.keys(ids)) {
|
||||
parent.references[name] = true;
|
||||
|
||||
for (const id of (ids[name]: Array<Object>)) {
|
||||
for (const id of ids[name]) {
|
||||
const local = this.getOwnBinding(name);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
hasUid(name): boolean {
|
||||
let scope = this;
|
||||
hasUid(name: string): boolean {
|
||||
let scope: Scope = this;
|
||||
|
||||
do {
|
||||
if (scope.uids[name]) return true;
|
||||
@ -683,7 +754,7 @@ export default class Scope {
|
||||
}
|
||||
|
||||
hasGlobal(name: string): boolean {
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
|
||||
do {
|
||||
if (scope.globals[name]) return true;
|
||||
@ -696,7 +767,7 @@ export default class Scope {
|
||||
return !!this.getProgramParent().references[name];
|
||||
}
|
||||
|
||||
isPure(node, constantsOnly?: boolean) {
|
||||
isPure(node: t.Node, constantsOnly?: boolean) {
|
||||
if (t.isIdentifier(node)) {
|
||||
const binding = this.getBinding(node.name);
|
||||
if (!binding) return false;
|
||||
@ -718,12 +789,12 @@ export default class Scope {
|
||||
this.isPure(node.right, constantsOnly)
|
||||
);
|
||||
} 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;
|
||||
}
|
||||
return true;
|
||||
} 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;
|
||||
}
|
||||
return true;
|
||||
@ -732,6 +803,7 @@ export default class Scope {
|
||||
if (node.kind === "get" || node.kind === "set") return false;
|
||||
return true;
|
||||
} 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;
|
||||
return this.isPure(node.value, constantsOnly);
|
||||
} else if (t.isUnaryExpression(node)) {
|
||||
@ -743,7 +815,7 @@ export default class Scope {
|
||||
this.isPure(node.quasi, constantsOnly)
|
||||
);
|
||||
} 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;
|
||||
}
|
||||
return true;
|
||||
@ -756,7 +828,7 @@ export default class Scope {
|
||||
* Set some arbitrary data on the current scope.
|
||||
*/
|
||||
|
||||
setData(key, val) {
|
||||
setData(key: string, val: any) {
|
||||
return (this.data[key] = val);
|
||||
}
|
||||
|
||||
@ -764,8 +836,8 @@ export default class Scope {
|
||||
* Recursively walk up scope tree looking for the data `key`.
|
||||
*/
|
||||
|
||||
getData(key) {
|
||||
let scope = this;
|
||||
getData(key: string): any {
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
const data = scope.data[key];
|
||||
if (data != null) return data;
|
||||
@ -777,8 +849,8 @@ export default class Scope {
|
||||
* remove it.
|
||||
*/
|
||||
|
||||
removeData(key) {
|
||||
let scope = this;
|
||||
removeData(key: string) {
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
const data = scope.data[key];
|
||||
if (data != null) scope.data[key] = null;
|
||||
@ -820,7 +892,7 @@ export default class Scope {
|
||||
const programParent = this.getProgramParent();
|
||||
if (programParent.crawling) return;
|
||||
|
||||
const state = {
|
||||
const state: CollectVisitorState = {
|
||||
references: [],
|
||||
constantViolations: [],
|
||||
assignments: [],
|
||||
@ -860,11 +932,11 @@ export default class Scope {
|
||||
}
|
||||
|
||||
push(opts: {
|
||||
id: Object,
|
||||
init: ?Object,
|
||||
unique: ?boolean,
|
||||
_blockHoist: ?number,
|
||||
kind: "var" | "let",
|
||||
id: t.LVal;
|
||||
init?: t.Expression;
|
||||
unique?: boolean;
|
||||
_blockHoist?: number | undefined;
|
||||
kind?: "var" | "let";
|
||||
}) {
|
||||
let path = this.path;
|
||||
|
||||
@ -878,6 +950,7 @@ export default class Scope {
|
||||
|
||||
if (path.isLoop() || path.isCatchClause() || path.isFunction()) {
|
||||
path.ensureBlock();
|
||||
// @ts-expect-error todo(flow->ts): improve types
|
||||
path = path.get("body");
|
||||
}
|
||||
|
||||
@ -890,6 +963,7 @@ export default class Scope {
|
||||
|
||||
if (!declarPath) {
|
||||
const declar = t.variableDeclaration(kind, []);
|
||||
// @ts-expect-error todo(flow->ts): avoid modifying nodes
|
||||
declar._blockHoist = blockHoist;
|
||||
|
||||
[declarPath] = path.unshiftContainer("body", [declar]);
|
||||
@ -906,7 +980,7 @@ export default class Scope {
|
||||
*/
|
||||
|
||||
getProgramParent() {
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
if (scope.path.isProgram()) {
|
||||
return scope;
|
||||
@ -919,8 +993,8 @@ export default class Scope {
|
||||
* Walk up the scope tree until we hit either a Function or return null.
|
||||
*/
|
||||
|
||||
getFunctionParent() {
|
||||
let scope = this;
|
||||
getFunctionParent(): Scope | null {
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
if (scope.path.isFunctionParent()) {
|
||||
return scope;
|
||||
@ -935,7 +1009,7 @@ export default class Scope {
|
||||
*/
|
||||
|
||||
getBlockParent() {
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
if (scope.path.isBlockParent()) {
|
||||
return scope;
|
||||
@ -950,10 +1024,10 @@ export default class Scope {
|
||||
* Walks the scope tree and gathers **all** bindings.
|
||||
*/
|
||||
|
||||
getAllBindings(): Object {
|
||||
getAllBindings(): any {
|
||||
const ids = Object.create(null);
|
||||
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
for (const key of Object.keys(scope.bindings)) {
|
||||
if (key in ids === false) {
|
||||
@ -970,11 +1044,11 @@ export default class Scope {
|
||||
* Walks the scope tree and gathers all declarations of `kind`.
|
||||
*/
|
||||
|
||||
getAllBindingsOfKind(): Object {
|
||||
getAllBindingsOfKind(...kinds: string[]): any {
|
||||
const ids = Object.create(null);
|
||||
|
||||
for (const kind of (arguments: Array)) {
|
||||
let scope = this;
|
||||
for (const kind of kinds) {
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
for (const name of Object.keys(scope.bindings)) {
|
||||
const binding = scope.bindings[name];
|
||||
@ -987,12 +1061,12 @@ export default class Scope {
|
||||
return ids;
|
||||
}
|
||||
|
||||
bindingIdentifierEquals(name: string, node: Object): boolean {
|
||||
bindingIdentifierEquals(name: string, node: t.Node): boolean {
|
||||
return this.getBindingIdentifier(name) === node;
|
||||
}
|
||||
|
||||
getBinding(name: string) {
|
||||
let scope = this;
|
||||
getBinding(name: string): Binding | undefined {
|
||||
let scope: Scope = this;
|
||||
let previousPath;
|
||||
|
||||
do {
|
||||
@ -1016,15 +1090,17 @@ export default class Scope {
|
||||
} while ((scope = scope.parent));
|
||||
}
|
||||
|
||||
getOwnBinding(name: string) {
|
||||
getOwnBinding(name: string): Binding | undefined {
|
||||
return this.bindings[name];
|
||||
}
|
||||
|
||||
getBindingIdentifier(name: string) {
|
||||
// todo: return probably can be undefined…
|
||||
getBindingIdentifier(name: string): t.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];
|
||||
return binding?.identifier;
|
||||
}
|
||||
@ -1051,7 +1127,7 @@ export default class Scope {
|
||||
* Move a binding of `name` to another `scope`.
|
||||
*/
|
||||
|
||||
moveBindingTo(name, scope) {
|
||||
moveBindingTo(name: string, scope: Scope) {
|
||||
const info = this.getBinding(name);
|
||||
if (info) {
|
||||
info.scope.removeOwnBinding(name);
|
||||
@ -1069,7 +1145,7 @@ export default class Scope {
|
||||
this.getBinding(name)?.scope.removeOwnBinding(name);
|
||||
|
||||
// clear uids with this name - https://github.com/babel/babel/issues/2101
|
||||
let scope = this;
|
||||
let scope: Scope = this;
|
||||
do {
|
||||
if (scope.uids[name]) {
|
||||
scope.uids[name] = false;
|
||||
@ -1,8 +1,9 @@
|
||||
import Binding from "../binding";
|
||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||
import * as t from "@babel/types";
|
||||
import type { Visitor } from "../../types";
|
||||
|
||||
const renameVisitor = {
|
||||
const renameVisitor: Visitor<Renamer> = {
|
||||
ReferencedIdentifier({ node }, state) {
|
||||
if (node.name === state.oldName) {
|
||||
node.name = state.newName;
|
||||
@ -135,11 +136,6 @@ export default class Renamer {
|
||||
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) {
|
||||
this.maybeConvertFromClassFunctionDeclaration(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);
|
||||
|
||||
// add type wrappers
|
||||
for (const nodeType of (Object.keys(visitor): Array)) {
|
||||
for (const nodeType of Object.keys(visitor)) {
|
||||
if (shouldIgnoreKey(nodeType)) continue;
|
||||
|
||||
const wrapper = virtualTypes[nodeType];
|
||||
@ -66,7 +66,7 @@ export function explode(visitor) {
|
||||
delete visitor[nodeType];
|
||||
|
||||
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
|
||||
if (visitor[type]) {
|
||||
mergePair(visitor[type], fns);
|
||||
@ -85,7 +85,7 @@ export function explode(visitor) {
|
||||
|
||||
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];
|
||||
if (deprecratedKey) {
|
||||
@ -176,9 +176,9 @@ function validateVisitorMethods(path, val) {
|
||||
}
|
||||
|
||||
export function merge(
|
||||
visitors: Array,
|
||||
states: Array = [],
|
||||
wrapper?: ?Function,
|
||||
visitors: any[],
|
||||
states: any[] = [],
|
||||
wrapper?: Function | null,
|
||||
) {
|
||||
const rootVisitor = {};
|
||||
|
||||
@ -204,7 +204,7 @@ export function merge(
|
||||
return rootVisitor;
|
||||
}
|
||||
|
||||
function wrapWithStateOrWrapper(oldVisitor, state, wrapper: ?Function) {
|
||||
function wrapWithStateOrWrapper(oldVisitor, state, wrapper?: Function | null) {
|
||||
const newVisitor = {};
|
||||
|
||||
for (const key of Object.keys(oldVisitor)) {
|
||||
@ -182,9 +182,9 @@ describe("modification", function () {
|
||||
const tagName = path.node.openingElement.name.name;
|
||||
if (tagName !== "span") return;
|
||||
path.insertBefore(
|
||||
t.JSXElement(
|
||||
t.JSXOpeningElement(t.JSXIdentifier("div"), [], false),
|
||||
t.JSXClosingElement(t.JSXIdentifier("div")),
|
||||
t.jsxElement(
|
||||
t.jsxOpeningElement(t.jsxIdentifier("div"), [], false),
|
||||
t.jsxClosingElement(t.jsxIdentifier("div")),
|
||||
[],
|
||||
),
|
||||
);
|
||||
@ -292,9 +292,9 @@ describe("modification", function () {
|
||||
const tagName = path.node.openingElement.name.name;
|
||||
if (tagName !== "span") return;
|
||||
path.insertAfter(
|
||||
t.JSXElement(
|
||||
t.JSXOpeningElement(t.JSXIdentifier("div"), [], false),
|
||||
t.JSXClosingElement(t.JSXIdentifier("div")),
|
||||
t.jsxElement(
|
||||
t.jsxOpeningElement(t.jsxIdentifier("div"), [], false),
|
||||
t.jsxClosingElement(t.jsxIdentifier("div")),
|
||||
[],
|
||||
),
|
||||
);
|
||||
|
||||
@ -40,9 +40,9 @@ export default function traverse<T>(
|
||||
|
||||
function traverseSimpleImpl<T>(
|
||||
node: any,
|
||||
enter: Function | undefined | null,
|
||||
exit: Function | undefined | null,
|
||||
state: T | undefined | null,
|
||||
enter: Function | undefined,
|
||||
exit: Function | undefined,
|
||||
state: T | undefined,
|
||||
ancestors: TraversalAncestors,
|
||||
) {
|
||||
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`.
|
||||
*/
|
||||
export default function isType(
|
||||
nodeType: string | undefined | null,
|
||||
targetType: string,
|
||||
): boolean {
|
||||
export default function isType(nodeType: string, targetType: string): boolean {
|
||||
if (nodeType === targetType) return true;
|
||||
|
||||
// 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