Skip to content

Commit

Permalink
Provide better parentPath typings (#14739)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jul 9, 2022
1 parent b4646fe commit 41582ee
Show file tree
Hide file tree
Showing 22 changed files with 7,167 additions and 510 deletions.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
24 changes: 16 additions & 8 deletions packages/babel-helper-wrap-function/src/index.ts
Original file line number Diff line number Diff line change
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,13 +67,14 @@ function classOrObjectMethod(
}

function plainFunction(
path: NodePath<any>,
callId: any,
path: NodePath<Exclude<t.Function, t.Method>>,
callId: t.Expression,
noNewArrows: boolean,
ignoreFunctionLength: boolean,
) {
const node = path.node;
const isDeclaration = path.isFunctionDeclaration();
// @ts-expect-error id is not in ArrowFunctionExpression
const functionId = node.id;
const wrapper = isDeclaration
? buildDeclarationWrapper
Expand All @@ -84,14 +85,16 @@ function plainFunction(
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading

0 comments on commit 41582ee

Please sign in to comment.