about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ext/base.rs11
-rw-r--r--src/libsyntax/ext/expand.rs6
-rw-r--r--src/libsyntax/ext/format.rs43
-rw-r--r--src/libsyntax/fold.rs2
5 files changed, 42 insertions, 22 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 7ad9a18a15e..614bbd1c3ed 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -256,7 +256,7 @@ pub struct Crate {
     pub attrs: Vec<Attribute>,
     pub config: CrateConfig,
     pub span: Span,
-    pub exported_macros: Vec<Span>
+    pub exported_macros: Vec<Gc<Item>>
 }
 
 pub type MetaItem = Spanned<MetaItem_>;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 49bd3697884..5341f0c2d61 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -104,9 +104,9 @@ pub type IdentMacroExpanderFn =
 /// just into the compiler's internal macro table, for `make_def`).
 pub trait MacResult {
     /// Define a new macro.
-    // this should go away; the idea that a macro might expand into
-    // either a macro definition or an expression, depending on what
-    // the context wants, is kind of silly.
+    // this particular flavor should go away; the idea that a macro might
+    // expand into either a macro definition or an expression, depending
+    // on what the context wants, is kind of silly.
     fn make_def(&self) -> Option<MacroDef> {
         None
     }
@@ -431,7 +431,7 @@ pub struct ExtCtxt<'a> {
 
     pub mod_path: Vec<ast::Ident> ,
     pub trace_mac: bool,
-    pub exported_macros: Vec<codemap::Span>
+    pub exported_macros: Vec<Gc<ast::Item>>
 }
 
 impl<'a> ExtCtxt<'a> {
@@ -562,9 +562,6 @@ impl<'a> ExtCtxt<'a> {
     pub fn name_of(&self, st: &str) -> ast::Name {
         token::intern(st)
     }
-    pub fn push_exported_macro(&mut self, span: codemap::Span) {
-        self.exported_macros.push(span);
-    }
 }
 
 /// Extract a string literal from the macro expanded version of `expr`,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index fdb698441fc..c10f3ce0774 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -536,7 +536,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
             // create issue to recommend refactoring here?
             fld.extsbox.insert(intern(name.as_slice()), ext);
             if attr::contains_name(it.attrs.as_slice(), "macro_export") {
-                fld.cx.push_exported_macro(it.span);
+                fld.cx.exported_macros.push(it);
             }
             SmallVector::zero()
         }
@@ -1039,7 +1039,7 @@ pub struct ExportedMacros {
 pub fn expand_crate(parse_sess: &parse::ParseSess,
                     cfg: ExpansionConfig,
                     // these are the macros being imported to this crate:
-                    macros: Vec<ExportedMacros>,
+                    imported_macros: Vec<ExportedMacros>,
                     user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
@@ -1048,7 +1048,7 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
         cx: &mut cx,
     };
 
-    for ExportedMacros { crate_name, macros } in macros.move_iter() {
+    for ExportedMacros { crate_name, macros } in imported_macros.move_iter() {
         let name = format!("<{} macros>", token::get_ident(crate_name))
             .into_string();
 
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 4b245f2c9fd..2e86d1c005d 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -49,6 +49,9 @@ struct Context<'a, 'b> {
     name_types: HashMap<String, ArgumentType>,
     name_ordering: Vec<String>,
 
+    /// The latest consecutive literal strings
+    literal: Option<String>,
+
     /// Collection of the compiled `rt::Piece` structures
     pieces: Vec<Gc<ast::Expr>>,
     name_positions: HashMap<String, uint>,
@@ -362,17 +365,29 @@ impl<'a, 'b> Context<'a, 'b> {
         }
     }
 
+    /// Translate the accumulated string literals to a static `rt::Piece`
+    fn trans_literal_string(&mut self) -> Option<Gc<ast::Expr>> {
+        let sp = self.fmtsp;
+        self.literal.take().map(|s| {
+            let s = token::intern_and_get_ident(s.as_slice());
+            self.ecx.expr_call_global(sp,
+                                      self.rtpath("String"),
+                                      vec!(
+                self.ecx.expr_str(sp, s)
+            ))
+        })
+    }
+
     /// Translate a `parse::Piece` to a static `rt::Piece`
-    fn trans_piece(&mut self, piece: &parse::Piece) -> Gc<ast::Expr> {
+    fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> {
         let sp = self.fmtsp;
         match *piece {
             parse::String(s) => {
-                let s = token::intern_and_get_ident(s);
-                self.ecx.expr_call_global(sp,
-                                          self.rtpath("String"),
-                                          vec!(
-                    self.ecx.expr_str(sp, s)
-                ))
+                match self.literal {
+                    Some(ref mut sb) => sb.push_str(s),
+                    ref mut empty => *empty = Some(String::from_str(s)),
+                }
+                None
             }
             parse::Argument(ref arg) => {
                 // Translate the position
@@ -430,7 +445,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 let s = self.ecx.expr_struct(sp, path, vec!(
                     self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
                     self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt)));
-                self.ecx.expr_call_global(sp, self.rtpath("Argument"), vec!(s))
+                Some(self.ecx.expr_call_global(sp, self.rtpath("Argument"), vec!(s)))
             }
         }
     }
@@ -694,6 +709,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         name_ordering: name_ordering,
         nest_level: 0,
         next_arg: 0,
+        literal: None,
         pieces: Vec::new(),
         method_statics: Vec::new(),
         fmtsp: sp,
@@ -712,8 +728,14 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
             Some(piece) => {
                 if parser.errors.len() > 0 { break }
                 cx.verify_piece(&piece);
-                let piece = cx.trans_piece(&piece);
-                cx.pieces.push(piece);
+                match cx.trans_piece(&piece) {
+                    Some(piece) => {
+                        cx.trans_literal_string().map(|piece|
+                                                      cx.pieces.push(piece));
+                        cx.pieces.push(piece);
+                    }
+                    None => {}
+                }
             }
             None => break
         }
@@ -727,6 +749,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         }
         None => {}
     }
+    cx.trans_literal_string().map(|piece| cx.pieces.push(piece));
 
     // Make sure that all arguments were used and all arguments have types.
     for (i, ty) in cx.arg_types.iter().enumerate() {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index e31ec048653..271eee7d08a 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -752,7 +752,7 @@ pub fn noop_fold_crate<T: Folder>(c: Crate, folder: &mut T) -> Crate {
         attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
         config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
         span: folder.new_span(c.span),
-        exported_macros: c.exported_macros.iter().map(|sp| folder.new_span(*sp)).collect(),
+        exported_macros: c.exported_macros
     }
 }