@@ -3,11 +3,12 @@ use std::error::Error;
33use oxc:: {
44 allocator:: { Allocator , StringBuilder } ,
55 ast:: ast:: {
6- AssignmentExpression , AssignmentTarget , BindingPattern , CallExpression ,
7- ComputedMemberExpression , DebuggerStatement , ExportAllDeclaration , ExportNamedDeclaration ,
8- Expression , FunctionBody , IdentifierReference , ImportDeclaration , ImportExpression ,
9- MemberExpression , MetaProperty , NewExpression , ObjectExpression , ObjectPattern ,
10- ObjectPropertyKind , ReturnStatement , SimpleAssignmentTarget , StringLiteral , ThisExpression ,
6+ AssignmentExpression , AssignmentTarget , AssignmentTargetMaybeDefault ,
7+ AssignmentTargetProperty , BindingPattern , CallExpression , ComputedMemberExpression ,
8+ DebuggerStatement , ExportAllDeclaration , ExportNamedDeclaration , Expression , FunctionBody ,
9+ IdentifierReference , ImportDeclaration , ImportExpression , MemberExpression , MetaProperty ,
10+ NewExpression , ObjectExpression , ObjectPattern , ObjectPropertyKind , PrivateIdentifier ,
11+ PropertyKey , ReturnStatement , SimpleAssignmentTarget , StringLiteral , ThisExpression ,
1112 UnaryExpression , UnaryOperator , UpdateExpression ,
1213 } ,
1314 ast_visit:: { Visit , walk} ,
@@ -327,24 +328,8 @@ where
327328 }
328329 }
329330
330- fn visit_assignment_expression ( & mut self , it : & AssignmentExpression < ' data > ) {
331- match & it. left {
332- AssignmentTarget :: AssignmentTargetIdentifier ( s) => {
333- if [ "location" ] . contains ( & s. name . to_string ( ) . as_str ( ) ) {
334- self . jschanges . add ( rewrite ! (
335- it. span,
336- Assignment {
337- name: s. name,
338- rhs: it. right. span( ) ,
339- op: it. operator,
340- }
341- ) ) ;
342-
343- // avoid walking rest of tree, i would need to figure out nested rewrites
344- // somehow
345- return ;
346- }
347- }
331+ fn visit_assignment_target ( & mut self , it : & AssignmentTarget < ' data > ) {
332+ match & it {
348333 AssignmentTarget :: StaticMemberExpression ( s) => {
349334 if UNSAFE_GLOBALS . contains ( & s. property . name . as_str ( ) ) {
350335 self . jschanges . add ( rewrite ! (
@@ -363,6 +348,73 @@ where
363348 walk:: walk_expression ( self , & s. object ) ;
364349 walk:: walk_expression ( self , & s. expression ) ;
365350 }
351+ AssignmentTarget :: ObjectAssignmentTarget ( s) => {
352+ if s. rest . is_some ( ) {
353+ // infeasible to rewrite :(
354+ eprintln ! ( "cannot rewrite rest parameters" ) ;
355+ return ;
356+ }
357+ for prop in & s. properties {
358+ match prop {
359+ AssignmentTargetProperty :: AssignmentTargetPropertyIdentifier ( p) => {
360+ // { location } = self;
361+ // correct thing to do here is to change it into an AsignmentTargetPropertyProperty
362+ // { $sj_location: location } = self;
363+ if UNSAFE_GLOBALS . contains ( & p. binding . name . to_string ( ) . as_str ( ) ) {
364+ self . jschanges . add ( rewrite ! (
365+ p. binding. span( ) ,
366+ RebindProperty {
367+ ident: p. binding. name. clone( )
368+ }
369+ ) ) ;
370+ }
371+ }
372+ AssignmentTargetProperty :: AssignmentTargetPropertyProperty ( p) => {
373+ // { location: x } = self;
374+ // { location: x = "..."} = self;
375+ // { location: { href } } = self;
376+ // { location: { href: x } } = self;
377+ // { ["location"]: x } = self;
378+
379+ match & p. name {
380+ PropertyKey :: StaticIdentifier ( id) => {
381+ // { location: x } = self;
382+ if UNSAFE_GLOBALS . contains ( & id. name . to_string ( ) . as_str ( ) ) {
383+ self . jschanges . add ( rewrite ! (
384+ p. name. span( ) ,
385+ RewriteProperty { ident: id. name }
386+ ) ) ;
387+ }
388+ }
389+ PropertyKey :: PrivateIdentifier ( _) => {
390+ // doesn't matter
391+ }
392+ // (expression variant)
393+ _ => {
394+ // { ["location"]: x } = self;
395+
396+ // TODO: check literals
397+ self . jschanges . add ( rewrite ! ( p. name. span( ) , WrapProperty ) ) ;
398+ }
399+ }
400+
401+ match & p. binding {
402+ AssignmentTargetMaybeDefault :: AssignmentTargetWithDefault ( d) => {
403+ // { location: x = parent } = {};
404+ // { location = parent } = {};
405+
406+ // we still need to rewrite whatever stuff might be in the default expression
407+ walk:: walk_expression ( self , & d. init ) ;
408+ }
409+ _ => {
410+ // { location: { href } } = {};
411+ walk:: walk_assignment_target_maybe_default ( self , & p. binding ) ;
412+ }
413+ }
414+ }
415+ }
416+ }
417+ }
366418 AssignmentTarget :: ArrayAssignmentTarget ( _) => {
367419 // [location] = ["https://example.com"]
368420 // this is such a ridiculously specific edge case. just ignore it
@@ -371,9 +423,34 @@ where
371423 _ => {
372424 // only walk the left side if it isn't an identifier, we can't replace the
373425 // identifier with a function obviously
374- walk:: walk_assignment_target ( self , & it. left ) ;
426+ walk:: walk_assignment_target ( self , & it) ;
427+ }
428+ }
429+ }
430+
431+ fn visit_assignment_expression ( & mut self , it : & AssignmentExpression < ' data > ) {
432+ // location = "https://example.com"
433+ match & it. left {
434+ AssignmentTarget :: AssignmentTargetIdentifier ( s) => {
435+ if [ "location" ] . contains ( & s. name . to_string ( ) . as_str ( ) ) {
436+ self . jschanges . add ( rewrite ! (
437+ it. span,
438+ Assignment {
439+ name: s. name,
440+ rhs: it. right. span( ) ,
441+ op: it. operator,
442+ }
443+ ) ) ;
444+
445+ // avoid walking rest of tree, i would need to figure out nested rewrites
446+ // somehow
447+ return ;
448+ }
449+ }
450+ _ => {
451+ // gets handled by visit_assignment_target
375452 }
376453 }
377- walk:: walk_expression ( self , & it . right ) ;
454+ walk:: walk_assignment_expression ( self , it ) ;
378455 }
379456}
0 commit comments