about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-10 21:01:41 -0700
committerbors <bors@rust-lang.org>2014-04-10 21:01:41 -0700
commitcea8def62068b405495ecd1810124ebc88b4f90b (patch)
tree65d5755bd532a9213799c52572db6d6683d5e942 /src/libsyntax/parse
parent0156af156d70efd5a3c96d0c5b8fc9bec39a7ae5 (diff)
parentdef90f43e2df9968cda730a2a30cb7ccb9513002 (diff)
downloadrust-cea8def62068b405495ecd1810124ebc88b4f90b.tar.gz
rust-cea8def62068b405495ecd1810124ebc88b4f90b.zip
auto merge of #13440 : huonw/rust/strbuf, r=alexcrichton
libstd: Implement `StrBuf`, a new string buffer type like `Vec`, and port all code over to use it.

Rebased & tests-fixed version of https://github.com/mozilla/rust/pull/13269
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/comments.rs24
-rw-r--r--src/libsyntax/parse/lexer.rs42
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/libsyntax/parse/token.rs18
4 files changed, 55 insertions, 38 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index bb812f7f6b4..1a246eb7f2c 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -19,6 +19,7 @@ use parse::token;
 
 use std::io;
 use std::str;
+use std::strbuf::StrBuf;
 use std::uint;
 
 #[deriving(Clone, Eq)]
@@ -134,13 +135,13 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
 }
 
 fn read_to_eol(rdr: &mut StringReader) -> ~str {
-    let mut val = ~"";
+    let mut val = StrBuf::new();
     while !rdr.curr_is('\n') && !is_eof(rdr) {
         val.push_char(rdr.curr.unwrap());
         bump(rdr);
     }
     if rdr.curr_is('\n') { bump(rdr); }
-    return val;
+    return val.into_owned();
 }
 
 fn read_one_line_comment(rdr: &mut StringReader) -> ~str {
@@ -255,7 +256,7 @@ fn read_block_comment(rdr: &mut StringReader,
     bump(rdr);
     bump(rdr);
 
-    let mut curr_line = ~"/*";
+    let mut curr_line = StrBuf::from_str("/*");
 
     // doc-comments are not really comments, they are attributes
     if (rdr.curr_is('*') && !nextch_is(rdr, '*')) || rdr.curr_is('!') {
@@ -268,9 +269,11 @@ fn read_block_comment(rdr: &mut StringReader,
             bump(rdr);
             bump(rdr);
         }
-        if !is_block_non_doc_comment(curr_line) { return; }
-        assert!(!curr_line.contains_char('\n'));
-        lines.push(curr_line);
+        if !is_block_non_doc_comment(curr_line.as_slice()) {
+            return
+        }
+        assert!(!curr_line.as_slice().contains_char('\n'));
+        lines.push(curr_line.into_owned());
     } else {
         let mut level: int = 1;
         while level > 0 {
@@ -279,9 +282,10 @@ fn read_block_comment(rdr: &mut StringReader,
                 rdr.fatal(~"unterminated block comment");
             }
             if rdr.curr_is('\n') {
-                trim_whitespace_prefix_and_push_line(&mut lines, curr_line,
+                trim_whitespace_prefix_and_push_line(&mut lines,
+                                                     curr_line.into_owned(),
                                                      col);
-                curr_line = ~"";
+                curr_line = StrBuf::new();
                 bump(rdr);
             } else {
                 curr_line.push_char(rdr.curr.unwrap());
@@ -301,7 +305,9 @@ fn read_block_comment(rdr: &mut StringReader,
             }
         }
         if curr_line.len() != 0 {
-            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(&mut lines,
+                                                 curr_line.into_owned(),
+                                                 col);
         }
     }
 
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 23d7cc0af97..c1c91cb6a4f 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -21,6 +21,7 @@ use std::mem::replace;
 use std::num::from_str_radix;
 use std::rc::Rc;
 use std::str;
+use std::strbuf::StrBuf;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader};
 
@@ -152,10 +153,10 @@ fn fatal_span_char(rdr: &mut StringReader,
                    m: ~str,
                    c: char)
                 -> ! {
-    let mut m = m;
+    let mut m = StrBuf::from_owned_str(m);
     m.push_str(": ");
     char::escape_default(c, |c| m.push_char(c));
-    fatal_span(rdr, from_pos, to_pos, m);
+    fatal_span(rdr, from_pos, to_pos, m.into_owned());
 }
 
 // report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -165,12 +166,12 @@ fn fatal_span_verbose(rdr: &mut StringReader,
                       to_pos: BytePos,
                       m: ~str)
                    -> ! {
-    let mut m = m;
+    let mut m = StrBuf::from_owned_str(m);
     m.push_str(": ");
     let from = byte_offset(rdr, from_pos).to_uint();
     let to = byte_offset(rdr, to_pos).to_uint();
     m.push_str(rdr.filemap.src.slice(from, to));
-    fatal_span(rdr, from_pos, to_pos, m);
+    fatal_span(rdr, from_pos, to_pos, m.into_owned());
 }
 
 // EFFECT: advance peek_tok and peek_span to refer to the next token.
@@ -440,7 +441,7 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
 fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
     // \x00 hits the `return None` case immediately, so this is fine.
     let mut c = rdr.curr.unwrap_or('\x00');
-    let mut rslt = ~"";
+    let mut rslt = StrBuf::new();
     if c == 'e' || c == 'E' {
         rslt.push_char(c);
         bump(rdr);
@@ -451,7 +452,8 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
         }
         let exponent = scan_digits(rdr, 10u);
         if exponent.len() > 0u {
-            return Some(rslt + exponent);
+            rslt.push_str(exponent);
+            return Some(rslt.into_owned());
         } else {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"scan_exponent: bad fp literal");
@@ -460,7 +462,7 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
 }
 
 fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
-    let mut rslt = ~"";
+    let mut rslt = StrBuf::new();
     loop {
         let c = rdr.curr;
         if c == Some('_') { bump(rdr); continue; }
@@ -469,7 +471,7 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
             rslt.push_char(c.unwrap());
             bump(rdr);
           }
-          _ => return rslt
+          _ => return rslt.into_owned()
         }
     };
 }
