@@ -7,10 +7,10 @@ use oxc::{
77 AssignmentTargetProperty , BindingPattern , BindingPatternKind , BindingProperty ,
88 CallExpression , ComputedMemberExpression , DebuggerStatement , ExportAllDeclaration ,
99 ExportNamedDeclaration , Expression , FunctionBody , IdentifierReference , ImportDeclaration ,
10- ImportExpression , MemberExpression , MetaProperty , NewExpression , ObjectExpression ,
11- ObjectPattern , ObjectPropertyKind , PrivateIdentifier , PropertyKey , ReturnStatement ,
12- SimpleAssignmentTarget , StringLiteral , ThisExpression , UnaryExpression , UnaryOperator ,
13- UpdateExpression ,
10+ ImportExpression , MemberExpression , MetaProperty , NewExpression , ObjectAssignmentTarget ,
11+ ObjectExpression , ObjectPattern , ObjectPropertyKind , PrivateIdentifier , PropertyKey ,
12+ ReturnStatement , SimpleAssignmentTarget , StringLiteral , ThisExpression , UnaryExpression ,
13+ UnaryOperator , UpdateExpression ,
1414 } ,
1515 ast_visit:: { Visit , walk} ,
1616 span:: { Atom , GetSpan , Span } ,
@@ -104,6 +104,79 @@ where
104104 }
105105 }
106106
107+ fn recurse_object_assignment_target ( & mut self , s : & ObjectAssignmentTarget < ' data > ) {
108+ if s. rest . is_some ( ) {
109+ // infeasible to rewrite :(
110+ eprintln ! ( "cannot rewrite rest parameters" ) ;
111+ return ;
112+ }
113+ for prop in & s. properties {
114+ match prop {
115+ AssignmentTargetProperty :: AssignmentTargetPropertyIdentifier ( p) => {
116+ // { location } = self;
117+ // correct thing to do here is to change it into an AsignmentTargetPropertyProperty
118+ // { $sj_location: location } = self;
119+ if UNSAFE_GLOBALS . contains ( & p. binding . name . to_string ( ) . as_str ( ) ) {
120+ self . jschanges . add ( rewrite ! (
121+ p. binding. span( ) ,
122+ RebindProperty {
123+ ident: p. binding. name. clone( )
124+ }
125+ ) ) ;
126+ }
127+
128+ if let Some ( d) = & p. init {
129+ // { location = parent } = {};
130+ // we still need to rewrite whatever stuff might be in the default expression
131+ walk:: walk_expression ( self , & d) ;
132+ }
133+ }
134+ AssignmentTargetProperty :: AssignmentTargetPropertyProperty ( p) => {
135+ // { location: x } = self;
136+ // { location: x = "..."} = self;
137+ // { location: { href } } = self;
138+ // { location: { href: x } } = self;
139+ // { ["location"]: x } = self;
140+
141+ match & p. name {
142+ PropertyKey :: StaticIdentifier ( id) => {
143+ // { location: x } = self;
144+ if UNSAFE_GLOBALS . contains ( & id. name . to_string ( ) . as_str ( ) ) {
145+ self . jschanges . add ( rewrite ! (
146+ p. name. span( ) ,
147+ RewriteProperty { ident: id. name }
148+ ) ) ;
149+ }
150+ }
151+ PropertyKey :: PrivateIdentifier ( _) => {
152+ // doesn't matter
153+ }
154+ // (expression variant)
155+ _ => {
156+ // { ["location"]: x } = self;
157+
158+ // TODO: check literals
159+ self . jschanges . add ( rewrite ! ( p. name. span( ) , WrapProperty ) ) ;
160+ }
161+ }
162+
163+ match & p. binding {
164+ AssignmentTargetMaybeDefault :: AssignmentTargetWithDefault ( d) => {
165+ // { location: x = parent } = {};
166+
167+ // we still need to rewrite whatever stuff might be in the default expression
168+ walk:: walk_expression ( self , & d. init ) ;
169+ }
170+ AssignmentTargetMaybeDefault :: ObjectAssignmentTarget ( p) => {
171+ self . recurse_object_assignment_target ( p) ;
172+ }
173+ _ => { }
174+ }
175+ }
176+ }
177+ }
178+ }
179+
107180 fn scramitize ( & mut self , span : Span ) {
108181 self . jschanges . add ( rewrite ! ( span, Scramitize ) ) ;
109182 }
@@ -376,106 +449,6 @@ where
376449 }
377450 }
378451
379- fn visit_assignment_target ( & mut self , it : & AssignmentTarget < ' data > ) {
380- match & it {
381- AssignmentTarget :: StaticMemberExpression ( s) => {
382- if UNSAFE_GLOBALS . contains ( & s. property . name . as_str ( ) ) {
383- self . jschanges . add ( rewrite ! (
384- s. property. span( ) ,
385- RewriteProperty {
386- ident: s. property. name
387- }
388- ) ) ;
389- }
390-
391- // more to walk
392- walk:: walk_expression ( self , & s. object ) ;
393- }
394- AssignmentTarget :: ComputedMemberExpression ( s) => {
395- self . walk_computed_member_expression ( s) ;
396- walk:: walk_expression ( self , & s. object ) ;
397- walk:: walk_expression ( self , & s. expression ) ;
398- }
399- AssignmentTarget :: ObjectAssignmentTarget ( s) => {
400- if s. rest . is_some ( ) {
401- // infeasible to rewrite :(
402- eprintln ! ( "cannot rewrite rest parameters" ) ;
403- return ;
404- }
405- for prop in & s. properties {
406- match prop {
407- AssignmentTargetProperty :: AssignmentTargetPropertyIdentifier ( p) => {
408- // { location } = self;
409- // correct thing to do here is to change it into an AsignmentTargetPropertyProperty
410- // { $sj_location: location } = self;
411- if UNSAFE_GLOBALS . contains ( & p. binding . name . to_string ( ) . as_str ( ) ) {
412- self . jschanges . add ( rewrite ! (
413- p. binding. span( ) ,
414- RebindProperty {
415- ident: p. binding. name. clone( )
416- }
417- ) ) ;
418- }
419- }
420- AssignmentTargetProperty :: AssignmentTargetPropertyProperty ( p) => {
421- // { location: x } = self;
422- // { location: x = "..."} = self;
423- // { location: { href } } = self;
424- // { location: { href: x } } = self;
425- // { ["location"]: x } = self;
426-
427- match & p. name {
428- PropertyKey :: StaticIdentifier ( id) => {
429- // { location: x } = self;
430- if UNSAFE_GLOBALS . contains ( & id. name . to_string ( ) . as_str ( ) ) {
431- self . jschanges . add ( rewrite ! (
432- p. name. span( ) ,
433- RewriteProperty { ident: id. name }
434- ) ) ;
435- }
436- }
437- PropertyKey :: PrivateIdentifier ( _) => {
438- // doesn't matter
439- }
440- // (expression variant)
441- _ => {
442- // { ["location"]: x } = self;
443-
444- // TODO: check literals
445- self . jschanges . add ( rewrite ! ( p. name. span( ) , WrapProperty ) ) ;
446- }
447- }
448-
449- match & p. binding {
450- AssignmentTargetMaybeDefault :: AssignmentTargetWithDefault ( d) => {
451- // { location: x = parent } = {};
452- // { location = parent } = {};
453-
454- // we still need to rewrite whatever stuff might be in the default expression
455- walk:: walk_expression ( self , & d. init ) ;
456- }
457- _ => {
458- // { location: { href } } = {};
459- walk:: walk_assignment_target_maybe_default ( self , & p. binding ) ;
460- }
461- }
462- }
463- }
464- }
465- }
466- AssignmentTarget :: ArrayAssignmentTarget ( _) => {
467- // [location] = ["https://example.com"]
468- // this is such a ridiculously specific edge case. just ignore it
469- return ;
470- }
471- _ => {
472- // only walk the left side if it isn't an identifier, we can't replace the
473- // identifier with a function obviously
474- walk:: walk_assignment_target ( self , & it) ;
475- }
476- }
477- }
478-
479452 fn visit_assignment_expression ( & mut self , it : & AssignmentExpression < ' data > ) {
480453 // location = "https://example.com"
481454 match & it. left {
@@ -495,9 +468,29 @@ where
495468 return ;
496469 }
497470 }
498- _ => {
499- // gets handled by visit_assignment_target
471+ AssignmentTarget :: StaticMemberExpression ( s) => {
472+ if UNSAFE_GLOBALS . contains ( & s. property . name . as_str ( ) ) {
473+ self . jschanges . add ( rewrite ! (
474+ s. property. span( ) ,
475+ RewriteProperty {
476+ ident: s. property. name
477+ }
478+ ) ) ;
479+ }
480+
481+ // more to walk
482+ walk:: walk_expression ( self , & s. object ) ;
483+ }
484+ AssignmentTarget :: ComputedMemberExpression ( s) => {
485+ self . walk_computed_member_expression ( s) ;
486+ walk:: walk_expression ( self , & s. object ) ;
487+ walk:: walk_expression ( self , & s. expression ) ;
500488 }
489+ AssignmentTarget :: ObjectAssignmentTarget ( o) => {
490+ self . recurse_object_assignment_target ( o) ;
491+ return ;
492+ }
493+ _ => { }
501494 }
502495 walk:: walk_assignment_expression ( self , it) ;
503496 }
0 commit comments