Skip to content

Commit c93fff5

Browse files
committed
fix(isolated-declarations): crash when transforming a class with a parameter property in a private constructor
1 parent 56468c7 commit c93fff5

File tree

3 files changed

+129
-16
lines changed

3 files changed

+129
-16
lines changed

crates/oxc_isolated_declarations/src/class.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -289,23 +289,35 @@ impl<'a> IsolatedDeclarations<'a> {
289289
fn transform_constructor_parameter_properties(
290290
&self,
291291
function: &Function<'a>,
292-
params: &FormalParameters<'a>,
292+
typed_params: &FormalParameters<'a>,
293293
) -> ArenaVec<'a, ClassElement<'a>> {
294-
self.ast.vec_from_iter(function.params.items.iter().enumerate().filter_map(
295-
|(index, param)| {
296-
if !param.has_modifier() {
297-
return None;
298-
}
299-
let type_annotation =
300-
if param.accessibility.is_some_and(TSAccessibility::is_private) {
301-
None
302-
} else {
303-
// transformed params will definitely have type annotation
304-
params.items[index].pattern.type_annotation.clone_in(self.ast.allocator)
305-
};
306-
self.transform_formal_parameter_to_class_property(param, type_annotation)
307-
},
308-
))
294+
self.ast.vec_from_iter(
295+
function
296+
.params
297+
.items
298+
.iter()
299+
.filter(|param| {
300+
// To follow up `transform_formal_parameters`'s behavior
301+
typed_params.items.len() == function.params.items.len() || param.has_modifier()
302+
})
303+
.enumerate()
304+
.filter_map(|(index, param)| {
305+
if !param.has_modifier() {
306+
return None;
307+
}
308+
let type_annotation =
309+
if param.accessibility.is_some_and(TSAccessibility::is_private) {
310+
None
311+
} else {
312+
// transformed params will definitely have type annotation
313+
typed_params.items[index]
314+
.pattern
315+
.type_annotation
316+
.clone_in(self.ast.allocator)
317+
};
318+
self.transform_formal_parameter_to_class_property(param, type_annotation)
319+
}),
320+
)
309321
}
310322

311323
/// Collect return_type of getter and first parma type of setter

crates/oxc_isolated_declarations/tests/fixtures/class.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,65 @@ export class ClassParameterProperties {
8181
a: number,
8282
readonly b: string,
8383
) {}
84+
}
85+
86+
export class PrivateConstructorWithParameterProperties {
87+
private constructor(
88+
foo: string,
89+
readonly bar: string,
90+
) {}
91+
}
92+
93+
export class ProtectedConstructorWithParameterProperties {
94+
protected constructor(
95+
public foo: string,
96+
private readonly bar: number,
97+
protected baz: boolean,
98+
readonly qux: string,
99+
) {}
100+
}
101+
102+
export class PrivateConstructorMixedParameterProperties {
103+
private constructor(
104+
public publicProp: string,
105+
private privateProp: number,
106+
protected protectedProp: boolean,
107+
readonly readonlyProp: string,
108+
public readonly publicReadonlyProp: number,
109+
private readonly privateReadonlyProp: boolean,
110+
normalParam: string,
111+
) {}
112+
}
113+
114+
export class PrivateConstructorWithOverloads {
115+
private constructor(a: number);
116+
private constructor(a: string);
117+
private constructor(a: number, b: string);
118+
private constructor(a: any, b?: string) {}
119+
}
120+
121+
export class PrivateConstructorWithOptionalParameters {
122+
private constructor(
123+
required: string,
124+
optional?: number,
125+
public publicOptional?: boolean,
126+
private privateOptional?: string,
127+
readonly readonlyOptional?: number,
128+
) {}
129+
}
130+
131+
export class PrivateConstructorWithRestParameters {
132+
private constructor(
133+
first: string,
134+
...rest: number[]
135+
) {}
136+
}
137+
138+
export class PrivateConstructorWithDefaultParameters {
139+
private constructor(
140+
public prop1: string = "default",
141+
private prop2: number = 42,
142+
readonly prop3: boolean = true,
143+
normalParam: string = "normal",
144+
) {}
84145
}

crates/oxc_isolated_declarations/tests/snapshots/class.snap

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,46 @@ export declare class ClassParameterProperties {
6868
readonly b: string;
6969
constructor(a: number, b: string);
7070
}
71+
export declare class PrivateConstructorWithParameterProperties {
72+
readonly bar: string;
73+
private constructor();
74+
}
75+
export declare class ProtectedConstructorWithParameterProperties {
76+
foo: string;
77+
private readonly bar;
78+
protected baz: boolean;
79+
readonly qux: string;
80+
protected constructor(foo: string, bar: number, baz: boolean, qux: string);
81+
}
82+
export declare class PrivateConstructorMixedParameterProperties {
83+
publicProp: string;
84+
private privateProp;
85+
protected protectedProp: boolean;
86+
readonly readonlyProp: string;
87+
readonly publicReadonlyProp: number;
88+
private readonly privateReadonlyProp;
89+
private constructor();
90+
}
91+
export declare class PrivateConstructorWithOverloads {
92+
private constructor();
93+
private constructor();
94+
private constructor();
95+
}
96+
export declare class PrivateConstructorWithOptionalParameters {
97+
publicOptional?: boolean;
98+
private privateOptional?;
99+
readonly readonlyOptional?: number;
100+
private constructor();
101+
}
102+
export declare class PrivateConstructorWithRestParameters {
103+
private constructor();
104+
}
105+
export declare class PrivateConstructorWithDefaultParameters {
106+
prop1: string;
107+
private prop2;
108+
readonly prop3: boolean;
109+
private constructor();
110+
}
71111

72112

73113
==================== Errors ====================

0 commit comments

Comments
 (0)