@@ -649,12 +649,8 @@ impl<'a> ParserImpl<'a> {
649
649
self . bump_any ( ) ; // `bump `typeof`
650
650
let entity_name = self . parse_ts_type_name ( ) ?; // TODO: parseEntityName
651
651
let entity_name = self . ast . ts_type_query_expr_name_type_name ( entity_name) ;
652
- let type_arguments = if self . cur_token ( ) . is_on_new_line {
653
- None
654
- } else {
655
- // TODO: tryParseTypeArguments
656
- self . parse_ts_type_arguments ( ) ?
657
- } ;
652
+ let type_arguments =
653
+ if self . cur_token ( ) . is_on_new_line { None } else { self . try_parse_type_arguments ( ) ? } ;
658
654
Ok ( self . ast . ts_type_query_type ( self . end_span ( span) , entity_name, type_arguments) )
659
655
}
660
656
@@ -751,18 +747,15 @@ impl<'a> ParserImpl<'a> {
751
747
fn parse_type_reference ( & mut self ) -> Result < TSType < ' a > > {
752
748
let span = self . start_span ( ) ;
753
749
let type_name = self . parse_ts_type_name ( ) ?;
754
- let type_parameters =
755
- if self . cur_token ( ) . is_on_new_line { None } else { self . parse_ts_type_arguments ( ) ? } ;
750
+ let type_parameters = self . parse_type_arguments_of_type_reference ( ) ?;
756
751
Ok ( self . ast . ts_type_reference ( self . end_span ( span) , type_name, type_parameters) )
757
752
}
758
753
759
754
fn parse_ts_implement_name ( & mut self ) -> Result < TSClassImplements < ' a > > {
760
755
let span = self . start_span ( ) ;
761
- let expression = self . parse_ts_type_name ( ) ?;
762
- let type_parameters =
763
- if self . cur_token ( ) . is_on_new_line { None } else { self . parse_ts_type_arguments ( ) ? } ;
764
-
765
- Ok ( self . ast . ts_type_implement ( self . end_span ( span) , expression, type_parameters) )
756
+ let type_name = self . parse_ts_type_name ( ) ?;
757
+ let type_parameters = self . parse_type_arguments_of_type_reference ( ) ?;
758
+ Ok ( self . ast . ts_type_implement ( self . end_span ( span) , type_name, type_parameters) )
766
759
}
767
760
768
761
pub ( crate ) fn parse_ts_type_name ( & mut self ) -> Result < TSTypeName < ' a > > {
@@ -781,42 +774,58 @@ impl<'a> ParserImpl<'a> {
781
774
Ok ( left)
782
775
}
783
776
784
- pub ( crate ) fn parse_ts_type_arguments (
777
+ pub ( crate ) fn try_parse_type_arguments (
785
778
& mut self ,
786
779
) -> Result < Option < Box < ' a , TSTypeParameterInstantiation < ' a > > > > {
787
- self . re_lex_ts_l_angle ( ) ;
788
- if !self . at ( Kind :: LAngle ) {
789
- return Ok ( None ) ;
780
+ if self . at ( Kind :: LAngle ) {
781
+ let span = self . start_span ( ) ;
782
+ let params = TSTypeArgumentList :: parse ( self , false ) ?. params ;
783
+ return Ok ( Some ( self . ast . ts_type_arguments ( self . end_span ( span) , params) ) ) ;
790
784
}
791
- let span = self . start_span ( ) ;
792
- let params = TSTypeArgumentList :: parse ( self , false ) ?. params ;
793
- Ok ( Some ( self . ast . ts_type_arguments ( self . end_span ( span) , params) ) )
785
+ Ok ( None )
786
+ }
787
+
788
+ fn parse_type_arguments_of_type_reference (
789
+ & mut self ,
790
+ ) -> Result < Option < Box < ' a , TSTypeParameterInstantiation < ' a > > > > {
791
+ self . re_lex_l_angle ( ) ;
792
+ if !self . cur_token ( ) . is_on_new_line && self . re_lex_l_angle ( ) == Kind :: LAngle {
793
+ let span = self . start_span ( ) ;
794
+ let params = TSTypeArgumentList :: parse ( self , false ) ?. params ;
795
+ return Ok ( Some ( self . ast . ts_type_arguments ( self . end_span ( span) , params) ) ) ;
796
+ }
797
+ Ok ( None )
794
798
}
795
799
796
- pub ( crate ) fn parse_ts_type_arguments_in_expression (
800
+ pub ( crate ) fn parse_type_arguments_in_expression (
797
801
& mut self ,
798
802
) -> Result < Option < Box < ' a , TSTypeParameterInstantiation < ' a > > > > {
799
803
if !self . ts_enabled ( ) {
800
804
return Ok ( None ) ;
801
805
}
802
-
803
806
let span = self . start_span ( ) ;
804
- self . re_lex_ts_l_angle ( ) ;
805
- if !self . at ( Kind :: LAngle ) {
807
+ if self . re_lex_l_angle ( ) != Kind :: LAngle {
806
808
return Ok ( None ) ;
807
809
}
808
-
809
810
let params = TSTypeArgumentList :: parse ( self , /* in_expression */ true ) ?. params ;
810
-
811
- let token = self . cur_token ( ) ;
812
-
813
- if token. is_on_new_line || token. kind . can_follow_type_arguments_in_expr ( ) {
811
+ if self . can_follow_type_arguments_in_expr ( ) {
814
812
return Ok ( Some ( self . ast . ts_type_arguments ( self . end_span ( span) , params) ) ) ;
815
813
}
816
-
817
814
Err ( self . unexpected ( ) )
818
815
}
819
816
817
+ fn can_follow_type_arguments_in_expr ( & mut self ) -> bool {
818
+ match self . cur_kind ( ) {
819
+ Kind :: LParen | Kind :: NoSubstitutionTemplate | Kind :: TemplateHead => true ,
820
+ Kind :: LAngle | Kind :: RAngle | Kind :: Plus | Kind :: Minus => false ,
821
+ _ => {
822
+ self . cur_token ( ) . is_on_new_line
823
+ || self . is_binary_operator ( )
824
+ || !self . is_start_of_expression ( )
825
+ }
826
+ }
827
+ }
828
+
820
829
fn parse_tuple_type ( & mut self ) -> Result < TSType < ' a > > {
821
830
let span = self . start_span ( ) ;
822
831
let elements = TSTupleElementList :: parse ( self ) ?. elements ;
@@ -951,7 +960,7 @@ impl<'a> ParserImpl<'a> {
951
960
if self . eat ( Kind :: Comma ) { Some ( self . parse_ts_import_attributes ( ) ?) } else { None } ;
952
961
self . expect ( Kind :: RParen ) ?;
953
962
let qualifier = if self . eat ( Kind :: Dot ) { Some ( self . parse_ts_type_name ( ) ?) } else { None } ;
954
- let type_parameters = self . parse_ts_type_arguments ( ) ?;
963
+ let type_parameters = self . parse_type_arguments_of_type_reference ( ) ?;
955
964
Ok ( self . ast . ts_import_type (
956
965
self . end_span ( span) ,
957
966
is_type_of,
@@ -1307,4 +1316,45 @@ impl<'a> ParserImpl<'a> {
1307
1316
let ty = self . parse_non_array_type ( ) ?;
1308
1317
Ok ( self . ast . js_doc_non_nullable_type ( self . end_span ( span) , ty, /* postfix */ false ) )
1309
1318
}
1319
+
1320
+ fn is_binary_operator ( & mut self ) -> bool {
1321
+ if self . ctx . has_in ( ) && self . at ( Kind :: In ) {
1322
+ return false ;
1323
+ }
1324
+ self . cur_kind ( ) . is_binary_operator ( )
1325
+ }
1326
+
1327
+ fn is_start_of_expression ( & mut self ) -> bool {
1328
+ if self . is_start_of_left_hand_side_expression ( ) {
1329
+ return true ;
1330
+ }
1331
+ match self . cur_kind ( ) {
1332
+ kind if kind. is_unary_operator ( ) => true ,
1333
+ kind if kind. is_update_operator ( ) => true ,
1334
+ Kind :: LAngle | Kind :: Await | Kind :: Yield | Kind :: Private | Kind :: At => true ,
1335
+ kind if kind. is_binary_operator ( ) => true ,
1336
+ kind => kind. is_identifier ( ) ,
1337
+ }
1338
+ }
1339
+
1340
+ fn is_start_of_left_hand_side_expression ( & mut self ) -> bool {
1341
+ match self . cur_kind ( ) {
1342
+ kind if kind. is_literal ( ) => true ,
1343
+ kind if kind. is_template_start_of_tagged_template ( ) => true ,
1344
+ Kind :: This
1345
+ | Kind :: Super
1346
+ | Kind :: LParen
1347
+ | Kind :: LBrack
1348
+ | Kind :: LCurly
1349
+ | Kind :: Function
1350
+ | Kind :: Class
1351
+ | Kind :: New
1352
+ | Kind :: Slash
1353
+ | Kind :: SlashEq => true ,
1354
+ Kind :: Import => {
1355
+ matches ! ( self . peek_kind( ) , Kind :: LParen | Kind :: LAngle | Kind :: Dot )
1356
+ }
1357
+ kind => kind. is_identifier ( ) ,
1358
+ }
1359
+ }
1310
1360
}
0 commit comments