about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-01 07:01:45 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-05 04:53:33 +0000
commit7a3ae576fa729e0465719f97aa7bb80c9721b446 (patch)
tree75cfae8d185e3269d93b2cbe7f6e0bdc1f16ef4b
parent79fa9eb643cfbb807813afed6f825f6654ee7662 (diff)
downloadrust-7a3ae576fa729e0465719f97aa7bb80c9721b446.tar.gz
rust-7a3ae576fa729e0465719f97aa7bb80c9721b446.zip
Refactor `expand_invoc(.., fld)` -> `self.expand_invoc(..)`.
-rw-r--r--src/libsyntax/ext/expand.rs419
1 files changed, 212 insertions, 207 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index a713196032c..17b2b2d25b9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -143,199 +143,6 @@ enum InvocationKind {
     },
 }
 
-fn expand_invoc(invoc: Invocation, fld: &mut MacroExpander) -> Expansion {
-    match invoc.kind {
-        InvocationKind::Bang { .. } => expand_bang_invoc(invoc, fld),
-        InvocationKind::Attr { .. } => expand_attr_invoc(invoc, fld),
-    }
-}
-
-fn expand_attr_invoc(invoc: Invocation, fld: &mut MacroExpander) -> Expansion {
-    let Invocation { expansion_kind: kind, .. } = invoc;
-    let (attr, item) = match invoc.kind {
-        InvocationKind::Attr { attr, item } => (attr, item),
-        _ => unreachable!(),
-    };
-
-    let extension = match fld.cx.syntax_env.find(intern(&attr.name())) {
-        Some(extension) => extension,
-        None => unreachable!(),
-    };
-
-    attr::mark_used(&attr);
-    fld.cx.bt_push(ExpnInfo {
-        call_site: attr.span,
-        callee: NameAndSpan {
-            format: MacroAttribute(intern(&attr.name())),
-            span: Some(attr.span),
-            allow_internal_unstable: false,
-        }
-    });
-
-    let modified = match *extension {
-        MultiModifier(ref mac) => {
-            kind.expect_from_annotatables(mac.expand(fld.cx, attr.span, &attr.node.value, item))
-        }
-        MultiDecorator(ref mac) => {
-            let mut items = Vec::new();
-            mac.expand(fld.cx, attr.span, &attr.node.value, &item, &mut |item| items.push(item));
-            items.push(item);
-            kind.expect_from_annotatables(items)
-        }
-        _ => unreachable!(),
-    };
-
-    fld.cx.bt_pop();
-
-    let configured = modified.fold_with(&mut fld.strip_unconfigured());
-    configured.fold_with(fld)
-}
-
-/// Expand a macro invocation. Returns the result of expansion.
-fn expand_bang_invoc(invoc: Invocation, fld: &mut MacroExpander) -> Expansion {
-    let Invocation { mark, expansion_kind: kind, .. } = invoc;
-    let (attrs, mac, ident, span) = match invoc.kind {
-        InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
-        _ => unreachable!(),
-    };
-    let Mac_ { path, tts, .. } = mac.node;
-
-    // Detect use of feature-gated or invalid attributes on macro invoations
-    // since they will not be detected after macro expansion.
-    for attr in attrs.iter() {
-        feature_gate::check_attribute(&attr, &fld.cx.parse_sess.span_diagnostic,
-                                      &fld.cx.parse_sess.codemap(),
-                                      &fld.cx.ecfg.features.unwrap());
-    }
-
-    if path.segments.len() > 1 || path.global || !path.segments[0].parameters.is_empty() {
-        fld.cx.span_err(path.span, "expected macro name without module separators");
-        return kind.dummy(span);
-    }
-
-    let extname = path.segments[0].identifier.name;
-    let extension = if let Some(extension) = fld.cx.syntax_env.find(extname) {
-        extension
-    } else {
-        let mut err =
-            fld.cx.struct_span_err(path.span, &format!("macro undefined: '{}!'", &extname));
-        fld.cx.suggest_macro_name(&extname.as_str(), &mut err);
-        err.emit();
-        return kind.dummy(span);
-    };
-
-    let ident = ident.unwrap_or(keywords::Invalid.ident());
-    let marked_tts = mark_tts(&tts, mark);
-    let opt_expanded = match *extension {
-        NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
-            if ident.name != keywords::Invalid.name() {
-                let msg =
-                    format!("macro {}! expects no ident argument, given '{}'", extname, ident);
-                fld.cx.span_err(path.span, &msg);
-                return kind.dummy(span);
-            }
-
-            fld.cx.bt_push(ExpnInfo {
-                call_site: span,
-                callee: NameAndSpan {
-                    format: MacroBang(extname),
-                    span: exp_span,
-                    allow_internal_unstable: allow_internal_unstable,
-                },
-            });
-
-            kind.make_from(expandfun.expand(fld.cx, span, &marked_tts))
-        }
-
-        IdentTT(ref expander, tt_span, allow_internal_unstable) => {
-            if ident.name == keywords::Invalid.name() {
-                fld.cx.span_err(path.span,
-                                &format!("macro {}! expects an ident argument", extname));
-                return kind.dummy(span);
-            };
-
-            fld.cx.bt_push(ExpnInfo {
-                call_site: span,
-                callee: NameAndSpan {
-                    format: MacroBang(extname),
-                    span: tt_span,
-                    allow_internal_unstable: allow_internal_unstable,
-                }
-            });
-
-            kind.make_from(expander.expand(fld.cx, span, ident, marked_tts))
-        }
-
-        MacroRulesTT => {
-            if ident.name == keywords::Invalid.name() {
-                fld.cx.span_err(path.span,
-                                &format!("macro {}! expects an ident argument", extname));
-                return kind.dummy(span);
-            };
-
-            fld.cx.bt_push(ExpnInfo {
-                call_site: span,
-                callee: NameAndSpan {
-                    format: MacroBang(extname),
-                    span: None,
-                    // `macro_rules!` doesn't directly allow unstable
-                    // (this is orthogonal to whether the macro it creates allows it)
-                    allow_internal_unstable: false,
-                }
-            });
-
-            let def = ast::MacroDef {
-                ident: ident,
-                id: ast::DUMMY_NODE_ID,
-                span: span,
-                imported_from: None,
-                use_locally: true,
-                body: marked_tts,
-                export: attr::contains_name(&attrs, "macro_export"),
-                allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
-                attrs: attrs,
-            };
-
-            fld.cx.insert_macro(def.clone());
-
-            // If keep_macs is true, expands to a MacEager::items instead.
-            if fld.keep_macs {
-                Some(reconstruct_macro_rules(&def, &path))
-            } else {
-                Some(macro_scope_placeholder())
-            }
-        }
-
-        MultiDecorator(..) | MultiModifier(..) => {
-            fld.cx.span_err(path.span,
-                            &format!("`{}` can only be used in attributes", extname));
-            return kind.dummy(span);
-        }
-    };
-
-    let expanded = if let Some(expanded) = opt_expanded {
-        expanded
-    } else {
-        let msg = format!("non-{kind} macro in {kind} position: {name}",
-                          name = path.segments[0].identifier.name, kind = kind.name());
-        fld.cx.span_err(path.span, &msg);
-        return kind.dummy(span);
-    };
-
-    let marked = expanded.fold_with(&mut Marker { mark: mark, expn_id: Some(fld.cx.backtrace()) });
-    let configured = marked.fold_with(&mut fld.strip_unconfigured());
-    fld.load_macros(&configured);
-
-    let fully_expanded = if fld.single_step {
-        configured
-    } else {
-        configured.fold_with(fld)
-    };
-
-    fld.cx.bt_pop();
-    fully_expanded
-}
-
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
@@ -467,6 +274,204 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
         false
     }
