Support visibility modifiers and attributes on view items
Issue #1893 Tangentially, issue #2357
This commit is contained in:
parent
5c0577f233
commit
96a159a6ea
9 changed files with 59 additions and 67 deletions
|
@ -612,7 +612,8 @@ enum view_path_ {
|
|||
}
|
||||
|
||||
#[auto_serialize]
|
||||
type view_item = spanned<view_item_>;
|
||||
type view_item = {node: view_item_, attrs: [attribute],
|
||||
vis: visibility, span: span};
|
||||
|
||||
#[auto_serialize]
|
||||
enum view_item_ {
|
||||
|
|
|
@ -679,6 +679,8 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
|
|||
fn f_view_item(afp: ast_fold_precursor, f: ast_fold, &&x: @view_item) ->
|
||||
@view_item {
|
||||
ret @{node: afp.fold_view_item(x.node, f),
|
||||
attrs: vec::map(x.attrs, {|a| fold_attribute_(a, f)}),
|
||||
vis: x.vis,
|
||||
span: afp.new_span(x.span)};
|
||||
}
|
||||
fn f_native_item(afp: ast_fold_precursor, f: ast_fold, &&x: @native_item)
|
||||
|
|
|
@ -39,7 +39,7 @@ fn parse_outer_attrs_or_ext(
|
|||
// 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 {
|
||||
while p.token == token::POUND && p.look_ahead(1u) == token::LBRACKET {
|
||||
attrs += [parse_attribute(p, ast::attr_outer)];
|
||||
}
|
||||
ret attrs;
|
||||
|
|
|
@ -58,12 +58,16 @@ fn require_keyword(p: parser, word: str) {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_keyword(p: parser, word: str) -> bool {
|
||||
fn token_is_keyword(p: parser, word: str, tok: token::token) -> bool {
|
||||
require_keyword(p, word);
|
||||
ret alt p.token {
|
||||
token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
|
||||
_ { false }
|
||||
};
|
||||
alt tok {
|
||||
token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
|
||||
_ { false }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_keyword(p: parser, word: str) -> bool {
|
||||
token_is_keyword(p, word, p.token)
|
||||
}
|
||||
|
||||
fn eat_keyword(p: parser, word: str) -> bool {
|
||||
|
|
|
@ -1606,8 +1606,8 @@ fn parse_block_tail_(p: parser, lo: uint, s: blk_check_mode,
|
|||
+first_item_attrs: [attribute]) -> blk {
|
||||
let mut stmts = [];
|
||||
let mut expr = none;
|
||||
let view_items = maybe_parse_view_import_only(p, first_item_attrs);
|
||||
let mut initial_attrs = first_item_attrs;
|
||||
let {attrs_remaining, view_items} = parse_view(p, first_item_attrs, true);
|
||||
let mut initial_attrs = attrs_remaining;
|
||||
|
||||
if p.token == token::RBRACE && !vec::is_empty(initial_attrs) {
|
||||
p.fatal("expected item");
|
||||
|
@ -2036,12 +2036,13 @@ fn parse_visibility(p: parser, def: visibility) -> visibility {
|
|||
fn parse_mod_items(p: parser, term: token::token,
|
||||
+first_item_attrs: [attribute]) -> _mod {
|
||||
// Shouldn't be any view items since we've already parsed an item attr
|
||||
let view_items = maybe_parse_view(p, first_item_attrs);
|
||||
let {attrs_remaining, view_items} =
|
||||
parse_view(p, first_item_attrs, false);
|
||||
let mut items: [@item] = [];
|
||||
let mut first = true;
|
||||
while p.token != term {
|
||||
let mut attrs = parse_outer_attributes(p);
|
||||
if first { attrs = first_item_attrs + attrs; first = false; }
|
||||
if first { attrs = attrs_remaining + attrs; first = false; }
|
||||
#debug["parse_mod_items: parse_item(attrs=%?)", attrs];
|
||||
let vis = parse_visibility(p, private);
|
||||
alt parse_item(p, attrs, vis) {
|
||||
|
@ -2054,7 +2055,7 @@ fn parse_mod_items(p: parser, term: token::token,
|
|||
#debug["parse_mod_items: attrs=%?", attrs];
|
||||
}
|
||||
|
||||
if first && first_item_attrs.len() > 0u {
|
||||
if first && attrs_remaining.len() > 0u {
|
||||
// We parsed attributes for the first item but didn't find the item
|
||||
p.fatal("expected item");
|
||||
}
|
||||
|
@ -2113,12 +2114,10 @@ fn parse_native_item(p: parser, +attrs: [attribute]) ->
|
|||
fn parse_native_mod_items(p: parser, +first_item_attrs: [attribute]) ->
|
||||
native_mod {
|
||||
// Shouldn't be any view items since we've already parsed an item attr
|
||||
let view_items =
|
||||
if vec::len(first_item_attrs) == 0u {
|
||||
parse_native_view(p)
|
||||
} else { [] };
|
||||
let {attrs_remaining, view_items} =
|
||||
parse_view(p, first_item_attrs, false);
|
||||
let mut items: [@native_item] = [];
|
||||
let mut initial_attrs = first_item_attrs;
|
||||
let mut initial_attrs = attrs_remaining;
|
||||
while p.token != token::RBRACE {
|
||||
let attrs = initial_attrs + parse_outer_attributes(p);
|
||||
initial_attrs = [];
|
||||
|
@ -2378,58 +2377,38 @@ fn parse_view_paths(p: parser) -> [@view_path] {
|
|||
ret vp;
|
||||
}
|
||||
|
||||
fn parse_view_item(p: parser) -> @view_item {
|
||||
let lo = p.span.lo;
|
||||
let the_item =
|
||||
if eat_keyword(p, "use") {
|
||||
parse_use(p)
|
||||
} else if eat_keyword(p, "import") {
|
||||
view_item_import(parse_view_paths(p))
|
||||
} else if eat_keyword(p, "export") {
|
||||
view_item_export(parse_view_paths(p))
|
||||
} else {
|
||||
fail
|
||||
};
|
||||
let mut hi = p.span.lo;
|
||||
expect(p, token::SEMI);
|
||||
ret @spanned(lo, hi, the_item);
|
||||
}
|
||||
|
||||
fn is_view_item(p: parser) -> bool {
|
||||
is_keyword(p, "use") || is_keyword(p, "import") || is_keyword(p, "export")
|
||||
let tok = if !is_keyword(p, "pub") && !is_keyword(p, "priv") { p.token }
|
||||
else { p.look_ahead(1u) };
|
||||
token_is_keyword(p, "use", tok) || token_is_keyword(p, "import", tok) ||
|
||||
token_is_keyword(p, "export", tok)
|
||||
}
|
||||
|
||||
fn maybe_parse_view(
|
||||
p: parser,
|
||||
first_item_attrs: [attribute]) -> [@view_item] {
|
||||
|
||||
maybe_parse_view_while(p, first_item_attrs, is_view_item)
|
||||
fn parse_view_item(p: parser, +attrs: [attribute]) -> @view_item {
|
||||
let lo = p.span.lo, vis = parse_visibility(p, private);
|
||||
let node = if eat_keyword(p, "use") {
|
||||
parse_use(p)
|
||||
} else if eat_keyword(p, "import") {
|
||||
view_item_import(parse_view_paths(p))
|
||||
} else if eat_keyword(p, "export") {
|
||||
view_item_export(parse_view_paths(p))
|
||||
} else { fail; };
|
||||
expect(p, token::SEMI);
|
||||
@{node: node, attrs: attrs,
|
||||
vis: vis, span: mk_sp(lo, p.last_span.hi)}
|
||||
}
|
||||
|
||||
fn maybe_parse_view_import_only(
|
||||
p: parser,
|
||||
first_item_attrs: [attribute]) -> [@view_item] {
|
||||
|
||||
maybe_parse_view_while(p, first_item_attrs, bind is_keyword(_, "import"))
|
||||
}
|
||||
|
||||
fn maybe_parse_view_while(
|
||||
p: parser,
|
||||
first_item_attrs: [attribute],
|
||||
f: fn@(parser) -> bool) -> [@view_item] {
|
||||
|
||||
if vec::len(first_item_attrs) == 0u {
|
||||
let mut items = [];
|
||||
while f(p) { items += [parse_view_item(p)]; }
|
||||
ret items;
|
||||
} else {
|
||||
// Shouldn't be any view items since we've already parsed an item attr
|
||||
ret [];
|
||||
fn parse_view(p: parser, +first_item_attrs: [attribute],
|
||||
only_imports: bool) -> {attrs_remaining: [attribute],
|
||||
view_items: [@view_item]} {
|
||||
let mut attrs = first_item_attrs + parse_outer_attributes(p);
|
||||
let mut items = [];
|
||||
while if only_imports { is_keyword(p, "import") }
|
||||
else { is_view_item(p) } {
|
||||
items += [parse_view_item(p, attrs)];
|
||||
attrs = parse_outer_attributes(p);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_native_view(p: parser) -> [@view_item] {
|
||||
maybe_parse_view_while(p, [], is_view_item)
|
||||
{attrs_remaining: attrs, view_items: items}
|
||||
}
|
||||
|
||||
// Parses a source module as a crate
|
||||
|
@ -2494,7 +2473,7 @@ fn parse_crate_directive(p: parser, first_outer_attr: [attribute]) ->
|
|||
_ { unexpected(p); }
|
||||
}
|
||||
} else if is_view_item(p) {
|
||||
let vi = parse_view_item(p);
|
||||
let vi = parse_view_item(p, outer_attrs);
|
||||
ret spanned(lo, vi.span.hi, cdir_view_item(vi));
|
||||
} else { ret p.fatal("expected crate directive"); }
|
||||
}
|
||||
|
|
|
@ -30,10 +30,16 @@ fn inject_libcore_ref(sess: session,
|
|||
let n1 = sess.next_node_id();
|
||||
let n2 = sess.next_node_id();
|
||||
|
||||
let vi1 = spanned(ast::view_item_use("core", [], n1));
|
||||
let vi1 = @{node: ast::view_item_use("core", [], n1),
|
||||
attrs: [],
|
||||
vis: ast::public,
|
||||
span: dummy_sp()};
|
||||
let vp = spanned(ast::view_path_glob(ident_to_path(dummy_sp(), "core"),
|
||||
n2));
|
||||
let vi2 = spanned(ast::view_item_import([vp]));
|
||||
let vi2 = @{node: ast::view_item_import([vp]),
|
||||
attrs: [],
|
||||
vis: ast::public,
|
||||
span: dummy_sp()};
|
||||
|
||||
let vis = [vi1, vi2] + crate.node.module.view_items;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// error-pattern:expecting '[' but found 'fmt'
|
||||
// error-pattern:expected item but found '#'
|
||||
|
||||
// Don't know how to deal with a syntax extension appearing after an
|
||||
// item attribute. Probably could use a better error message.
|
||||
|
|
Loading…
Add table
Reference in a new issue