Skip to content

Commit a42d85f

Browse files
leaysgurautofix-ci[bot]overlookmotel
authored
fix(estree): FormalParameters serializer for TS types (#10462)
Fixes #10068 --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: overlookmotel <[email protected]>
1 parent d6b7982 commit a42d85f

File tree

6 files changed

+190
-99
lines changed

6 files changed

+190
-99
lines changed

crates/oxc_ast/src/ast/ts.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,7 @@ pub struct TSCallSignatureDeclaration<'a> {
10181018
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
10191019
#[estree(skip)]
10201020
pub this_param: Option<TSThisParameter<'a>>,
1021+
#[estree(via = TSCallSignatureDeclarationFormalParameters)]
10211022
pub params: Box<'a, FormalParameters<'a>>,
10221023
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
10231024
}
@@ -1056,6 +1057,7 @@ pub struct TSMethodSignature<'a> {
10561057
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
10571058
#[estree(skip)]
10581059
pub this_param: Option<Box<'a, TSThisParameter<'a>>>,
1060+
#[estree(via = TSMethodSignatureFormalParameters)]
10591061
pub params: Box<'a, FormalParameters<'a>>,
10601062
pub return_type: Option<Box<'a, TSTypeAnnotation<'a>>>,
10611063
pub scope_id: Cell<Option<ScopeId>>,
@@ -1366,6 +1368,7 @@ pub struct TSFunctionType<'a> {
13661368
#[estree(skip)]
13671369
pub this_param: Option<Box<'a, TSThisParameter<'a>>>,
13681370
/// Function parameters. Akin to [`Function::params`].
1371+
#[estree(via = TSFunctionTypeFormalParameters)]
13691372
pub params: Box<'a, FormalParameters<'a>>,
13701373
/// Return type of the function.
13711374
/// ```ts

crates/oxc_ast/src/generated/derive_estree.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,7 +2930,10 @@ impl ESTree for TSCallSignatureDeclaration<'_> {
29302930
state.serialize_field("start", &self.span.start);
29312931
state.serialize_field("end", &self.span.end);
29322932
state.serialize_field("typeParameters", &self.type_parameters);
2933-
state.serialize_field("params", &self.params);
2933+
state.serialize_field(
2934+
"params",
2935+
&crate::serialize::TSCallSignatureDeclarationFormalParameters(self),
2936+
);
29342937
state.serialize_field("returnType", &self.return_type);
29352938
state.end();
29362939
}
@@ -2957,7 +2960,7 @@ impl ESTree for TSMethodSignature<'_> {
29572960
state.serialize_field("optional", &self.optional);
29582961
state.serialize_field("kind", &self.kind);
29592962
state.serialize_field("typeParameters", &self.type_parameters);
2960-
state.serialize_field("params", &self.params);
2963+
state.serialize_field("params", &crate::serialize::TSMethodSignatureFormalParameters(self));
29612964
state.serialize_field("returnType", &self.return_type);
29622965
state.serialize_field("accessibility", &crate::serialize::Null(self));
29632966
state.serialize_field("readonly", &crate::serialize::False(self));
@@ -3149,7 +3152,7 @@ impl ESTree for TSFunctionType<'_> {
31493152
state.serialize_field("start", &self.span.start);
31503153
state.serialize_field("end", &self.span.end);
31513154
state.serialize_field("typeParameters", &self.type_parameters);
3152-
state.serialize_field("params", &self.params);
3155+
state.serialize_field("params", &crate::serialize::TSFunctionTypeFormalParameters(self));
31533156
state.serialize_field("returnType", &self.return_type);
31543157
state.end();
31553158
}

crates/oxc_ast/src/serialize.rs

Lines changed: 156 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -634,45 +634,6 @@ impl ESTree for FormalParametersRest<'_, '_> {
634634
}
635635
}
636636

