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 plugin/preset typings from plugin-utils #14499

Merged
merged 22 commits into from Apr 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cf26c37
type: refine assumptions interface
JLHwung Apr 26, 2022
dd73f4c
fix: use UidIdentifier when partial callee is not identifier
JLHwung Apr 27, 2022
7a21c70
perf: scan object properties in one pass
JLHwung Apr 27, 2022
11c80b9
fix: support private name in member proeprty
JLHwung Apr 27, 2022
1a016a2
fix: add pipeline operator to BinaryOperators
JLHwung Apr 27, 2022
dc43dd0
typings: fix GeneratorOptions
JLHwung Apr 27, 2022
046daab
update babel parser typings
JLHwung Apr 27, 2022
8ef9dd2
fix: add predicate to @babel/types
JLHwung Apr 27, 2022
381fd18
typings: export Plugin/Preset related types
JLHwung Apr 27, 2022
99d3abd
feat: add declarePreset method and refine declare types
JLHwung Apr 27, 2022
beda280
use helper-plugin-utils in named-capturing-groups
JLHwung Apr 27, 2022
c20d40b
fix typing issues
JLHwung Apr 27, 2022
e82aa35
Update packages/babel-core/src/config/validation/plugins.ts
JLHwung Apr 27, 2022
d39e051
Update packages/babel-plugin-proposal-nullish-coalescing-operator/src…
JLHwung Apr 27, 2022
cc42fdf
Update packages/babel-helper-plugin-utils/src/index.ts
JLHwung Apr 27, 2022
cd4cdf2
simplify declare/declarePreset
JLHwung Apr 27, 2022
032ebf4
improve decorator 2021-12 transformer typings
JLHwung Apr 27, 2022
84153ee
Do not expose plugin state
JLHwung Apr 28, 2022
dd42d4f
bump typescript to 4.6.3
JLHwung Apr 28, 2022
e2106bf
fix AssumptionFunction return type
JLHwung Apr 28, 2022
b0fd195
misc
JLHwung Apr 28, 2022
6c2d2d9
noNewArrows defaults to true
JLHwung Apr 28, 2022
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
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -74,7 +74,7 @@
"semver": "^6.3.0",
"test262-stream": "^1.4.0",
"through2": "^4.0.0",
"typescript": "~4.5.0"
"typescript": "~4.6.3"
},
"workspaces": [
"codemods/*",
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-core/src/config/helpers/config-api.ts
Expand Up @@ -9,7 +9,7 @@ import type {
SimpleType,
} from "../caching";

import type { CallerMetadata } from "../validation/options";
import type { AssumptionName, CallerMetadata } from "../validation/options";

import * as Context from "../cache-contexts";

Expand All @@ -24,7 +24,7 @@ type CallerFactory = (
extractor: (callerMetadata: CallerMetadata | void) => unknown,
) => SimpleType;
type TargetsFunction = () => Targets;
type AssumptionFunction = (name: string) => boolean | void;
type AssumptionFunction = (name: AssumptionName) => boolean | void;

export type ConfigAPI = {
version: string;
Expand Down
11 changes: 11 additions & 0 deletions packages/babel-core/src/config/index.ts
Expand Up @@ -9,6 +9,17 @@ export type {

import type { PluginTarget } from "./validation/options";

import type {
PluginAPI as basePluginAPI,
PresetAPI as basePresetAPI,
} from "./helpers/config-api";
export type { PluginObject } from "./validation/plugins";
type PluginAPI = basePluginAPI & typeof import("..");
type PresetAPI = basePresetAPI & typeof import("..");
export type { PluginAPI, PresetAPI };
// todo: may need to refine PresetObject to be a subset of ValidatedOptions
export type { ValidatedOptions as PresetObject } from "./validation/options";

import loadFullConfig from "./full";
import { loadPartialConfig as loadPartialConfigRunner } from "./partial";

Expand Down
Expand Up @@ -20,6 +20,7 @@ import type {
CallerMetadata,
RootMode,
TargetsListOrObject,
AssumptionName,
} from "./options";

import { assumptionsNames } from "./options";
Expand Down Expand Up @@ -462,7 +463,7 @@ export function assertAssumptions(

for (const name of Object.keys(value)) {
const subLoc = access(loc, name);
if (!assumptionsNames.has(name)) {
if (!assumptionsNames.has(name as AssumptionName)) {
throw new Error(`${msg(subLoc)} is not a supported assumption.`);
}
if (typeof value[name] !== "boolean") {
Expand Down
12 changes: 8 additions & 4 deletions packages/babel-core/src/config/validation/options.ts
Expand Up @@ -28,6 +28,8 @@ import {
} from "./option-assertions";
import type { ValidatorSet, Validator, OptionPath } from "./option-assertions";
import type { UnloadedDescriptor } from "../config-descriptors";
import type { ParserOptions } from "@babel/parser";
import type { GeneratorOptions } from "@babel/generator";

const ROOT_VALIDATORS: ValidatorSet = {
cwd: assertString as Validator<ValidatedOptions["cwd"]>,
Expand Down Expand Up @@ -181,9 +183,9 @@ export type ValidatedOptions = {
sourceFileName?: string;
sourceRoot?: string;
// Deprecate top level parserOpts
parserOpts?: {};
parserOpts?: ParserOptions;
// Deprecate top level generatorOpts
generatorOpts?: {};
generatorOpts?: GeneratorOptions;
};

export type NormalizedOptions = {
Expand Down Expand Up @@ -254,7 +256,7 @@ type EnvPath = Readonly<{

export type NestingPath = RootPath | OverridesPath | EnvPath;

export const assumptionsNames = new Set<string>([
const knownAssumptions = [
"arrayLikeIsIterable",
"constantReexports",
"constantSuper",
Expand All @@ -276,7 +278,9 @@ export const assumptionsNames = new Set<string>([
"setSpreadProperties",
"skipForOfIteratorClosing",
"superIsCallableConstructor",
]);
] as const;
export type AssumptionName = typeof knownAssumptions[number];
export const assumptionsNames = new Set(knownAssumptions);

function getSource(loc: NestingPath): OptionsSource {
return loc.type === "root" ? loc.source : getSource(loc.parent);
Expand Down
21 changes: 12 additions & 9 deletions packages/babel-core/src/config/validation/plugins.ts
Expand Up @@ -11,6 +11,10 @@ import type {
OptionPath,
RootPath,
} from "./option-assertions";
import type { ParserOptions } from "@babel/parser";
import type { Visitor } from "@babel/traverse";
import type PluginPass from "../../transformation/plugin-pass";
import type { ValidatedOptions } from "./options";

// Note: The casts here are just meant to be static assertions to make sure
// that the assertion functions actually assert that the value's type matches
Expand All @@ -31,7 +35,7 @@ const VALIDATORS: ValidatorSet = {
>,
};

function assertVisitorMap(loc: OptionPath, value: unknown): VisitorMap {
function assertVisitorMap(loc: OptionPath, value: unknown): Visitor {
const obj = assertObject(loc, value);
if (obj) {
Object.keys(obj).forEach(prop => assertVisitorHandler(prop, obj[prop]));
Expand All @@ -45,7 +49,7 @@ function assertVisitorMap(loc: OptionPath, value: unknown): VisitorMap {
);
}
}
return obj as VisitorMap;
return obj as Visitor;
}

function assertVisitorHandler(
Expand Down Expand Up @@ -74,17 +78,16 @@ type VisitorHandler =
exit?: Function;
};

export type VisitorMap = {
[x: string]: VisitorHandler;
};

export type PluginObject = {
export type PluginObject<S = PluginPass> = {
name?: string;
manipulateOptions?: (options: unknown, parserOpts: unknown) => void;
manipulateOptions?: (
options: ValidatedOptions,
parserOpts: ParserOptions,
) => void;
pre?: Function;
post?: Function;
inherits?: Function;
visitor?: VisitorMap;
visitor?: Visitor<S>;
parserOverride?: Function;
generatorOverride?: Function;
};
Expand Down
7 changes: 7 additions & 0 deletions packages/babel-core/src/index.ts
Expand Up @@ -29,6 +29,13 @@ export {
loadOptionsAsync,
} from "./config";

export type {
PluginAPI,
PluginObject,
PresetAPI,
PresetObject,
} from "./config";

export { transform, transformSync, transformAsync } from "./transform";
export {
transformFile,
Expand Down
1 change: 0 additions & 1 deletion packages/babel-generator/src/generators/methods.ts
Expand Up @@ -146,7 +146,6 @@ function hasTypesOrComments(
return !!(
node.typeParameters ||
node.returnType ||
// @ts-expect-error
node.predicate ||
param.typeAnnotation ||
param.optional ||
Expand Down
19 changes: 6 additions & 13 deletions packages/babel-generator/src/index.ts
@@ -1,7 +1,7 @@
import SourceMap from "./source-map";
import Printer from "./printer";
import type * as t from "@babel/types";

import type { Opts as jsescOptions } from "jsesc";
import type { Format } from "./printer";

/**
Expand Down Expand Up @@ -186,19 +186,12 @@ export interface GeneratorOptions {
/**
* Options for outputting jsesc representation.
*/
jsescOption?: {
/**
* The type of quote to use in the output. If omitted, autodetects based on `ast.tokens`.
*/
quotes?: "single" | "double";

/**
* When enabled, the output is a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified through the quotes setting.
* Defaults to `true`.
*/
wrap?: boolean;
};
jsescOption?: jsescOptions;

/**
* For use with the recordAndTuple token.
*/
recordAndTupleSyntaxType?: "hash" | "bar";
/**
* For use with the Hack-style pipe operator.
* Changes what token is used for pipe bodies’ topic references.
Expand Down
21 changes: 9 additions & 12 deletions packages/babel-helper-create-class-features-plugin/src/index.ts
@@ -1,5 +1,5 @@
import { types as t } from "@babel/core";
import type { File } from "@babel/core";
import type { File, PluginAPI, PluginObject } from "@babel/core";
import type { NodePath } from "@babel/traverse";
import nameFunction from "@babel/helper-function-name";
import splitExportDeclaration from "@babel/helper-split-export-declaration";
Expand All @@ -14,7 +14,6 @@ import { buildDecoratedClass, hasDecorators } from "./decorators";
import { injectInitialization, extractComputedKeys } from "./misc";
import { enableFeature, FEATURES, isLoose, shouldTransform } from "./features";
import { assertFieldTransformed } from "./typescript";
import type { ParserOptions } from "@babel/parser";

export { FEATURES, enableFeature, injectInitialization };

Expand All @@ -33,19 +32,17 @@ interface Options {
name: string;
feature: number;
loose?: boolean;
inherits?: (api: any, options: any) => any;
// same as PluginObject.manipulateOptions
manipulateOptions?: (options: unknown, parserOpts: ParserOptions) => void;
// TODO(flow->ts): change to babel api
api?: { assumption: (key?: string) => boolean | undefined };
inherits?: PluginObject["inherits"];
manipulateOptions?: PluginObject["manipulateOptions"];
api?: PluginAPI;
}

export function createClassFeaturePlugin({
name,
feature,
loose,
manipulateOptions,
// TODO(Babel 8): Remove the default value
// @ts-ignore TODO(Babel 8): Remove the default value
api = { assumption: () => void 0 },
inherits,
}: Options) {
Expand Down Expand Up @@ -188,7 +185,7 @@ export function createClassFeaturePlugin({
const privateNamesMap = buildPrivateNamesMap(props);
const privateNamesNodes = buildPrivateNamesNodes(
privateNamesMap,
privateFieldsAsProperties ?? loose,
(privateFieldsAsProperties ?? loose) as boolean,
state,
);

Expand Down Expand Up @@ -227,9 +224,9 @@ export function createClassFeaturePlugin({
props,
privateNamesMap,
state,
setPublicClassFields ?? loose,
privateFieldsAsProperties ?? loose,
constantSuper ?? loose,
(setPublicClassFields ?? loose) as boolean,
(privateFieldsAsProperties ?? loose) as boolean,
(constantSuper ?? loose) as boolean,
innerBinding,
));
}
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { featuresKey, FEATURES, enableFeature, runtimeKey } from "./features";
import { generateRegexpuOptions, canSkipRegexpu, transformFlags } from "./util";

import { types as t } from "@babel/core";
import type { PluginObject } from "@babel/core";
import annotateAsPure from "@babel/helper-annotate-as-pure";

declare const PACKAGE_JSON: { name: string; version: string };
Expand All @@ -20,8 +21,8 @@ export function createRegExpFeaturePlugin({
name,
feature,
options = {} as any,
manipulateOptions = (() => {}) as (opts: any, parserOpts: any) => void,
}) {
manipulateOptions = (() => {}) as PluginObject["manipulateOptions"],
}): PluginObject {
return {
name,

Expand Down
Expand Up @@ -4,7 +4,7 @@ type RootOptions = {
sourceRoot?: string;
};

type PluginOptions = {
export type PluginOptions = {
moduleId?: string;
moduleIds?: boolean;
getModuleId?: (moduleName: string) => string | null | undefined;
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-helper-module-transforms/src/index.ts
Expand Up @@ -34,6 +34,7 @@ import type {
import type { NodePath } from "@babel/traverse";

export { default as getModuleName } from "./get-module-name";
export type { PluginOptions } from "./get-module-name";

export { hasExports, isSideEffectImport, isModule, rewriteThis };

Expand Down Expand Up @@ -184,7 +185,7 @@ export function wrapInterop(
export function buildNamespaceInitStatements(
metadata: ModuleMetadata,
sourceMetadata: SourceModuleMetadata,
constantReexports: boolean = false,
constantReexports: boolean | void = false,
) {
const statements = [];

Expand Down
40 changes: 24 additions & 16 deletions packages/babel-helper-plugin-utils/src/index.ts
@@ -1,20 +1,24 @@
export function declare<
Args extends
| [any]
| [any, any?]
| [any, any?, any?]
| [any, any]
| [any, any, any?]
| [any, any, any],
Builder extends (...args: Args) => any,
>(
builder: Builder,
// todo(flow->ts) maybe add stricter type for returned function
// reason any is there to not expose exact implementation details in type
// example of issue with this packages/babel-preset-typescript/src/index.ts
): Builder extends (...args: infer A) => any ? (...args: A) => any : never {
import type {
PluginAPI,
PluginObject,
PluginPass,
PresetAPI,
PresetObject,
} from "@babel/core";

export function declare<State = {}, Option = {}>(
builder: (
api: PluginAPI,
options: Option,
dirname: string,
) => PluginObject<State & PluginPass>,
): (
api: PluginAPI,
options: Option,
dirname: string,
) => PluginObject<State & PluginPass> {
// @ts-ignore
return (api, options, dirname) => {
return (api, options: Option, dirname: string) => {
let clonedApi;

for (const name of Object.keys(apiPolyfills)) {
Expand All @@ -30,6 +34,10 @@ export function declare<
};
}

export const declarePreset = declare as <Option = {}>(
builder: (api: PresetAPI, options: Option, dirname: string) => PresetObject,
) => (api: PresetAPI, options: Option, dirname: string) => PresetObject;

const apiPolyfills = {
// Not supported by Babel 7 and early versions of Babel 7 beta.
// It's important that this is polyfilled for older Babel versions
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/plugins/flow/index.js
Expand Up @@ -353,7 +353,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return type;
}

flowParsePredicate(): N.FlowType {
flowParsePredicate(): N.FlowPredicate {
const node = this.startNode();
const moduloLoc = this.state.startLoc;
this.next(); // eat `%`
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-parser/typings/babel-parser.d.ts
Expand Up @@ -182,7 +182,7 @@ export interface DecoratorsPluginOptions {

export interface PipelineOperatorPluginOptions {
proposal: "minimal" | "fsharp" | "hack" | "smart";
topicToken?: "%" | "#" | "@@" | "^^";
topicToken?: "%" | "#" | "@@" | "^^" | "^";
}

export interface RecordAndTuplePluginOptions {
Expand All @@ -191,6 +191,7 @@ export interface RecordAndTuplePluginOptions {

export interface FlowPluginOptions {
all?: boolean;
enums?: boolean;
}

export interface TypeScriptPluginOptions {
Expand Down