about summary refs log tree commit diff
path: root/src/librustsyntax
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-04-11 16:18:00 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-04-11 16:20:01 -0700
commit5c12cd72f4774af8ca1c3c9c0115b4b1a72404bb (patch)
tree6e6982510b2cb091ed01f3072841fadd18691460 /src/librustsyntax
parent9fda1578a219a8762fadddfd37c45abdd6a271a1 (diff)
Allow classes to implement ifaces
Introduce syntax like:

iface animal { ... }
class cat implements animal { ... }

to allow classes to implement ifaces. Casting classes to ifaces
is *not* yet supported. ifaces that a class implements are not
yet included in metadata.

The syntax is subject to change, and may go away completely if we
decide to use duck typing to relate classes with ifaces (see
http://smallcultfollowing.com/babysteps/blog/2012/04/10/declared-vs-duckish-typing/ )
Diffstat (limited to 'src/librustsyntax')
-rw-r--r--src/librustsyntax/ast.rs4
-rw-r--r--src/librustsyntax/fold.rs6
-rw-r--r--src/librustsyntax/parse/parser.rs13
-rw-r--r--src/librustsyntax/print/pprust.rs5
-rw-r--r--src/librustsyntax/visit.rs3
5 files changed, 24 insertions, 7 deletions
diff --git a/src/librustsyntax/ast.rs b/src/librustsyntax/ast.rs
index 885e0943b9b..fa190a120e9 100644
--- a/src/librustsyntax/ast.rs
+++ b/src/librustsyntax/ast.rs
@@ -642,6 +642,9 @@ enum attr_style { attr_outer, attr_inner, }
 type attribute_ = {style: attr_style, value: meta_item};
 
 #[auto_serialize]
+type iface_ref = {path: @path, id: node_id};
+
+#[auto_serialize]
 type item = {ident: ident, attrs: [attribute],
              id: node_id, node: item_, span: span};
 
@@ -656,6 +659,7 @@ enum item_ {
     item_res(fn_decl /* dtor */, [ty_param], blk /* dtor body */,
              node_id /* dtor id */, node_id /* ctor id */),
     item_class([ty_param], /* ty params for class */
+               [iface_ref],   /* ifaces this class implements */
                [@class_member], /* methods, etc. */
                                /* (not including ctor) */
                class_ctor
diff --git a/src/librustsyntax/fold.rs b/src/librustsyntax/fold.rs
index afde21d2965..f40c351b4ef 100644
--- a/src/librustsyntax/fold.rs
+++ b/src/librustsyntax/fold.rs
@@ -269,11 +269,13 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
             item_enum(vec::map(variants, fld.fold_variant),
                       fold_ty_params(typms, fld))
           }
-          item_class(typms, items, ctor) {
+          item_class(typms, ifaces, items, ctor) {
               let ctor_body = fld.fold_block(ctor.node.body);
               let ctor_decl = fold_fn_decl(ctor.node.dec, fld);
               let ctor_id   = fld.new_id(ctor.node.id);
-              item_class(typms,
+              item_class(typms, vec::map(ifaces, {|p|
+                              {path: fld.fold_path(p.path),
+                               id: fld.new_id(p.id)}}),
                          vec::map(items, fld.fold_class_item),
                          {node: {body: ctor_body,
                                  dec: ctor_decl,
diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs
index 01224845338..17a2c4e217f 100644
--- a/src/librustsyntax/parse/parser.rs
+++ b/src/librustsyntax/parse/parser.rs
@@ -2143,11 +2143,19 @@ fn ident_to_path_tys(p: parser, i: ast::ident,
     @spanned(s.lo, s.hi, p_)
 }
 
+fn parse_iface_ref_list(p:parser) -> [ast::iface_ref] {
+    parse_seq_to_before_end(token::LBRACE, seq_sep(token::COMMA),
+                   {|p| {path: parse_path(p), id: p.get_id()}}, p)
+}
+
 fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
     let lo = p.last_span.lo;
     let class_name = parse_value_ident(p);
     let ty_params = parse_ty_params(p);
     let class_path = ident_to_path_tys(p, class_name, ty_params);
+    let ifaces : [ast::iface_ref] = if eat_word(p, "implements")
+                                       { parse_iface_ref_list(p) }
+                                    else { [] };
     expect(p, token::LBRACE);
     let mut ms: [@ast::class_member] = [];
     let ctor_id = p.get_id();
@@ -2163,9 +2171,8 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
     p.bump();
     alt the_ctor {
       some((ct_d, ct_b, ct_s)) {
-          ret mk_item(p, lo, p.last_span.hi,
-                                             class_name,
-         ast::item_class(ty_params, ms,
+          ret mk_item(p, lo, p.last_span.hi, class_name,
+                      ast::item_class(ty_params, ifaces, ms,
                          {node: {id: ctor_id,
                                  self_id: p.get_id(),
                                  dec: ct_d,
diff --git a/src/librustsyntax/print/pprust.rs b/src/librustsyntax/print/pprust.rs
index 1d2094762f1..d45ae9e0056 100644
--- a/src/librustsyntax/print/pprust.rs
+++ b/src/librustsyntax/print/pprust.rs
@@ -493,10 +493,13 @@ fn print_item(s: ps, &&item: @ast::item) {
             bclose(s, item.span);
         }
       }
-      ast::item_class(tps,items,ctor) {
+      ast::item_class(tps,ifaces,items,ctor) {
           head(s, "class");
           word_nbsp(s, item.ident);
           print_type_params(s, tps);
+          word_space(s, "implements");
+          commasep(s, inconsistent, ifaces, {|s, p|
+                      print_path(s, p.path, false)});
           bopen(s);
           hardbreak_if_not_bol(s);
           maybe_print_comment(s, ctor.span.lo);
diff --git a/src/librustsyntax/visit.rs b/src/librustsyntax/visit.rs
index 33af7fe3661..20d85e08989 100644
--- a/src/librustsyntax/visit.rs
+++ b/src/librustsyntax/visit.rs
@@ -137,11 +137,12 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
             visit_method_helper(m, e, v)
         }
       }
-      item_class(tps, members, ctor) {
+      item_class(tps, ifaces, members, ctor) {
           v.visit_ty_params(tps, e, v);
           for members.each {|m|
              v.visit_class_item(m, e, v);
           }
+          for ifaces.each {|p| visit_path(p.path, e, v); }
           visit_class_ctor_helper(ctor, i.ident, tps,
                                   ast_util::local_def(i.id), e, v);
       }