Access parse/attrs.rs with an impl.
This commit is contained in:
parent
09652c8f5f
commit
5b72e52e47
|
@ -13,6 +13,7 @@ export parse_item_from_source_str;
|
|||
export parse_from_source_str;
|
||||
|
||||
import parser::parser;
|
||||
import attr::parser_attr;
|
||||
import common::parser_common;
|
||||
import ast::node_id;
|
||||
import util::interner;
|
||||
|
@ -44,7 +45,7 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg,
|
|||
let p = new_parser_from_file(sess, cfg, input, parser::CRATE_FILE);
|
||||
let lo = p.span.lo;
|
||||
let prefix = path::dirname(p.reader.filemap.name);
|
||||
let leading_attrs = attr::parse_inner_attrs_and_next(p);
|
||||
let leading_attrs = p.parse_inner_attrs_and_next();
|
||||
let crate_attrs = leading_attrs.inner;
|
||||
let first_cdir_attr = leading_attrs.next;
|
||||
let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
|
||||
|
|
|
@ -3,116 +3,130 @@ import ast_util::spanned;
|
|||
import common::{parser_common, seq_sep};
|
||||
|
||||
export attr_or_ext;
|
||||
export parse_outer_attributes;
|
||||
export parse_outer_attrs_or_ext;
|
||||
export parse_inner_attrs_and_next;
|
||||
export parse_optional_meta;
|
||||
export parser_attr;
|
||||
|
||||
// A type to distingush between the parsing of item attributes or syntax
|
||||
// extensions, which both begin with token.POUND
|
||||
type attr_or_ext = option<either<[ast::attribute], @ast::expr>>;
|
||||
|
||||
fn parse_outer_attrs_or_ext(
|
||||
p: parser,
|
||||
first_item_attrs: [ast::attribute]) -> attr_or_ext {
|
||||
let expect_item_next = vec::is_not_empty(first_item_attrs);
|
||||
if p.token == token::POUND {
|
||||
let lo = p.span.lo;
|
||||
if p.look_ahead(1u) == token::LBRACKET {
|
||||
p.bump();
|
||||
let first_attr = parse_attribute_naked(p, ast::attr_outer, lo);
|
||||
ret some(left([first_attr] + parse_outer_attributes(p)));
|
||||
} else if !(p.look_ahead(1u) == token::LT
|
||||
|| p.look_ahead(1u) == token::LBRACKET
|
||||
|| expect_item_next) {
|
||||
p.bump();
|
||||
ret some(right(p.parse_syntax_ext_naked(lo)));
|
||||
impl parser_attr for parser {
|
||||
|
||||
fn parse_outer_attrs_or_ext(first_item_attrs: [ast::attribute])
|
||||
-> attr_or_ext
|
||||
{
|
||||
let expect_item_next = vec::is_not_empty(first_item_attrs);
|
||||
if self.token == token::POUND {
|
||||
let lo = self.span.lo;
|
||||
if self.look_ahead(1u) == token::LBRACKET {
|
||||
self.bump();
|
||||
let first_attr =
|
||||
self.parse_attribute_naked(ast::attr_outer, lo);
|
||||
ret some(left([first_attr] + self.parse_outer_attributes()));
|
||||
} else if !(self.look_ahead(1u) == token::LT
|
||||
|| self.look_ahead(1u) == token::LBRACKET
|
||||
|| expect_item_next) {
|
||||
self.bump();
|
||||
ret some(right(self.parse_syntax_ext_naked(lo)));
|
||||
} else { ret none; }
|
||||
} else { ret none; }
|
||||
} else { ret none; }
|
||||
}
|
||||
|
||||
// Parse attributes that appear before an item
|
||||
fn parse_outer_attributes(p: parser) -> [ast::attribute] {
|
||||
let mut attrs: [ast::attribute] = [];
|
||||
while p.token == token::POUND && p.look_ahead(1u) == token::LBRACKET {
|
||||
attrs += [parse_attribute(p, ast::attr_outer)];
|
||||
}
|
||||
ret attrs;
|
||||
}
|
||||
|
||||
fn parse_attribute(p: parser, style: ast::attr_style) -> ast::attribute {
|
||||
let lo = p.span.lo;
|
||||
p.expect(token::POUND);
|
||||
ret parse_attribute_naked(p, style, lo);
|
||||
}
|
||||
|
||||
fn parse_attribute_naked(p: parser, style: ast::attr_style, lo: uint) ->
|
||||
ast::attribute {
|
||||
p.expect(token::LBRACKET);
|
||||
let meta_item = parse_meta_item(p);
|
||||
p.expect(token::RBRACKET);
|
||||
let mut hi = p.span.hi;
|
||||
ret spanned(lo, hi, {style: style, value: *meta_item});
|
||||
}
|
||||
|
||||
// Parse attributes that appear after the opening of an item, each terminated
|
||||
// by a semicolon. In addition to a vector of inner attributes, this function
|
||||
// also returns a vector that may contain the first outer attribute of the
|
||||
// next item (since we can't know whether the attribute is an inner attribute
|
||||
// of the containing item or an outer attribute of the first contained item
|
||||
// until we see the semi).
|
||||
fn parse_inner_attrs_and_next(p: parser) ->
|
||||
{inner: [ast::attribute], next: [ast::attribute]} {
|
||||
let mut inner_attrs: [ast::attribute] = [];
|
||||
let mut next_outer_attrs: [ast::attribute] = [];
|
||||
while p.token == token::POUND {
|
||||
if p.look_ahead(1u) != token::LBRACKET {
|
||||
// This is an extension
|
||||
break;
|
||||
// Parse attributes that appear before an item
|
||||
fn parse_outer_attributes() -> [ast::attribute] {
|
||||
let mut attrs: [ast::attribute] = [];
|
||||
while self.token == token::POUND
|
||||
&& self.look_ahead(1u) == token::LBRACKET {
|
||||
attrs += [self.parse_attribute(ast::attr_outer)];
|
||||
}
|
||||
let attr = parse_attribute(p, ast::attr_inner);
|
||||
if p.token == token::SEMI {
|
||||
p.bump();
|
||||
inner_attrs += [attr];
|
||||
} else {
|
||||
// It's not really an inner attribute
|
||||
let outer_attr =
|
||||
spanned(attr.span.lo, attr.span.hi,
|
||||
{style: ast::attr_outer, value: attr.node.value});
|
||||
next_outer_attrs += [outer_attr];
|
||||
break;
|
||||
ret attrs;
|
||||
}
|
||||
|
||||
fn parse_attribute(style: ast::attr_style) -> ast::attribute {
|
||||
let lo = self.span.lo;
|
||||
self.expect(token::POUND);
|
||||
ret self.parse_attribute_naked(style, lo);
|
||||
}
|
||||
|
||||
fn parse_attribute_naked(style: ast::attr_style, lo: uint) ->
|
||||
ast::attribute {
|
||||
self.expect(token::LBRACKET);
|
||||
let meta_item = self.parse_meta_item();
|
||||
self.expect(token::RBRACKET);
|
||||
let mut hi = self.span.hi;
|
||||
ret spanned(lo, hi, {style: style, value: *meta_item});
|
||||
}
|
||||
|
||||
// Parse attributes that appear after the opening of an item, each
|
||||
// terminated by a semicolon. In addition to a vector of inner attributes,
|
||||
// this function also returns a vector that may contain the first outer
|
||||
// attribute of the next item (since we can't know whether the attribute
|
||||
// is an inner attribute of the containing item or an outer attribute of
|
||||
// the first contained item until we see the semi).
|
||||
fn parse_inner_attrs_and_next() ->
|
||||
{inner: [ast::attribute], next: [ast::attribute]} {
|
||||
let mut inner_attrs: [ast::attribute] = [];
|
||||
let mut next_outer_attrs: [ast::attribute] = [];
|
||||
while self.token == token::POUND {
|
||||
if self.look_ahead(1u) != token::LBRACKET {
|
||||
// This is an extension
|
||||
break;
|
||||
}
|
||||
let attr = self.parse_attribute(ast::attr_inner);
|
||||
if self.token == token::SEMI {
|
||||
self.bump();
|
||||
inner_attrs += [attr];
|
||||
} else {
|
||||
// It's not really an inner attribute
|
||||
let outer_attr =
|
||||
spanned(attr.span.lo, attr.span.hi,
|
||||
{style: ast::attr_outer, value: attr.node.value});
|
||||
next_outer_attrs += [outer_attr];
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret {inner: inner_attrs, next: next_outer_attrs};
|
||||
}
|
||||
|
||||
fn parse_meta_item() -> @ast::meta_item {
|
||||
let lo = self.span.lo;
|
||||
let ident = self.parse_ident();
|
||||
alt self.token {
|
||||
token::EQ {
|
||||
self.bump();
|
||||
let lit = self.parse_lit();
|
||||
let mut hi = self.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
|
||||
}
|
||||
token::LPAREN {
|
||||
let inner_items = self.parse_meta_seq();
|
||||
let mut hi = self.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_list(ident, inner_items));
|
||||
}
|
||||
_ {
|
||||
let mut hi = self.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_word(ident));
|
||||
}
|
||||
}
|
||||
}
|
||||
ret {inner: inner_attrs, next: next_outer_attrs};
|
||||
}
|
||||
|
||||
fn parse_meta_item(p: parser) -> @ast::meta_item {
|
||||
let lo = p.span.lo;
|
||||
let ident = p.parse_ident();
|
||||
alt p.token {
|
||||
token::EQ {
|
||||
p.bump();
|
||||
let lit = p.parse_lit();
|
||||
let mut hi = p.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
|
||||
}
|
||||
token::LPAREN {
|
||||
let inner_items = parse_meta_seq(p);
|
||||
let mut hi = p.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_list(ident, inner_items));
|
||||
}
|
||||
_ {
|
||||
let mut hi = p.span.hi;
|
||||
ret @spanned(lo, hi, ast::meta_word(ident));
|
||||
}
|
||||
fn parse_meta_seq() -> [@ast::meta_item] {
|
||||
ret self.parse_seq(token::LPAREN, token::RPAREN,
|
||||
seq_sep(token::COMMA),
|
||||
{|p| p.parse_meta_item()}).node;
|
||||
}
|
||||
|
||||
fn parse_optional_meta() -> [@ast::meta_item] {
|
||||
alt self.token { token::LPAREN { ret self.parse_meta_seq(); }
|
||||
_ { ret []; } }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_meta_seq(p: parser) -> [@ast::meta_item] {
|
||||
ret p.parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA),
|
||||
{|p| parse_meta_item(p)}).node;
|
||||
}
|
||||
|
||||
fn parse_optional_meta(p: parser) -> [@ast::meta_item] {
|
||||
alt p.token { token::LPAREN { ret parse_meta_seq(p); } _ { ret []; } }
|
||||
}
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import parser::{parser, SOURCE_FILE};
|
||||
import attr::parse_inner_attrs_and_next;
|
||||
import attr::parser_attr;
|
||||
|
||||
export eval_crate_directives_to_mod;
|
||||
|
||||
|
@ -65,7 +65,7 @@ fn parse_companion_mod(cx: ctx, prefix: str, suffix: option<str>)
|
|||
if file_exists(modpath) {
|
||||
#debug("found companion mod");
|
||||
let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath, SOURCE_FILE);
|
||||
let inner_attrs = parse_inner_attrs_and_next(p0);
|
||||
let inner_attrs = p0.parse_inner_attrs_and_next();
|
||||
let first_item_outer_attrs = inner_attrs.next;
|
||||
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
|
||||
cx.sess.chpos = p0.reader.chpos;
|
||||
|
@ -97,7 +97,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
|
|||
} else { prefix + path::path_sep() + file_path };
|
||||
let p0 =
|
||||
new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE);
|
||||
let inner_attrs = parse_inner_attrs_and_next(p0);
|
||||
let inner_attrs = p0.parse_inner_attrs_and_next();
|
||||
let mod_attrs = attrs + inner_attrs.inner;
|
||||
let first_item_outer_attrs = inner_attrs.next;
|
||||
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
|
||||
|
|
|
@ -8,10 +8,7 @@ import ast_util::{spanned, mk_sp, ident_to_path, operator_prec};
|
|||
import ast::*;
|
||||
import lexer::reader;
|
||||
import prec::{as_prec, token_to_binop};
|
||||
import attr::{parse_outer_attrs_or_ext,
|
||||
parse_inner_attrs_and_next,
|
||||
parse_outer_attributes,
|
||||
parse_optional_meta};
|
||||
import attr::parser_attr;
|
||||
import common::*;
|
||||
import dvec::{dvec, extensions};
|
||||
|
||||
|
@ -168,7 +165,7 @@ class parser {
|
|||
|
||||
fn parse_ty_methods() -> [ty_method] {
|
||||
(self.parse_seq(token::LBRACE, token::RBRACE, seq_sep_none()) { |p|
|
||||
let attrs = parse_outer_attributes(p);
|
||||
let attrs = p.parse_outer_attributes();
|
||||
let flo = p.span.lo;
|
||||
let pur = p.parse_fn_purity();
|
||||
let ident = p.parse_method_name();
|
||||
|
@ -1529,7 +1526,7 @@ class parser {
|
|||
ret @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id()));
|
||||
} else {
|
||||
let mut item_attrs;
|
||||
alt parse_outer_attrs_or_ext(self, first_item_attrs) {
|
||||
alt self.parse_outer_attrs_or_ext(first_item_attrs) {
|
||||
none { item_attrs = []; }
|
||||
some(left(attrs)) { item_attrs = attrs; }
|
||||
some(right(ext)) {
|
||||
|
@ -1575,7 +1572,7 @@ class parser {
|
|||
fn maybe_parse_inner_attrs_and_next(p: parser, parse_attrs: bool) ->
|
||||
{inner: [attribute], next: [attribute]} {
|
||||
if parse_attrs {
|
||||
parse_inner_attrs_and_next(p)
|
||||
p.parse_inner_attrs_and_next()
|
||||
} else {
|
||||
{inner: [], next: []}
|
||||
}
|
||||
|
@ -1832,7 +1829,7 @@ class parser {
|
|||
}
|
||||
|
||||
fn parse_method(pr: visibility) -> @method {
|
||||
let attrs = parse_outer_attributes(self);
|
||||
let attrs = self.parse_outer_attributes();
|
||||
let lo = self.span.lo, pur = self.parse_fn_purity();
|
||||
let ident = self.parse_method_name();
|
||||
let tps = self.parse_ty_params();
|
||||
|
@ -2072,7 +2069,7 @@ class parser {
|
|||
let mut items: [@item] = [];
|
||||
let mut first = true;
|
||||
while self.token != term {
|
||||
let mut attrs = parse_outer_attributes(self);
|
||||
let mut attrs = self.parse_outer_attributes();
|
||||
if first { attrs = attrs_remaining + attrs; first = false; }
|
||||
#debug["parse_mod_items: parse_item(attrs=%?)", attrs];
|
||||
let vis = self.parse_visibility(private);
|
||||
|
@ -2107,7 +2104,7 @@ class parser {
|
|||
fn parse_item_mod() -> item_info {
|
||||
let id = self.parse_ident();
|
||||
self.expect(token::LBRACE);
|
||||
let inner_attrs = parse_inner_attrs_and_next(self);
|
||||
let inner_attrs = self.parse_inner_attrs_and_next();
|
||||
let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
|
||||
self.expect(token::RBRACE);
|
||||
(id, item_mod(m), some(inner_attrs.inner))
|
||||
|
@ -2152,7 +2149,7 @@ class parser {
|
|||
let mut items: [@native_item] = [];
|
||||
let mut initial_attrs = attrs_remaining;
|
||||
while self.token != token::RBRACE {
|
||||
let attrs = initial_attrs + parse_outer_attributes(self);
|
||||
let attrs = initial_attrs + self.parse_outer_attributes();
|
||||
initial_attrs = [];
|
||||
items += [self.parse_native_item(attrs)];
|
||||
}
|
||||
|
@ -2164,7 +2161,7 @@ class parser {
|
|||
self.expect_keyword("mod");
|
||||
let id = self.parse_ident();
|
||||
self.expect(token::LBRACE);
|
||||
let more_attrs = parse_inner_attrs_and_next(self);
|
||||
let more_attrs = self.parse_inner_attrs_and_next();
|
||||
let m = self.parse_native_mod_items(more_attrs.next);
|
||||
self.expect(token::RBRACE);
|
||||
(id, item_native_mod(m), some(more_attrs.inner))
|
||||
|
@ -2221,7 +2218,7 @@ class parser {
|
|||
let mut all_nullary = true, have_disr = false;
|
||||
|
||||
while self.token != token::RBRACE {
|
||||
let variant_attrs = parse_outer_attributes(self);
|
||||
let variant_attrs = self.parse_outer_attributes();
|
||||
let vlo = self.span.lo;
|
||||
let vis = self.parse_visibility(default_vis);
|
||||
let ident = self.parse_value_ident();
|
||||
|
@ -2331,7 +2328,7 @@ class parser {
|
|||
|
||||
fn parse_use() -> view_item_ {
|
||||
let ident = self.parse_ident();
|
||||
let metadata = parse_optional_meta(self);
|
||||
let metadata = self.parse_optional_meta();
|
||||
ret view_item_use(ident, metadata, self.get_id());
|
||||
}
|
||||
|
||||
|
@ -2439,12 +2436,12 @@ class parser {
|
|||
fn parse_view(+first_item_attrs: [attribute],
|
||||
only_imports: bool) -> {attrs_remaining: [attribute],
|
||||
view_items: [@view_item]} {
|
||||
let mut attrs = first_item_attrs + parse_outer_attributes(self);
|
||||
let mut attrs = first_item_attrs + self.parse_outer_attributes();
|
||||
let mut items = [];
|
||||
while if only_imports { self.is_keyword("import") }
|
||||
else { self.is_view_item() } {
|
||||
items += [self.parse_view_item(attrs)];
|
||||
attrs = parse_outer_attributes(self);
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
{attrs_remaining: attrs, view_items: items}
|
||||
}
|
||||
|
@ -2452,7 +2449,7 @@ class parser {
|
|||
// Parses a source module as a crate
|
||||
fn parse_crate_mod(_cfg: crate_cfg) -> @crate {
|
||||
let lo = self.span.lo;
|
||||
let crate_attrs = parse_inner_attrs_and_next(self);
|
||||
let crate_attrs = self.parse_inner_attrs_and_next();
|
||||
let first_item_outer_attrs = crate_attrs.next;
|
||||
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
|
||||
ret @spanned(lo, self.span.lo,
|
||||
|
@ -2481,7 +2478,7 @@ class parser {
|
|||
crate_directive {
|
||||
|
||||
// Collect the next attributes
|
||||
let outer_attrs = first_outer_attr + parse_outer_attributes(self);
|
||||
let outer_attrs = first_outer_attr + self.parse_outer_attributes();
|
||||
// In a crate file outer attributes are only going to apply to mods
|
||||
let expect_mod = vec::len(outer_attrs) > 0u;
|
||||
|
||||
|
@ -2499,7 +2496,7 @@ class parser {
|
|||
// mod x = "foo_dir" { ...directives... }
|
||||
token::LBRACE {
|
||||
self.bump();
|
||||
let inner_attrs = parse_inner_attrs_and_next(self);
|
||||
let inner_attrs = self.parse_inner_attrs_and_next();
|
||||
let mod_attrs = outer_attrs + inner_attrs.inner;
|
||||
let next_outer_attr = inner_attrs.next;
|
||||
let cdirs = self.parse_crate_directives(token::RBRACE,
|
||||
|
|
|
@ -23,6 +23,7 @@ mod test {
|
|||
fn parse_attributes(source: str) -> [ast::attribute] {
|
||||
import syntax::parse;
|
||||
import parse::parser;
|
||||
import parse::attr::parser_attr;
|
||||
import syntax::codemap;
|
||||
import syntax::diagnostic;
|
||||
|
||||
|
@ -38,7 +39,7 @@ mod test {
|
|||
let parser = parse::new_parser_from_source_str(
|
||||
parse_sess, [], "-", codemap::fss_none, @source);
|
||||
|
||||
parse::attr::parse_outer_attributes(parser)
|
||||
parser.parse_outer_attributes()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue