about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/comp/metadata/tyencode.rs7
-rw-r--r--src/comp/middle/resolve.rs14
-rw-r--r--src/comp/middle/shape.rs2
-rw-r--r--src/comp/middle/ty.rs19
-rw-r--r--src/comp/middle/typeck.rs29
-rw-r--r--src/test/run-pass/classes-simple.rs10
6 files changed, 75 insertions, 6 deletions
diff --git a/src/comp/metadata/tyencode.rs b/src/comp/metadata/tyencode.rs
index fd2f20c4913..4d8042477d0 100644
--- a/src/comp/metadata/tyencode.rs
+++ b/src/comp/metadata/tyencode.rs
@@ -192,6 +192,13 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
         w.write_char(']');
       }
       ty::ty_opaque_box { w.write_char('B'); }
+      ty::ty_class(def, tys) {
+          w.write_str("c[");
+          w.write_str(cx.ds(def));
+          w.write_char('|');
+          for t: ty::t in tys { enc_ty(w, cx, t); }
+          w.write_char(']');
+      }
     }
 }
 fn enc_proto(w: io::writer, proto: proto) {
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index aeb22d88c49..1d47fb0857a 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -472,6 +472,16 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
             v.visit_ty(m.decl.output, msc, v);
         }
       }
+      ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
+        visit::visit_ty_params(tps, sc, v);
+        let ctor_scope = cons(scope_fn_expr(ctor_decl, ctor_id, tps), @sc);
+        for cm in members {
+            alt cm.node.decl {
+              class_method(i) { visit_item_with_scope(e, i, ctor_scope, v); }
+              _ { } // instance var -- nothing to do
+            }
+        }
+      }
       _ { visit::visit_item(i, sc, v); }
     }
 
@@ -1209,7 +1219,9 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
         }
       }
       ast::item_class(_, _, _, _, _) {
-          fail "class! don't know what to do";
+          if ns == ns_type {
+            ret some(ast::def_class(local_def(i.id)));
+          }
       }
       ast::item_impl(_,_,_,_) { /* ??? */ }
     }
diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs
index 5da184d1b5a..bdd43b883db 100644
--- a/src/comp/middle/shape.rs
+++ b/src/comp/middle/shape.rs
@@ -63,6 +63,7 @@ const shape_stack_fn: u8 = 26u8;
 const shape_bare_fn: u8 = 27u8;
 const shape_tydesc: u8 = 28u8;
 const shape_send_tydesc: u8 = 29u8;
+const shape_class: u8 = 30u8;
 
 // FIXME: This is a bad API in trans_common.
 fn C_u8(n: u8) -> ValueRef { ret trans::common::C_u8(n as uint); }
@@ -404,6 +405,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
         add_substr(s, sub);
       }
       ty::ty_iface(_, _) { s += [shape_iface]; }
