From 8499c77cee3b745dfde576d1dbd03f292ab3c00f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 5 Jul 2011 12:38:53 -0700 Subject: [PATCH] Parse attributes for native items. Closes #609 --- src/comp/syntax/ast.rs | 1 + src/comp/syntax/fold.rs | 3 +++ src/comp/syntax/parse/parser.rs | 40 +++++++++++++++++++++------- src/comp/syntax/print/pprust.rs | 2 ++ src/test/run-pass/item-attributes.rs | 12 +++++++++ 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index 0b05d2122d58..7d1bb124c4e5 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -542,6 +542,7 @@ tag item_ { } type native_item = rec(ident ident, + vec[attribute] attrs, native_item_ node, node_id id, span span); diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index 5cf447a862c4..f36eeddeeb67 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -161,8 +161,11 @@ fn noop_fold_view_item(&view_item_ vi, ast_fold fld) -> view_item_ { fn noop_fold_native_item(&@native_item ni, ast_fold fld) -> @native_item { auto fold_arg = bind fold_arg_(_, fld); + auto fold_meta_item = bind fold_meta_item_(_,fld); + auto fold_attribute = bind fold_attribute_(_,fold_meta_item); ret @rec(ident=fld.fold_ident(ni.ident), + attrs=map(fold_attribute, ni.attrs), node=alt (ni.node) { case (native_item_ty) { native_item_ty } case (native_item_fn(?st, ?fdec, ?typms)) { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 48213c1f1acd..e852fdcb0af9 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1870,17 +1870,20 @@ fn parse_item_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item { ret mk_item(p, lo, hi, id, ast::item_mod(m), attrs + inner_attrs._0); } -fn parse_item_native_type(&parser p) -> @ast::native_item { +fn parse_item_native_type(&parser p, + &vec[ast::attribute] attrs) -> @ast::native_item { auto t = parse_type_decl(p); auto hi = p.get_hi_pos(); expect(p, token::SEMI); ret @rec(ident=t._1, + attrs=attrs, node=ast::native_item_ty, id=p.get_id(), span=rec(lo=t._0, hi=hi)); } -fn parse_item_native_fn(&parser p) -> @ast::native_item { +fn parse_item_native_fn(&parser p, + &vec[ast::attribute] attrs) -> @ast::native_item { auto lo = p.get_last_lo_pos(); auto t = parse_fn_header(p); auto decl = parse_fn_decl(p, ast::impure_fn); @@ -1892,25 +1895,38 @@ fn parse_item_native_fn(&parser p) -> @ast::native_item { auto hi = p.get_hi_pos(); expect(p, token::SEMI); ret @rec(ident=t._0, + attrs=attrs, node=ast::native_item_fn(link_name, decl, t._1), id=p.get_id(), span=rec(lo=lo, hi=hi)); } -fn parse_native_item(&parser p) -> @ast::native_item { +fn parse_native_item(&parser p, + &vec[ast::attribute] attrs) -> @ast::native_item { parse_layer(p); if (eat_word(p, "type")) { - ret parse_item_native_type(p); + ret parse_item_native_type(p, attrs); } else if (eat_word(p, "fn")) { - ret parse_item_native_fn(p); + ret parse_item_native_fn(p, attrs); } else { unexpected(p, p.peek()); fail; } } -fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi) -> +fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi, + &vec[ast::attribute] first_item_attrs) -> ast::native_mod { + auto view_items = if (vec::len(first_item_attrs) == 0u) { + parse_native_view(p) + } else { + // Shouldn't be any view items since we've already parsed an item attr + [] + }; let vec[@ast::native_item] items = []; - auto view_items = parse_native_view(p); - while (p.peek() != token::RBRACE) { items += [parse_native_item(p)]; } + auto initial_attrs = first_item_attrs; + while (p.peek() != token::RBRACE) { + auto attrs = initial_attrs + parse_outer_attributes(p); + initial_attrs = []; + items += [parse_native_item(p, attrs)]; + } ret rec(native_name=native_name, abi=abi, view_items=view_items, @@ -1941,10 +1957,14 @@ fn parse_item_native_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item { native_name = id; } expect(p, token::LBRACE); - auto m = parse_native_mod_items(p, native_name, abi); + auto more_attrs = parse_inner_attrs_and_next(p); + auto inner_attrs = more_attrs._0; + auto first_item_outer_attrs = more_attrs._1; + auto m = parse_native_mod_items(p, native_name, abi, + first_item_outer_attrs); auto hi = p.get_hi_pos(); expect(p, token::RBRACE); - ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs); + ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs + inner_attrs); } fn parse_type_decl(&parser p) -> tup(uint, ast::ident) { diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index b146d703471e..d4806cccbb33 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -383,8 +383,10 @@ fn print_item(&ps s, &@ast::item item) { word_nbsp(s, "mod"); word_nbsp(s, item.ident); bopen(s); + print_inner_attributes(s, item.attrs); for (@ast::native_item item in nmod.items) { hardbreak_if_not_bol(s); + print_outer_attributes(s, item.attrs); ibox(s, indent_unit); maybe_print_comment(s, item.span.lo); alt (item.node) { diff --git a/src/test/run-pass/item-attributes.rs b/src/test/run-pass/item-attributes.rs index cf8fc4098f2e..c66a41e8d0be 100644 --- a/src/test/run-pass/item-attributes.rs +++ b/src/test/run-pass/item-attributes.rs @@ -192,6 +192,18 @@ mod test_other_forms { } } +mod test_native_items { + native "rust" mod rustrt { + #[attr]; + + #[attr] + type vbuf; + + #[attr] + fn vec_len[T](vec[T] v) -> uint; + } +} + fn main() { }