Skip to content

Commit 4cf5c9e

Browse files
[babel 8] Use @babel/types for parser's return type (#17117)
1 parent 56ff65a commit 4cf5c9e

File tree

18 files changed

+306
-382
lines changed

18 files changed

+306
-382
lines changed

Gulpfile.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ function buildRollupDts(packages) {
621621
"packages/babel-parser/typings/babel-parser.source.d.ts",
622622
"packages/babel-parser/typings/babel-parser.d.ts",
623623
"// This file is auto-generated! Do not modify it directly.\n" +
624+
"// Run `yarn gulp bundle-dts` to re-generate it.\n" +
624625
// @typescript-eslint/no-redundant-type-constituents can be removed once we drop the IF_BABEL_7 type
625626
"/* eslint-disable @typescript-eslint/consistent-type-imports, @typescript-eslint/no-redundant-type-constituents */",
626627
"packages/babel-parser"

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default [
5656
"packages/babel-standalone/babel.min.js",
5757
"packages/babel-parser/test/expressions",
5858
"packages/babel-core/src/vendor",
59+
"packages/babel-parser/typings/**/*",
5960
"eslint/*/lib",
6061
"eslint/*/node_modules",
6162
"eslint/*/test/fixtures",

packages/babel-core/src/parser/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Handler } from "gensync";
2-
import { parse, type File as ParseResult } from "@babel/parser";
2+
import { parse, type ParseResult } from "@babel/parser";
33
import { codeFrameColumns } from "@babel/code-frame";
44
import generateMissingPluginMessage from "./util/missing-plugin-helper.ts";
55
import type { PluginPasses } from "../config/index.ts";

packages/babel-core/src/transformation/normalize-file.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export default function* normalizeFile(
4646
ast = cloneDeep(ast);
4747
}
4848
} else {
49-
// @ts-expect-error todo: use babel-types ast typings in Babel parser
5049
ast = yield* parser(pluginPasses, options, code);
5150
}
5251

@@ -101,7 +100,7 @@ export default function* normalizeFile(
101100

102101
return new File(options, {
103102
code,
104-
ast: ast as t.File,
103+
ast: ast,
105104
inputMap,
106105
});
107106
}