+
+    fn expand_invoc(&mut self, invoc: Invocation) -> Expansion {
+        match invoc.kind {
+            InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc),
+            InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc),
+        }
+    }
+
+    fn expand_attr_invoc(&mut self, invoc: Invocation) -> Expansion {
+        let Invocation { expansion_kind: kind, .. } = invoc;
+        let (attr, item) = match invoc.kind {
+            InvocationKind::Attr { attr, item } => (attr, item),
+            _ => unreachable!(),
+        };
+
+        let extension = match self.cx.syntax_env.find(intern(&attr.name())) {
+            Some(extension) => extension,
+            None => unreachable!(),
+        };
+
+        attr::mark_used(&attr);
+        self.cx.bt_push(ExpnInfo {
+            call_site: attr.span,
+            callee: NameAndSpan {
+                format: MacroAttribute(intern(&attr.name())),
+                span: Some(attr.span),
+                allow_internal_unstable: false,
+            }
+        });
+
+        let modified = match *extension {
+            MultiModifier(ref mac) => {
+                let item = mac.expand(self.cx, attr.span, &attr.node.value, item);
+                kind.expect_from_annotatables(item)
+            }
+            MultiDecorator(ref mac) => {
+                let mut items = Vec::new();
+                mac.expand(self.cx, attr.span, &attr.node.value, &item,
+                           &mut |item| items.push(item));
+                items.push(item);
+                kind.expect_from_annotatables(items)
+            }
+            _ => unreachable!(),
+        };
+
+        self.cx.bt_pop();
+
+        let configured = modified.fold_with(&mut self.strip_unconfigured());
+        configured.fold_with(self)
+    }
+
+    /// Expand a macro invocation. Returns the result of expansion.
+    fn expand_bang_invoc(&mut self, invoc: Invocation) -> Expansion {
+        let Invocation { mark, expansion_kind: kind, .. } = invoc;
+        let (attrs, mac, ident, span) = match invoc.kind {
+            InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
+            _ => unreachable!(),
+        };
+        let Mac_ { path, tts, .. } = mac.node;
+
+        // Detect use of feature-gated or invalid attributes on macro invoations
+        // since they will not be detected after macro expansion.
+        for attr in attrs.iter() {
+            feature_gate::check_attribute(&attr, &self.cx.parse_sess.span_diagnostic,
+                                          &self.cx.parse_sess.codemap(),
+                                          &self.cx.ecfg.features.unwrap());
+        }
+
+        if path.segments.len() > 1 || path.global || !path.segments[0].parameters.is_empty() {
+            self.cx.span_err(path.span, "expected macro name without module separators");
+            return kind.dummy(span);
+        }
+
+        let extname = path.segments[0].identifier.name;
+        let extension = if let Some(extension) = self.cx.syntax_env.find(extname) {
+            extension
+        } else {
+            let mut err =
+                self.cx.struct_span_err(path.span, &format!("macro undefined: '{}!'", &extname));
+            self.cx.suggest_macro_name(&extname.as_str(), &mut err);
+            err.emit();
+            return kind.dummy(span);
+        };
+
+        let ident = ident.unwrap_or(keywords::Invalid.ident());
+        let marked_tts = mark_tts(&tts, mark);
+        let opt_expanded = match *extension {
+            NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
+                if ident.name != keywords::Invalid.name() {
+                    let msg =
+                        format!("macro {}! expects no ident argument, given '{}'", extname, ident);
+                    self.cx.span_err(path.span, &msg);
+                    return kind.dummy(span);
+                }
+
+                self.cx.bt_push(ExpnInfo {
+                    call_site: span,
+                    callee: NameAndSpan {
+                        format: MacroBang(extname),
+                        span: exp_span,
+                        allow_internal_unstable: allow_internal_unstable,
+                    },
+                });
+
+                kind.make_from(expandfun.expand(self.cx, span, &marked_tts))
+            }
+
+            IdentTT(ref expander, tt_span, allow_internal_unstable) => {
+                if ident.name == keywords::Invalid.name() {
+                    self.cx.span_err(path.span,
+                                    &format!("macro {}! expects an ident argument", extname));
+                    return kind.dummy(span);
+                };
+
+                self.cx.bt_push(ExpnInfo {
+                    call_site: span,
+                    callee: NameAndSpan {
+                        format: MacroBang(extname),
+                        span: tt_span,
+                        allow_internal_unstable: allow_internal_unstable,
+                    }
+                });
+
+                kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
+            }
+
+            MacroRulesTT => {
+                if ident.name == keywords::Invalid.name() {
+                    self.cx.span_err(path.span,
+                                    &format!("macro {}! expects an ident argument", extname));
+                    return kind.dummy(span);
+                };
+
+                self.cx.bt_push(ExpnInfo {
+                    call_site: span,
+                    callee: NameAndSpan {
+                        format: MacroBang(extname),
+                        span: None,
+                        // `macro_rules!` doesn't directly allow unstable
+                        // (this is orthogonal to whether the macro it creates allows it)
+                        allow_internal_unstable: false,
+                    }
+                });
+
+                let def = ast::MacroDef {
+                    ident: ident,
+                    id: ast::DUMMY_NODE_ID,
+                    span: span,
+                    imported_from: None,
+                    use_locally: true,
+                    body: marked_tts,
+                    export: attr::contains_name(&attrs, "macro_export"),
+                    allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
+                    attrs: attrs,
+                };
+
+                self.cx.insert_macro(def.clone());
+
+                // If keep_macs is true, expands to a MacEager::items instead.
+                if self.keep_macs {
+                    Some(reconstruct_macro_rules(&def, &path))
+                } else {
+                    Some(macro_scope_placeholder())
+                }
+            }
+
+            MultiDecorator(..) | MultiModifier(..) => {
+                self.cx.span_err(path.span,
+                                 &format!("`{}` can only be used in attributes", extname));
+                return kind.dummy(span);
+            }
+        };
+
+        let expanded = if let Some(expanded) = opt_expanded {
+            expanded
+        } else {
+            let msg = format!("non-{kind} macro in {kind} position: {name}",
+                              name = path.segments[0].identifier.name, kind = kind.name());
+            self.cx.span_err(path.span, &msg);
+            return kind.dummy(span);
+        };
+
+        let marked = expanded.fold_with(&mut Marker {
+            mark: mark,
+            expn_id: Some(self.cx.backtrace())
+        });
+        let configured = marked.fold_with(&mut self.strip_unconfigured());
+        self.load_macros(&configured);
+
+        let fully_expanded = if self.single_step {
+            configured
+        } else {
+            configured.fold_with(self)
+        };
+
+        self.cx.bt_pop();
+        fully_expanded
+    }
 }
 
 impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
