@@ -10,10 +10,6 @@ use crate::Scopes;
1010
1111pub ( crate ) use swc_ecma_parser:: error:: Error as ParseError ;
1212
13- // TODO:
14- // - getters / setters
15- // - maybe even computed properties?
16-
1713pub fn parse_with_swc ( src : & str ) -> Result < Scopes , ParseError > {
1814 let syntax = tracing:: trace_span!( "parsing source" ) . in_scope ( || {
1915 let input = StringInput :: new ( src, BytePos ( 0 ) , BytePos ( src. len ( ) as u32 ) ) ;
@@ -116,6 +112,46 @@ impl VisitAstPath for ScopeCollector {
116112
117113 node. visit_children_with_path ( self , path) ;
118114 }
115+
116+ fn visit_getter_prop < ' ast : ' r , ' r > (
117+ & mut self ,
118+ node : & ' ast ast:: GetterProp ,
119+ path : & mut AstNodePath < ' r > ,
120+ ) {
121+ let mut name = match infer_name_from_ctx ( path) {
122+ Some ( mut scope_name) => {
123+ scope_name. components . push_back ( NameComponent :: interp ( "." ) ) ;
124+ scope_name
125+ }
126+ None => ScopeName :: new ( ) ,
127+ } ;
128+ name. components . push_back ( prop_name_to_component ( & node. key ) ) ;
129+ name. components . push_front ( NameComponent :: interp ( "get " ) ) ;
130+
131+ self . scopes . push ( ( convert_span ( node. span ) , Some ( name) ) ) ;
132+
133+ node. visit_children_with_path ( self , path) ;
134+ }
135+
136+ fn visit_setter_prop < ' ast : ' r , ' r > (
137+ & mut self ,
138+ node : & ' ast ast:: SetterProp ,
139+ path : & mut AstNodePath < ' r > ,
140+ ) {
141+ let mut name = match infer_name_from_ctx ( path) {
142+ Some ( mut scope_name) => {
143+ scope_name. components . push_back ( NameComponent :: interp ( "." ) ) ;
144+ scope_name
145+ }
146+ None => ScopeName :: new ( ) ,
147+ } ;
148+ name. components . push_back ( prop_name_to_component ( & node. key ) ) ;
149+ name. components . push_front ( NameComponent :: interp ( "set " ) ) ;
150+
151+ self . scopes . push ( ( convert_span ( node. span ) , Some ( name) ) ) ;
152+
153+ node. visit_children_with_path ( self , path) ;
154+ }
119155}
120156
121157/// Uses either the provided [`ast::Ident`] or infers the name from the `path`.
@@ -133,6 +169,7 @@ fn name_from_ident_or_ctx(ident: Option<ast::Ident>, path: &AstNodePath) -> Opti
133169/// Tries to infer a name by walking up the path of ancestors.
134170fn infer_name_from_ctx ( path : & AstNodePath ) -> Option < ScopeName > {
135171 let mut scope_name = ScopeName :: new ( ) ;
172+ let mut kind = ast:: MethodKind :: Method ;
136173
137174 fn push_sep ( name : & mut ScopeName ) {
138175 if !name. components . is_empty ( ) {
@@ -150,27 +187,33 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
150187 // have part of the name.
151188 Parent :: ClassExpr ( class_expr, _) => {
152189 if let Some ( ident) = & class_expr. ident {
190+ push_sep ( & mut scope_name) ;
153191 scope_name
154192 . components
155193 . push_front ( NameComponent :: ident ( ident. clone ( ) ) ) ;
194+
195+ prefix_getters_setters ( kind, & mut scope_name) ;
196+
197+ return Some ( scope_name) ;
156198 }
157199 }
158200 Parent :: ClassDecl ( class_decl, _) => {
159201 push_sep ( & mut scope_name) ;
160202 scope_name
161203 . components
162204 . push_front ( NameComponent :: ident ( class_decl. ident . clone ( ) ) ) ;
205+
206+ prefix_getters_setters ( kind, & mut scope_name) ;
207+
163208 return Some ( scope_name) ;
164209 }
165210
166211 // An object literal member:
167212 // `{ $name() ... }`
168213 Parent :: MethodProp ( method, _) => {
169- if let Some ( ident) = method. key . as_ident ( ) {
170- scope_name
171- . components
172- . push_front ( NameComponent :: ident ( ident. clone ( ) ) ) ;
173- }
214+ scope_name
215+ . components
216+ . push_front ( prop_name_to_component ( & method. key ) ) ;
174217 }
175218
176219 // An object literal property:
@@ -186,11 +229,11 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
186229 // A class method:
187230 // `class { $name() ... }`
188231 Parent :: ClassMethod ( method, _) => {
189- if let Some ( ident ) = method . key . as_ident ( ) {
190- scope_name
191- . components
192- . push_front ( NameComponent :: ident ( ident . clone ( ) ) ) ;
193- }
232+ scope_name
233+ . components
234+ . push_front ( prop_name_to_component ( & method . key ) ) ;
235+
236+ kind = method . kind ;
194237 }
195238
196239 // A private class method:
@@ -210,6 +253,9 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
210253 scope_name
211254 . components
212255 . push_front ( NameComponent :: ident ( ident. id . clone ( ) ) ) ;
256+
257+ prefix_getters_setters ( kind, & mut scope_name) ;
258+
213259 return Some ( scope_name) ;
214260 }
215261 }
@@ -224,6 +270,8 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
224270 expr_name. components . append ( & mut scope_name. components ) ;
225271 scope_name. components = expr_name. components ;
226272
273+ prefix_getters_setters ( kind, & mut scope_name) ;
274+
227275 return Some ( scope_name) ;
228276 }
229277 }
@@ -233,6 +281,9 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
233281 scope_name
234282 . components
235283 . push_front ( NameComponent :: ident ( ident. id . clone ( ) ) ) ;
284+
285+ prefix_getters_setters ( kind, & mut scope_name) ;
286+
236287 return Some ( scope_name) ;
237288 }
238289 ast:: Pat :: Expr ( expr) => {
@@ -242,6 +293,8 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
242293 expr_name. components . append ( & mut scope_name. components ) ;
243294 scope_name. components = expr_name. components ;
244295
296+ prefix_getters_setters ( kind, & mut scope_name) ;
297+
245298 return Some ( scope_name) ;
246299 }
247300 }
@@ -256,6 +309,18 @@ fn infer_name_from_ctx(path: &AstNodePath) -> Option<ScopeName> {
256309 None
257310}
258311
312+ fn prefix_getters_setters ( kind : ast:: MethodKind , scope_name : & mut ScopeName ) {
313+ match kind {
314+ ast:: MethodKind :: Getter => scope_name
315+ . components
316+ . push_front ( NameComponent :: interp ( "get " ) ) ,
317+ ast:: MethodKind :: Setter => scope_name
318+ . components
319+ . push_front ( NameComponent :: interp ( "set " ) ) ,
320+ _ => { }
321+ }
322+ }
323+
259324/// Returns a [`ScopeName`] corresponding to the given [`ast::Expr`].
260325///
261326/// This is only possible if the expression is an identifier or a member expression.
@@ -291,3 +356,13 @@ fn infer_name_from_expr(mut expr: &ast::Expr) -> Option<ScopeName> {
291356 }
292357 }
293358}
359+
360+ fn prop_name_to_component ( prop : & ast:: PropName ) -> NameComponent {
361+ match prop {
362+ ast:: PropName :: Ident ( ref i) => NameComponent :: ident ( i. clone ( ) ) ,
363+ ast:: PropName :: Str ( s) => NameComponent :: interp ( format ! ( "<\" {}\" >" , s. value) ) ,
364+ ast:: PropName :: Num ( n) => NameComponent :: interp ( format ! ( "<{}>" , n) ) ,
365+ ast:: PropName :: Computed ( _) => NameComponent :: interp ( "<computed property name>" ) ,
366+ ast:: PropName :: BigInt ( i) => NameComponent :: interp ( format ! ( "<{}n>" , i. value) ) ,
367+ }
368+ }
0 commit comments