637-
/// Serializer for `params` field of `Function`.
638-
///
639-
/// In TS AST, this adds `this_param` to start of the array.
640-
#[ast_meta]
641-
#[estree(
642-
ts_type = "ParamPattern[]",
643-
raw_deser = "
644-
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
645-
/* IF_TS */
646-
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
647-
if (thisParam !== null) params.unshift(thisParam);
648-
/* END_IF_TS */
649-
params
650-
"
651-
)]
652-
pub struct FunctionFormalParameters<'a, 'b>(pub &'b Function<'a>);
653-
654-
impl ESTree for FunctionFormalParameters<'_, '_> {
655-
fn serialize<S: Serializer>(&self, serializer: S) {
656-
let mut seq = serializer.serialize_sequence();
657-
658-
if S::INCLUDE_TS_FIELDS {
659-
if let Some(this_param) = &self.0.this_param {
660-
seq.serialize_element(this_param);
661-
}
662-
}
663-
664-
for item in &self.0.params.items {
665-
seq.serialize_element(item);
666-
}
667-
668-
if let Some(rest) = &self.0.params.rest {
669-
seq.serialize_element(&FormalParametersRest(rest));
670-
}
671-
672-
seq.end();
673-
}
674-
}
675-
676637
/// Serializer for `key` field of `MethodDefinition`.
677638
///
678639
/// In TS-ESTree `"constructor"` in `class C { "constructor"() {} }`
@@ -719,29 +680,6 @@ impl ESTree for MethodDefinitionKey<'_, '_> {
719680
}
720681
}
721682

722-
/// Serializer for `extends` field of `TSInterfaceDeclaration`.
723-
///
724-
/// Serialize `extends` as an empty array if it's `None`.
725-
#[ast_meta]
726-
#[estree(
727-
ts_type = "Array<TSInterfaceHeritage>",
728-
raw_deser = "
729-
const extendsArr = DESER[Option<Vec<TSInterfaceHeritage>>](POS_OFFSET.extends);
730-
extendsArr === null ? [] : extendsArr
731-
"
732-
)]
733-
pub struct TSInterfaceDeclarationExtends<'a, 'b>(pub &'b TSInterfaceDeclaration<'a>);
734-
735-
impl ESTree for TSInterfaceDeclarationExtends<'_, '_> {
736-
fn serialize<S: Serializer>(&self, serializer: S) {
737-
if let Some(extends) = &self.0.extends {
738-
extends.serialize(serializer);
739-
} else {
740-
[(); 0].serialize(serializer);
741-
}
742-
}
743-
}
744-
745683
/// Serializer for `specifiers` field of `ImportDeclaration`.
746684
///
747685
/// Serialize `specifiers` as an empty array if it's `None`.
@@ -1127,6 +1065,162 @@ impl ESTree for TSMappedTypeModifierOperatorConverter<'_> {
11271065
}
11281066
}
11291067