+      ty::ty_class(_, _) { s += [shape_class]; }
       ty::ty_res(did, raw_subt, tps) {
         let subt = ty::substitute_type_params(ccx.tcx, tps, raw_subt);
         let ri = {did: did, t: subt};
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 11f5c2ac3a0..a90e04c0373 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -40,6 +40,7 @@ export is_pred_ty;
 export lookup_item_type;
 export method;
 export method_idx;
+export mk_class;
 export mk_ctxt;
 export mk_named, type_name;
 export mt;
@@ -225,6 +226,7 @@ enum sty {
     ty_rec([field]),
     ty_fn(fn_ty),
     ty_iface(def_id, [t]),
+    ty_class(def_id, [t]),
     ty_res(def_id, t, [t]),
     ty_tup([t]),
 
@@ -354,7 +356,7 @@ fn mk_t_named(cx: ctxt, st: sty, name: option<str>) -> t {
       ty_opaque_box {}
       ty_param(_, _) { has_params = true; }
       ty_var(_) | ty_self(_) { has_vars = true; }
-      ty_enum(_, tys) | ty_iface(_, tys) {
+      ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
         for tt in tys { derive_flags(has_params, has_vars, tt); }
       }
       ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_ptr(m) {
@@ -442,6 +444,10 @@ fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
     mk_t(cx, ty_iface(did, tys))
 }
 
+fn mk_class(cx: ctxt, class_id: ast::def_id, tys: [t]) -> t {
+    mk_t(cx, ty_class(class_id, tys))
+}
+
 fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
     mk_t(cx, ty_res(did, inner, tps))
 }
@@ -487,7 +493,8 @@ fn walk_ty(cx: ctxt, ty: t, f: fn(t)) {
       ty_str | ty_send_type | ty_type | ty_opaque_box |
       ty_opaque_closure_ptr(_) | ty_var(_) | ty_param(_, _) {}
       ty_box(tm) | ty_vec(tm) | ty_ptr(tm) { walk_ty(cx, tm.ty, f); }
-      ty_enum(_, subtys) | ty_iface(_, subtys) | ty_self(subtys) {
+      ty_enum(_, subtys) | ty_iface(_, subtys) | ty_class(_, subtys)
+       | ty_self(subtys) {
         for subty: t in subtys { walk_ty(cx, subty, f); }
       }
       ty_rec(fields) {
@@ -1155,6 +1162,11 @@ fn hash_type_structure(st: sty) -> uint {
       ty_opaque_closure_ptr(ck_box) { 42u }
       ty_opaque_closure_ptr(ck_uniq) { 43u }
       ty_opaque_box { 44u }
+      ty_class(did, tys) {
+          let h = hash_def(45u, did);
+          for typ: t in tys { h = hash_subty(h, typ); }
+          h
+      }
     }
 }
 
@@ -2410,6 +2422,9 @@ fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
     alt cx.tcache.find(did) {
       some(tpt) { ret tpt; }
       none {
+          /* where do things get added to the cache?
+             Have to add class members */
+
         // The item is in this crate. The caller should have added it to the
         // type cache already
         assert did.crate != ast::local_crate;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index dcc257956c7..3a7f8e2d55e 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -108,7 +108,9 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
         }
       }
       ast::def_fn(id, _) | ast::def_const(id) |
-      ast::def_variant(_, id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
+      ast::def_variant(_, id) | ast::def_class(id)
+          | ast::def_class_method(_, id) | ast::def_class_field(_, id)
+         { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
       ast::def_binding(id) {
         assert (fcx.locals.contains_key(id.node));
         let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node));
@@ -422,8 +424,12 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
         tcx.tcache.insert(local_def(it.id), tpt);
         ret tpt;
       }
-      ast::item_class(_,_,_,_,_) {
-          fail "ty_of_item: implement item_class";
+      ast::item_class(tps,_,_,_,_) {
+          let {bounds,params} = mk_ty_params(tcx, tps);
+          let t = ty::mk_class(tcx, local_def(it.id), params);
+          let tpt = {bounds: bounds, ty: t};
+          tcx.tcache.insert(local_def(it.id), tpt);
+          ret tpt;
       }
       ast::item_impl(_, _, _, _) | ast::item_mod(_) |
       ast::item_native_mod(_) { fail; }
@@ -755,6 +761,10 @@ mod collect {
           _ { fail; }
         }
     }
+    fn convert_class_item(cx: @ctxt, parent_ty: ty::t,
+                          ci: ast::class_member) {
+        /* TODO */
+    }
     fn convert(cx: @ctxt, it: @ast::item) {
         alt it.node {
           // These don't define types.
@@ -847,6 +857,19 @@ mod collect {
             write_ty(cx.tcx, it.id, tpt.ty);
             ensure_iface_methods(cx.tcx, it.id);
           }
+          ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
+              let parent_ty = ty::lookup_item_type(cx.tcx, local_def(it.id));
+              // Write the ctor type
+              let t_ctor = ty::mk_fn(cx.tcx,
+                                     ty_of_fn_decl(cx.tcx, m_collect,
+                                             ast::proto_any, ctor_decl));
+              write_ty(cx.tcx, ctor_id, t_ctor);
+              /* FIXME: check for proper public/privateness */
+              // Write the type of each of the members
+              for m in members {
+                 convert_class_item(cx, parent_ty.ty, m.node.decl);
+              }
+          }
           _ {
             // This call populates the type cache with the converted type
             // of the item in passing. All we have to do here is to write
diff --git a/src/test/run-pass/classes-simple.rs b/src/test/run-pass/classes-simple.rs
new file mode 100644
index 00000000000..006c6392a6b
--- /dev/null
+++ b/src/test/run-pass/classes-simple.rs
@@ -0,0 +1,10 @@
+// xfail-test
+class cat {
+  priv {
+    let mutable meows : uint;
+  }
+
+  let how_hungry : int;
+
+  new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+}
\ No newline at end of file