@@ -165,9 +165,10 @@ fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos {
165
165
( pos - rdr. filemap . start_pos )
166
166
}
167
167
168
- pub fn get_str_from ( rdr : @mut StringReader , start : BytePos ) -> ~str {
169
- return str:: slice ( * rdr. src , start. to_uint ( ) ,
170
- byte_offset ( rdr, rdr. last_pos ) . to_uint ( ) ) . to_owned ( ) ;
168
+ pub fn with_str_from < T > ( rdr : @mut StringReader , start : BytePos , f : & fn ( s : & str ) -> T ) -> T {
169
+ f ( rdr. src . slice (
170
+ byte_offset ( rdr, start) . to_uint ( ) ,
171
+ byte_offset ( rdr, rdr. last_pos ) . to_uint ( ) ) )
171
172
}
172
173
173
174
// EFFECT: advance the StringReader by one character. If a newline is
@@ -259,18 +260,24 @@ fn consume_any_line_comment(rdr: @mut StringReader)
259
260
bump ( rdr) ;
260
261
// line comments starting with "///" or "//!" are doc-comments
261
262
if rdr. curr == '/' || rdr. curr == '!' {
262
- let start_bpos = rdr. pos - BytePos ( 2 u) ;
263
- let mut acc = ~"//";
263
+ let start_bpos = rdr. pos - BytePos ( 3 u) ;
264
264
while rdr. curr != '\n' && !is_eof ( rdr) {
265
- str:: push_char ( & mut acc, rdr. curr ) ;
266
265
bump ( rdr) ;
267
266
}
268
- // but comments with only more "/"s are not
269
- if !is_line_non_doc_comment ( acc) {
270
- return Some ( TokenAndSpan {
271
- tok : token:: DOC_COMMENT ( str_to_ident ( acc) ) ,
272
- sp : codemap:: mk_sp ( start_bpos, rdr. pos )
273
- } ) ;
267
+ let ret = do with_str_from ( rdr, start_bpos) |string| {
268
+ // but comments with only more "/"s are not
269
+ if !is_line_non_doc_comment ( string) {
270
+ Some ( TokenAndSpan {
271
+ tok : token:: DOC_COMMENT ( str_to_ident ( string) ) ,
272
+ sp : codemap:: mk_sp ( start_bpos, rdr. pos )
273
+ } )
274
+ } else {
275
+ None
276
+ }
277
+ } ;
278
+
279
+ if ret. is_some ( ) {
280
+ return ret;
274
281
}
275
282
} else {
276
283
while rdr. curr != '\n' && !is_eof ( rdr) { bump ( rdr) ; }
@@ -306,25 +313,26 @@ pub fn is_block_non_doc_comment(s: &str) -> bool {
306
313
fn consume_block_comment ( rdr : @mut StringReader )
307
314
-> Option < TokenAndSpan > {
308
315
// block comments starting with "/**" or "/*!" are doc-comments
309
- if rdr. curr == '*' || rdr. curr == '!' {
310
- let start_bpos = rdr. pos - BytePos ( 2 u) ;
311
- let mut acc = ~"/* ";
316
+ let res = if rdr. curr == '*' || rdr. curr == '!' {
317
+ let start_bpos = rdr. pos - BytePos ( 3 u) ;
312
318
while !( rdr. curr == '*' && nextch ( rdr) == '/' ) && !is_eof ( rdr) {
313
- str::push_char(&mut acc, rdr.curr);
314
319
bump ( rdr) ;
315
320
}
316
321
if is_eof ( rdr) {
317
322
rdr. fatal ( ~"unterminated block doc-comment") ;
318
323
} else {
319
- acc += "*/" ;
320
324
bump ( rdr) ;
321
325
bump ( rdr) ;
322
- // but comments with only "*"s between two "/"s are not
323
- if !is_block_non_doc_comment ( acc) {
324
- return Some ( TokenAndSpan {
325
- tok : token:: DOC_COMMENT ( str_to_ident ( acc) ) ,
326
- sp : codemap:: mk_sp ( start_bpos, rdr. pos )
327
- } ) ;
326
+ do with_str_from ( rdr, start_bpos) |string| {
327
+ // but comments with only "*"s between two "/"s are not
328
+ if !is_block_non_doc_comment ( string) {
329
+ Some ( TokenAndSpan {
330
+ tok : token:: DOC_COMMENT ( str_to_ident ( string) ) ,
331
+ sp : codemap:: mk_sp ( start_bpos, rdr. pos )
332
+ } )
333
+ } else {
334
+ None
335
+ }
328
336
}
329
337
}
330
338
} else {
@@ -338,10 +346,11 @@ fn consume_block_comment(rdr: @mut StringReader)
338
346
bump ( rdr) ;
339
347
}
340
348
}
341
- }
349
+ None
350
+ } ;
342
351
// restart whitespace munch.
343
352
344
- return consume_whitespace_and_comments ( rdr) ;
353
+ if res . is_some ( ) { res } else { consume_whitespace_and_comments ( rdr) }
345
354
}
346
355
347
356
fn scan_exponent ( rdr : @mut StringReader ) -> Option < ~str > {
@@ -540,17 +549,21 @@ fn ident_continue(c: char) -> bool {
540
549
fn next_token_inner ( rdr : @mut StringReader ) -> token:: Token {
541
550
let mut c = rdr. curr ;
542
551
if ident_start ( c) {
543
- let start = byte_offset ( rdr, rdr . last_pos ) ;
552
+ let start = rdr. last_pos ;
544
553
while ident_continue ( rdr. curr ) {
545
554
bump ( rdr) ;
546
555
}
547
- let string = get_str_from ( rdr, start) ;
548
556
549
- if "_" == string { return token:: UNDERSCORE ; }
550
- let is_mod_name = rdr. curr == ':' && nextch ( rdr) == ':' ;
557
+ return do with_str_from ( rdr, start) |string| {
558
+ if string == "_" {
559
+ token:: UNDERSCORE
560
+ } else {
561
+ let is_mod_name = rdr. curr == ':' && nextch ( rdr) == ':' ;
551
562
552
- // FIXME: perform NFKC normalization here. (Issue #2253)
553
- return token:: IDENT ( str_to_ident ( string) , is_mod_name) ;
563
+ // FIXME: perform NFKC normalization here. (Issue #2253)
564
+ token:: IDENT ( str_to_ident ( string) , is_mod_name)
565
+ }
566
+ }
554
567
}
555
568
if is_dec_digit ( c) {
556
569
return scan_number ( c, rdr) ;
@@ -648,19 +661,19 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
648
661
'\'' => {
649
662
// Either a character constant 'a' OR a lifetime name 'abc
650
663
bump ( rdr) ;
664
+ let start = rdr. last_pos ;
651
665
let mut c2 = rdr. curr ;
652
666
bump ( rdr) ;
653
667
654
668
// If the character is an ident start not followed by another single
655
669
// quote, then this is a lifetime name:
656
670
if ident_start ( c2) && rdr. curr != '\'' {
657
- let mut lifetime_name = ~"";
658
- lifetime_name. push_char ( c2) ;
659
671
while ident_continue ( rdr. curr ) {
660
- lifetime_name. push_char ( rdr. curr ) ;
661
672
bump ( rdr) ;
662
673
}
663
- return token:: LIFETIME ( str_to_ident ( lifetime_name) ) ;
674
+ return do with_str_from ( rdr, start) |lifetime_name| {
675
+ token:: LIFETIME ( str_to_ident ( lifetime_name) )
676
+ }
664
677
}
665
678
666
679
// Otherwise it is a character constant:
@@ -691,12 +704,13 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
691
704
}
692
705
'"' => {
693
706
let mut accum_str = ~"";
694
- let n = byte_offset ( rdr, rdr . last_pos ) ;
707
+ let n = rdr. last_pos ;
695
708
bump ( rdr) ;
696
709
while rdr. curr != '"' {
697
710
if is_eof ( rdr) {
698
- rdr. fatal ( fmt ! ( "unterminated double quote string: %s" ,
699
- get_str_from( rdr, n) ) ) ;
711
+ do with_str_from ( rdr, n) |s| {
712
+ rdr. fatal ( fmt ! ( "unterminated double quote string: %s" , s) ) ;
713
+ }
700
714
}
701
715
702
716
let ch = rdr. curr ;
0 commit comments