diff options
| author | bors <bors@rust-lang.org> | 2014-07-13 19:16:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-07-13 19:16:28 +0000 |
| commit | 7a6208f2cc1bbe29dc42b21d27e98894b8bacc04 (patch) | |
| tree | d4341cdd32f5d747a6289b2335012ec8f435d151 /src/libsyntax/parse/parser.rs | |
| parent | fbeee04f31ac16fe61f29749145a29e562d065fe (diff) | |
| parent | aee5917556856428072cc090fb892176eaa075b3 (diff) | |
| download | rust-7a6208f2cc1bbe29dc42b21d27e98894b8bacc04.tar.gz rust-7a6208f2cc1bbe29dc42b21d27e98894b8bacc04.zip | |
auto merge of #15646 : jbclements/rust/method-macros, r=cmr
This patch adds support for macros in method position. It follows roughly the template for Item macros, where an outer `Method` wrapper contains a `Method_` enum which can either be a macro invocation or a standard macro definition. One note; adding support for macros that expand into multiple methods is not included here, but should be a simple parser change, since this patch updates the type of fold_macro to return a smallvector of methods. For reviewers, please pay special attention to the parser changes; these are the ones I'm most concerned about. Because of the small change to the interface of fold_method, this is a ... [breaking change]
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 84db2bc5a22..e0c94dffb5c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1249,16 +1249,10 @@ impl<'a> Parser<'a> { p.parse_inner_attrs_and_block(); let attrs = attrs.append(inner_attrs.as_slice()); Provided(box(GC) ast::Method { - ident: ident, attrs: attrs, - generics: generics, - explicit_self: explicit_self, - fn_style: style, - decl: d, - body: body, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - vis: vis, + node: ast::MethDecl(ident, generics, explicit_self, style, d, body, vis) }) } @@ -3252,6 +3246,7 @@ impl<'a> Parser<'a> { } else if is_ident(&self.token) && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) { + // it's a macro invocation: check_expected_item(self, !item_attrs.is_empty()); @@ -4027,7 +4022,7 @@ impl<'a> Parser<'a> { } /// Parse a method in a trait impl, starting with `attrs` attributes. - fn parse_method(&mut self, + pub fn parse_method(&mut self, already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> { let next_attrs = self.parse_outer_attributes(); let attrs = match already_parsed_attrs { @@ -4037,28 +4032,50 @@ impl<'a> Parser<'a> { let lo = self.span.lo; - let visa = self.parse_visibility(); - let fn_style = self.parse_fn_style(); - let ident = self.parse_ident(); - let generics = self.parse_generics(); - let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| { - p.parse_arg() - }); + // code copied from parse_macro_use_or_failure... abstraction! + let (method_, hi, new_attrs) = { + if !token::is_any_keyword(&self.token) + && self.look_ahead(1, |t| *t == token::NOT) + && (self.look_ahead(2, |t| *t == token::LPAREN) + || self.look_ahead(2, |t| *t == token::LBRACE)) { + // method macro. + let pth = self.parse_path(NoTypesAllowed).path; + self.expect(&token::NOT); - let (inner_attrs, body) = self.parse_inner_attrs_and_block(); - let hi = body.span.hi; - let attrs = attrs.append(inner_attrs.as_slice()); + // eat a matched-delimiter token tree: + let tts = match token::close_delimiter_for(&self.token) { + Some(ket) => { + self.bump(); + self.parse_seq_to_end(&ket, + seq_sep_none(), + |p| p.parse_token_tree()) + } + None => self.fatal("expected open delimiter") + }; + let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT); + let m: ast::Mac = codemap::Spanned { node: m_, + span: mk_sp(self.span.lo, + self.span.hi) }; + (ast::MethMac(m), self.span.hi, attrs) + } else { + let visa = self.parse_visibility(); + let fn_style = self.parse_fn_style(); + let ident = self.parse_ident(); + let generics = self.parse_generics(); + let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| { + p.parse_arg() + }); + let (inner_attrs, body) = self.parse_inner_attrs_and_block(); + let new_attrs = attrs.append(inner_attrs.as_slice()); + (ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa), + body.span.hi, new_attrs) + } + }; box(GC) ast::Method { - ident: ident, - attrs: attrs, - generics: generics, - explicit_self: explicit_self, - fn_style: fn_style, - decl: decl, - body: body, + attrs: new_attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - vis: visa, + node: method_, } } |