@@ -474,7 +479,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         let expr = expr.unwrap();
         if let ast::ExprKind::Mac(mac) = expr.node {
             let invoc = self.new_bang_invoc(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr);
-            expand_invoc(invoc, self).make_expr()
+            self.expand_invoc(invoc).make_expr()
         } else {
             P(noop_fold_expr(expr, self))
         }
@@ -485,7 +490,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         if let ast::ExprKind::Mac(mac) = expr.node {
             let invoc =
                 self.new_bang_invoc(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr);
-            expand_invoc(invoc, self).make_opt_expr()
+            self.expand_invoc(invoc).make_opt_expr()
         } else {
             Some(P(noop_fold_expr(expr, self)))
         }
@@ -494,13 +499,13 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
     fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
         match pat.node {
             PatKind::Mac(_) => {}
-            _ => return noop_fold_pat(pat, self)
+            _ => return noop_fold_pat(pat, self),
         }
 
         pat.and_then(|pat| match pat.node {
             PatKind::Mac(mac) => {
                 let invoc = self.new_bang_invoc(mac, Vec::new(), pat.span, ExpansionKind::Pat);
-                expand_invoc(invoc, self).make_pat()
+                self.expand_invoc(invoc).make_pat()
             }
             _ => unreachable!(),
         })
