about summary refs log tree commit diff
path: root/src/rustc/syntax
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-03-28 18:50:33 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-03-28 20:30:07 -0700
commitf7bbe537c11b83c529d755622bc7fdb831d751cd (patch)
tree6a822e808ac48046ab8932dbacf802036bb31150 /src/rustc/syntax
parentfe610f04d89ae30e7ad68b9b519aa8461cd8d0fb (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.rs17
-rw-r--r--src/rustc/syntax/ast_util.rs37
-rw-r--r--src/rustc/syntax/fold.rs39
-rw-r--r--src/rustc/syntax/parse/parser.rs57
-rw-r--r--src/rustc/syntax/print/pprust.rs9
-rw-r--r--src/rustc/syntax/visit.rs27
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, _, _,
-                                                    _, _, _)
+                                                    _)
                });
 }