Skip to content

Commit

Permalink
typings: intersect input node types for is* functions
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jul 8, 2022
1 parent 5d769d0 commit 32dfc31
Show file tree
Hide file tree
Showing 14 changed files with 1,322 additions and 502 deletions.
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 @@ -122,7 +122,7 @@ export function extractComputedKeys(
};
for (const computedPath of computedPaths) {
const computedKey = computedPath.get("key");
if (computedKey.isIdentifier() && computedKey.isReferencedIdentifier()) {
if (computedKey.isReferencedIdentifier()) {
handleClassTDZ(computedKey, state);
} else {
computedKey.traverse(classFieldDefinitionEvaluationTDZVisitor, state);
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,
);
}
}
Expand Up @@ -24,17 +24,15 @@ export function shouldTransform(
): boolean {
let optionalPath: NodePath<t.Expression> = path;
const chains = [];
while (
optionalPath.isOptionalMemberExpression() ||
optionalPath.isOptionalCallExpression()
) {
const { node } = optionalPath;
chains.push(node);

for (;;) {
if (optionalPath.isOptionalMemberExpression()) {
optionalPath = skipTransparentExprWrappers(optionalPath.get("object"));
chains.push(optionalPath.node);
} else if (optionalPath.isOptionalCallExpression()) {
optionalPath = skipTransparentExprWrappers(optionalPath.get("callee"));
chains.push(optionalPath.node);
} else {
break;
}
}
for (let i = 0; i < chains.length; i++) {
Expand Down
Expand Up @@ -49,10 +49,7 @@ export default declare(({ types: t, template, assertVersion }) => {
const body = classBody.get("body");
for (const path of body) {
if (path.isPrivate()) {
privateNames.add(
// @ts-expect-error TS can't infer that NodePath<t.ClassBody[body][number]> & NodePath<t.Private> equals to NodePath<t.ClassBody[body][number] & isPrivate>
path.get("key.id").node.name,
);
privateNames.add(path.get("key.id").node.name);
}
}
for (const path of body) {
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
5 changes: 1 addition & 4 deletions packages/babel-plugin-transform-typescript/src/enum.ts
Expand Up @@ -156,10 +156,7 @@ export function translateEnumValues(
} else {
const initializerPath = memberPath.get("initializer");

if (
initializerPath.isIdentifier() &&
initializerPath.isReferencedIdentifier()
) {
if (initializerPath.isReferencedIdentifier()) {
ReferencedIdentifier(initializerPath, {
t,
seen,
Expand Down
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

0 comments on commit 32dfc31

Please sign in to comment.