packages/babel-helpers/src/helpers/asyncIterator.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ declare class AsyncFromSyncIterator<T = any, TReturn = any, TNext = undefined>
5656
// This makes ESLint and TypeScript complain a lot, but it's the only way
5757
function AsyncFromSyncIterator<T, TReturn = any, TNext = undefined>(s: any) {
5858
// @ts-expect-error - Intentionally overriding the constructor.
59-
// eslint-disable-next-line no-class-assign
6059
AsyncFromSyncIterator = function (
6160
this: AsyncFromSyncIterator,
6261
s: Iterator<T>,

packages/babel-helpers/src/helpers/isNativeFunction.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
export default function _isNativeFunction(fn: unknown): fn is Function {
44
// Note: This function returns "true" for core-js functions.
55
try {
6-
// eslint-disable-next-line @typescript-eslint/prefer-includes
76
return Function.toString.call(fn).indexOf("[native code]") !== -1;
87
} catch (_e) {
98
// Firefox 31 throws when "toString" is applied to an HTMLElement

packages/babel-parser/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"conditions": {
5050
"BABEL_8_BREAKING": [
5151
{
52+
"types": null,
5253
"engines": {
5354
"node": "^18.20.0 || ^20.17.0 || >=22.8.0"
5455
}

packages/babel-parser/src/index.ts

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import {
44
mixinPluginNames,
55
mixinPlugins,
66
} from "./plugin-utils.ts";
7-
import type {
7+
export type {
88
PluginConfig as ParserPlugin,
9+
DecoratorsPluginOptions,
910
FlowPluginOptions,
10-
RecordAndTuplePluginOptions,
1111
PipelineOperatorPluginOptions,
12+
RecordAndTuplePluginOptions,
13+
TypeScriptPluginOptions,
1214
} from "./typings.ts";
1315
import Parser, { type PluginsMap } from "./parser/index.ts";
1416

@@ -20,10 +22,28 @@ import {
2022
} from "./tokenizer/types.ts";
2123
export type { Token } from "./tokenizer/index.ts";
2224

23-
import type { Expression, File } from "./types.ts";
25+
// TODO: Rather than type-casting the internal AST definitions to the
26+
// @babel/types one, we should actually unify them.
27+
import type { Expression, File } from "@babel/types";
2428
export type { Expression, File };
2529

26-
export function parse(input: string, options?: Options): File {
30+
export type ParserOptions = Partial<Options>;
31+
32+
export interface ParseError {
33+
code: string;
34+
reasonCode: string;
35+
}
36+
export type ParseResult<Result extends File | Expression = File> = Result & {
37+
errors: null | ParseError[];
38+
};
39+
40+
/**
41+
* Parse the provided code as an entire ECMAScript program.
42+
*/
43+
export function parse(
44+
input: string,
45+
options?: ParserOptions,
46+
): ParseResult<File> {
2747
if (options?.sourceType === "unambiguous") {
2848
options = {
2949
...options,
@@ -34,7 +54,7 @@ export function parse(input: string, options?: Options): File {
3454
const ast = parser.parse();
3555

3656
if (parser.sawUnambiguousESM) {
37-
return ast;
57+
return ast as unknown as ParseResult<File>;
3858
}
3959

4060
if (parser.ambiguousScriptDifferentAst) {
@@ -45,34 +65,43 @@ export function parse(input: string, options?: Options): File {
4565
// can be parsed either as an AwaitExpression, or as two ExpressionStatements.
4666
try {
4767
options.sourceType = "script";
48-
return getParser(options, input).parse();
68+
return getParser(
69+
options,
70+
input,
71+
).parse() as unknown as ParseResult<File>;
4972
} catch {}
5073
} else {
5174
// This is both a valid module and a valid script, but
5275
// we parse it as a script by default
5376
ast.program.sourceType = "script";
5477
}
5578

56-
return ast;
79+
return ast as unknown as ParseResult<File>;
5780
} catch (moduleError) {
5881
try {
5982
options.sourceType = "script";
60-
return getParser(options, input).parse();
83+
return getParser(
84+
options,
85+
input,
86+
).parse() as unknown as ParseResult<File>;
6187
} catch {}
6288

6389
throw moduleError;
6490
}
6591
} else {
66-
return getParser(options, input).parse();
92+
return getParser(options, input).parse() as unknown as ParseResult<File>;
6793
}
6894
}
6995

70-
export function parseExpression(input: string, options?: Options): Expression {
96+
export function parseExpression(
97+
input: string,
98+
options?: ParserOptions,
99+
): ParseResult<Expression> {
71100
const parser = getParser(options, input);
72101
if (parser.options.strictMode) {
73102
parser.state.strict = true;
74103
}
75-
return parser.getExpression();
104+
return parser.getExpression() as unknown as ParseResult<Expression>;
76105
}
77106

78107
function generateExportedTokenTypes(
@@ -135,11 +164,3 @@ function getParserClass(
135164
}
136165
return cls;
137166
}
138-
139-
export type {
140-
FlowPluginOptions,
141-
ParserPlugin,
142-
PipelineOperatorPluginOptions,
143-
RecordAndTuplePluginOptions,
144-
};
145-
export type ParserOptions = Partial<Options>;

packages/babel-parser/src/options.ts

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,138 @@
1-
import type { PluginList } from "./plugin-utils.ts";
1+
import type { Plugin } from "./plugin-utils.ts";
22

33
// A second optional argument can be given to further configure
44
// the parser process. These options are recognized:
55

66
export type SourceType = "script" | "module" | "unambiguous";
77

88
export interface Options {
9-
sourceType?: SourceType;
10-
sourceFilename?: string;
11-
startIndex?: number;
12-
startColumn?: number;
13-
startLine?: number;
9+
/**
10+
* By default, import and export declarations can only appear at a program's top level.
11+
* Setting this option to true allows them anywhere where a statement is allowed.
12+
*/
13+
allowImportExportEverywhere?: boolean;
14+
15+
/**
16+
* By default, await use is not allowed outside of an async function.
17+
* Set this to true to accept such code.
18+
*/
1419
allowAwaitOutsideFunction?: boolean;
20+
21+
/**
22+
* By default, a return statement at the top level raises an error.
23+
* Set this to true to accept such code.
24+
*/
1525
allowReturnOutsideFunction?: boolean;
26+
27+
/**
28+
* By default, new.target use is not allowed outside of a function or class.
29+
* Set this to true to accept such code.
30+
*/
1631
allowNewTargetOutsideFunction?: boolean;
17-
allowImportExportEverywhere?: boolean;
32+
1833
allowSuperOutsideMethod?: boolean;
34+
35+
/**
36+
* By default, exported identifiers must refer to a declared variable.
37+
* Set this to true to allow export statements to reference undeclared variables.
38+
*/
1939
allowUndeclaredExports?: boolean;
20-
plugins?: PluginList;
21-
strictMode?: boolean | undefined | null;
40+
41+
/**
42+
* By default, Babel parser JavaScript code according to Annex B syntax.
43+
* Set this to `false` to disable such behavior.
44+
*/
45+
annexB?: boolean;
46+
47+
/**
48+
* By default, Babel attaches comments to adjacent AST nodes.
49+
* When this option is set to false, comments are not attached.
50+
* It can provide up to 30% performance improvement when the input code has many comments.
51+
* @babel/eslint-parser will set it for you.
52+
* It is not recommended to use attachComment: false with Babel transform,
53+
* as doing so removes all the comments in output code, and renders annotations such as
54+
* /* istanbul ignore next *\/ nonfunctional.
55+
*/
56+
attachComment?: boolean;
57+
58+
/**
59+
* By default, Babel always throws an error when it finds some invalid code.
60+
* When this option is set to true, it will store the parsing error and
61+
* try to continue parsing the invalid input file.
62+
*/
63+
errorRecovery?: boolean;
64+
65+
/**
66+
* Indicate the mode the code should be parsed in.
67+
* Can be one of "script", "module", or "unambiguous". Defaults to "script".
68+
* "unambiguous" will make @babel/parser attempt to guess, based on the presence
69+
* of ES6 import or export statements.
70+
* Files with ES6 imports and exports are considered "module" and are otherwise "script".
71+
*/
72+
sourceType?: "script" | "module" | "unambiguous";
73+
74+
/**
75+
* Correlate output AST nodes with their source filename.
76+
* Useful when generating code and source maps from the ASTs of multiple input files.
77+
*/
78+
sourceFilename?: string;
79+
80+
/**
81+
* By default, all source indexes start from 0.
82+
* You can provide a start index to alternatively start with.
83+
* Useful for integration with other source tools.
84+
*/
85+
startIndex?: number;
86+
87+
/**
88+
* By default, the first line of code parsed is treated as line 1.
89+
* You can provide a line number to alternatively start with.
90+
* Useful for integration with other source tools.
91+
*/
92+
startLine?: number;
93+
94+
/**
95+
* By default, the parsed code is treated as if it starts from line 1, column 0.
96+
* You can provide a column number to alternatively start with.
97+
* Useful for integration with other source tools.
98+
*/
99+
startColumn?: number;
100+
101+
/**
102+
* Array containing the plugins that you want to enable.
103+
*/
104+
plugins?: Plugin[];
105+
106+
/**
107+
* Should the parser work in strict mode.
108+
* Defaults to true if sourceType === 'module'. Otherwise, false.
109+
*/
110+
strictMode?: boolean;
111+
112+
/**
113+
* Adds a ranges property to each node: [node.start, node.end]
114+
*/
22115
ranges?: boolean;
116+
117+
/**
118+
* Adds all parsed tokens to a tokens property on the File node.
119+
*/
23120
tokens?: boolean;
24-
createImportExpressions?: boolean;
121+
122+
/**
123+
* By default, the parser adds information about parentheses by setting
124+
* `extra.parenthesized` to `true` as needed.
125+
* When this option is `true` the parser creates `ParenthesizedExpression`
126+
* AST nodes instead of using the `extra` property.
127+
*/
25128
createParenthesizedExpressions?: boolean;
26-
errorRecovery?: boolean;
27-
attachComment?: boolean;
28-
annexB?: boolean;
129+
130+
/**
131+
* The default is false in Babel 7 and true in Babel 8
132+
* Set this to true to parse it as an `ImportExpression` node.
133+
* Otherwise `import(foo)` is parsed as `CallExpression(Import, [Identifier(foo)])`.
134+
*/
135+
createImportExpressions?: boolean;
29136
}
30137

31138
export const enum OptionFlags {

packages/babel-parser/src/plugin-utils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import type { PluginConfig } from "./typings.ts";
33

44
export type Plugin = PluginConfig;
55

6-
export type PluginList = PluginConfig[];
7-
86
export type MixinPlugin = (
97
superClass: new (...args: any) => Parser,
108
) => new (...args: any) => Parser;

0 commit comments

Comments
 (0)