### 🚀 Features -8dd67a6transform-react: Expose TypeScript transform options (Tomas Särnhammar) -deed7dcparser: More friendly error for duplicate import attribute key (#28262) (sapphi-red) ### 🐛 Bug Fixes -eaa8e90ecmascript: Avoid numeric `+` folding when an operand may be a string (#28544) (camc314) -b03c7b8regular_expression: Allow incomplete oversized legacy quantifiers (#28449) (Boshen) -128c67dsemantic: Check strict eval and arguments writes by reference flags (#28445) (Boshen) -c97c43cparser: Reject TypeScript default exports in JavaScript (#28440) (Boshen) -fdd119fspan: Count Unicode characters when filtering typo suggestions (#28452) (Boshen) -cb64638regular_expression: Reject incomplete Unicode atom escapes (#28448) (Boshen) -fc0eed3semantic: Stop let-binding scans at arrow functions (#28444) (Boshen) -3421516parser: Preserve default import names in reexports (#28442) (Boshen) -a1e7e5fparser: Reject optional class members in JavaScript (#28439) (Boshen) -5b9a7bcparser: Parse sloppy let expressions and labels (#28438) (Boshen) -8e61652regex: Reject templates without cooked values (#28345) (Boshen) -3b36543parser: Preserve in-context after TypeScript type arguments (#28300) (Boshen) -2e3126cregex: Decode constructor patterns and flags consistently (#28298) (Boshen) -8a90be2regex: Track capture groups and disjunction identity (#28297) (Boshen) -3dc2cb0regex: Preserve escape values and boundaries (#28296) (Boshen) -fc8acbcparser: Handle leading-zero numeric exponents (#28295) (Boshen) -91a638dparser: Normalize raw template line endings with invalid escapes (#28285) (Boshen) -2ac9a42parser: Allow parenthesized private-in expressions (#28284) (Boshen) -052bca9ast: Prevent greyed out fields in AST types in IDEs (#28335) (overlookmotel) -ed7df7dast/estree: Include comments in TS Program span (#28326) (camc314) ### ⚡ Performance -9b6b7bfregular_expression: Advance validated Unicode escapes directly (#28514) (Boshen) -82e1982regular_expression: Share Unicode property name prefixes (#28513) (Boshen) -5395a40regular_expression: Parse class set character prefixes once (#28512) (Boshen) -3708934regular_expression: Defer literal range dash allocation (#28511) (Boshen) -d85ee3dsemantic: Skip arguments ancestry checks outside classes (#28510) (Boshen) -cf81d07semantic: Reuse private reference resolution (#28509) (Boshen) -a79eebcsemantic: Avoid duplicate maps for public JavaScript members (#28508) (Boshen) -235ca3bsemantic: Skip escape checks for unescaped strings (#28507) (Boshen) -babf44cparser: Reuse shorthand assignment target identifiers (#28504) (Boshen) -444f24aecmascript: Short-circuit simple parameter checks for rest (#28503) (Boshen) -04b20c0semantic: Compute duplicate parameter policy once per list (#28446) (Boshen) -dbf8482parser: Use token lookahead for simple function types (#28489) (Boshen) -bca1275parser: Avoid unused destructuring rest capacity (#28499) (Boshen) -691be5cparser: Compact cover initialized name storage (#28495) (Boshen) -b3b5444parser: Build simple arrow bindings directly (#28493) (Boshen) -e1c9bafparser: Disambiguate single-identifier arrow heads (#28491) (Boshen) -550e98aregular_expression: Avoid rescanning unique capture names (#28450) (Boshen) -10e9fc7parser: Skip duplicate lookup for singleton import attributes (#28441) (Boshen) -5238839parser: Use a stack buffer for float separators (#28435) (Boshen) -6e35e3cparser: Fast-path leaf expressions before delimiters (#28432) (Boshen) -3d7512cparser: Decode Unicode identifiers once (#28414) (Boshen) -30f59f4parser: Factor object type opening brace (#28430) (Boshen) -028a267parser: Always inline postfix update parsing (#28429) (Boshen) -1b5a171parser: Reuse export kind classification (#28424) (Boshen) -179a432parser: Factor return type identifier parsing (#28416) (Boshen) -553dd1dparser: Inline hot paths and fold function dispatch (#28404) (Boshen) -de75d56parser: Combine parenthesized arrow lookahead (#28412) (Boshen) -a768a0cparser: Reuse comment annotations after rewind (#28408) (Boshen) -563d92aparser: Skip redundant source cursor updates (#28409) (Boshen) -7941ca9parser: Factor tuple identifier parsing (#28398) (Boshen) -426c151parser: Construct completed tokens without intermediate writes (#28291) (Boshen) -df42953minifier: Don't request another pass for block unwrapping (#28315) (Dunqing) -c2d663dparser: Avoid vectors for single parenthesized expressions (#28374) (Boshen) -50bd0a9parser: Size delimited lists after the first element (#28373) (Boshen) -bd869b5parser: Bypass redundant operand parsing (#28372) (Boshen) -455fc09parser: Skip keyword checks for plain identifier expressions (#28371) (Boshen) -61303fbparser: Fast-path identifier operands (#28306) (Boshen) -6cf5b1aparser: Guard arrow and conditional parsing (#28305) (Boshen) -3666939parser: Specialize identifier reference parsing (#28303) (Boshen) -0d6641aparser: Skip inapplicable expression parsing paths (#28294) (Boshen) -3be7997parser: Reduce lexer search batch size (#28292) (Boshen) -ab5655aregex: Remove redundant character-class and quantifier checks (#28288) (Boshen) -ec8e8d4parser: Remove redundant grammar and lexer checks (#28287) (Boshen) -c903f5cparser: Specialize known-token parsing (#28286) (Boshen) -2683225str: `static_ident!` and `static_str!` macros guarantee const evaluation (#28340) (overlookmotel) -df90836ast: Reduce compile time of `#[ast]` macro (#28336) (overlookmotel) -8239dacparser: Replace dragonbox_ecma with zmij_ecma (#28282) (Boshen)
Oxc Parser
See usage instructions.
Features
Supports WASM
See https://stackblitz.com/edit/oxc-parser for usage example.
ESTree
When parsing JS or JSX files, the AST returned is fully conformant with the ESTree standard, the same as produced by Acorn.
When parsing TypeScript, the AST conforms to @typescript-eslint/typescript-estree's TS-ESTree format.
If you need all ASTs in the same with-TS-properties format, use the astType: 'ts' option.
The only differences between Oxc's AST and ESTree / TS-ESTree are:
- Support for Stage 3 decorators.
- Support for Stage 3 ECMA features
import deferandimport source. - In TS-ESTree AST,
import.defer(...)andimport.source(...)are represented as anImportExpressionwith'defer'or'source'inphasefield (as in ESTree spec), where TS-ESLint represents these as aCallExpressionwithMetaPropertyas itscallee. - Addition of a non-standard
hashbangfield toProgram.
That aside, the AST should completely align with Acorn's ESTree AST or TS-ESLint's TS-ESTree. Any deviation would be considered a bug.
Property order
ESTree and TS-ESTree do not define an order for node properties. oxc-parser emits them in this
order:
type.- Node-specific fields in Oxc's defined serialization order. Properties containing child nodes
have the same relative order as the entries in
visitorKeys[node.type]. start, thenend.range, when therangeoption is enabled.
visitorKeys is an exported map from a node type to the properties containing that node's children,
in traversal order. For example, visitorKeys.ConditionalExpression is
['test', 'consequent', 'alternate']. This is not alphabetical order: walking alternate before
test would not match the syntax or evaluation order of a conditional expression.
Fields omitted by the selected astType do not change the relative order of the remaining fields.
A generic walker which recursively inspects Object.keys(node) therefore visits standard ESTree
children in the same relative order as Oxc's Visitor and the exported visitorKeys.
AST Types
@oxc-project/types can be used. For example:
import { Statement } from "@oxc-project/types";
Visitor
An AST visitor is provided. See example below.
This package also exports visitor keys which can be used with any other ESTree walker.
import { visitorKeys } from "oxc-parser";
Fast Mode
By default, Oxc parser does not produce semantic errors where symbols and scopes are needed.
To enable semantic errors, apply the option showSemanticErrors: true.
For example,
let foo;
let foo;
Does not produce any errors when showSemanticErrors is false, which is the default behavior.
Fast mode is best suited for parser plugins, where other parts of your build pipeline has already checked for errors.
Please note that turning off fast mode incurs a small performance overhead.
Returns ESM information.
It is likely that you are writing a parser plugin that requires ESM information.
To avoid walking the AST again, Oxc Parser returns ESM information directly.
This information can be used to rewrite import and exports with the help of magic-string,
without any AST manipulations.
export interface EcmaScriptModule {
/**
* Has ESM syntax.
*
* i.e. `import` and `export` statements, and `import.meta`.
*
* Dynamic imports `import('foo')` are ignored since they can be used in non-ESM files.
*/
hasModuleSyntax: boolean;
/** Import statements */
staticImports: Array<StaticImport>;
/** Export statements */
staticExports: Array<StaticExport>;
/** Dynamic import expressions */
dynamicImports: Array<DynamicImport>;
/** Span positions of `import.meta` */
importMetas: Array<Span>;
}
API
Functions
// Synchronous parsing
parseSync(filename: string, sourceText: string, options?: ParserOptions): ParseResult
// Asynchronous parsing
parse(filename: string, sourceText: string, options?: ParserOptions): Promise<ParseResult>
Use parseSync for synchronous parsing. Use parse for asynchronous parsing, which can be beneficial in I/O-bound or concurrent scenarios, though it adds async overhead.
Example
import { parseSync, Visitor } from "oxc-parser";
const code = "const url: String = /* 🤨 */ import.meta.url;";
// File extension is used to determine which dialect to parse source as.
const filename = "test.tsx";
const result = parseSync(filename, code);
// Or use async version: const result = await parse(filename, code);
// An array of errors, if any.
console.log(result.errors);
// AST and comments.
console.log(result.program, result.comments);
// ESM information - imports, exports, `import.meta`s.
console.log(result.module);
// Visit the AST
const visitations = [];
const visitor = new Visitor({
VariableDeclaration(decl) {
visitations.push(`enter ${decl.kind}`);
},
"VariableDeclaration:exit"(decl) {
visitations.push(`exit ${decl.kind}`);
},
Identifier(ident) {
visitations.push(ident.name);
},
});
visitor.visit(result.program);
// Logs: [ 'enter const', 'url', 'String', 'import', 'meta', 'url', 'exit const' ]
console.log(visitations);
Options
All options are optional.
lang:'js'|'jsx'|'ts'|'tsx'. Set language of source. If omitted, language is deduced from file extension.sourceType:'script'|'module'|'unambiguous'. Set source type. Defaults to'module'.astType:'js'|'ts'. Set to'ts'if you want ASTs of plain JS/JSX files to contain TypeScript-specific properties.range:true|false. Iftrue, AST nodes contain arangefield. Defaults tofalse.preserveParens:true|false. Iftrue, parenthesized expressions are represented by (non-standard)ParenthesizedExpressionandTSParenthesizedTypeAST nodes. Defaults totrue.showSemanticErrors:true|false. Iftrue, check file for semantic errors which parser does not otherwise emit e.g.let x; let x;. Has a small performance cost. Defaults tofalse.