Skip to content

Commit 96a159a

Browse files
committed
Support visibility modifiers and attributes on view items
Issue #1893 Tangentially, issue #2357
1 parent 5c0577f commit 96a159a

File tree

9 files changed

+61
-69
lines changed

9 files changed

+61
-69
lines changed

src/librustsyntax/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,8 @@ enum view_path_ {
612612
}
613613

614614
#[auto_serialize]
615-
type view_item = spanned<view_item_>;
615+
type view_item = {node: view_item_, attrs: [attribute],
616+
vis: visibility, span: span};
616617

617618
#[auto_serialize]
618619
enum view_item_ {

src/librustsyntax/fold.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,8 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
679679
fn f_view_item(afp: ast_fold_precursor, f: ast_fold, &&x: @view_item) ->
680680
@view_item {
681681
ret @{node: afp.fold_view_item(x.node, f),
682+
attrs: vec::map(x.attrs, {|a| fold_attribute_(a, f)}),
683+
vis: x.vis,
682684
span: afp.new_span(x.span)};
683685
}
684686
fn f_native_item(afp: ast_fold_precursor, f: ast_fold, &&x: @native_item)

src/librustsyntax/parse/attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn parse_outer_attrs_or_ext(
3939
// Parse attributes that appear before an item
4040
fn parse_outer_attributes(p: parser) -> [ast::attribute] {
4141
let mut attrs: [ast::attribute] = [];
42-
while p.token == token::POUND {
42+
while p.token == token::POUND && p.look_ahead(1u) == token::LBRACKET {
4343
attrs += [parse_attribute(p, ast::attr_outer)];
4444
}
4545
ret attrs;

src/librustsyntax/parse/common.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,16 @@ fn require_keyword(p: parser, word: str) {
5858
}
5959
}
6060

61-
fn is_keyword(p: parser, word: str) -> bool {
61+
fn token_is_keyword(p: parser, word: str, tok: token::token) -> bool {
6262
require_keyword(p, word);
63-
ret alt p.token {
64-
token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
65-
_ { false }
66-
};
63+
alt tok {
64+
token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
65+
_ { false }
66+
}
67+
}
68+
69+
fn is_keyword(p: parser, word: str) -> bool {
70+
token_is_keyword(p, word, p.token)
6771
}
6872

6973
fn eat_keyword(p: parser, word: str) -> bool {

src/librustsyntax/parse/parser.rs

Lines changed: 38 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,8 +1606,8 @@ fn parse_block_tail_(p: parser, lo: uint, s: blk_check_mode,
16061606
+first_item_attrs: [attribute]) -> blk {
16071607
let mut stmts = [];
16081608
let mut expr = none;
1609-
let view_items = maybe_parse_view_import_only(p, first_item_attrs);
1610-
let mut initial_attrs = first_item_attrs;
1609+
let {attrs_remaining, view_items} = parse_view(p, first_item_attrs, true);
1610+
let mut initial_attrs = attrs_remaining;
16111611

16121612
if p.token == token::RBRACE && !vec::is_empty(initial_attrs) {
16131613
p.fatal("expected item");
@@ -2036,12 +2036,13 @@ fn parse_visibility(p: parser, def: visibility) -> visibility {
20362036
fn parse_mod_items(p: parser, term: token::token,
20372037
+first_item_attrs: [attribute]) -> _mod {
20382038
// Shouldn't be any view items since we've already parsed an item attr
2039-
let view_items = maybe_parse_view(p, first_item_attrs);
2039+
let {attrs_remaining, view_items} =
2040+
parse_view(p, first_item_attrs, false);
20402041
let mut items: [@item] = [];
20412042
let mut first = true;
20422043
while p.token != term {
20432044
let mut attrs = parse_outer_attributes(p);
2044-
if first { attrs = first_item_attrs + attrs; first = false; }
2045+
if first { attrs = attrs_remaining + attrs; first = false; }
20452046
#debug["parse_mod_items: parse_item(attrs=%?)", attrs];
20462047
let vis = parse_visibility(p, private);
20472048
alt parse_item(p, attrs, vis) {
@@ -2054,7 +2055,7 @@ fn parse_mod_items(p: parser, term: token::token,
20542055
#debug["parse_mod_items: attrs=%?", attrs];
20552056
}
20562057

2057-
if first && first_item_attrs.len() > 0u {
2058+
if first && attrs_remaining.len() > 0u {
20582059
// We parsed attributes for the first item but didn't find the item
20592060
p.fatal("expected item");
20602061
}
@@ -2113,12 +2114,10 @@ fn parse_native_item(p: parser, +attrs: [attribute]) ->
21132114
fn parse_native_mod_items(p: parser, +first_item_attrs: [attribute]) ->
21142115
native_mod {
21152116
// Shouldn't be any view items since we've already parsed an item attr
2116-
let view_items =
2117-
if vec::len(first_item_attrs) == 0u {
2118-
parse_native_view(p)
2119-
} else { [] };
2117+
let {attrs_remaining, view_items} =
2118+
parse_view(p, first_item_attrs, false);
21202119
let mut items: [@native_item] = [];
2121-
let mut initial_attrs = first_item_attrs;
2120+
let mut initial_attrs = attrs_remaining;
21222121
while p.token != token::RBRACE {
21232122
let attrs = initial_attrs + parse_outer_attributes(p);
21242123
initial_attrs = [];
@@ -2378,58 +2377,38 @@ fn parse_view_paths(p: parser) -> [@view_path] {
23782377
ret vp;
23792378
}
23802379

2381-
fn parse_view_item(p: parser) -> @view_item {
2382-
let lo = p.span.lo;
2383-
let the_item =
2384-
if eat_keyword(p, "use") {
2385-
parse_use(p)
2386-
} else if eat_keyword(p, "import") {
2387-
view_item_import(parse_view_paths(p))
2388-
} else if eat_keyword(p, "export") {
2389-
view_item_export(parse_view_paths(p))
2390-
} else {
2391-
fail
2392-
};
2393-
let mut hi = p.span.lo;
2394-
expect(p, token::SEMI);
2395-
ret @spanned(lo, hi, the_item);
2396-
}
2397-
23982380
fn is_view_item(p: parser) -> bool {
2399-
is_keyword(p, "use") || is_keyword(p, "import") || is_keyword(p, "export")
2400-
}
2401-
2402-
fn maybe_parse_view(
2403-
p: parser,
2404-
first_item_attrs: [attribute]) -> [@view_item] {
2405-
2406-
maybe_parse_view_while(p, first_item_attrs, is_view_item)
2407-
}
2408-
2409-
fn maybe_parse_view_import_only(
2410-
p: parser,
2411-
first_item_attrs: [attribute]) -> [@view_item] {
2412-
2413-
maybe_parse_view_while(p, first_item_attrs, bind is_keyword(_, "import"))
2381+
let tok = if !is_keyword(p, "pub") && !is_keyword(p, "priv") { p.token }
2382+
else { p.look_ahead(1u) };
2383+
token_is_keyword(p, "use", tok) || token_is_keyword(p, "import", tok) ||
2384+
token_is_keyword(p, "export", tok)
2385+
}
2386+
2387+
fn parse_view_item(p: parser, +attrs: [attribute]) -> @view_item {
2388+
let lo = p.span.lo, vis = parse_visibility(p, private);
2389+
let node = if eat_keyword(p, "use") {
2390+
parse_use(p)
2391+
} else if eat_keyword(p, "import") {
2392+
view_item_import(parse_view_paths(p))
2393+
} else if eat_keyword(p, "export") {
2394+
view_item_export(parse_view_paths(p))
2395+
} else { fail; };
2396+
expect(p, token::SEMI);
2397+
@{node: node, attrs: attrs,
2398+
vis: vis, span: mk_sp(lo, p.last_span.hi)}
24142399
}
24152400

2416-
fn maybe_parse_view_while(
2417-
p: parser,
2418-
first_item_attrs: [attribute],
2419-
f: fn@(parser) -> bool) -> [@view_item] {
2420-
2421-
if vec::len(first_item_attrs) == 0u {
2422-
let mut items = [];
2423-
while f(p) { items += [parse_view_item(p)]; }
2424-
ret items;
2425-
} else {
2426-
// Shouldn't be any view items since we've already parsed an item attr
2427-
ret [];
2401+
fn parse_view(p: parser, +first_item_attrs: [attribute],
2402+
only_imports: bool) -> {attrs_remaining: [attribute],
2403+
view_items: [@view_item]} {
2404+
let mut attrs = first_item_attrs + parse_outer_attributes(p);
2405+
let mut items = [];
2406+
while if only_imports { is_keyword(p, "import") }
2407+
else { is_view_item(p) } {
2408+
items += [parse_view_item(p, attrs)];
2409+
attrs = parse_outer_attributes(p);
24282410
}
2429-
}
2430-
2431-
fn parse_native_view(p: parser) -> [@view_item] {
2432-
maybe_parse_view_while(p, [], is_view_item)
2411+
{attrs_remaining: attrs, view_items: items}
24332412
}
24342413

24352414
// Parses a source module as a crate
@@ -2494,7 +2473,7 @@ fn parse_crate_directive(p: parser, first_outer_attr: [attribute]) ->
24942473
_ { unexpected(p); }
24952474
}
24962475
} else if is_view_item(p) {
2497-
let vi = parse_view_item(p);
2476+
let vi = parse_view_item(p, outer_attrs);
24982477
ret spanned(lo, vi.span.hi, cdir_view_item(vi));
24992478
} else { ret p.fatal("expected crate directive"); }
25002479
}

src/rustc/front/core_inject.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,16 @@ fn inject_libcore_ref(sess: session,
3030
let n1 = sess.next_node_id();
3131
let n2 = sess.next_node_id();
3232

33-
let vi1 = spanned(ast::view_item_use("core", [], n1));
33+
let vi1 = @{node: ast::view_item_use("core", [], n1),
34+
attrs: [],
35+
vis: ast::public,
36+
span: dummy_sp()};
3437
let vp = spanned(ast::view_path_glob(ident_to_path(dummy_sp(), "core"),
3538
n2));
36-
let vi2 = spanned(ast::view_item_import([vp]));
39+
let vi2 = @{node: ast::view_item_import([vp]),
40+
attrs: [],
41+
vis: ast::public,
42+
span: dummy_sp()};
3743

3844
let vis = [vi1, vi2] + crate.node.module.view_items;
3945

src/test/compile-fail/ext-after-attrib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// error-pattern:expecting '[' but found 'fmt'
1+
// error-pattern:expected item but found '#'
22

33
// Don't know how to deal with a syntax extension appearing after an
44
// item attribute. Probably could use a better error message.

0 commit comments

Comments
 (0)