Skip to content

Commit 5b2c840

Browse files
committed
fix(napi/parser): raw transfer preserveParens option apply to TSParenthesizedType
1 parent 830b733 commit 5b2c840

File tree

6 files changed

+61
-19
lines changed

6 files changed

+61
-19
lines changed

crates/oxc_ast/src/ast/ts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ pub struct TSIntersectionType<'a> {
403403
#[ast(visit)]
404404
#[derive(Debug)]
405405
#[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
406+
#[estree(via = TSParenthesizedTypeConverter)]
406407
pub struct TSParenthesizedType<'a> {
407408
pub span: Span,
408409
pub type_annotation: TSType<'a>,

crates/oxc_ast/src/generated/derive_estree.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,11 +2346,7 @@ impl ESTree for TSIntersectionType<'_> {
23462346

23472347
impl ESTree for TSParenthesizedType<'_> {
23482348
fn serialize<S: Serializer>(&self, serializer: S) {
2349-
let mut state = serializer.serialize_struct();
2350-
state.serialize_field("type", &JsonSafeString("TSParenthesizedType"));
2351-
state.serialize_field("typeAnnotation", &self.type_annotation);
2352-
state.serialize_span(self.span);
2353-
state.end();
2349+
crate::serialize::ts::TSParenthesizedTypeConverter(self).serialize(serializer)
23542350
}
23552351
}
23562352

crates/oxc_ast/src/serialize/ts.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,38 @@ impl ESTree for TSFunctionTypeParams<'_, '_> {
401401
Concat2(&fn_type.this_param, fn_type.params.as_ref()).serialize(serializer);
402402
}
403403
}
404+
405+
/// Converter for [`TSParenthesizedType`].
406+
///
407+
/// In raw transfer, do not produce a `TSParenthesizedType` node in AST if `preserveParens` is false.
408+
///
409+
/// Not useful in `oxc-parser`, as can use parser option `preserve_parens`.
410+
/// Required for `oxlint` plugins where we run parser with `preserve_parens` set to `true`,
411+
/// to preserve them on Rust side, but need to remove them on JS side.
412+
///
413+
/// ESTree implementation is unchanged from the auto-generated version.
414+
#[ast_meta]
415+
#[estree(raw_deser = "
416+
let node = DESER[TSType](POS_OFFSET.type_annotation);
417+
if (preserveParens) {
418+
node = {
419+
type: 'TSParenthesizedType',
420+
typeAnnotation: node,
421+
start: DESER[u32]( POS_OFFSET.span.start ),
422+
end: DESER[u32]( POS_OFFSET.span.end ),
423+
};
424+
}
425+
node
426+
")]
427+
pub struct TSParenthesizedTypeConverter<'a, 'b>(pub &'b TSParenthesizedType<'a>);
428+
429+
impl ESTree for TSParenthesizedTypeConverter<'_, '_> {
430+
fn serialize<S: Serializer>(&self, serializer: S) {
431+
let paren_type = self.0;
432+
let mut state = serializer.serialize_struct();
433+
state.serialize_field("type", &JsonSafeString("TSParenthesizedType"));
434+
state.serialize_field("typeAnnotation", &paren_type.type_annotation);
435+
state.serialize_span(paren_type.span);
436+
state.end();
437+
}
438+
}

napi/parser/generated/deserialize/js.mjs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,12 +1371,16 @@ function deserializeTSIntersectionType(pos) {
13711371
}
13721372

13731373
function deserializeTSParenthesizedType(pos) {
1374-
return {
1375-
type: 'TSParenthesizedType',
1376-
typeAnnotation: deserializeTSType(pos + 8),
1377-
start: deserializeU32(pos),
1378-
end: deserializeU32(pos + 4),
1379-
};
1374+
let node = deserializeTSType(pos + 8);
1375+
if (preserveParens) {
1376+
node = {
1377+
type: 'TSParenthesizedType',
1378+
typeAnnotation: node,
1379+
start: deserializeU32(pos),
1380+
end: deserializeU32(pos + 4),
1381+
};
1382+
}
1383+
return node;
13801384
}
13811385

13821386
function deserializeTSTypeOperator(pos) {

napi/parser/generated/deserialize/ts.mjs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,12 +1502,16 @@ function deserializeTSIntersectionType(pos) {
15021502
}
15031503

15041504
function deserializeTSParenthesizedType(pos) {
1505-
return {
1506-
type: 'TSParenthesizedType',
1507-
typeAnnotation: deserializeTSType(pos + 8),
1508-
start: deserializeU32(pos),
1509-
end: deserializeU32(pos + 4),
1510-
};
1505+
let node = deserializeTSType(pos + 8);
1506+
if (preserveParens) {
1507+
node = {
1508+
type: 'TSParenthesizedType',
1509+
typeAnnotation: node,
1510+
start: deserializeU32(pos),
1511+
end: deserializeU32(pos + 4),
1512+
};
1513+
}
1514+
return node;
15111515
}
15121516

15131517
function deserializeTSTypeOperator(pos) {

napi/parser/test/parse-raw.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,13 @@ describe.concurrent('`preserveParens` option', () => {
277277
});
278278

279279
it.concurrent('TS', async () => {
280-
const code = 'let x = (1 + 2);';
280+
const code = 'let x = (1 + 2); type T = (string);';
281281

282282
// @ts-ignore
283283
let ret = parseSync('test.ts', code, { experimentalRawTransfer: true, preserveParens: false });
284284
expect(ret.errors.length).toBe(0);
285285
expect(ret.program.body[0].declarations[0].init.type).toBe('BinaryExpression');
286+
expect(ret.program.body[1].typeAnnotation.type).toBe('TSStringKeyword');
286287
});
287288
});
288289

@@ -297,12 +298,13 @@ describe.concurrent('`preserveParens` option', () => {
297298
});
298299

299300
it.concurrent('TS', async () => {
300-
const code = 'let x = (1 + 2);';
301+
const code = 'let x = (1 + 2); type T = (string);';
301302

302303
// @ts-ignore
303304
let ret = parseSync('test.ts', code, { experimentalRawTransfer: true, preserveParens: true });
304305
expect(ret.errors.length).toBe(0);
305306
expect(ret.program.body[0].declarations[0].init.type).toBe('ParenthesizedExpression');
307+
expect(ret.program.body[1].typeAnnotation.type).toBe('TSParenthesizedType');
306308
});
307309
});
308310
});

0 commit comments

Comments
 (0)