@@ -506,7 +508,7 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         bump(rdr);
         base = 2u;
     }
-    num_str = scan_digits(rdr, base);
+    num_str = StrBuf::from_owned_str(scan_digits(rdr, base));
     c = rdr.curr.unwrap_or('\x00');
     nextch(rdr);
     if c == 'u' || c == 'i' {
@@ -544,7 +546,8 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"no valid digits found for number");
         }
-        let parsed = match from_str_radix::<u64>(num_str, base as uint) {
+        let parsed = match from_str_radix::<u64>(num_str.as_slice(),
+                                                 base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
                                ~"int literal is too large")
@@ -579,12 +582,14 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
             bump(rdr);
             bump(rdr);
             check_float_base(rdr, start_bpos, rdr.last_pos, base);
-            return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF32);
+            return token::LIT_FLOAT(str_to_ident(num_str.into_owned()),
+                                    ast::TyF32);
         } else if c == '6' && n == '4' {
             bump(rdr);
             bump(rdr);
             check_float_base(rdr, start_bpos, rdr.last_pos, base);
-            return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF64);
+            return token::LIT_FLOAT(str_to_ident(num_str.into_owned()),
+                                    ast::TyF64);
             /* FIXME (#2252): if this is out of range for either a
             32-bit or 64-bit float, it won't be noticed till the
             back-end.  */
@@ -595,19 +600,22 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
     }
     if is_float {
         check_float_base(rdr, start_bpos, rdr.last_pos, base);
-        return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(num_str));
+        return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(
+                num_str.into_owned()));
     } else {
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"no valid digits found for number");
         }
-        let parsed = match from_str_radix::<u64>(num_str, base as uint) {
+        let parsed = match from_str_radix::<u64>(num_str.as_slice(),
+                                                 base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
                                ~"int literal is too large")
         };
 
