@@ -26,11 +26,20 @@ function isNode(node: unknown): node is Node {
2626 return typeof node === 'object' && node !== null && 'type' in node ;
2727}
2828
29+ function unwrapParentheses ( node : unknown ) : unknown {
30+ while ( isNode ( node ) && node . type === 'ParenthesizedExpression' ) {
31+ node = node . expression ;
32+ }
33+
34+ return node ;
35+ }
36+
2937/**
3038 * An implementation of `AstHost` that queries information from `oxc-parser` AST nodes.
3139 */
3240export class OxcAstHost implements AstHost < unknown > {
3341 getSymbolName ( node : unknown ) : string | null {
42+ node = unwrapParentheses ( node ) ;
3443 if ( ! isNode ( node ) ) {
3544 return null ;
3645 }
@@ -47,10 +56,13 @@ export class OxcAstHost implements AstHost<unknown> {
4756 }
4857
4958 isStringLiteral ( node : unknown ) : node is StringLiteral {
59+ node = unwrapParentheses ( node ) ;
60+
5061 return isNode ( node ) && node . type === 'Literal' && typeof node . value === 'string' ;
5162 }
5263
5364 parseStringLiteral ( str : unknown ) : string {
65+ str = unwrapParentheses ( str ) ;
5466 if ( ! this . isStringLiteral ( str ) ) {
5567 throw new FatalLinkerError ( str as object , 'Unsupported syntax, expected a string literal.' ) ;
5668 }
@@ -59,10 +71,13 @@ export class OxcAstHost implements AstHost<unknown> {
5971 }
6072
6173 isNumericLiteral ( node : unknown ) : node is NumericLiteral {
74+ node = unwrapParentheses ( node ) ;
75+
6276 return isNode ( node ) && node . type === 'Literal' && typeof node . value === 'number' ;
6377 }
6478
6579 parseNumericLiteral ( num : unknown ) : number {
80+ num = unwrapParentheses ( num ) ;
6681 if ( ! this . isNumericLiteral ( num ) ) {
6782 throw new FatalLinkerError ( num as object , 'Unsupported syntax, expected a numeric literal.' ) ;
6883 }
@@ -71,6 +86,7 @@ export class OxcAstHost implements AstHost<unknown> {
7186 }
7287
7388 isBooleanLiteral ( node : unknown ) : node is BooleanLiteral | UnaryExpression {
89+ node = unwrapParentheses ( node ) ;
7490 if ( ! isNode ( node ) ) {
7591 return false ;
7692 }
@@ -81,6 +97,7 @@ export class OxcAstHost implements AstHost<unknown> {
8197 }
8298
8399 parseBooleanLiteral ( bool : unknown ) : boolean {
100+ bool = unwrapParentheses ( bool ) ;
84101 if ( isNode ( bool ) ) {
85102 if ( bool . type === 'Literal' && typeof bool . value === 'boolean' ) {
86103 return bool . value ;
@@ -94,14 +111,19 @@ export class OxcAstHost implements AstHost<unknown> {
94111 }
95112
96113 isNull ( node : unknown ) : node is NullLiteral {
114+ node = unwrapParentheses ( node ) ;
115+
97116 return isNode ( node ) && node . type === 'Literal' && node . value === null ;
98117 }
99118
100119 isArrayLiteral ( node : unknown ) : node is ArrayExpression {
120+ node = unwrapParentheses ( node ) ;
121+
101122 return isNode ( node ) && node . type === 'ArrayExpression' ;
102123 }
103124
104125 parseArrayLiteral ( array : unknown ) : unknown [ ] {
126+ array = unwrapParentheses ( array ) ;
105127 if ( ! this . isArrayLiteral ( array ) ) {
106128 throw new FatalLinkerError ( array as object , 'Unsupported syntax, expected an array literal.' ) ;
107129 }
@@ -115,23 +137,27 @@ export class OxcAstHost implements AstHost<unknown> {
115137 'Unsupported syntax, element in array not to be empty.' ,
116138 ) ;
117139 }
118- if ( element . type === 'SpreadElement' ) {
140+ const unwrappedElement = unwrapParentheses ( element ) ;
141+ if ( isNode ( unwrappedElement ) && unwrappedElement . type === 'SpreadElement' ) {
119142 throw new FatalLinkerError (
120- element as object ,
143+ unwrappedElement as object ,
121144 'Unsupported syntax, element in array not to use spread syntax.' ,
122145 ) ;
123146 }
124- result . push ( element ) ;
147+ result . push ( unwrappedElement ) ;
125148 }
126149
127150 return result ;
128151 }
129152
130153 isObjectLiteral ( node : unknown ) : node is ObjectExpression {
154+ node = unwrapParentheses ( node ) ;
155+
131156 return isNode ( node ) && node . type === 'ObjectExpression' ;
132157 }
133158
134159 parseObjectLiteral ( obj : unknown ) : Map < string , unknown > {
160+ obj = unwrapParentheses ( obj ) ;
135161 if ( ! this . isObjectLiteral ( obj ) ) {
136162 throw new FatalLinkerError ( obj as object , 'Unsupported syntax, expected an object literal.' ) ;
137163 }
@@ -146,7 +172,13 @@ export class OxcAstHost implements AstHost<unknown> {
146172 ) ;
147173 }
148174
149- const keyNode = property . key ;
175+ const keyNode = unwrapParentheses ( property . key ) ;
176+ if ( ! isNode ( keyNode ) ) {
177+ throw new FatalLinkerError (
178+ property . key as object ,
179+ 'Unsupported syntax, expected a property name.' ,
180+ ) ;
181+ }
150182
151183 let key : string ;
152184 if ( keyNode . type === 'Identifier' ) {
@@ -162,13 +194,14 @@ export class OxcAstHost implements AstHost<unknown> {
162194 ) ;
163195 }
164196
165- result . set ( key , property . value ) ;
197+ result . set ( key , unwrapParentheses ( property . value ) ) ;
166198 }
167199
168200 return result ;
169201 }
170202
171203 isFunctionExpression ( node : unknown ) : node is FunctionNode | ArrowFunctionExpression {
204+ node = unwrapParentheses ( node ) ;
172205 if ( ! isNode ( node ) ) {
173206 return false ;
174207 }
@@ -181,6 +214,7 @@ export class OxcAstHost implements AstHost<unknown> {
181214 }
182215
183216 parseReturnValue ( fn : unknown ) : unknown {
217+ fn = unwrapParentheses ( fn ) ;
184218 if ( ! this . isFunctionExpression ( fn ) ) {
185219 throw new FatalLinkerError ( fn as object , 'Unsupported syntax, expected a function.' ) ;
186220 }
@@ -191,7 +225,7 @@ export class OxcAstHost implements AstHost<unknown> {
191225 }
192226
193227 if ( body . type !== 'BlockStatement' ) {
194- return body ;
228+ return unwrapParentheses ( body ) ;
195229 }
196230
197231 const statements = body . body ;
@@ -217,10 +251,11 @@ export class OxcAstHost implements AstHost<unknown> {
217251 ) ;
218252 }
219253
220- return stmt . argument ;
254+ return unwrapParentheses ( stmt . argument ) ;
221255 }
222256
223257 parseParameters ( fn : unknown ) : unknown [ ] {
258+ fn = unwrapParentheses ( fn ) ;
224259 if ( ! this . isFunctionExpression ( fn ) ) {
225260 throw new FatalLinkerError ( fn as object , 'Unsupported syntax, expected a function.' ) ;
226261 }
@@ -229,38 +264,44 @@ export class OxcAstHost implements AstHost<unknown> {
229264 }
230265
231266 isCallExpression ( node : unknown ) : node is CallExpression {
267+ node = unwrapParentheses ( node ) ;
268+
232269 return isNode ( node ) && node . type === 'CallExpression' ;
233270 }
234271
235272 parseCallee ( call : unknown ) : unknown {
273+ call = unwrapParentheses ( call ) ;
236274 if ( ! this . isCallExpression ( call ) ) {
237275 throw new FatalLinkerError ( call as object , 'Unsupported syntax, expected a call expression.' ) ;
238276 }
239277
240- return call . callee ;
278+ return unwrapParentheses ( call . callee ) ;
241279 }
242280
243281 parseArguments ( call : unknown ) : unknown [ ] {
282+ call = unwrapParentheses ( call ) ;
244283 if ( ! this . isCallExpression ( call ) ) {
245284 throw new FatalLinkerError ( call as object , 'Unsupported syntax, expected a call expression.' ) ;
246285 }
247286
248287 const result : unknown [ ] = [ ] ;
249288
250289 for ( const arg of call . arguments ) {
251- if ( arg . type === 'SpreadElement' ) {
290+ const unwrappedArg = unwrapParentheses ( arg ) ;
291+ if ( isNode ( unwrappedArg ) && unwrappedArg . type === 'SpreadElement' ) {
252292 throw new FatalLinkerError (
253- arg as object ,
293+ unwrappedArg as object ,
254294 'Unsupported syntax, argument not to use spread syntax.' ,
255295 ) ;
256296 }
257- result . push ( arg ) ;
297+ result . push ( unwrappedArg ) ;
258298 }
259299
260300 return result ;
261301 }
262302
263303 getRange ( node : unknown ) : Range {
304+ node = unwrapParentheses ( node ) ;
264305 if ( ! isNode ( node ) || typeof node . start !== 'number' || typeof node . end !== 'number' ) {
265306 throw new FatalLinkerError (
266307 node as object ,
0 commit comments