diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-15 15:53:58 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-15 16:20:35 -0700 |
| commit | 3038968f2895df915ca397864e96338edaa32e4b (patch) | |
| tree | f8bbc81702ce4683b0e9859efb4ca16346ab7c32 /src/libsyntax | |
| parent | 353c632c2dce8eb990410f20e4991006f1fcb3eb (diff) | |
rustc: Perform some AST surgery to separate out class fields from methods
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 30 | ||||
| -rw-r--r-- | src/libsyntax/ast_map.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 47 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 61 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 62 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 53 |
7 files changed, 158 insertions, 150 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a09bd073c44..cb46f6feabc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -718,9 +718,26 @@ type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id}; enum visibility { public, private, inherited } #[auto_serialize] +type struct_field_ = { + kind: struct_field_kind, + id: node_id, + ty: @ty +}; + +#[auto_serialize] +type struct_field = spanned<struct_field_>; + +#[auto_serialize] +enum struct_field_kind { + named_field(ident, class_mutability, visibility), + unnamed_field // element of a tuple-like struct +} + +#[auto_serialize] type struct_def = { - traits: ~[@trait_ref], /* traits this class implements */ - members: ~[@class_member], /* methods, etc. */ + traits: ~[@trait_ref], /* traits this struct implements */ + fields: ~[@struct_field], /* fields */ + methods: ~[@method], /* methods */ /* (not including ctor or dtor) */ /* ctor is optional, and will soon go away */ ctor: option<class_ctor>, @@ -751,15 +768,6 @@ enum item_ { } #[auto_serialize] -type class_member = spanned<class_member_>; - -#[auto_serialize] -enum class_member_ { - instance_var(ident, @ty, class_mutability, node_id, visibility), - class_method(@method) -} - -#[auto_serialize] enum class_mutability { class_mutable, class_immutable } #[auto_serialize] diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 5b2b4fb0561..c9b6b879427 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -248,7 +248,6 @@ fn map_item(i: @item, cx: ctx, v: vt) { fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, ident: ast::ident, id: ast::node_id, cx: ctx, _v: vt) { - let (_, ms) = ast_util::split_class_items(struct_def.members); // Map trait refs to their parent classes. This is // so we can find the self_ty for struct_def.traits.each |p| { @@ -260,7 +259,7 @@ fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, let d_id = ast_util::local_def(id); let p = extend(cx, ident); // only need to handle methods - do vec::iter(ms) |m| { map_method(d_id, p, m, cx); } + do vec::iter(struct_def.methods) |m| { map_method(d_id, p, m, cx); } } fn map_view_item(vi: @view_item, cx: ctx, _v: vt) { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 4a6f8b1e77a..0495ea7cd34 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -295,16 +295,6 @@ pure fn unguarded_pat(a: arm) -> option<~[@pat]> { if is_unguarded(a) { some(/* FIXME (#2543) */ copy a.pats) } else { none } } -pure fn class_item_ident(ci: @class_member) -> ident { - match ci.node { - instance_var(i,_,_,_,_) => /* FIXME (#2543) */ copy i, - class_method(it) => /* FIXME (#2543) */ copy it.ident - } -} - -type ivar = {ident: ident, ty: @ty, cm: class_mutability, - id: node_id, vis: visibility}; - fn public_methods(ms: ~[@method]) -> ~[@method] { vec::filter(ms, |m| match m.vis { @@ -313,23 +303,6 @@ fn public_methods(ms: ~[@method]) -> ~[@method] { }) } -fn split_class_items(cs: ~[@class_member]) -> (~[ivar], ~[@method]) { - let mut vs = ~[], ms = ~[]; - for cs.each |c| { - match c.node { - instance_var(i, t, cm, id, vis) => { - vec::push(vs, {ident: /* FIXME (#2543) */ copy i, - ty: t, - cm: cm, - id: id, - vis: vis}); - } - class_method(m) => vec::push(ms, m) - } - }; - (vs, ms) -} - // extract a ty_method from a trait_method. if the trait_method is // a default, pull out the useful fields to make a ty_method fn trait_method_to_ty_method(method: trait_method) -> ty_method { @@ -355,11 +328,11 @@ fn split_trait_methods(trait_methods: ~[trait_method]) (reqd, provd) } -pure fn class_member_visibility(ci: @class_member) -> visibility { - match ci.node { - instance_var(_, _, _, _, vis) => vis, - class_method(m) => m.vis - } +pure fn struct_field_visibility(field: ast::struct_field) -> visibility { + match field.node.kind { + ast::named_field(_, _, visibility) => visibility, + ast::unnamed_field => ast::public + } } trait inlined_item_utils { @@ -570,11 +543,11 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { _id: node_id) { }, - visit_class_item: fn@(c: @class_member) { - match c.node { - instance_var(_, _, _, id,_) => vfn(id), - class_method(_) => () - } + visit_struct_field: fn@(f: @struct_field) { + vfn(f.node.id); + }, + + visit_struct_method: fn@(_m: @method) { } }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5bd35490f0e..705f21895b6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -24,7 +24,7 @@ trait ast_fold { fn fold_view_item(&&@view_item) -> @view_item; fn fold_foreign_item(&&@foreign_item) -> @foreign_item; fn fold_item(&&@item) -> option<@item>; - fn fold_class_item(&&@class_member) -> @class_member; + fn fold_struct_field(&&@struct_field) -> @struct_field; fn fold_item_underscore(item_) -> item_; fn fold_method(&&@method) -> @method; fn fold_block(blk) -> blk; @@ -55,7 +55,7 @@ type ast_fold_precursor = @{ fold_view_item: fn@(view_item_, ast_fold) -> view_item_, fold_foreign_item: fn@(&&@foreign_item, ast_fold) -> @foreign_item, fold_item: fn@(&&@item, ast_fold) -> option<@item>, - fold_class_item: fn@(&&@class_member, ast_fold) -> @class_member, + fold_struct_field: fn@(&&@struct_field, ast_fold) -> @struct_field, fold_item_underscore: fn@(item_, ast_fold) -> item_, fold_method: fn@(&&@method, ast_fold) -> @method, fold_block: fn@(blk_, span, ast_fold) -> (blk_, span), @@ -214,16 +214,12 @@ fn noop_fold_item(&&i: @item, fld: ast_fold) -> option<@item> { span: fld.new_span(i.span)}); } -fn noop_fold_class_item(&&ci: @class_member, fld: ast_fold) - -> @class_member { - @{node: match ci.node { - instance_var(ident, t, cm, id, p) => { - instance_var(/* FIXME (#2543) */ copy ident, - fld.fold_ty(t), cm, id, p) - } - class_method(m) => class_method(fld.fold_method(m)) - }, - span: ci.span} +fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold) + -> @struct_field { + @{node: {kind: copy sf.node.kind, + id: sf.node.id, + ty: fld.fold_ty(sf.node.ty)}, + span: sf.span} } fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { @@ -295,7 +291,8 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) with dtor}}; return @{ traits: vec::map(struct_def.traits, |p| fold_trait_ref(p, fld)), - members: vec::map(struct_def.members, |x| fld.fold_class_item(x)), + fields: vec::map(struct_def.fields, |f| fold_struct_field(f, fld)), + methods: vec::map(struct_def.methods, |m| fld.fold_method(m)), ctor: resulting_optional_constructor, dtor: dtor }; @@ -306,6 +303,13 @@ fn fold_trait_ref(&&p: @trait_ref, fld: ast_fold) -> @trait_ref { impl_id: fld.new_id(p.impl_id)} } +fn fold_struct_field(&&f: @struct_field, fld: ast_fold) -> @struct_field { + @{node: {kind: copy f.node.kind, + id: fld.new_id(f.node.id), + ty: fld.fold_ty(f.node.ty)}, + span: fld.new_span(f.span)} +} + fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { return @{ident: fld.fold_ident(m.ident), attrs: /* FIXME (#2543) */ copy m.attrs, @@ -570,8 +574,9 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { with dtor}}; kind = struct_variant_kind(@{ traits: ~[], - members: vec::map(struct_def.members, - |x| fld.fold_class_item(x)), + fields: vec::map(struct_def.fields, + |f| fld.fold_struct_field(f)), + methods: vec::map(struct_def.methods, |m| fld.fold_method(m)), ctor: none, dtor: dtor }) @@ -644,7 +649,7 @@ fn default_ast_fold() -> ast_fold_precursor { fold_view_item: noop_fold_view_item, fold_foreign_item: noop_fold_foreign_item, fold_item: noop_fold_item, - fold_class_item: noop_fold_class_item, + fold_struct_field: noop_fold_struct_field, fold_item_underscore: noop_fold_item_underscore, fold_method: noop_fold_method, fold_block: wrap(noop_fold_block), @@ -692,16 +697,11 @@ impl ast_fold_precursor: ast_fold { fn fold_item(&&i: @item) -> option<@item> { return self.fold_item(i, self as ast_fold); } - fn fold_class_item(&&ci: @class_member) -> @class_member { - @{node: match ci.node { - instance_var(nm, t, mt, id, p) => { - instance_var(/* FIXME (#2543) */ copy nm, - (self as ast_fold).fold_ty(t), mt, id, p) - } - class_method(m) => { - class_method(self.fold_method(m, self as ast_fold)) - } - }, span: self.new_span(ci.span)} + fn fold_struct_field(&&sf: @struct_field) -> @struct_field { + @{node: {kind: copy sf.node.kind, + id: sf.node.id, + ty: (self as ast_fold).fold_ty(sf.node.ty)}, + span: self.new_span(sf.span)} } fn fold_item_underscore(i: item_) -> item_ { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4b8707d6858..09930bc2553 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -21,7 +21,7 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, bound_copy, bound_send, bound_trait, bound_owned, box, by_copy, by_move, by_mutbl_ref, by_ref, by_val, capture_clause, capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item, - class_immutable, class_member, class_method, class_mutable, + class_immutable, class_mutable, crate, crate_cfg, crate_directive, decl, decl_item, decl_local, default_blk, deref, div, enum_def, enum_variant_kind, expl, expr, expr_, expr_addr_of, expr_match, expr_again, expr_assert, @@ -33,20 +33,21 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item, foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited, - init_assign, init_move, initializer, instance_var, item, item_, + init_assign, init_move, initializer, item, item_, item_class, item_const, item_enum, item_fn, item_foreign_mod, item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_, lit_bool, lit_float, lit_int, lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq, mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq, match_tok, method, mode, mt, mul, - mutability, neg, noreturn, not, pat, pat_box, pat_enum, + mutability, named_field, neg, noreturn, not, pat, pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare, proto_block, proto_box, proto_uniq, provided, public, pure_fn, purity, re_anon, re_named, region, rem, required, ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr, - stmt_semi, struct_def, struct_variant_kind, subtract, sty_box, + stmt_semi, struct_def, struct_field, struct_variant_kind, + subtract, sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn, @@ -94,6 +95,11 @@ enum pexpr { pexpr(@expr), } +enum class_member { + field_member(@struct_field), + method_member(@method) +} + /* So that we can distinguish a class ctor or dtor from other class members @@ -2043,8 +2049,11 @@ class parser { let name = self.parse_ident(); self.expect(token::COLON); let ty = self.parse_ty(false); - return @{node: instance_var(name, ty, is_mutbl, self.get_id(), pr), - span: mk_sp(lo, self.last_span.hi)}; + return @field_member(@spanned(lo, self.last_span.hi, { + kind: named_field(name, is_mutbl, pr), + id: self.get_id(), + ty: ty + })); } fn parse_stmt(+first_item_attrs: ~[attribute]) -> @stmt { @@ -2556,7 +2565,8 @@ class parser { { self.parse_trait_ref_list(token::LBRACE) } else { ~[] }; self.expect(token::LBRACE); - let mut ms: ~[@class_member] = ~[]; + let mut fields: ~[@struct_field] = ~[]; + let mut methods: ~[@method] = ~[]; let ctor_id = self.get_id(); let mut the_ctor : option<(fn_decl, ~[attribute], blk, codemap::span)> = none; @@ -2589,7 +2599,16 @@ class parser { } } } - members(mms) => { ms = vec::append(ms, mms); } + members(mms) => { + for mms.each |mm| { + match mm { + @field_member(struct_field) => + vec::push(fields, struct_field), + @method_member(the_method_member) => + vec::push(methods, the_method_member) + } + } + } } } let actual_dtor = do option::map(the_dtor) |dtor| { @@ -2605,7 +2624,8 @@ class parser { (class_name, item_class(@{ traits: traits, - members: ms, + fields: move fields, + methods: move methods, ctor: some({ node: {id: ctor_id, attrs: ct_attrs, @@ -2621,7 +2641,8 @@ class parser { (class_name, item_class(@{ traits: traits, - members: ms, + fields: move fields, + methods: move methods, ctor: none, dtor: actual_dtor }, ty_params), @@ -2647,7 +2668,7 @@ class parser { return a_var; } else { let m = self.parse_method(vis); - return @{node: class_method(m), span: m.span}; + return @method_member(m); } } @@ -2883,7 +2904,8 @@ class parser { fn parse_struct_def(path: @path) -> @struct_def { let mut the_dtor: option<(blk, ~[attribute], codemap::span)> = none; - let mut ms: ~[@class_member] = ~[]; + let mut fields: ~[@struct_field] = ~[]; + let mut methods: ~[@method] = ~[]; while self.token != token::RBRACE { match self.parse_class_item(path) { ctor_decl(*) => { @@ -2906,8 +2928,16 @@ class parser { } } } - members(mms) => - ms = vec::append(ms, mms) + members(mms) => { + for mms.each |mm| { + match mm { + @field_member(struct_field) => + vec::push(fields, struct_field), + @method_member(the_method_member) => + vec::push(methods, the_method_member) + } + } + } } } self.bump(); @@ -2922,7 +2952,8 @@ class parser { return @{ traits: ~[], - members: ms, + fields: move fields, + methods: move methods, ctor: none, dtor: actual_dtor }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 49ded036e04..edcdd7d2baf 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -629,45 +629,29 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], head(s, ~"drop"); print_block(s, dtor.node.body); } - for struct_def.members.each |ci| { - /* - FIXME (#1893): collect all private items and print - them in a single "priv" section - - tjc: I'm not going to fix this yet b/c we might - change how exports work, including for class items - */ - hardbreak_if_not_bol(s); - maybe_print_comment(s, ci.span.lo); - let pr = ast_util::class_member_visibility(ci); - match pr { - ast::private => { - head(s, ~"priv"); - bopen(s); - hardbreak_if_not_bol(s); - } - _ => () - } - match ci.node { - ast::instance_var(nm, t, mt, _,_) => { - word_nbsp(s, ~"let"); - match mt { - ast::class_mutable => word_nbsp(s, ~"mut"), - _ => () - } - word(s.s, *nm); - word_nbsp(s, ~":"); - print_type(s, t); - word(s.s, ~";"); - } - ast::class_method(m) => { - print_method(s, m); - } - } - match pr { - ast::private => bclose(s, ci.span), - _ => () - } + for struct_def.fields.each |field| { + match field.node.kind { + ast::unnamed_field => {} // We don't print here. + ast::named_field(ident, mutability, visibility) => { + hardbreak_if_not_bol(s); + maybe_print_comment(s, field.span.lo); + if visibility == ast::private { + head(s, ~"priv"); + bopen(s); + hardbreak_if_not_bol(s); + } + if mutability == ast::class_mutable { + word_nbsp(s, ~"mut"); + } + word(s.s, *ident); + word_nbsp(s, ~":"); + print_type(s, field.node.ty); + word(s.s, ~";"); + } + } + } + for struct_def.methods.each |method| { + print_method(s, method); } bclose(s, span); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 93d253d2163..f9d861f15e1 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -63,7 +63,8 @@ type visitor<E> = visit_trait_method: fn@(trait_method, E, vt<E>), visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id, E, vt<E>), - visit_class_item: fn@(@class_member, E, vt<E>)}; + visit_struct_field: fn@(@struct_field, E, vt<E>), + visit_struct_method: fn@(@method, E, vt<E>)}; fn default_visitor<E>() -> visitor<E> { return @{visit_mod: |a,b,c,d,e|visit_mod::<E>(a, b, c, d, e), @@ -85,7 +86,8 @@ fn default_visitor<E>() -> visitor<E> { visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c), visit_struct_def: |a,b,c,d,e,f|visit_struct_def::<E>(a, b, c, d, e, f), - visit_class_item: |a,b,c|visit_class_item::<E>(a, b, c)}; + visit_struct_field: |a,b,c|visit_struct_field::<E>(a, b, c), + visit_struct_method: |a,b,c|visit_struct_method::<E>(a, b, c)}; } fn visit_crate<E>(c: crate, e: E, v: vt<E>) { @@ -183,13 +185,6 @@ fn visit_enum_def<E>(enum_definition: ast::enum_def, tps: ~[ast::ty_param], } } -fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) { - match cm.node { - instance_var(_, t, _, _, _) => v.visit_ty(t, e, v), - class_method(m) => visit_method_helper(m, e, v) - } -} - fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {} fn visit_ty<E>(t: @ty, e: E, v: vt<E>) { @@ -332,8 +327,11 @@ fn visit_trait_method<E>(m: trait_method, e: E, v: vt<E>) { fn visit_struct_def<E>(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], id: node_id, e: E, v: vt<E>) { - for sd.members.each |m| { - v.visit_class_item(m, e, v); + for sd.fields.each |f| { + v.visit_struct_field(f, e, v); + } + for sd.methods.each |m| { + v.visit_struct_method(m, e, v); } for sd.traits.each |p| { visit_path(p.path, e, v); } do option::iter(sd.ctor) |ctor| { @@ -344,6 +342,14 @@ fn visit_struct_def<E>(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], }; } +fn visit_struct_field<E>(sf: @struct_field, e: E, v: vt<E>) { + v.visit_ty(sf.node.ty, e, v); +} + +fn visit_struct_method<E>(m: @method, e: E, v: vt<E>) { + visit_method_helper(m, e, v); +} + fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) { for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); } for b.node.stmts.each |s| { v.visit_stmt(s, e, v); } @@ -492,7 +498,8 @@ type simple_visitor = visit_ty_method: fn@(ty_method), visit_trait_method: fn@(trait_method), visit_struct_def: fn@(@struct_def, ident, ~[ty_param], node_id), - visit_class_item: fn@(@class_member)}; + visit_struct_field: fn@(@struct_field), + visit_struct_method: fn@(@method)}; fn simple_ignore_ty(_t: @ty) {} @@ -517,7 +524,8 @@ fn default_simple_visitor() -> simple_visitor { visit_trait_method: fn@(_m: trait_method) { }, visit_struct_def: fn@(_sd: @struct_def, _nm: ident, _tps: ~[ty_param], _id: node_id) { }, - visit_class_item: fn@(_c: @class_member) {} + visit_struct_field: fn@(_f: @struct_field) { }, + visit_struct_method: fn@(_m: @method) { } }; } @@ -607,11 +615,14 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { } else { |a,b,c| v_ty(v.visit_ty, a, b, c) }; - fn v_class_item(f: fn@(@class_member), - cm: @class_member, &&e: (), - v: vt<()>) { - f(cm); - visit_class_item(cm, e, v); + fn v_struct_field(f: fn@(@struct_field), sf: @struct_field, &&e: (), + v: vt<()>) { + f(sf); + visit_struct_field(sf, e, v); + } + fn v_struct_method(f: fn@(@method), m: @method, &&e: (), v: vt<()>) { + f(m); + visit_struct_method(m, e, v); } return mk_vt(@{visit_mod: |a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e), visit_view_item: |a,b,c| @@ -639,8 +650,10 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_trait_method(v.visit_trait_method, a, b, c), visit_struct_def: |a,b,c,d,e,f| v_struct_def(v.visit_struct_def, a, b, c, d, e, f), - visit_class_item: |a,b,c| - v_class_item(v.visit_class_item, a, b, c) + visit_struct_field: |a,b,c| + v_struct_field(v.visit_struct_field, a, b, c), + visit_struct_method: |a,b,c| + v_struct_method(v.visit_struct_method, a, b, c) }); } |
