Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide better parentPath typings #14739

Merged
merged 6 commits into from Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -94,13 +94,17 @@ function extractElementDescriptor(

const { node, scope } = path as NodePath<SupportedElement>;

new ReplaceSupers({
methodPath: path,
objectRef: classRef,
superRef,
file,
refToPreserve: classRef,
}).replace();
if (!path.isTSDeclareMethod()) {
new ReplaceSupers({
methodPath: path as NodePath<
Exclude<SupportedElement, t.TSDeclareMethod>
>,
objectRef: classRef,
superRef,
file,
refToPreserve: classRef,
}).replace();
}

const properties: t.ObjectExpression["properties"] = [
prop("kind", t.stringLiteral(t.isClassMethod(node) ? node.kind : "field")),
Expand Down
Expand Up @@ -215,9 +215,12 @@ const handle = {
);
}

// @ts-expect-error isOptionalMemberExpression does not work with NodePath union
const startingNode = startingOptional.isOptionalMemberExpression()
? startingOptional.node.object
: startingOptional.node.callee;
? // @ts-expect-error isOptionalMemberExpression does not work with NodePath union
startingOptional.node.object
: // @ts-expect-error isOptionalMemberExpression does not work with NodePath union
startingOptional.node.callee;
const baseNeedsMemoised = scope.maybeGenerateMemoised(startingNode);
const baseRef = baseNeedsMemoised ?? startingNode;

Expand Down
Expand Up @@ -36,7 +36,7 @@ const awaitVisitor = traverse.visitors.merge<{ wrapAwait: t.Expression }>([
]);

export default function (
path: NodePath<any>,
path: NodePath<t.Function>,
helpers: {
wrapAsync: t.Expression;
wrapAwait?: t.Expression;
Expand Down
22 changes: 16 additions & 6 deletions packages/babel-helper-replace-supers/src/index.ts
@@ -1,4 +1,4 @@
import type { HubInterface, NodePath, Scope } from "@babel/traverse";
import type { NodePath, Scope } from "@babel/traverse";
import traverse from "@babel/traverse";
import memberExpressionToFunctions from "@babel/helper-member-expression-to-functions";
import type { HandlerState } from "@babel/helper-member-expression-to-functions";
Expand Down Expand Up @@ -317,9 +317,16 @@ const looseHandlers = {
};

type ReplaceSupersOptionsBase = {
methodPath: NodePath<any>;
methodPath: NodePath<
| t.ClassMethod
| t.ClassProperty
| t.ObjectMethod
| t.ClassPrivateMethod
| t.ClassPrivateProperty
| t.StaticBlock
>;
constantSuper?: boolean;
file: any;
file: File;
// objectRef might have been shadowed in child scopes,
// in that case, we need to rename related variables.
refToPreserve?: t.Identifier;
Expand All @@ -336,7 +343,7 @@ type ReplaceSupersOptions = ReplaceSupersOptionsBase &
);

interface ReplaceState {
file: unknown;
file: File;
scope: Scope;
isDerivedConstructor: boolean;
isStatic: boolean;
Expand All @@ -353,7 +360,10 @@ export default class ReplaceSupers {
this.isDerivedConstructor =
path.isClassMethod({ kind: "constructor" }) && !!opts.superRef;
this.isStatic =
path.isObjectMethod() || path.node.static || path.isStaticBlock?.();
path.isObjectMethod() ||
// @ts-expect-error static is not in ClassPrivateMethod
path.node.static ||
path.isStaticBlock?.();
this.isPrivateMethod = path.isPrivate() && path.isMethod();

this.file = opts.file;
Expand All @@ -364,7 +374,7 @@ export default class ReplaceSupers {
this.opts = opts;
}

declare file: HubInterface;
declare file: File;
declare isDerivedConstructor: boolean;
declare constantSuper: boolean;
declare isPrivateMethod: boolean;
Expand Down
30 changes: 19 additions & 11 deletions packages/babel-helper-wrap-function/src/index.ts
Expand Up @@ -40,7 +40,7 @@ const buildDeclarationWrapper = template.statements(`

function classOrObjectMethod(
path: NodePath<t.ClassMethod | t.ClassPrivateMethod | t.ObjectMethod>,
callId: any,
callId: t.Expression,
) {
const node = path.node;
const body = node.body;
Expand All @@ -67,31 +67,34 @@ function classOrObjectMethod(
}

function plainFunction(
path: NodePath<any>,
callId: any,
path: NodePath<Exclude<t.Function, t.Method>>,
callId: t.Expression,
noNewArrows: boolean,
ignoreFunctionLength: boolean,
) {
if (path.isArrowFunctionExpression()) {
path.arrowFunctionToExpression({ noNewArrows });
}
const node = path.node;
const isDeclaration = path.isFunctionDeclaration();
// @ts-expect-error node is FunctionDeclaration|FunctionExpression
const functionId = node.id;
const wrapper = isDeclaration
? buildDeclarationWrapper
: functionId
? buildNamedExpressionWrapper
: buildAnonymousExpressionWrapper;

if (path.isArrowFunctionExpression()) {
path.arrowFunctionToExpression({ noNewArrows });
}

// @ts-expect-error node is FunctionDeclaration|FunctionExpression
node.id = null;

if (isDeclaration) {
node.type = "FunctionExpression";
}

const built = callExpression(callId, [node]);
const built = callExpression(callId, [
node as Exclude<t.Function, t.Method | t.FunctionDeclaration>,
]);

const params: t.Identifier[] = [];
for (const param of node.params) {
Expand Down Expand Up @@ -138,15 +141,20 @@ function plainFunction(
}

export default function wrapFunction(
path: NodePath,
callId: any,
path: NodePath<t.Function>,
callId: t.Expression,
// TODO(Babel 8): Consider defaulting to false for spec compliancy
noNewArrows: boolean = true,
ignoreFunctionLength: boolean = false,
) {
if (path.isMethod()) {
classOrObjectMethod(path, callId);
} else {
plainFunction(path, callId, noNewArrows, ignoreFunctionLength);
plainFunction(
path as NodePath<Exclude<t.Function, t.Method>>,
callId,
noNewArrows,
ignoreFunctionLength,
);
}
}
1 change: 1 addition & 0 deletions packages/babel-helpers/src/index.ts
Expand Up @@ -59,6 +59,7 @@ function getHelperMetadata(file: File): HelperMetadata {
}
if (
child.get("specifiers").length !== 1 ||
// @ts-expect-error isImportDefaultSpecifier does not work with NodePath union
!child.get("specifiers.0").isImportDefaultSpecifier()
) {
throw child.buildCodeFrameError(
Expand Down
Expand Up @@ -23,18 +23,16 @@ export function shouldTransform(
path: NodePath<t.OptionalMemberExpression | t.OptionalCallExpression>,
): boolean {
let optionalPath: NodePath<t.Expression> = path;
const chains = [];
while (
optionalPath.isOptionalMemberExpression() ||
optionalPath.isOptionalCallExpression()
) {
const { node } = optionalPath;
chains.push(node);

const chains: (t.OptionalCallExpression | t.OptionalMemberExpression)[] = [];
for (;;) {
if (optionalPath.isOptionalMemberExpression()) {
chains.push(optionalPath.node);
optionalPath = skipTransparentExprWrappers(optionalPath.get("object"));
} else if (optionalPath.isOptionalCallExpression()) {
chains.push(optionalPath.node);
optionalPath = skipTransparentExprWrappers(optionalPath.get("callee"));
} else {
break;
}
}
for (let i = 0; i < chains.length; i++) {
Expand Down
Expand Up @@ -685,10 +685,10 @@ function transformClass(

const replaceSupers = new ReplaceSupers({
constantSuper,
methodPath: element,
methodPath: element as NodePath<t.ClassPrivateMethod>,
objectRef: classLocal,
superRef: path.node.superClass,
file: state,
file: state.file,
refToPreserve: classLocal,
});

Expand Down
11 changes: 4 additions & 7 deletions packages/babel-plugin-proposal-object-rest-spread/src/index.ts
Expand Up @@ -243,7 +243,9 @@ export default declare((api, opts: Options) => {

function replaceRestElement(
parentPath: NodePath<t.Function | t.CatchClause>,
paramPath: Param | NodePath<t.AssignmentPattern["left"]>,
paramPath: NodePath<
t.Function["params"][number] | t.AssignmentPattern["left"]
>,
container?: t.VariableDeclaration[],
): void {
if (paramPath.isAssignmentPattern()) {
Expand All @@ -255,12 +257,7 @@ export default declare((api, opts: Options) => {
const elements = paramPath.get("elements");

for (let i = 0; i < elements.length; i++) {
replaceRestElement(
parentPath,
// @ts-expect-error Fixme: handle TSAsExpression
elements[i],
container,
);
replaceRestElement(parentPath, elements[i], container);
}
}

Expand Down
Expand Up @@ -37,6 +37,7 @@ function needsMemoize(
) {
const { node } = optionalPath;
const childPath = skipTransparentExprWrappers(
// @ts-expect-error isOptionalMemberExpression does not work with NodePath union
optionalPath.isOptionalMemberExpression()
? optionalPath.get("object")
: optionalPath.get("callee"),
Expand Down Expand Up @@ -87,7 +88,7 @@ export function transform(
if (node.optional) {
optionals.push(node);
}

// @ts-expect-error isOptionalMemberExpression does not work with NodePath union
if (optionalPath.isOptionalMemberExpression()) {
// @ts-expect-error todo(flow->ts) avoid changing more type
optionalPath.node.type = "MemberExpression";
Expand Down
4 changes: 3 additions & 1 deletion packages/babel-plugin-transform-block-scoping/src/index.ts
Expand Up @@ -113,7 +113,9 @@ export default declare((api, opts: Options) => {
};
});

function ignoreBlock(path: NodePath) {
function ignoreBlock(
path: NodePath<t.BlockStatement | t.SwitchStatement | t.Program>,
) {
return t.isLoop(path.parent) || t.isCatchClause(path.parent);
}

Expand Down
12 changes: 5 additions & 7 deletions packages/babel-plugin-transform-classes/src/index.ts
Expand Up @@ -5,7 +5,6 @@ import splitExportDeclaration from "@babel/helper-split-export-declaration";
import { types as t } from "@babel/core";
import globals from "globals";
import transformClass from "./transformClass";
import type { Visitor, NodePath } from "@babel/traverse";

const getBuiltinClasses = (category: keyof typeof globals) =>
Object.keys(globals[category]).filter(name => /^[A-Z]/.test(name));
Expand Down Expand Up @@ -68,7 +67,7 @@ export default declare((api, options: Options) => {

VISITED.add(node);

path.replaceWith(
const [replacedPath] = path.replaceWith(
transformClass(path, state.file, builtinClasses, loose, {
setClassMethods,
constantSuper,
Expand All @@ -77,16 +76,15 @@ export default declare((api, options: Options) => {
}),
);

if (path.isCallExpression()) {
annotateAsPure(path);
// todo: improve babel types
const callee = path.get("callee") as unknown as NodePath;
if (replacedPath.isCallExpression()) {
annotateAsPure(replacedPath);
const callee = replacedPath.get("callee");
if (callee.isArrowFunctionExpression()) {
// This is an IIFE, so we don't need to worry about the noNewArrows assumption
callee.arrowFunctionToExpression();
}
}
},
} as Visitor<any>,
},
};
});
6 changes: 3 additions & 3 deletions packages/babel-traverse/scripts/generators/validators.js
Expand Up @@ -14,7 +14,7 @@ export interface NodePathValidators {
`;

for (const type of [...t.TYPES].sort()) {
output += `is${type}(opts?: object): this is NodePath<t.${type}>;`;
output += `is${type}<T extends t.Node>(this: NodePath<T>, opts?: object): this is NodePath<T & t.${type}>;`;
}

for (const type of Object.keys(virtualTypes)) {
Expand All @@ -24,9 +24,9 @@ export interface NodePathValidators {
const { types } = virtualTypes[type];
if (type[0] === "_") continue;
if (t.NODE_FIELDS[type] || t.FLIPPED_ALIAS_KEYS[type]) {
output += `is${type}(opts?: object): this is NodePath<t.${type}>;`;
output += `is${type}<T extends t.Node>(this: NodePath<T>, opts?: object): this is NodePath<T & t.${type}>;`;
} else if (types /* in VirtualTypeAliases */) {
output += `is${type}(opts?: object): this is NodePath<VirtualTypeAliases["${type}"]>;`;
output += `is${type}<T extends t.Node>(this: NodePath<T>, opts?: object): this is NodePath<T & VirtualTypeAliases["${type}"]>;`;
} else if (type === "Pure") {
output += `isPure(constantsOnly?: boolean): boolean;`;
} else {
Expand Down