Skip to content

Commit

Permalink
Improve plugins typings (Part 1) (#14633)
Browse files Browse the repository at this point in the history
* change AssumptionFunction return type

* helper-create-regexp-features-plugin

* create-class-features-plugin

* transform-for-of

* improve unicode-escapes typings

* transform-object-super

* transform-react-constant-elements

* proto-to-assign

* function-name

* flow-comments

TS cannot infer Flow visitor type because we have both Flow type and Flow virtual type.
  • Loading branch information
JLHwung committed Jun 20, 2022
1 parent 183567d commit f9c6d5e
Show file tree
Hide file tree
Showing 21 changed files with 189 additions and 92 deletions.
17 changes: 17 additions & 0 deletions lib/regexpu-core.d.ts
@@ -0,0 +1,17 @@
declare module "regexpu-core" {
type RegexpuOptions = {
unicodeFlag?: "transform" | false;
unicodeSetsFlag?: "transform" | "parse" | false;
dotAllFlag?: "transform" | false;
unicodePropertyEscapes?: "transform" | false;
namedGroups?: "transform" | false;
onNamedGroup?: (name: string, index: number) => void;
};
function rewritePattern(
pattern: string,
flags: string,
options: RegexpuOptions
): string;
export = rewritePattern;
export { RegexpuOptions };
}
2 changes: 1 addition & 1 deletion packages/babel-core/src/config/helpers/config-api.ts
Expand Up @@ -24,7 +24,7 @@ type CallerFactory = (
extractor: (callerMetadata: CallerMetadata | undefined) => unknown,
) => SimpleType;
type TargetsFunction = () => Targets;
type AssumptionFunction = (name: AssumptionName) => boolean | void;
type AssumptionFunction = (name: AssumptionName) => boolean | undefined;

export type ConfigAPI = {
version: string;
Expand Down
Expand Up @@ -108,9 +108,20 @@ function extractElementDescriptor(
].filter(Boolean);

if (t.isClassMethod(node)) {
const id = node.computed ? null : node.key;
t.toExpression(node);
properties.push(prop("value", nameFunction({ node, id, scope }) || node));
const id = node.computed
? null
: (node.key as
| t.Identifier
| t.StringLiteral
| t.NumericLiteral
| t.BigIntLiteral);
const transformed = t.toExpression(node);
properties.push(
prop(
"value",
nameFunction({ node: transformed, id, scope }) || transformed,
),
);
} else if (t.isClassProperty(node) && node.value) {
properties.push(
method("value", template.statements.ast`return ${node.value}`),
Expand Down
22 changes: 15 additions & 7 deletions packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -490,7 +490,15 @@ export function transformPrivateNamesUsage(
ref: t.Identifier,
path: NodePath<t.Class>,
privateNamesMap: PrivateNamesMap,
{ privateFieldsAsProperties, noDocumentAll, innerBinding },
{
privateFieldsAsProperties,
noDocumentAll,
innerBinding,
}: {
privateFieldsAsProperties: boolean;
noDocumentAll: boolean;
innerBinding: t.Identifier;
},
state: File,
) {
if (!privateNamesMap.size) return;
Expand Down Expand Up @@ -539,7 +547,7 @@ function buildPrivateInstanceFieldInitSpec(
ref: t.Expression,
prop: NodePath<t.ClassPrivateProperty>,
privateNamesMap: PrivateNamesMap,
state,
state: File,
) {
const { id } = privateNamesMap.get(prop.node.key.id.name);
const value = prop.node.value || prop.scope.buildUndefinedNode();
Expand Down Expand Up @@ -646,7 +654,7 @@ function buildPrivateInstanceMethodInitSpec(
ref: t.Expression,
prop: NodePath<t.ClassPrivateMethod>,
privateNamesMap: PrivateNamesMap,
state,
state: File,
) {
const privateName = privateNamesMap.get(prop.node.key.id.name);
const { getId, setId, initAdded } = privateName;
Expand Down Expand Up @@ -675,7 +683,7 @@ function buildPrivateAccessorInitialization(
ref: t.Expression,
prop: NodePath<t.ClassPrivateMethod>,
privateNamesMap: PrivateNamesMap,
state,
state: File,
) {
const privateName = privateNamesMap.get(prop.node.key.id.name);
const { id, getId, setId } = privateName;
Expand Down Expand Up @@ -711,7 +719,7 @@ function buildPrivateInstanceMethodInitalization(
ref: t.Expression,
prop: NodePath<t.ClassPrivateMethod>,
privateNamesMap: PrivateNamesMap,
state,
state: File,
) {
const privateName = privateNamesMap.get(prop.node.key.id.name);
const { id } = privateName;
Expand Down Expand Up @@ -748,7 +756,7 @@ function buildPublicFieldInitLoose(
function buildPublicFieldInitSpec(
ref: t.Expression,
prop: NodePath<t.ClassProperty>,
state,
state: File,
) {
const { key, computed } = prop.node;
const value = prop.node.value || prop.scope.buildUndefinedNode();
Expand All @@ -767,7 +775,7 @@ function buildPublicFieldInitSpec(
function buildPrivateStaticMethodInitLoose(
ref: t.Expression,
prop: NodePath<t.ClassPrivateMethod>,
state,
state: File,
privateNamesMap: PrivateNamesMap,
) {
const privateName = privateNamesMap.get(prop.node.key.id.name);
Expand Down
21 changes: 16 additions & 5 deletions packages/babel-helper-create-regexp-features-plugin/src/index.ts
@@ -1,6 +1,7 @@
import rewritePattern from "regexpu-core";
import { featuresKey, FEATURES, enableFeature, runtimeKey } from "./features";
import { generateRegexpuOptions, canSkipRegexpu, transformFlags } from "./util";
import type { NodePath } from "@babel/traverse";

import { types as t } from "@babel/core";
import type { PluginObject } from "@babel/core";
Expand All @@ -17,12 +18,22 @@ const version = PACKAGE_JSON.version
.reduce((v, x) => v * 1e5 + +x, 0);
const versionKey = "@babel/plugin-regexp-features/version";

export interface Options {
name: string;
feature: keyof typeof FEATURES;
options?: {
useUnicodeFlag?: boolean;
runtime?: boolean;
};
manipulateOptions?: PluginObject["manipulateOptions"];
}

export function createRegExpFeaturePlugin({
name,
feature,
options = {} as any,
manipulateOptions = (() => {}) as PluginObject["manipulateOptions"],
}): PluginObject {
options = {},
manipulateOptions = () => {},
}: Options): PluginObject {
return {
name,

Expand Down Expand Up @@ -60,7 +71,7 @@ export function createRegExpFeaturePlugin({
const regexpuOptions = generateRegexpuOptions(features);
if (canSkipRegexpu(node, regexpuOptions)) return;

const namedCaptureGroups = {};
const namedCaptureGroups: Record<string, number> = {};
if (regexpuOptions.namedGroups === "transform") {
regexpuOptions.onNamedGroup = (name, index) => {
namedCaptureGroups[name] = index;
Expand Down Expand Up @@ -90,7 +101,7 @@ export function createRegExpFeaturePlugin({
};
}

function isRegExpTest(path) {
function isRegExpTest(path: NodePath<t.RegExpLiteral>) {
return (
path.parentPath.isMemberExpression({
object: path.node,
Expand Down
@@ -1,14 +1,7 @@
import type { types as t } from "@babel/core";
import { FEATURES, hasFeature } from "./features";

type RegexpuOptions = {
unicodeFlag: "transform" | false;
unicodeSetsFlag: "transform" | "parse" | false;
dotAllFlag: "transform" | false;
unicodePropertyEscapes: "transform" | false;
namedGroups: "transform" | false;
onNamedGroup: (name: string, index: number) => void;
};
import type { RegexpuOptions } from "regexpu-core";

export function generateRegexpuOptions(toTransform: number): RegexpuOptions {
type Experimental = 1;
Expand Down
10 changes: 5 additions & 5 deletions packages/babel-helper-function-name/src/index.ts
Expand Up @@ -102,7 +102,7 @@ function getNameFromLiteralId(id: t.Literal) {

function wrap(
state: State,
method: t.FunctionExpression | t.ClassExpression,
method: t.FunctionExpression | t.Class,
id: t.Identifier,
scope: Scope,
) {
Expand Down Expand Up @@ -148,7 +148,7 @@ function wrap(
}

function visit(
node: t.FunctionExpression | t.ClassExpression,
node: t.FunctionExpression | t.Class,
name: string,
scope: Scope,
) {
Expand Down Expand Up @@ -201,21 +201,21 @@ function visit(
* @param {Boolean} localBinding whether a name could shadow a self-reference (e.g. converting arrow function)
* @param {Boolean} supportUnicodeId whether a target support unicodeId or not
*/
export default function (
export default function <N extends t.FunctionExpression | t.Class>(
{
node,
parent,
scope,
id,
}: {
node: t.FunctionExpression | t.ClassExpression;
node: N;
parent?: t.Node;
scope: Scope;
id?: any;
},
localBinding = false,
supportUnicodeId = false,
) {
): t.CallExpression | N {
// has an `id` so we don't need to infer one
if (node.id) return;

Expand Down
38 changes: 23 additions & 15 deletions packages/babel-plugin-transform-flow-comments/src/index.ts
Expand Up @@ -7,7 +7,7 @@ import type { NodePath } from "@babel/traverse";
export default declare(api => {
api.assertVersion(7);

function commentFromString(comment) {
function commentFromString(comment: string | t.Comment): t.Comment {
return typeof comment === "string"
? { type: "CommentBlock", value: comment }
: comment;
Expand All @@ -21,12 +21,12 @@ export default declare(api => {
comments = generateComment(ofPath, optional),
keepType = false,
}: {
ofPath?;
toPath?;
where?: string;
optional?;
comments?;
keepType?;
ofPath?: NodePath;
toPath?: NodePath;
where?: t.CommentTypeShorthand;
optional?: boolean;
comments?: string | t.Comment | (string | t.Comment)[];
keepType?: boolean;
}) {
if (!toPath?.node) {
toPath = ofPath.getPrevSibling();
Expand All @@ -43,7 +43,7 @@ export default declare(api => {
if (!Array.isArray(comments)) {
comments = [comments];
}
comments = comments.map(commentFromString);
const newComments = comments.map(commentFromString);
if (!keepType && ofPath?.node) {
// Removes the node at `ofPath` while conserving the comments attached
// to it.
Expand All @@ -58,24 +58,28 @@ export default declare(api => {
if (isSingleChild && leading) {
parent.addComments("inner", leading);
}
toPath.addComments(where, comments);
toPath.addComments(where, newComments);
ofPath.remove();
if (isSingleChild && trailing) {
parent.addComments("inner", trailing);
}
} else {
toPath.addComments(where, comments);
toPath.addComments(where, newComments);
}
}

function wrapInFlowComment(path) {
function wrapInFlowComment(path: NodePath) {
attachComment({
ofPath: path,
comments: generateComment(path, path.parent.optional),
comments: generateComment(
path,
// @ts-ignore
path.parent.optional,
),
});
}

function generateComment(path, optional?) {
function generateComment(path: NodePath, optional?: boolean | void) {
let comment = path
.getSource()
.replace(/\*-\//g, "*-ESCAPED/")
Expand All @@ -85,7 +89,7 @@ export default declare(api => {
return comment;
}

function isTypeImport(importKind) {
function isTypeImport(importKind: "type" | "typeof" | "value") {
return importKind === "type" || importKind === "typeof";
}

Expand Down Expand Up @@ -236,7 +240,11 @@ export default declare(api => {
}
},

Flow(path) {
Flow(
path: NodePath<
t.Flow | t.ImportDeclaration | t.ExportDeclaration | t.ImportSpecifier
>,
) {
wrapInFlowComment(path);
},

Expand Down
@@ -1,6 +1,7 @@
import { declare } from "@babel/helper-plugin-utils";
import syntaxFlow from "@babel/plugin-syntax-flow";
import { types as t } from "@babel/core";
import type { NodePath } from "@babel/traverse";

export interface Options {
requireDirective?: boolean;
Expand Down Expand Up @@ -75,7 +76,11 @@ export default declare((api, opts: Options) => {
}
},

Flow(path) {
Flow(
path: NodePath<
t.Flow | t.ImportDeclaration | t.ExportDeclaration | t.ImportSpecifier
>,
) {
if (skipStrip) {
throw path.buildCodeFrameError(
"A @flow directive is required when using Flow annotations with " +
Expand Down
9 changes: 6 additions & 3 deletions packages/babel-plugin-transform-for-of/src/index.ts
Expand Up @@ -154,15 +154,17 @@ export default declare((api, options: Options) => {
? {
build: buildForOfNoIteratorClosing,
helper: "createForOfIteratorHelperLoose",
getContainer: nodes => nodes,
getContainer: (nodes: t.Statement[]): [t.ForStatement] =>
nodes as [t.ForStatement],
}
: {
build: buildForOf,
helper: "createForOfIteratorHelper",
getContainer: nodes => nodes[1].block.body,
getContainer: (nodes: t.Statement[]): [t.ForStatement] =>
(nodes[1] as t.TryStatement).block.body as [t.ForStatement],
};

function _ForOfStatementArray(path) {
function _ForOfStatementArray(path: NodePath<t.ForOfStatement>) {
const { node, scope } = path;

const right = scope.generateUidIdentifierBasedOnNode(node.right, "arr");
Expand Down Expand Up @@ -257,6 +259,7 @@ export default declare((api, options: Options) => {
t.inherits(container[0].body, node.body);

if (t.isLabeledStatement(parent)) {
// @ts-expect-error replacing node types
container[0] = t.labeledStatement(parent.label, container[0]);

path.parentPath.replaceWithMultiple(nodes);
Expand Down

0 comments on commit f9c6d5e

Please sign in to comment.