@@ -561,6 +561,17 @@ impl Visit for TsStrip {
561
561
}
562
562
563
563
' type_params: {
564
+ // ```TypeScript
565
+ // let f = async <
566
+ // T
567
+ // >(v: T) => v;
568
+ // ```
569
+
570
+ // ```TypeScript
571
+ // let f = async (
572
+ //
573
+ // v ) => v;
574
+ // ```
564
575
if let Some ( tp) = & n. type_params {
565
576
self . add_replacement ( tp. span ) ;
566
577
@@ -673,7 +684,12 @@ impl Visit for TsStrip {
673
684
return ;
674
685
}
675
686
676
- self . strip_class_modifier ( n. span . lo , n. key . span_lo ( ) ) ;
687
+ // TODO(AST): constructor can not be optional
688
+ debug_assert ! ( !n. is_optional) ;
689
+
690
+ if n. accessibility . is_some ( ) {
691
+ self . strip_class_modifier ( n. span . lo , n. key . span_lo ( ) ) ;
692
+ }
677
693
678
694
n. visit_children_with ( self ) ;
679
695
}
@@ -684,20 +700,49 @@ impl Visit for TsStrip {
684
700
return ;
685
701
}
686
702
703
+ let has_modifier = n. is_override || n. accessibility . is_some ( ) ;
704
+
687
705
// @foo public m(): void {}
688
706
let start_pos = n
689
707
. function
690
708
. decorators
691
709
. last ( )
692
710
. map_or ( n. span . lo , |d| d. span . hi ) ;
693
711
694
- self . strip_class_modifier ( start_pos, n. key . span_lo ( ) ) ;
712
+ if has_modifier {
713
+ self . strip_class_modifier ( start_pos, n. key . span_lo ( ) ) ;
714
+ }
695
715
696
716
if n. is_optional {
697
717
let mark_index = self . get_next_token_index ( n. key . span_hi ( ) ) ;
698
718
self . strip_optional_mark ( mark_index) ;
699
719
}
700
720
721
+ // It's dangerous to strip TypeScript modifiers if the key is computed, a
722
+ // generator, or `in`/`instanceof` keyword. However, it is safe to do so
723
+ // if the key is preceded by a `static` keyword or decorators.
724
+ //
725
+ // `public [foo]()`
726
+ // `; [foo]()`
727
+ //
728
+ // `public *foo()`
729
+ // `; *foo()`
730
+ //
731
+ // `public in()`
732
+ // `; in()`
733
+ if has_modifier
734
+ && !n. is_static
735
+ && n. function . decorators . is_empty ( )
736
+ && ( n. key . is_computed ( )
737
+ || n. function . is_generator
738
+ || n. key
739
+ . as_ident ( )
740
+ . filter ( |k| matches ! ( k. sym. as_ref( ) , "in" | "instanceof" ) )
741
+ . is_some ( ) )
742
+ {
743
+ self . add_overwrite ( start_pos, b';' ) ;
744
+ }
745
+
701
746
n. visit_children_with ( self ) ;
702
747
}
703
748
@@ -707,9 +752,12 @@ impl Visit for TsStrip {
707
752
return ;
708
753
}
709
754
755
+ let has_modifier = n. readonly || n. is_override || n. accessibility . is_some ( ) ;
710
756
let start_pos = n. decorators . last ( ) . map_or ( n. span . lo , |d| d. span . hi ) ;
711
757
712
- self . strip_class_modifier ( start_pos, n. key . span_lo ( ) ) ;
758
+ if has_modifier {
759
+ self . strip_class_modifier ( start_pos, n. key . span_lo ( ) ) ;
760
+ }
713
761
714
762
if n. is_optional {
715
763
let mark_index = self . get_next_token_index ( n. key . span_hi ( ) ) ;
@@ -720,23 +768,53 @@ impl Visit for TsStrip {
720
768
self . strip_definite_mark ( mark_index) ;
721
769
}
722
770
723
- if n. value . is_none ( ) && n. key . as_ident ( ) . filter ( |k| k. sym == "static" ) . is_some ( ) {
724
- if let Some ( type_ann) = & n. type_ann {
725
- self . add_overwrite ( type_ann. span . lo , b';' ) ;
771
+ // It's dangerous to strip types if the key is `get`, `set`, or `static`.
772
+ if n. value . is_none ( ) {
773
+ if let Some ( key) = n. key . as_ident ( ) {
774
+ if matches ! ( key. sym. as_ref( ) , "get" | "set" | "static" ) {
775
+ // `get: number`
776
+ // `get; `
777
+ if let Some ( type_ann) = & n. type_ann {
778
+ self . add_overwrite ( type_ann. span . lo , b';' ) ;
779
+ }
780
+ }
726
781
}
727
782
}
728
783
784
+ // `private [foo]`
785
+ // `; [foo]`
786
+ //
787
+ // `private in`
788
+ // `; in`
789
+ if !n. is_static
790
+ && has_modifier
791
+ && n. decorators . is_empty ( )
792
+ && ( n. key . is_computed ( )
793
+ || n. key
794
+ . as_ident ( )
795
+ . filter ( |k| matches ! ( k. sym. as_ref( ) , "in" | "instanceof" ) )
796
+ . is_some ( ) )
797
+ {
798
+ self . add_overwrite ( start_pos, b';' ) ;
799
+ }
800
+
729
801
n. visit_children_with ( self ) ;
730
802
}
731
803
732
804
fn visit_private_method ( & mut self , n : & PrivateMethod ) {
733
- let start_pos = n
734
- . function
735
- . decorators
736
- . last ( )
737
- . map_or ( n. span . lo , |d| d. span . hi ) ;
738
-
739
- self . strip_class_modifier ( start_pos, n. key . span . lo ) ;
805
+ debug_assert ! ( !n. is_override) ;
806
+ debug_assert ! ( !n. is_abstract) ;
807
+
808
+ // Is `private #foo()` valid?
809
+ if n. accessibility . is_some ( ) {
810
+ let start_pos = n
811
+ . function
812
+ . decorators
813
+ . last ( )
814
+ . map_or ( n. span . lo , |d| d. span . hi ) ;
815
+
816
+ self . strip_class_modifier ( start_pos, n. key . span . lo ) ;
817
+ }
740
818
741
819
if n. is_optional {
742
820
let mark_index = self . get_next_token_index ( n. key . span . hi ) ;
@@ -747,9 +825,12 @@ impl Visit for TsStrip {
747
825
}
748
826
749
827
fn visit_private_prop ( & mut self , n : & PrivateProp ) {
750
- let start_pos = n . decorators . last ( ) . map_or ( n . span . lo , |d| d . span . hi ) ;
828
+ debug_assert ! ( !n . is_override ) ;
751
829
752
- self . strip_class_modifier ( start_pos, n. key . span . lo ) ;
830
+ if n. readonly || n. accessibility . is_some ( ) {
831
+ let start_pos = n. decorators . last ( ) . map_or ( n. span . lo , |d| d. span . hi ) ;
832
+ self . strip_class_modifier ( start_pos, n. key . span . lo ) ;
833
+ }
753
834
754
835
if n. is_optional {
755
836
let mark_index = self . get_next_token_index ( n. key . span . hi ) ;
0 commit comments