Skip to content

Commit df3bf7c

Browse files
committed
parser: Consolidate some duplicated code
1 parent 4885ffb commit df3bf7c

File tree

1 file changed

+79
-96
lines changed

1 file changed

+79
-96
lines changed

src/librustsyntax/parse/parser.rs

Lines changed: 79 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ fn parse_field(p: parser, sep: token::token) -> ast::field {
618618
ret spanned(lo, e.span.hi, {mutbl: m, ident: i, expr: e});
619619
}
620620

621-
fn mk_expr(p: parser, lo: uint, hi: uint, node: ast::expr_) -> @ast::expr {
621+
fn mk_expr(p: parser, lo: uint, hi: uint, +node: ast::expr_) -> @ast::expr {
622622
ret @{id: p.get_id(), node: node, span: mk_sp(lo, hi)};
623623
}
624624

@@ -1501,7 +1501,7 @@ fn parse_instance_var(p:parser, pr: ast::privacy) -> @ast::class_member {
15011501
span: mk_sp(lo, p.last_span.hi)};
15021502
}
15031503

1504-
fn parse_stmt(p: parser, first_item_attrs: [ast::attribute]) -> @ast::stmt {
1504+
fn parse_stmt(p: parser, +first_item_attrs: [ast::attribute]) -> @ast::stmt {
15051505
fn check_expected_item(p: parser, current_attrs: [ast::attribute]) {
15061506
// If we have attributes then we should have an item
15071507
if vec::is_not_empty(current_attrs) {
@@ -1603,7 +1603,7 @@ fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
16031603
}
16041604

16051605
fn parse_block_tail_(p: parser, lo: uint, s: ast::blk_check_mode,
1606-
first_item_attrs: [ast::attribute]) -> ast::blk {
1606+
+first_item_attrs: [ast::attribute]) -> ast::blk {
16071607
let mut stmts = [];
16081608
let mut expr = none;
16091609
let view_items = maybe_parse_view_import_only(p, first_item_attrs);
@@ -1788,24 +1788,22 @@ fn parse_fn_header(p: parser) -> {ident: ast::ident, tps: [ast::ty_param]} {
17881788
ret {ident: id, tps: ty_params};
17891789
}
17901790

1791-
fn mk_item(p: parser, lo: uint, hi: uint, ident: ast::ident, node: ast::item_,
1792-
attrs: [ast::attribute]) -> @ast::item {
1791+
fn mk_item(p: parser, lo: uint, hi: uint, +ident: ast::ident,
1792+
+node: ast::item_, +attrs: [ast::attribute]) -> @ast::item {
17931793
ret @{ident: ident,
17941794
attrs: attrs,
17951795
id: p.get_id(),
17961796
node: node,
17971797
span: mk_sp(lo, hi)};
17981798
}
17991799

1800-
fn parse_item_fn(p: parser, purity: ast::purity,
1801-
attrs: [ast::attribute]) -> @ast::item {
1802-
let lo = p.last_span.lo;
1800+
type item_info = (ast::ident, ast::item_, option<[ast::attribute]>);
1801+
1802+
fn parse_item_fn(p: parser, purity: ast::purity) -> item_info {
18031803
let t = parse_fn_header(p);
18041804
let (decl, _) = parse_fn_decl(p, purity, parse_arg);
18051805
let (inner_attrs, body) = parse_inner_attrs_and_block(p, true);
1806-
let attrs = attrs + inner_attrs;
1807-
ret mk_item(p, lo, body.span.hi, t.ident,
1808-
ast::item_fn(decl, t.tps, body), attrs);
1806+
(t.ident, ast::item_fn(decl, t.tps, body), some(inner_attrs))
18091807
}
18101808

18111809
fn parse_method_name(p: parser) -> ast::ident {
@@ -1834,21 +1832,19 @@ fn parse_method(p: parser, pr: ast::privacy) -> @ast::method {
18341832
self_id: p.get_id(), privacy: pr}
18351833
}
18361834

1837-
fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
1838-
let lo = p.last_span.lo, ident = parse_ident(p);
1835+
fn parse_item_iface(p: parser) -> item_info {
1836+
let ident = parse_ident(p);
18391837
let rp = parse_region_param(p);
18401838
let tps = parse_ty_params(p);
18411839
let meths = parse_ty_methods(p);
1842-
ret mk_item(p, lo, p.last_span.hi, ident,
1843-
ast::item_iface(tps, rp, meths), attrs);
1840+
(ident, ast::item_iface(tps, rp, meths), none)
18441841
}
18451842

18461843
// Parses three variants (with the region/type params always optional):
18471844
// impl /&<T: copy> of to_str for [T] { ... }
18481845
// impl name/&<T> of to_str for [T] { ... }
18491846
// impl name/&<T> for [T] { ... }
1850-
fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
1851-
let lo = p.last_span.lo;
1847+
fn parse_item_impl(p: parser) -> item_info {
18521848
fn wrap_path(p: parser, pt: @ast::path) -> @ast::ty {
18531849
@{id: p.get_id(), node: ast::ty_path(pt, p.get_id()), span: pt.span}
18541850
}
@@ -1882,12 +1878,10 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
18821878
let mut meths = [];
18831879
expect(p, token::LBRACE);
18841880
while !eat(p, token::RBRACE) { meths += [parse_method(p, ast::pub)]; }
1885-
ret mk_item(p, lo, p.last_span.hi, ident,
1886-
ast::item_impl(tps, rp, ifce, ty, meths), attrs);
1881+
(ident, ast::item_impl(tps, rp, ifce, ty, meths), none)
18871882
}
18881883

1889-
fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
1890-
let lo = p.last_span.lo;
1884+
fn parse_item_res(p: parser) -> item_info {
18911885
let ident = parse_value_ident(p);
18921886
let rp = parse_region_param(p);
18931887
let ty_params = parse_ty_params(p);
@@ -1897,20 +1891,17 @@ fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
18971891
let t = parse_ty(p, false);
18981892
expect(p, token::RPAREN);
18991893
let dtor = parse_block_no_value(p);
1900-
let decl =
1901-
{inputs:
1902-
[{mode: ast::expl(ast::by_ref), ty: t,
1903-
ident: arg_ident, id: p.get_id()}],
1904-
output: @{id: p.get_id(),
1905-
node: ast::ty_nil,
1906-
span: mk_sp(lo, lo)},
1907-
purity: ast::impure_fn,
1908-
cf: ast::return_val,
1909-
constraints: []};
1910-
ret mk_item(p, lo, dtor.span.hi, ident,
1911-
ast::item_res(decl, ty_params, dtor,
1912-
p.get_id(), p.get_id(), rp),
1913-
attrs);
1894+
let decl = {
1895+
inputs: [{mode: ast::expl(ast::by_ref), ty: t,
1896+
ident: arg_ident, id: p.get_id()}],
1897+
output: @{id: p.get_id(), node: ast::ty_nil,
1898+
span: ast_util::dummy_sp()},
1899+
purity: ast::impure_fn,
1900+
cf: ast::return_val,
1901+
constraints: []
1902+
};
1903+
(ident, ast::item_res(decl, ty_params, dtor,
1904+
p.get_id(), p.get_id(), rp), none)
19141905
}
19151906

19161907
// Instantiates ident <i> with references to <typarams> as arguments. Used to
@@ -1946,8 +1937,7 @@ fn parse_iface_ref_list(p:parser) -> [@ast::iface_ref] {
19461937
parse_iface_ref, p)
19471938
}
19481939

1949-
fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
1950-
let lo = p.last_span.lo;
1940+
fn parse_item_class(p: parser) -> item_info {
19511941
let class_name = parse_value_ident(p);
19521942
let rp = parse_region_param(p);
19531943
let ty_params = parse_ty_params(p);
@@ -1970,13 +1960,15 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
19701960
p.bump();
19711961
alt the_ctor {
19721962
some((ct_d, ct_b, ct_s)) {
1973-
ret mk_item(p, lo, p.last_span.hi, class_name,
1974-
ast::item_class(ty_params, ifaces, ms,
1975-
{node: {id: ctor_id,
1976-
self_id: p.get_id(),
1977-
dec: ct_d,
1978-
body: ct_b},
1979-
span: ct_s}, rp), attrs); }
1963+
(class_name,
1964+
ast::item_class(ty_params, ifaces, ms, {
1965+
node: {id: ctor_id,
1966+
self_id: p.get_id(),
1967+
dec: ct_d,
1968+
body: ct_b},
1969+
span: ct_s}, rp),
1970+
none)
1971+
}
19801972
/*
19811973
Is it strange for the parser to check this?
19821974
*/
@@ -2034,13 +2026,14 @@ fn parse_class_item(p:parser, class_name_with_tps: @ast::path)
20342026
}
20352027

20362028
fn parse_mod_items(p: parser, term: token::token,
2037-
first_item_attrs: [ast::attribute]) -> ast::_mod {
2029+
+first_item_attrs: [ast::attribute]) -> ast::_mod {
20382030
// Shouldn't be any view items since we've already parsed an item attr
20392031
let view_items = maybe_parse_view(p, first_item_attrs);
20402032
let mut items: [@ast::item] = [];
2041-
let mut initial_attrs = first_item_attrs;
2033+
let mut first = true;
20422034
while p.token != term {
2043-
let attrs = initial_attrs + parse_outer_attributes(p);
2035+
let mut attrs = parse_outer_attributes(p);
2036+
if first { attrs = first_item_attrs + attrs; first = false; }
20442037
#debug["parse_mod_items: parse_item(attrs=%?)", attrs];
20452038
alt parse_item(p, attrs) {
20462039
some(i) { items += [i]; }
@@ -2050,42 +2043,36 @@ fn parse_mod_items(p: parser, term: token::token,
20502043
}
20512044
}
20522045
#debug["parse_mod_items: attrs=%?", attrs];
2053-
initial_attrs = [];
20542046
}
20552047

2056-
if vec::is_not_empty(initial_attrs) {
2048+
if first && first_item_attrs.len() > 0u {
20572049
// We parsed attributes for the first item but didn't find the item
20582050
p.fatal("expected item");
20592051
}
20602052

20612053
ret {view_items: view_items, items: items};
20622054
}
20632055

2064-
fn parse_item_const(p: parser, attrs: [ast::attribute]) -> @ast::item {
2065-
let lo = p.last_span.lo;
2056+
fn parse_item_const(p: parser) -> item_info {
20662057
let id = parse_value_ident(p);
20672058
expect(p, token::COLON);
20682059
let ty = parse_ty(p, false);
20692060
expect(p, token::EQ);
20702061
let e = parse_expr(p);
2071-
let mut hi = p.span.hi;
20722062
expect(p, token::SEMI);
2073-
ret mk_item(p, lo, hi, id, ast::item_const(ty, e), attrs);
2063+
(id, ast::item_const(ty, e), none)
20742064
}
20752065

2076-
fn parse_item_mod(p: parser, attrs: [ast::attribute]) -> @ast::item {
2077-
let lo = p.last_span.lo;
2066+
fn parse_item_mod(p: parser) -> item_info {
20782067
let id = parse_ident(p);
20792068
expect(p, token::LBRACE);
20802069
let inner_attrs = parse_inner_attrs_and_next(p);
2081-
let first_item_outer_attrs = inner_attrs.next;
2082-
let m = parse_mod_items(p, token::RBRACE, first_item_outer_attrs);
2083-
let mut hi = p.span.hi;
2070+
let m = parse_mod_items(p, token::RBRACE, inner_attrs.next);
20842071
expect(p, token::RBRACE);
2085-
ret mk_item(p, lo, hi, id, ast::item_mod(m), attrs + inner_attrs.inner);
2072+
(id, ast::item_mod(m), some(inner_attrs.inner))
20862073
}
20872074

2088-
fn parse_item_native_fn(p: parser, attrs: [ast::attribute],
2075+
fn parse_item_native_fn(p: parser, +attrs: [ast::attribute],
20892076
purity: ast::purity) -> @ast::native_item {
20902077
let lo = p.last_span.lo;
20912078
let t = parse_fn_header(p);
@@ -2109,12 +2096,12 @@ fn parse_fn_purity(p: parser) -> ast::purity {
21092096
else { unexpected(p); }
21102097
}
21112098

2112-
fn parse_native_item(p: parser, attrs: [ast::attribute]) ->
2099+
fn parse_native_item(p: parser, +attrs: [ast::attribute]) ->
21132100
@ast::native_item {
21142101
parse_item_native_fn(p, attrs, parse_fn_purity(p))
21152102
}
21162103

2117-
fn parse_native_mod_items(p: parser, first_item_attrs: [ast::attribute]) ->
2104+
fn parse_native_mod_items(p: parser, +first_item_attrs: [ast::attribute]) ->
21182105
ast::native_mod {
21192106
// Shouldn't be any view items since we've already parsed an item attr
21202107
let view_items =
@@ -2132,18 +2119,14 @@ fn parse_native_mod_items(p: parser, first_item_attrs: [ast::attribute]) ->
21322119
items: items};
21332120
}
21342121

2135-
fn parse_item_native_mod(p: parser, attrs: [ast::attribute]) -> @ast::item {
2136-
let lo = p.last_span.lo;
2122+
fn parse_item_native_mod(p: parser) -> item_info {
21372123
expect_keyword(p, "mod");
21382124
let id = parse_ident(p);
21392125
expect(p, token::LBRACE);
21402126
let more_attrs = parse_inner_attrs_and_next(p);
2141-
let inner_attrs = more_attrs.inner;
2142-
let first_item_outer_attrs = more_attrs.next;
2143-
let m = parse_native_mod_items(p, first_item_outer_attrs);
2144-
let mut hi = p.span.hi;
2127+
let m = parse_native_mod_items(p, more_attrs.next);
21452128
expect(p, token::RBRACE);
2146-
ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs + inner_attrs);
2129+
(id, ast::item_native_mod(m), some(more_attrs.inner))
21472130
}
21482131

21492132
fn parse_type_decl(p: parser) -> {lo: uint, ident: ast::ident} {
@@ -2152,15 +2135,14 @@ fn parse_type_decl(p: parser) -> {lo: uint, ident: ast::ident} {
21522135
ret {lo: lo, ident: id};
21532136
}
21542137

2155-
fn parse_item_type(p: parser, attrs: [ast::attribute]) -> @ast::item {
2138+
fn parse_item_type(p: parser) -> item_info {
21562139
let t = parse_type_decl(p);
21572140
let rp = parse_region_param(p);
21582141
let tps = parse_ty_params(p);
21592142
expect(p, token::EQ);
21602143
let ty = parse_ty(p, false);
2161-
let mut hi = p.span.hi;
21622144
expect(p, token::SEMI);
2163-
ret mk_item(p, t.lo, hi, t.ident, ast::item_ty(ty, tps, rp), attrs);
2145+
(t.ident, ast::item_ty(ty, tps, rp), none)
21642146
}
21652147

21662148
fn parse_region_param(p: parser) -> ast::region_param {
@@ -2172,8 +2154,7 @@ fn parse_region_param(p: parser) -> ast::region_param {
21722154
}
21732155
}
21742156

2175-
fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
2176-
let lo = p.last_span.lo;
2157+
fn parse_item_enum(p: parser) -> item_info {
21772158
let id = parse_ident(p);
21782159
let rp = parse_region_param(p);
21792160
let ty_params = parse_ty_params(p);
@@ -2191,8 +2172,7 @@ fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
21912172
args: [{ty: ty, id: p.get_id()}],
21922173
id: p.get_id(),
21932174
disr_expr: none});
2194-
ret mk_item(p, lo, ty.span.hi, id,
2195-
ast::item_enum([variant], ty_params, rp), attrs);
2175+
ret (id, ast::item_enum([variant], ty_params, rp), none);
21962176
}
21972177
expect(p, token::LBRACE);
21982178

@@ -2227,8 +2207,7 @@ fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
22272207
if (have_disr && !all_nullary) {
22282208
p.fatal("discriminator values can only be used with a c-like enum");
22292209
}
2230-
ret mk_item(p, lo, p.last_span.hi, id,
2231-
ast::item_enum(variants, ty_params, rp), attrs);
2210+
(id, ast::item_enum(variants, ty_params, rp), none)
22322211
}
22332212

22342213
fn parse_fn_ty_proto(p: parser) -> ast::proto {
@@ -2262,40 +2241,44 @@ fn fn_expr_lookahead(tok: token::token) -> bool {
22622241
}
22632242
}
22642243

2265-
fn parse_item(p: parser, attrs: [ast::attribute]) -> option<@ast::item> {
2266-
if eat_keyword(p, "const") {
2267-
ret some(parse_item_const(p, attrs));
2244+
fn parse_item(p: parser, +attrs: [ast::attribute]) -> option<@ast::item> {
2245+
let lo = p.span.lo;
2246+
let (ident, item_, extra_attrs) = if eat_keyword(p, "const") {
2247+
parse_item_const(p)
22682248
} else if is_keyword(p, "fn") && !fn_expr_lookahead(p.look_ahead(1u)) {
22692249
p.bump();
2270-
ret some(parse_item_fn(p, ast::impure_fn, attrs));
2250+
parse_item_fn(p, ast::impure_fn)
22712251
} else if eat_keyword(p, "pure") {
22722252
expect_keyword(p, "fn");
2273-
ret some(parse_item_fn(p, ast::pure_fn, attrs));
2253+
parse_item_fn(p, ast::pure_fn)
22742254
} else if is_keyword(p, "unsafe") && p.look_ahead(1u) != token::LBRACE {
22752255
p.bump();
22762256
expect_keyword(p, "fn");
2277-
ret some(parse_item_fn(p, ast::unsafe_fn, attrs));
2257+
parse_item_fn(p, ast::unsafe_fn)
22782258
} else if eat_keyword(p, "crust") {
22792259
expect_keyword(p, "fn");
2280-
ret some(parse_item_fn(p, ast::crust_fn, attrs));
2260+
parse_item_fn(p, ast::crust_fn)
22812261
} else if eat_keyword(p, "mod") {
2282-
ret some(parse_item_mod(p, attrs));
2262+
parse_item_mod(p)
22832263
} else if eat_keyword(p, "native") {
2284-
ret some(parse_item_native_mod(p, attrs));
2285-
} if eat_keyword(p, "type") {
2286-
ret some(parse_item_type(p, attrs));
2264+
parse_item_native_mod(p)
2265+
} else if eat_keyword(p, "type") {
2266+
parse_item_type(p)
22872267
} else if eat_keyword(p, "enum") {
2288-
ret some(parse_item_enum(p, attrs));
2268+
parse_item_enum(p)
22892269
} else if eat_keyword(p, "iface") {
2290-
ret some(parse_item_iface(p, attrs));
2270+
parse_item_iface(p)
22912271
} else if eat_keyword(p, "impl") {
2292-
ret some(parse_item_impl(p, attrs));
2272+
parse_item_impl(p)
22932273
} else if eat_keyword(p, "resource") {
2294-
ret some(parse_item_res(p, attrs));
2274+
parse_item_res(p)
22952275
} else if eat_keyword(p, "class") {
2296-
ret some(parse_item_class(p, attrs));
2297-
}
2298-
else { ret none; }
2276+
parse_item_class(p)
2277+
} else { ret none; };
2278+
some(mk_item(p, lo, p.last_span.hi, ident, item_, alt extra_attrs {
2279+
some(as) { attrs + as }
2280+
none { attrs }
2281+
}))
22992282
}
23002283

23012284
fn parse_use(p: parser) -> ast::view_item_ {

0 commit comments

Comments
 (0)