diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-03-28 18:50:33 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-03-28 20:30:07 -0700 |
| commit | f7bbe537c11b83c529d755622bc7fdb831d751cd (patch) | |
| tree | 6a822e808ac48046ab8932dbacf802036bb31150 /src/rustc/syntax | |
| parent | fe610f04d89ae30e7ad68b9b519aa8461cd8d0fb (diff) | |
Allow explicit self-calls within classes
Allow writing self.f() within a class that has a method f. In a future commit, this syntax will be required. For now, you can write either self.f() or f(). I added a "privacy" field to all methods (whether class methods or not), which allowed me to refactor the AST somewhat (getting rid of the class_item type; now there's just class_member).
Diffstat (limited to 'src/rustc/syntax')
| -rw-r--r-- | src/rustc/syntax/ast.rs | 17 | ||||
| -rw-r--r-- | src/rustc/syntax/ast_util.rs | 37 | ||||
| -rw-r--r-- | src/rustc/syntax/fold.rs | 39 | ||||
| -rw-r--r-- | src/rustc/syntax/parse/parser.rs | 57 | ||||
| -rw-r--r-- | src/rustc/syntax/print/pprust.rs | 9 | ||||
| -rw-r--r-- | src/rustc/syntax/visit.rs | 27 |
6 files changed, 83 insertions, 103 deletions
diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs index 447d754895e..c88f44d7153 100644 --- a/src/rustc/syntax/ast.rs +++ b/src/rustc/syntax/ast.rs @@ -553,7 +553,9 @@ enum ret_style { #[auto_serialize] type method = {ident: ident, attrs: [attribute], tps: [ty_param], decl: fn_decl, body: blk, - id: node_id, span: span, self_id: node_id}; + id: node_id, span: span, self_id: node_id, + privacy: privacy}; // privacy is always public, unless it's a + // class method #[auto_serialize] type _mod = {view_items: [@view_item], items: [@item]}; @@ -649,8 +651,8 @@ enum item_ { item_res(fn_decl /* dtor */, [ty_param], blk, node_id /* dtor id */, node_id /* ctor id */), item_class([ty_param], /* ty params for class */ - [@class_item], /* methods, etc. */ - /* (not including ctor) */ + [@class_member], /* methods, etc. */ + /* (not including ctor) */ class_ctor ), item_iface([ty_param], [ty_method]), @@ -659,14 +661,11 @@ enum item_ { } #[auto_serialize] -type class_item_ = {privacy: privacy, decl: class_member}; +type class_member = spanned<class_member_>; #[auto_serialize] -type class_item = spanned<class_item_>; - -#[auto_serialize] -enum class_member { - instance_var(ident, @ty, class_mutability, node_id), +enum class_member_ { + instance_var(ident, @ty, class_mutability, node_id, privacy), class_method(@method) // without constrained types, have to duplicate some stuff. or factor out // item to separate out things with type params? diff --git a/src/rustc/syntax/ast_util.rs b/src/rustc/syntax/ast_util.rs index 4ab7c325a69..bf32bb0ebf3 100644 --- a/src/rustc/syntax/ast_util.rs +++ b/src/rustc/syntax/ast_util.rs @@ -262,9 +262,9 @@ pure fn unguarded_pat(a: arm) -> option<[@pat]> { // for reserving this id. fn op_expr_callee_id(e: @expr) -> node_id { e.id - 1 } -pure fn class_item_ident(ci: @class_item) -> ident { - alt ci.node.decl { - instance_var(i,_,_,_) { i } +pure fn class_item_ident(ci: @class_member) -> ident { + alt ci.node { + instance_var(i,_,_,_,_) { i } class_method(it) { it.ident } } } @@ -272,31 +272,32 @@ pure fn class_item_ident(ci: @class_item) -> ident { type ivar = {ident: ident, ty: @ty, cm: class_mutability, id: node_id, privacy: privacy}; -type cmethod = {privacy: privacy, meth: @method}; - -fn public_methods(cms: [cmethod]) -> [@method] { - vec::filter_map(cms, {|cm| alt cm.privacy { - pub { some(cm.meth) } - _ { none }}}) -} - -fn ignore_privacy(cms: [cmethod]) -> [@method] { - vec::map(cms, {|cm| cm.meth}) +fn public_methods(ms: [@method]) -> [@method] { + vec::filter(ms, {|m| alt m.privacy { + pub { true } + _ { false }}}) } -fn split_class_items(cs: [@class_item]) -> ([ivar], [cmethod]) { +fn split_class_items(cs: [@class_member]) -> ([ivar], [@method]) { let mut vs = [], ms = []; for c in cs { - alt c.node.decl { - instance_var(i, t, cm, id) { - vs += [{ident: i, ty: t, cm: cm, id: id, privacy: c.node.privacy}]; + alt c.node { + instance_var(i, t, cm, id, privacy) { + vs += [{ident: i, ty: t, cm: cm, id: id, privacy: privacy}]; } - class_method(m) { ms += [{privacy: c.node.privacy, meth: m}]; } + class_method(m) { ms += [m]; } } } (vs, ms) } +pure fn class_member_privacy(ci: @class_member) -> privacy { + alt ci.node { + instance_var(_, _, _, _, p) { p } + class_method(m) { m.privacy } + } +} + impl inlined_item_methods for inlined_item { fn ident() -> ident { alt self { diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs index 3f98ce5c29e..2cf567d74f1 100644 --- a/src/rustc/syntax/fold.rs +++ b/src/rustc/syntax/fold.rs @@ -27,7 +27,7 @@ type ast_fold_precursor = fold_view_item: fn@(view_item_, ast_fold) -> view_item_, fold_native_item: fn@(&&@native_item, ast_fold) -> @native_item, fold_item: fn@(&&@item, ast_fold) -> @item, - fold_class_item: fn@(&&@class_item, ast_fold) -> @class_item, + fold_class_item: fn@(&&@class_member, ast_fold) -> @class_member, fold_item_underscore: fn@(item_, ast_fold) -> item_, fold_method: fn@(&&@method, ast_fold) -> @method, fold_block: fn@(blk_, span, ast_fold) -> (blk_, span), @@ -54,7 +54,7 @@ type a_f = fold_view_item: fn@(&&@view_item) -> @view_item, fold_native_item: fn@(&&@native_item) -> @native_item, fold_item: fn@(&&@item) -> @item, - fold_class_item: fn@(&&@class_item) -> @class_item, + fold_class_item: fn@(&&@class_member) -> @class_member, fold_item_underscore: fn@(item_) -> item_, fold_method: fn@(&&@method) -> @method, fold_block: fn@(blk) -> blk, @@ -84,7 +84,7 @@ fn nf_crate_directive_dummy(&&_c: @crate_directive) -> @crate_directive { fn nf_view_item_dummy(&&_v: @view_item) -> @view_item { fail; } fn nf_native_item_dummy(&&_n: @native_item) -> @native_item { fail; } fn nf_item_dummy(&&_i: @item) -> @item { fail; } -fn nf_class_item_dummy(&&_ci: @class_item) -> @class_item { fail; } +fn nf_class_item_dummy(&&_ci: @class_member) -> @class_member { fail; } fn nf_item_underscore_dummy(_i: item_) -> item_ { fail; } fn nf_method_dummy(&&_m: @method) -> @method { fail; } fn nf_blk_dummy(_b: blk) -> blk { fail; } @@ -240,18 +240,15 @@ fn noop_fold_item(&&i: @item, fld: ast_fold) -> @item { span: fld.new_span(i.span)}; } -fn noop_fold_class_item(&&ci: @class_item, fld: ast_fold) - -> @class_item { - @{node: { - privacy:ci.node.privacy, - decl: - alt ci.node.decl { - instance_var(ident, t, cm, id) { - instance_var(ident, fld.fold_ty(t), cm, id) +fn noop_fold_class_item(&&ci: @class_member, fld: ast_fold) + -> @class_member { + @{node: alt ci.node { + instance_var(ident, t, cm, id, p) { + instance_var(ident, fld.fold_ty(t), cm, id, p) } class_method(m) { class_method(fld.fold_method(m)) } - }}, - span: fld.new_span(ci.span)} + }, + span: ci.span} } fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { @@ -302,7 +299,8 @@ fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { body: fld.fold_block(m.body), id: fld.new_id(m.id), span: fld.new_span(m.span), - self_id: fld.new_id(m.self_id)}; + self_id: fld.new_id(m.self_id), + privacy: m.privacy}; } @@ -655,19 +653,16 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold { ret afp.fold_item(i, f); } fn f_class_item(afp: ast_fold_precursor, f: ast_fold, - &&ci: @class_item) -> @class_item { - @{node: - {privacy:ci.node.privacy, - decl: - alt ci.node.decl { - instance_var(nm, t, mt, id) { + &&ci: @class_member) -> @class_member { + @{node: alt ci.node { + instance_var(nm, t, mt, id, p) { instance_var(nm, f_ty(afp, f, t), - mt, id) + mt, id, p) } class_method(m) { class_method(afp.fold_method(m, f)) } - }}, span: afp.new_span(ci.span)} + }, span: afp.new_span(ci.span)} } fn f_item_underscore(afp: ast_fold_precursor, f: ast_fold, i: item_) -> item_ { diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs index 61cc675c492..0ef54e09993 100644 --- a/src/rustc/syntax/parse/parser.rs +++ b/src/rustc/syntax/parse/parser.rs @@ -1681,7 +1681,7 @@ fn parse_let(p: parser) -> @ast::decl { } /* assumes "let" token has already been consumed */ -fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) { +fn parse_instance_var(p:parser, pr: ast::privacy) -> @ast::class_member { let mut is_mutbl = ast::class_immutable; let lo = p.span.lo; if eat_word(p, "mut") || eat_word(p, "mutable") { @@ -1693,8 +1693,8 @@ fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) { let name = parse_ident(p); expect(p, token::COLON); let ty = parse_ty(p, false); - ret (ast::instance_var(name, ty, is_mutbl, p.get_id()), - ast_util::mk_sp(lo, p.last_span.hi)); + ret @{node: ast::instance_var(name, ty, is_mutbl, p.get_id(), pr), + span: ast_util::mk_sp(lo, p.last_span.hi)}; } fn parse_stmt(p: parser, first_item_attrs: [ast::attribute]) -> @ast::stmt { @@ -1986,7 +1986,7 @@ fn parse_method_name(p: parser) -> ast::ident { } } -fn parse_method(p: parser) -> @ast::method { +fn parse_method(p: parser, pr: ast::privacy) -> @ast::method { let attrs = parse_outer_attributes(p); let lo = p.span.lo, pur = parse_fn_purity(p); let ident = parse_method_name(p); @@ -1996,7 +1996,7 @@ fn parse_method(p: parser) -> @ast::method { let attrs = attrs + inner_attrs; @{ident: ident, attrs: attrs, tps: tps, decl: decl, body: body, id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi), - self_id: p.get_id()} + self_id: p.get_id(), privacy: pr} } fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item { @@ -2034,7 +2034,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item { let ty = parse_ty(p, false); let mut meths = []; expect(p, token::LBRACE); - while !eat(p, token::RBRACE) { meths += [parse_method(p)]; } + while !eat(p, token::RBRACE) { meths += [parse_method(p, ast::pub)]; } ret mk_item(p, lo, p.last_span.hi, ident, ast::item_impl(tps, ifce, ty, meths), attrs); } @@ -2070,24 +2070,15 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { let class_path = ident_to_path(p.last_span, class_name); let ty_params = parse_ty_params(p); expect(p, token::LBRACE); - let mut items: [@ast::class_item] = []; + let mut ms: [@ast::class_member] = []; let ctor_id = p.get_id(); let mut the_ctor : option<(ast::fn_decl, ast::blk, codemap::span)> = none; while p.token != token::RBRACE { alt parse_class_item(p, class_path) { - ctor_decl(a_fn_decl, blk, s) { + ctor_decl(a_fn_decl, blk, s) { the_ctor = some((a_fn_decl, blk, s)); } - plain_decl(a_decl, s) { - items += [@{node: {privacy: ast::pub, decl: a_decl}, - span: s}]; - } - priv_decls(some_decls) { - items += vec::map(some_decls, {|p| - let (d, s) = p; - @{node: {privacy: ast::priv, decl: d}, - span: s}}); - } + members(mms) { ms += mms; } } } p.bump(); @@ -2095,7 +2086,7 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { some((ct_d, ct_b, ct_s)) { ret mk_item(p, lo, p.last_span.hi, class_name, - ast::item_class(ty_params, items, + ast::item_class(ty_params, ms, {node: {id: ctor_id, self_id: p.get_id(), dec: ct_d, @@ -2112,16 +2103,10 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { // lets us identify the constructor declaration at // parse time -// we don't really want just the fn_decl... enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span), - // assumed to be public - plain_decl(ast::class_member, codemap::span), - // contents of a priv section -- - // parse_class_item ensures that - // none of these are a ctor decl - priv_decls([(ast::class_member, codemap::span)])} - - fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents { + members([@ast::class_member]) } + +fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents { if eat_word(p, "new") { let lo = p.last_span.lo; // Can ctors have attrs? @@ -2140,28 +2125,28 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span), let mut results = []; while p.token != token::RBRACE { if eat_word(p, "let") { - let a_var = parse_instance_var(p); + let a_var = parse_instance_var(p, ast::priv); expect(p, token::SEMI); results += [a_var]; } else { - let m = parse_method(p); - results += [(ast::class_method(m), m.span)]; + let m = parse_method(p, ast::priv); + results += [@{node: ast::class_method(m), span: m.span}]; } } p.bump(); - ret priv_decls(results); + ret members(results); } else { // Probably need to parse attrs ret if eat_word(p, "let") { - let (a_var, a_span) = parse_instance_var(p); + let ivar = parse_instance_var(p, ast::pub); expect(p, token::SEMI); - plain_decl(a_var, a_span) + members([ivar]) } else { - let m = parse_method(p); - plain_decl(ast::class_method(m), m.span) + let m = parse_method(p, ast::pub); + members([@{node: ast::class_method(m), span: m.span}]) } } } diff --git a/src/rustc/syntax/print/pprust.rs b/src/rustc/syntax/print/pprust.rs index 5d259e9bf4a..a1c118c3144 100644 --- a/src/rustc/syntax/print/pprust.rs +++ b/src/rustc/syntax/print/pprust.rs @@ -506,7 +506,8 @@ fn print_item(s: ps, &&item: @ast::item) { */ hardbreak_if_not_bol(s); maybe_print_comment(s, ci.span.lo); - alt ci.node.privacy { + let pr = ast_util::class_member_privacy(ci); + alt pr { ast::priv { head(s, "priv"); bopen(s); @@ -514,8 +515,8 @@ fn print_item(s: ps, &&item: @ast::item) { } _ {} } - alt ci.node.decl { - ast::instance_var(nm, t, mt, _) { + alt ci.node { + ast::instance_var(nm, t, mt, _,_) { word_nbsp(s, "let"); alt mt { ast::class_mutable { word_nbsp(s, "mut"); } @@ -530,7 +531,7 @@ fn print_item(s: ps, &&item: @ast::item) { print_method(s, m); } } - alt ci.node.privacy { + alt pr { ast::priv { bclose(s, ci.span); } _ {} } diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs index 7a84052fa90..b4bcb3aaa31 100644 --- a/src/rustc/syntax/visit.rs +++ b/src/rustc/syntax/visit.rs @@ -55,7 +55,7 @@ type visitor<E> = visit_ty_params: fn@([ty_param], E, vt<E>), visit_constr: fn@(@path, span, node_id, E, vt<E>), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>), - visit_class_item: fn@(span, privacy, class_member, E, vt<E>)}; + visit_class_item: fn@(@class_member, E, vt<E>)}; fn default_visitor<E>() -> visitor<E> { ret @{visit_mod: bind visit_mod::<E>(_, _, _, _, _), @@ -73,7 +73,7 @@ fn default_visitor<E>() -> visitor<E> { visit_ty_params: bind visit_ty_params::<E>(_, _, _), visit_constr: bind visit_constr::<E>(_, _, _, _, _), visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _), - visit_class_item: bind visit_class_item::<E>(_,_,_,_,_)}; + visit_class_item: bind visit_class_item::<E>(_,_,_)}; } fn visit_crate<E>(c: crate, e: E, v: vt<E>) { @@ -139,7 +139,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { item_class(tps, members, ctor) { v.visit_ty_params(tps, e, v); for m in members { - v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v); + v.visit_class_item(m, e, v); } // make up a fake fn so as to call visit_fn on the ctor v.visit_fn(fk_ctor(i.ident, tps), ctor.node.dec, @@ -155,10 +155,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { } } -fn visit_class_item<E>(_s: span, _p: privacy, cm: class_member, - e:E, v:vt<E>) { - alt cm { - instance_var(ident, t, mt, id) { +fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) { + alt cm.node { + instance_var(_, t, _, _, _) { v.visit_ty(t, e, v); } class_method(m) { @@ -427,7 +426,7 @@ type simple_visitor = visit_ty_params: fn@([ty_param]), visit_constr: fn@(@path, span, node_id), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id), - visit_class_item: fn@(span, privacy, class_member)}; + visit_class_item: fn@(@class_member)}; fn simple_ignore_ty(_t: @ty) {} @@ -448,7 +447,7 @@ fn default_simple_visitor() -> simple_visitor { visit_constr: fn@(_p: @path, _sp: span, _id: node_id) { }, visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span, _id: node_id) { }, - visit_class_item: fn@(_s: span, _p: privacy, _c: class_member) {} + visit_class_item: fn@(_c: @class_member) {} }; } @@ -523,11 +522,11 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { } else { bind v_ty(v.visit_ty, _, _, _) }; - fn v_class_item(f: fn@(span, privacy, class_member), - s:span, p:privacy, cm: class_member, &&e: (), + fn v_class_item(f: fn@(@class_member), + cm: @class_member, &&e: (), v: vt<()>) { - f(s, p, cm); - visit_class_item(s, p, cm, e, v); + f(cm); + visit_class_item(cm, e, v); } ret mk_vt(@{visit_mod: bind v_mod(v.visit_mod, _, _, _, _, _), visit_view_item: bind v_view_item(v.visit_view_item, _, _, _), @@ -546,7 +545,7 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _), visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _), visit_class_item: bind v_class_item(v.visit_class_item, _, _, - _, _, _) + _) }); } |