-        debug!("lexing {} as an unsuffixed integer literal", num_str);
+        debug!("lexing {} as an unsuffixed integer literal",
+               num_str.as_slice());
         return token::LIT_INT_UNSUFFIXED(parsed as i64);
     }
 }
@@ -863,7 +871,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
         return token::LIT_CHAR(c2 as u32);
       }
       '"' => {
-        let mut accum_str = ~"";
+        let mut accum_str = StrBuf::new();
         let start_bpos = rdr.last_pos;
         bump(rdr);
         while !rdr.curr_is('"') {
@@ -912,7 +920,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
             }
         }
         bump(rdr);
-        return token::LIT_STR(str_to_ident(accum_str));
+        return token::LIT_STR(str_to_ident(accum_str.as_slice()));
       }
       'r' => {
         let start_bpos = rdr.last_pos;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe4bd87c4eb..6bc325bffcc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -79,6 +79,7 @@ use owned_slice::OwnedSlice;
 use collections::HashSet;
 use std::mem::replace;
 use std::rc::Rc;
+use std::strbuf::StrBuf;
 
 #[allow(non_camel_case_types)]
 #[deriving(Eq)]
@@ -4136,14 +4137,14 @@ impl<'a> Parser<'a> {
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
         match included_mod_stack.iter().position(|p| *p == path) {
             Some(i) => {
-                let mut err = ~"circular modules: ";
+                let mut err = StrBuf::from_str("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in included_mod_stack.slice(i, len).iter() {
                     err.push_str(p.display().as_maybe_owned().as_slice());
                     err.push_str(" -> ");
                 }
                 err.push_str(path.display().as_maybe_owned().as_slice());
-                self.span_fatal(id_sp, err);
+                self.span_fatal(id_sp, err.into_owned());
             }
             None => ()
         }
@@ -4711,14 +4712,14 @@ impl<'a> Parser<'a> {
 
         // FAILURE TO PARSE ITEM
         if visibility != Inherited {
-            let mut s = ~"unmatched visibility `";
+            let mut s = StrBuf::from_str("unmatched visibility `");
             if visibility == Public {
                 s.push_str("pub")
             } else {
                 s.push_str("priv")
             }
             s.push_char('`');
-            self.span_fatal(self.last_span, s);
+            self.span_fatal(self.last_span, s.as_slice());
         }
         return IoviNone(attrs);
     }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index ff1509fe23a..baade21d942 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -23,6 +23,7 @@ use std::fmt;
 use std::local_data;
 use std::path::BytesContainer;
 use std::rc::Rc;
+use std::strbuf::StrBuf;
 
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash, Show)]
@@ -193,12 +194,12 @@ pub fn to_str(t: &Token) -> ~str {
 
       /* Literals */
       LIT_CHAR(c) => {
-          let mut res = ~"'";
+          let mut res = StrBuf::from_str("'");
           char::from_u32(c).unwrap().escape_default(|c| {
               res.push_char(c);
           });
           res.push_char('\'');
-          res
+          res.into_owned()
       }
       LIT_INT(i, t) => {
           i.to_str() + ast_util::int_ty_to_str(t)
@@ -208,18 +209,19 @@ pub fn to_str(t: &Token) -> ~str {
       }
       LIT_INT_UNSUFFIXED(i) => { i.to_str() }
       LIT_FLOAT(s, t) => {
-        let mut body = get_ident(s).get().to_str();
-        if body.ends_with(".") {
+        let mut body = StrBuf::from_str(get_ident(s).get());
+        if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body + ast_util::float_ty_to_str(t)
+        body.push_str(ast_util::float_ty_to_str(t));
+        body.into_owned()
       }
       LIT_FLOAT_UNSUFFIXED(s) => {
-        let mut body = get_ident(s).get().to_str();
-        if body.ends_with(".") {
+        let mut body = StrBuf::from_str(get_ident(s).get());
+        if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body
+        body.into_owned()
       }
       LIT_STR(s) => {
           format!("\"{}\"", get_ident(s).get().escape_default())