@@ -654,6 +654,121 @@ impl<'a> Lexer<'a> {
654
654
Token :: AssignOp ( AssignOp :: Assign )
655
655
} ) )
656
656
}
657
+
658
+ fn read_token_back_quote ( & mut self ) -> LexResult < Option < Token > > {
659
+ let start = self . cur_pos ( ) ;
660
+ self . rescan_token_back_quote ( start) . map ( |t| Some ( t) )
661
+ }
662
+
663
+ fn rescan_token_back_quote ( & mut self , start : BytePos ) -> LexResult < Token > {
664
+ let mut cooked = Ok ( String :: new ( ) ) ;
665
+ let mut cooked_slice_start = start;
666
+ let raw_slice_start = start;
667
+
668
+ macro_rules! consume_cooked {
669
+ ( ) => { {
670
+ if let Ok ( cooked) = & mut cooked {
671
+ let last_pos = self . cur_pos( ) ;
672
+ cooked. push_str( unsafe {
673
+ // Safety: Both of start and last_pos are valid position because we got them
674
+ // from `self.input`
675
+ self . input. slice( cooked_slice_start, last_pos)
676
+ } ) ;
677
+ }
678
+ } } ;
679
+ }
680
+
681
+ while let Some ( c) = self . cur ( ) {
682
+ if c == '`' || ( c == '$' && self . peek ( ) == Some ( '{' ) ) {
683
+ if start == self . cur_pos ( ) && self . state . last_was_tpl_element ( ) {
684
+ if c == '$' {
685
+ self . bump ( ) ;
686
+ self . bump ( ) ;
687
+ return Ok ( tok ! ( "${" ) ) ;
688
+ } else {
689
+ self . bump ( ) ;
690
+ return Ok ( tok ! ( '`' ) ) ;
691
+ }
692
+ }
693
+
694
+ // If we don't have any escape
695
+ let cooked = if cooked_slice_start == raw_slice_start {
696
+ let last_pos = self . cur_pos ( ) ;
697
+ let s = unsafe {
698
+ // Safety: Both of start and last_pos are valid position because we got them
699
+ // from `self.input`
700
+ self . input . slice ( cooked_slice_start, last_pos)
701
+ } ;
702
+
703
+ Ok ( self . atoms . atom ( s) )
704
+ } else {
705
+ consume_cooked ! ( ) ;
706
+
707
+ cooked. map ( |s| self . atoms . atom ( s) )
708
+ } ;
709
+
710
+ // TODO: Handle error
711
+ let end = self . input . cur_pos ( ) ;
712
+ let raw = unsafe {
713
+ // Safety: Both of start and last_pos are valid position because we got them
714
+ // from `self.input`
715
+ self . input . slice ( raw_slice_start, end)
716
+ } ;
717
+ return Ok ( Token :: Template {
718
+ cooked,
719
+ raw : self . atoms . atom ( raw) ,
720
+ } ) ;
721
+ }
722
+
723
+ if c == '\\' {
724
+ consume_cooked ! ( ) ;
725
+
726
+ match self . read_escaped_char ( true ) {
727
+ Ok ( Some ( chars) ) => {
728
+ if let Ok ( ref mut cooked) = cooked {
729
+ for c in chars {
730
+ cooked. extend ( c) ;
731
+ }
732
+ }
733
+ }
734
+ Ok ( None ) => { }
735
+ Err ( error) => {
736
+ cooked = Err ( error) ;
737
+ }
738
+ }
739
+
740
+ cooked_slice_start = self . cur_pos ( ) ;
741
+ } else if c. is_line_terminator ( ) {
742
+ self . state . had_line_break = true ;
743
+
744
+ consume_cooked ! ( ) ;
745
+
746
+ let c = if c == '\r' && self . peek ( ) == Some ( '\n' ) {
747
+ self . bump ( ) ; // '\r'
748
+ '\n'
749
+ } else {
750
+ match c {
751
+ '\n' => '\n' ,
752
+ '\r' => '\n' ,
753
+ '\u{2028}' => '\u{2028}' ,
754
+ '\u{2029}' => '\u{2029}' ,
755
+ _ => unreachable ! ( ) ,
756
+ }
757
+ } ;
758
+
759
+ self . bump ( ) ;
760
+
761
+ if let Ok ( ref mut cooked) = cooked {
762
+ cooked. push ( c) ;
763
+ }
764
+ cooked_slice_start = self . cur_pos ( ) ;
765
+ } else {
766
+ self . bump ( ) ;
767
+ }
768
+ }
769
+
770
+ self . error ( start, SyntaxError :: UnterminatedTpl ) ?
771
+ }
657
772
}
658
773
659
774
impl Lexer < ' _ > {
@@ -1240,118 +1355,6 @@ impl Lexer<'_> {
1240
1355
Ok ( Some ( self . atoms . atom ( s) ) )
1241
1356
}
1242
1357
1243
- fn read_tmpl_token ( & mut self , start_of_tpl : BytePos ) -> LexResult < Token > {
1244
- let start = self . cur_pos ( ) ;
1245
-
1246
- let mut cooked = Ok ( String :: new ( ) ) ;
1247
- let mut cooked_slice_start = start;
1248
- let raw_slice_start = start;
1249
-
1250
- macro_rules! consume_cooked {
1251
- ( ) => { {
1252
- if let Ok ( cooked) = & mut cooked {
1253
- let last_pos = self . cur_pos( ) ;
1254
- cooked. push_str( unsafe {
1255
- // Safety: Both of start and last_pos are valid position because we got them
1256
- // from `self.input`
1257
- self . input. slice( cooked_slice_start, last_pos)
1258
- } ) ;
1259
- }
1260
- } } ;
1261
- }
1262
-
1263
- while let Some ( c) = self . cur ( ) {
1264
- if c == '`' || ( c == '$' && self . peek ( ) == Some ( '{' ) ) {
1265
- if start == self . cur_pos ( ) && self . state . last_was_tpl_element ( ) {
1266
- if c == '$' {
1267
- self . bump ( ) ;
1268
- self . bump ( ) ;
1269
- return Ok ( tok ! ( "${" ) ) ;
1270
- } else {
1271
- self . bump ( ) ;
1272
- return Ok ( tok ! ( '`' ) ) ;
1273
- }
1274
- }
1275
-
1276
- // If we don't have any escape
1277
- let cooked = if cooked_slice_start == raw_slice_start {
1278
- let last_pos = self . cur_pos ( ) ;
1279
- let s = unsafe {
1280
- // Safety: Both of start and last_pos are valid position because we got them
1281
- // from `self.input`
1282
- self . input . slice ( cooked_slice_start, last_pos)
1283
- } ;
1284
-
1285
- Ok ( self . atoms . atom ( s) )
1286
- } else {
1287
- consume_cooked ! ( ) ;
1288
-
1289
- cooked. map ( |s| self . atoms . atom ( s) )
1290
- } ;
1291
-
1292
- // TODO: Handle error
1293
- let end = self . input . cur_pos ( ) ;
1294
- let raw = unsafe {
1295
- // Safety: Both of start and last_pos are valid position because we got them
1296
- // from `self.input`
1297
- self . input . slice ( raw_slice_start, end)
1298
- } ;
1299
- return Ok ( Token :: Template {
1300
- cooked,
1301
- raw : self . atoms . atom ( raw) ,
1302
- } ) ;
1303
- }
1304
-
1305
- if c == '\\' {
1306
- consume_cooked ! ( ) ;
1307
-
1308
- match self . read_escaped_char ( true ) {
1309
- Ok ( Some ( chars) ) => {
1310
- if let Ok ( ref mut cooked) = cooked {
1311
- for c in chars {
1312
- cooked. extend ( c) ;
1313
- }
1314
- }
1315
- }
1316
- Ok ( None ) => { }
1317
- Err ( error) => {
1318
- cooked = Err ( error) ;
1319
- }
1320
- }
1321
-
1322
- cooked_slice_start = self . cur_pos ( ) ;
1323
- } else if c. is_line_terminator ( ) {
1324
- self . state . had_line_break = true ;
1325
-
1326
- consume_cooked ! ( ) ;
1327
-
1328
- let c = if c == '\r' && self . peek ( ) == Some ( '\n' ) {
1329
- self . bump ( ) ; // '\r'
1330
- '\n'
1331
- } else {
1332
- match c {
1333
- '\n' => '\n' ,
1334
- '\r' => '\n' ,
1335
- '\u{2028}' => '\u{2028}' ,
1336
- '\u{2029}' => '\u{2029}' ,
1337
- _ => unreachable ! ( ) ,
1338
- }
1339
- } ;
1340
-
1341
- self . bump ( ) ;
1342
-
1343
- if let Ok ( ref mut cooked) = cooked {
1344
- cooked. push ( c) ;
1345
- }
1346
- cooked_slice_start = self . cur_pos ( ) ;
1347
- } else {
1348
- self . bump ( ) ;
1349
- }
1350
- }
1351
-
1352
- self . error ( start_of_tpl, SyntaxError :: UnterminatedTpl ) ?
1353
- }
1354
-
1355
1358
#[ inline]
1356
1359
#[ allow( clippy:: misnamed_getters) ]
1357
1360
pub fn had_line_break_before_last ( & self ) -> bool {
0 commit comments