1068+
/// Serializer for `params` field of `Function`.
1069+
///
1070+
/// In TS AST, this adds `this_param` to start of the `params` array.
1071+
#[ast_meta]
1072+
#[estree(
1073+
ts_type = "ParamPattern[]",
1074+
raw_deser = "
1075+
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
1076+
/* IF_TS */
1077+
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
1078+
if (thisParam !== null) params.unshift(thisParam);
1079+
/* END_IF_TS */
1080+
params
1081+
"
1082+
)]
1083+
pub struct FunctionFormalParameters<'a, 'b>(pub &'b Function<'a>);
1084+
1085+
impl ESTree for FunctionFormalParameters<'_, '_> {
1086+
fn serialize<S: Serializer>(&self, serializer: S) {
1087+
let mut seq = serializer.serialize_sequence();
1088+
1089+
if S::INCLUDE_TS_FIELDS {
1090+
if let Some(this_param) = &self.0.this_param {
1091+
seq.serialize_element(this_param);
1092+
}
1093+
}
1094+
1095+
for item in &self.0.params.items {
1096+
seq.serialize_element(item);
1097+
}
1098+
1099+
if let Some(rest) = &self.0.params.rest {
1100+
seq.serialize_element(&FormalParametersRest(rest));
1101+
}
1102+
1103+
seq.end();
1104+
}
1105+
}
1106+
1107+
/// Serializer for `params` field of `TSCallSignatureDeclaration`.
1108+
///
1109+
/// These add `this_param` to start of the `params` array.
1110+
#[ast_meta]
1111+
#[estree(
1112+
ts_type = "ParamPattern[]",
1113+
raw_deser = "
1114+
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
1115+
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
1116+
if (thisParam !== null) params.unshift(thisParam);
1117+
params
1118+
"
1119+
)]
1120+
pub struct TSCallSignatureDeclarationFormalParameters<'a, 'b>(
1121+
pub &'b TSCallSignatureDeclaration<'a>,
1122+
);
1123+
1124+
impl ESTree for TSCallSignatureDeclarationFormalParameters<'_, '_> {
1125+
fn serialize<S: Serializer>(&self, serializer: S) {
1126+
let v = self.0;
1127+
serialize_formal_params_with_this_param(v.this_param.as_ref(), &v.params, serializer);
1128+
}
1129+
}
1130+
1131+
/// Serializer for `params` field of `TSMethodSignature`.
1132+
///
1133+
/// These add `this_param` to start of the `params` array.
1134+
#[ast_meta]
1135+
#[estree(
1136+
ts_type = "ParamPattern[]",
1137+
raw_deser = "
1138+
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
1139+
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
1140+
if (thisParam !== null) params.unshift(thisParam);
1141+
params
1142+
"
1143+
)]
1144+
pub struct TSMethodSignatureFormalParameters<'a, 'b>(pub &'b TSMethodSignature<'a>);
1145+
1146+
impl ESTree for TSMethodSignatureFormalParameters<'_, '_> {
1147+
fn serialize<S: Serializer>(&self, serializer: S) {
1148+
let v = self.0;
1149+
serialize_formal_params_with_this_param(v.this_param.as_deref(), &v.params, serializer);
1150+
}
1151+
}
1152+
1153+
/// Serializer for `params` field of `TSFunctionType`.
1154+
///
1155+
/// These add `this_param` to start of the `params` array.
1156+
#[ast_meta]
1157+
#[estree(
1158+
ts_type = "ParamPattern[]",
1159+
raw_deser = "
1160+
const params = DESER[Box<FormalParameters>](POS_OFFSET.params);
1161+
const thisParam = DESER[Option<Box<TSThisParameter>>](POS_OFFSET.this_param)
1162+
if (thisParam !== null) params.unshift(thisParam);
1163+
params
1164+
"
1165+
)]
1166+
pub struct TSFunctionTypeFormalParameters<'a, 'b>(pub &'b TSFunctionType<'a>);
1167+
1168+
impl ESTree for TSFunctionTypeFormalParameters<'_, '_> {
1169+
fn serialize<S: Serializer>(&self, serializer: S) {
1170+
let v = self.0;
1171+
serialize_formal_params_with_this_param(v.this_param.as_deref(), &v.params, serializer);
1172+
}
1173+
}
1174+
1175+
/// Shared serialization logic used by:
1176+
/// - `TSCallSignatureDeclarationFormalParameters`
1177+
/// - `TSMethodSignatureFormalParameters`
1178+
/// - `TSFunctionTypeFormalParameters`
1179+
fn serialize_formal_params_with_this_param<'a, S: Serializer>(
1180+
this_param: Option<&TSThisParameter<'a>>,
1181+
params: &FormalParameters<'a>,
1182+
serializer: S,
1183+
) {
1184+
let mut seq = serializer.serialize_sequence();
1185+
1186+
if let Some(this_param) = this_param {
1187+
seq.serialize_element(this_param);
1188+
}
1189+
1190+
for item in &params.items {
1191+
seq.serialize_element(item);
1192+
}
1193+
1194+
if let Some(rest) = &params.rest {
1195+
seq.serialize_element(&FormalParametersRest(rest));
1196+
}
1197+
1198+
seq.end();
1199+
}
1200+
1201+
/// Serializer for `extends` field of `TSInterfaceDeclaration`.
1202+
///
1203+
/// Serialize `extends` as an empty array if it's `None`.
1204+
#[ast_meta]
1205+
#[estree(
1206+
ts_type = "Array<TSInterfaceHeritage>",
1207+
raw_deser = "
1208+
const extendsArr = DESER[Option<Vec<TSInterfaceHeritage>>](POS_OFFSET.extends);
1209+
extendsArr === null ? [] : extendsArr
1210+
"
1211+
)]
1212+
pub struct TSInterfaceDeclarationExtends<'a, 'b>(pub &'b TSInterfaceDeclaration<'a>);
1213+
1214+
impl ESTree for TSInterfaceDeclarationExtends<'_, '_> {
1215+
fn serialize<S: Serializer>(&self, serializer: S) {
1216+
if let Some(extends) = &self.0.extends {
1217+
extends.serialize(serializer);
1218+
} else {
1219+
EmptyArray(()).serialize(serializer);
1220+
}
1221+
}
1222+
}
1223+
11301224
// --------------------
11311225
// Comments
11321226
// --------------------

