@@ -40,18 +40,33 @@ impl<'a> ClassDetails<'a> {
40
40
pub ( super ) struct PrivateProp < ' a > {
41
41
pub binding : BoundIdentifier < ' a > ,
42
42
pub is_static : bool ,
43
- pub is_method : bool ,
43
+ pub method_kind : Option < MethodDefinitionKind > ,
44
44
pub is_accessor : bool ,
45
+ // For accessor methods, they have two bindings,
46
+ // one for getter and another for setter.
47
+ pub binding2 : Option < BoundIdentifier < ' a > > ,
45
48
}
46
49
47
50
impl < ' a > PrivateProp < ' a > {
48
51
pub fn new (
49
52
binding : BoundIdentifier < ' a > ,
50
53
is_static : bool ,
51
- is_method : bool ,
54
+ method_kind : Option < MethodDefinitionKind > ,
52
55
is_accessor : bool ,
53
56
) -> Self {
54
- Self { binding, is_static, is_method, is_accessor }
57
+ Self { binding, is_static, method_kind, is_accessor, binding2 : None }
58
+ }
59
+
60
+ pub fn is_method ( & self ) -> bool {
61
+ self . method_kind . is_some ( )
62
+ }
63
+
64
+ pub fn is_accessor ( & self ) -> bool {
65
+ self . is_accessor || self . method_kind . is_some_and ( |kind| kind. is_accessor ( ) )
66
+ }
67
+
68
+ pub fn set_binding2 ( & mut self , binding : BoundIdentifier < ' a > ) {
69
+ self . binding2 = Some ( binding) ;
55
70
}
56
71
}
57
72
@@ -101,46 +116,152 @@ impl<'a> ClassesStack<'a> {
101
116
self . stack . last_mut ( )
102
117
}
103
118
104
- /// Lookup details of private property referred to by `ident`.
105
- pub fn find_private_prop < ' b > (
119
+ fn lookup_private_prop <
120
+ ' b ,
121
+ Ret ,
122
+ RetFn : Fn ( & ' b PrivateProp < ' a > , & ' b mut ClassBindings < ' a > , bool ) -> Ret ,
123
+ > (
106
124
& ' b mut self ,
107
125
ident : & PrivateIdentifier < ' a > ,
108
- ) -> ResolvedPrivateProp < ' a , ' b > {
126
+ ret_fn : RetFn ,
127
+ ) -> Ret {
109
128
// Check for binding in closest class first, then enclosing classes.
110
129
// We skip the first, because this is a `NonEmptyStack` with dummy first entry.
111
130
// TODO: Check there are tests for bindings in enclosing classes.
112
131
for class in self . stack [ 1 ..] . iter_mut ( ) . rev ( ) {
113
132
if let Some ( private_props) = & mut class. private_props {
114
133
if let Some ( prop) = private_props. get ( & ident. name ) {
115
- return ResolvedPrivateProp {
116
- prop_binding : & prop. binding ,
117
- class_bindings : & mut class. bindings ,
118
- is_static : prop. is_static ,
119
- is_method : prop. is_method ,
120
- is_accessor : prop. is_accessor ,
121
- is_declaration : class. is_declaration ,
122
- } ;
134
+ return ret_fn ( prop, & mut class. bindings , class. is_declaration ) ;
123
135
}
124
136
}
125
137
}
126
-
127
138
unreachable ! ( ) ;
128
139
}
140
+
141
+ /// Lookup details of private property referred to by `ident`.
142
+ pub fn find_private_prop < ' b > (
143
+ & ' b mut self ,
144
+ ident : & PrivateIdentifier < ' a > ,
145
+ ) -> ResolvedPrivateProp < ' a , ' b > {
146
+ self . lookup_private_prop ( ident, move |prop, class_bindings, is_declaration| {
147
+ ResolvedPrivateProp {
148
+ prop_binding : & prop. binding ,
149
+ class_bindings,
150
+ is_static : prop. is_static ,
151
+ is_method : prop. is_method ( ) ,
152
+ is_accessor : prop. is_accessor ( ) ,
153
+ is_declaration,
154
+ }
155
+ } )
156
+ }
157
+
158
+ /// Lookup details of readable private property referred to by `ident`.
159
+ pub fn find_readable_private_prop < ' b > (
160
+ & ' b mut self ,
161
+ ident : & PrivateIdentifier < ' a > ,
162
+ ) -> Option < ResolvedPrivateProp < ' a , ' b > > {
163
+ self . lookup_private_prop ( ident, move |prop, class_bindings, is_declaration| {
164
+ let prop_binding = if matches ! ( prop. method_kind, Some ( MethodDefinitionKind :: Set ) ) {
165
+ prop. binding2 . as_ref ( )
166
+ } else {
167
+ Some ( & prop. binding )
168
+ } ;
169
+ prop_binding. map ( |prop_binding| ResolvedPrivateProp {
170
+ prop_binding,
171
+ class_bindings,
172
+ is_static : prop. is_static ,
173
+ is_method : prop. is_method ( ) ,
174
+ is_accessor : prop. is_accessor ( ) ,
175
+ is_declaration,
176
+ } )
177
+ } )
178
+ }
179
+
180
+ /// Lookup details of writeable private property referred to by `ident`.
181
+ /// Returns `Some` if it refers to a private prop and setter method
182
+ pub fn find_writeable_private_prop < ' b > (
183
+ & ' b mut self ,
184
+ ident : & PrivateIdentifier < ' a > ,
185
+ ) -> Option < ResolvedPrivateProp < ' a , ' b > > {
186
+ self . lookup_private_prop ( ident, move |prop, class_bindings, is_declaration| {
187
+ let prop_binding = if matches ! ( prop. method_kind, Some ( MethodDefinitionKind :: Set ) | None )
188
+ {
189
+ Some ( & prop. binding )
190
+ } else {
191
+ prop. binding2 . as_ref ( )
192
+ } ;
193
+ prop_binding. map ( |prop_binding| ResolvedPrivateProp {
194
+ prop_binding,
195
+ class_bindings,
196
+ is_static : prop. is_static ,
197
+ is_method : prop. is_method ( ) ,
198
+ is_accessor : prop. is_accessor ( ) ,
199
+ is_declaration,
200
+ } )
201
+ } )
202
+ }
203
+
204
+ /// Look up details of the private property referred to by ident and it can either be read or written.
205
+ pub fn find_get_set_private_prop < ' b > (
206
+ & ' b mut self ,
207
+ ident : & PrivateIdentifier < ' a > ,
208
+ ) -> ResolvedGetSetPrivateProp < ' a , ' b > {
209
+ self . lookup_private_prop ( ident, move |prop, class_bindings, is_declaration| {
210
+ let ( get_binding, set_binding) = match prop. method_kind {
211
+ Some ( MethodDefinitionKind :: Set ) => ( prop. binding2 . as_ref ( ) , Some ( & prop. binding ) ) ,
212
+ Some ( _) => ( Some ( & prop. binding ) , prop. binding2 . as_ref ( ) ) ,
213
+ _ => ( Some ( & prop. binding ) , Some ( & prop. binding ) ) ,
214
+ } ;
215
+ ResolvedGetSetPrivateProp {
216
+ get_binding,
217
+ set_binding,
218
+ class_bindings,
219
+ is_static : prop. is_static ,
220
+ is_method : prop. is_method ( ) ,
221
+ is_accessor : prop. is_accessor ( ) ,
222
+ is_declaration,
223
+ }
224
+ } )
225
+ }
129
226
}
130
227
131
228
/// Details of a private property resolved for a private field.
132
229
///
133
- /// This is the return value of [`ClassesStack::find_private_prop`].
230
+ /// This is the return value of [`ClassesStack::find_private_prop`],
231
+ /// [`ClassesStack::find_readable_private_prop`] and
232
+ /// [`ClassesStack::find_writeable_private_prop`].
134
233
pub ( super ) struct ResolvedPrivateProp < ' a , ' b > {
135
234
/// Binding for temp var representing the property
136
235
pub prop_binding : & ' b BoundIdentifier < ' a > ,
137
236
/// Bindings for class name and temp var for class
138
237
pub class_bindings : & ' b mut ClassBindings < ' a > ,
139
238
/// `true` if is a static property
140
239
pub is_static : bool ,
141
- /// `true` if is a private method
240
+ /// `true` if is a private method or accessor property
241
+ pub is_method : bool ,
242
+ /// `true` if is a private accessor property or [`PrivateProp::method_kind`] is
243
+ /// `Some(MethodDefinitionKind::Get)` or `Some(MethodDefinitionKind::Set)`
244
+ pub is_accessor : bool ,
245
+ /// `true` if class which defines this property is a class declaration
246
+ pub is_declaration : bool ,
247
+ }
248
+
249
+ /// Details of a private property resolved for a private field.
250
+ ///
251
+ /// This is the return value of [`ClassesStack::find_get_set_private_prop`].
252
+ pub ( super ) struct ResolvedGetSetPrivateProp < ' a , ' b > {
253
+ /// Binding for temp var representing the property or getter method
254
+ pub get_binding : Option < & ' b BoundIdentifier < ' a > > ,
255
+ /// Binding for temp var representing the property or setter method
256
+ pub set_binding : Option < & ' b BoundIdentifier < ' a > > ,
257
+ /// Bindings for class name and temp var for class
258
+ pub class_bindings : & ' b mut ClassBindings < ' a > ,
259
+ /// `true` if is a static property
260
+ pub is_static : bool ,
261
+ /// `true` if is a private method or accessor property
142
262
pub is_method : bool ,
143
- /// `true` if is a private accessor property
263
+ /// `true` if is a private accessor property or [`PrivateProp::method_kind`] is
264
+ /// `Some(MethodDefinitionKind::Get)` or `Some(MethodDefinitionKind::Set)`
144
265
pub is_accessor : bool ,
145
266
/// `true` if class which defines this property is a class declaration
146
267
pub is_declaration : bool ,
0 commit comments