@@ -509,11 +514,11 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
     fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
         let (mac, style, attrs) = match stmt.node {
             StmtKind::Mac(mac) => mac.unwrap(),
-            _ => return noop_fold_stmt(stmt, self)
+            _ => return noop_fold_stmt(stmt, self),
         };
 
         let invoc = self.new_bang_invoc(mac, attrs.into(), stmt.span, ExpansionKind::Stmts);
-        let mut fully_expanded = expand_invoc(invoc, self).make_stmts();
+        let mut fully_expanded = self.expand_invoc(invoc).make_stmts();
 
         // If this is a macro invocation with a semicolon, then apply that
         // semicolon to the final statement produced by expansion.
@@ -540,7 +545,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         let (item, attr) = self.classify_item(item);
         if let Some(attr) = attr {
             let invoc = self.new_attr_invoc(attr, Annotatable::Item(item), ExpansionKind::Items);
-            return expand_invoc(invoc, self).make_items();
+            return self.expand_invoc(invoc).make_items();
         }
 
         match item.node {
@@ -560,7 +565,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
                             ident: Some(item.ident),
                             span: item.span,
                         });
-                        expand_invoc(invoc, self).make_items()
+                        self.expand_invoc(invoc).make_items()
                     }
                     _ => unreachable!(),
                 })
@@ -598,14 +603,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         if let Some(attr) = attr {
             let item = Annotatable::TraitItem(P(item));
             let invoc = self.new_attr_invoc(attr, item, ExpansionKind::TraitItems);
-            return expand_invoc(invoc, self).make_trait_items();
+            return self.expand_invoc(invoc).make_trait_items();
         }
 
         match item.node {
             ast::TraitItemKind::Macro(mac) => {
                 let ast::TraitItem { attrs, span, .. } = item;
                 let invoc = self.new_bang_invoc(mac, attrs, span, ExpansionKind::TraitItems);
-                expand_invoc(invoc, self).make_trait_items()
+                self.expand_invoc(invoc).make_trait_items()
             }
             _ => fold::noop_fold_trait_item(item, self),
         }
@@ -616,16 +621,16 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         if let Some(attr) = attr {
             let item = Annotatable::ImplItem(P(item));
             let invoc = self.new_attr_invoc(attr, item, ExpansionKind::ImplItems);
-            return expand_invoc(invoc, self).make_impl_items();
+            return self.expand_invoc(invoc).make_impl_items();
         }
 
         match item.node {
             ast::ImplItemKind::Macro(mac) => {
                 let ast::ImplItem { attrs, span, .. } = item;
                 let invoc = self.new_bang_invoc(mac, attrs, span, ExpansionKind::ImplItems);
-                expand_invoc(invoc, self).make_impl_items()
+                self.expand_invoc(invoc).make_impl_items()
             }
-            _ => fold::noop_fold_impl_item(item, self)
+            _ => fold::noop_fold_impl_item(item, self),
         }
     }
 
@@ -638,7 +643,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         match ty.node {
             ast::TyKind::Mac(mac) => {
                 let invoc = self.new_bang_invoc(mac, Vec::new(), ty.span, ExpansionKind::Ty);
-                expand_invoc(invoc, self).make_ty()
+                self.expand_invoc(invoc).make_ty()
             }
             _ => unreachable!(),
         }