napi/parser/deserialize-js.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,17 +1685,23 @@ function deserializeTSIndexSignature(pos) {
16851685
}
16861686

16871687
function deserializeTSCallSignatureDeclaration(pos) {
1688+
const params = deserializeBoxFormalParameters(pos + 48);
1689+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 16);
1690+
if (thisParam !== null) params.unshift(thisParam);
16881691
return {
16891692
type: 'TSCallSignatureDeclaration',
16901693
start: deserializeU32(pos),
16911694
end: deserializeU32(pos + 4),
16921695
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8),
1693-
params: deserializeBoxFormalParameters(pos + 48),
1696+
params,
16941697
returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56),
16951698
};
16961699
}
16971700

16981701
function deserializeTSMethodSignature(pos) {
1702+
const params = deserializeBoxFormalParameters(pos + 48);
1703+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 40);
1704+
if (thisParam !== null) params.unshift(thisParam);
16991705
return {
17001706
type: 'TSMethodSignature',
17011707
start: deserializeU32(pos),
@@ -1705,7 +1711,7 @@ function deserializeTSMethodSignature(pos) {
17051711
optional: deserializeBool(pos + 25),
17061712
kind: deserializeTSMethodSignatureKind(pos + 26),
17071713
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 32),
1708-
params: deserializeBoxFormalParameters(pos + 48),
1714+
params,
17091715
returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56),
17101716
accessibility: null,
17111717
readonly: false,
@@ -1823,12 +1829,15 @@ function deserializeTSImportType(pos) {
18231829
}
18241830

18251831
function deserializeTSFunctionType(pos) {
1832+
const params = deserializeBoxFormalParameters(pos + 24);
1833+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 16);
1834+
if (thisParam !== null) params.unshift(thisParam);
18261835
return {
18271836
type: 'TSFunctionType',
18281837
start: deserializeU32(pos),
18291838
end: deserializeU32(pos + 4),
18301839
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8),
1831-
params: deserializeBoxFormalParameters(pos + 24),
1840+
params,
18321841
returnType: deserializeBoxTSTypeAnnotation(pos + 32),
18331842
};
18341843
}

napi/parser/deserialize-ts.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,17 +1804,23 @@ function deserializeTSIndexSignature(pos) {
18041804
}
18051805

18061806
function deserializeTSCallSignatureDeclaration(pos) {
1807+
const params = deserializeBoxFormalParameters(pos + 48);
1808+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 16);
1809+
if (thisParam !== null) params.unshift(thisParam);
18071810
return {
18081811
type: 'TSCallSignatureDeclaration',
18091812
start: deserializeU32(pos),
18101813
end: deserializeU32(pos + 4),
18111814
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8),
1812-
params: deserializeBoxFormalParameters(pos + 48),
1815+
params,
18131816
returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56),
18141817
};
18151818
}
18161819

18171820
function deserializeTSMethodSignature(pos) {
1821+
const params = deserializeBoxFormalParameters(pos + 48);
1822+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 40);
1823+
if (thisParam !== null) params.unshift(thisParam);
18181824
return {
18191825
type: 'TSMethodSignature',
18201826
start: deserializeU32(pos),
@@ -1824,7 +1830,7 @@ function deserializeTSMethodSignature(pos) {
18241830
optional: deserializeBool(pos + 25),
18251831
kind: deserializeTSMethodSignatureKind(pos + 26),
18261832
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 32),
1827-
params: deserializeBoxFormalParameters(pos + 48),
1833+
params,
18281834
returnType: deserializeOptionBoxTSTypeAnnotation(pos + 56),
18291835
accessibility: null,
18301836
readonly: false,
@@ -1942,12 +1948,15 @@ function deserializeTSImportType(pos) {
19421948
}
19431949

19441950
function deserializeTSFunctionType(pos) {
1951+
const params = deserializeBoxFormalParameters(pos + 24);
1952+
const thisParam = deserializeOptionBoxTSThisParameter(pos + 16);
1953+
if (thisParam !== null) params.unshift(thisParam);
19451954
return {
19461955
type: 'TSFunctionType',
19471956
start: deserializeU32(pos),
19481957
end: deserializeU32(pos + 4),
19491958
typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 8),
1950-
params: deserializeBoxFormalParameters(pos + 24),
1959+
params,
19511960
returnType: deserializeBoxTSTypeAnnotation(pos + 32),
19521961
};
19531962
}

0 commit comments

Comments
 (0)