comparison libinterp/octave-value/ov-classdef.cc @ 15909:b8bff84022d6 classdef

Use strong reference between objects and their class. * libinterp/octave-value/ov-classdef.h (cdef_object_rep::cname): Remove member. (cdef_object_rep::cdef_object_rep (void), cdef_object_rep::cdef_object_rep (cdef_object_rep)): Do not initialize it. (cdef_object_rep::cdef_object_rep (std::string)): Remove constructor. (cdef_object_rep::set_class_name): Remove method. (cdef_object_rep::grip_invalid_object): New private method. (cdef_object_rep::set_class, cdef_object_rep::is_class, cdef_object_rep::is_property, cdef_object_rep::is_method, cdef_object_rep::is_package): New methods. (cdef_object_rep::map, cdef_object_rep::ctor_list): Move members to cdef_object_scalar. (cdef_object_rep::put, cdef_object_rep::get, cdef_object_rep::subsref, cdef_object_rep::subsasgn, cdef_object_rep::mark_for_construction, cdef_object_rep::is_constructed_for, cdef_object_rep::mark_as_constructed, cdef_object_rep::is_partially_constructed_for, cdef_object_rep::is_constructed): Move implementation to cdef_object_scalar. (cdef_object_rep::is_constructed_for, cdef_object_rep::mark_as_constructed, cdef_object_rep::is_partially_constructed_for): Change signature, use cdef_class argument instead of std::string. (cdef_object_rep::class_name): Use get_class () and move inline definition after cdef_class declaration. (cdef_object::set_class_name): Remove method. (cdef_object::is_class, cdef_object::is_property, cdef_object::is_method, cdef_object::is_package): New methods. (cdef_object::is_constructed_for, cdef_object::mark_as_constructed, cdef_object::is_partially_constructed_for): Change signature, use cdef_class instead of std::string. (class cdef_object_base, class cdef_object_scalar): New classes. (class handle_cdef_object, class value_cdef_object): Inherits from cdef_object_scalar. (handle_cdef_object::handle_cdef_object (std::string)): Remove constructor. (value_cdef_object::value_cdef_object (std::string)): Likewise. (value_cdef_object::value_cdef_object (value_cdef_object)): Implement copy constructor. (value_cdef_object::clone): Use it. (cdef_class::cdef_class_rep::cdef_class_rep): Remove first string argument. (cdef_class::cdef_class_rep::is_class, cdef_class::cdef_class_rep::set_name, cdef_class::cdef_class_rep::wrap): New methods. (cdef_class::cdef_class_rep::implicit_ctor_list): Change type to std::list<cdef_class>. (cdef_class::cdef_class (std::string): Remove constructor. (cdef_class::cdef_class (std::list<cdef_class>)): Use string argument as the class name. (cdef_class::cdef_class (cdef_object), cdef_class::operator= (cdef_object)): Use is_class method. (cdef_class::_meta_class, cdef_class::_meta_property, cdef_class::_meta_method, cdef_class::_meta_package): New static members. (cdef_class::meta_class, cdef_class::meta_property, cdef_class::meta_method, cdef_class::meta_package): New static methods. (operator< (cdef_cass, cdef_class)): New function. (cdef_property::cdef_property_rep::cdef_property_rep): Remove first argument string. (cdef_property::cdef_property_rep::is_property, cdef_property::cdef_property_rep::get_name, cdef_property::cdef_property_rep::set_name, cdef_property::cdef_property_rep::is_constant): New methods. (cdef_property::get_name, cdef_property::is_constant): Use them. (cdef_property::cdef_property (std::string)): Use string argument as property name. (cdef_property::cdef_property (cdef_object)): Use is_property method. (cdef_method::cdef_method_rep::cdef_method_rep): Remove first argument string. (cdef_method::cdef_method_rep::is_method, cdef_method::cdef_method_rep::get_name, cdef_method::cdef_method_rep::set_name, cdef_method::cdef_method_rep::is_static): New methods. (cdef_method::get_name, cdef_method::is_static): Use them. (cdef_method::cdef_method (std::string)): Use string argument as method name. (cdef_method::cdef_method (cdef_object)): Use is_method method. (cdef_package::cdef_package_rep::cdef_package_rep): Remove first argument string. (cdef_package::cdef_package_rep::is_package, cdef_package::cdef_package_rep::get_name, cdef_package::cdef_package_rep::set_name): New methods. (cdef_package::get_name): Likewise. (cdef_package::cdef_package (std::string)): Use string argument as package name. (cdef_package::cdef_package (cdef_object)): Use is_package method. (cdef_package::_meta): New static member. (cdef_package::meta): New static method. * libinterp/octave-value/ov-classdef.cc (lookup_class (cdef_class), lookup_class (octave_value)): New static function overloads. (lookup_classes): Change argument name to reflect the fact we're using now a list of cdef_class objects, not a list of names. (make_class, make_property, make_method, make_package): Use name as constructor argument. Set object class. (cdef_object_rep::get_class): Move implementation to header. (cdef_object_rep::subsref, cdef_object_rep::subsasgn, cdef_object_rep::mark_for_construction): Move implementation to cdef_object_scalar. (cdef_object_scalar::is_constructed_for, cdef_object_scalar::is_partially_constructed_for): Moved from cdef_object_rep. (handle_cdef_object::~handle_cdef_object, value_cdef_object::~value_cdef_object): Do not use cname. (cdef_class::cdef_class_rep::cdef_class_rep (std::list<cdef_class>)): Remove first string argument. Keep strong references to cdef_class superclass objects. (cdef_class::cdef_class_rep::find_method, cdef_class::cdef_class_rep::find_methods, cdef_class::cdef_class_rep::find_property, cdef_class::cdef_class_rep::find_properties, cdef_class::cdef_class_rep::find_names, cdef_class::cdef_class_rep::delete_object): Superclasses are now strong references for cdef_class objects. (ctor_analyzer::available_ctor_list): Remove member. (ctor_analyzer::ctor_analyzer): Do not use it. (ctor_analyzer::ctor_list): Change type to std::list<cdef_class>. (ctor_analyzer::visit_funcall): Use it. Do not produce any error. (cdef_class::cdef_class_rep::install_method): Use strong references to cdef_class superclass objects. (cdef_class::cdef_class_rep::run_constructor): Likewise. (cdef_class::cdef_class_rep::construct): Use strong reference to cdef_class object. (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Likewise. (cdef_class::_meta_class, cdef_class::_meta_property, cdef_class::_meta_method, cdef_class::_meta_package): Initialize static members. (cdef_package::_meta): Likewise. (install_classdef): Bootstrap meta classes with strong references to cdef_class. Assign cdef_class and cdef_package static members.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 06 Jan 2013 12:19:16 -0500
parents a413c6fe1726
children dfd0dc594c4f
comparison
equal deleted inserted replaced
15897:a413c6fe1726 15909:b8bff84022d6
177 } 177 }
178 178
179 return cdef_class (); 179 return cdef_class ();
180 } 180 }
181 181
182 static cdef_class
183 lookup_class (const cdef_class& cls)
184 {
185 // FIXME: placeholder for the time being, the purpose
186 // is to centralized any class update activity here.
187
188 return cls;
189 }
190
191 static cdef_class
192 lookup_class (const octave_value& ov)
193 {
194 if (ov.is_string())
195 return lookup_class (ov.string_value ());
196 else
197 {
198 cdef_class cls (to_cdef (ov));
199
200 if (! error_state)
201 return lookup_class (cls);
202 }
203
204 return cdef_class ();
205 }
206
182 static std::list<cdef_class> 207 static std::list<cdef_class>
183 lookup_classes (const Cell& cls_names) 208 lookup_classes (const Cell& cls_list)
184 { 209 {
185 std::list<cdef_class> retval; 210 std::list<cdef_class> retval;
186 211
187 for (int i = 0; i < cls_names.numel (); i++) 212 for (int i = 0; i < cls_list.numel (); i++)
188 { 213 {
189 cdef_class c = lookup_class (cls_names(i).string_value ()); 214 cdef_class c = lookup_class (cls_list(i));
190 215
191 if (! error_state) 216 if (! error_state)
192 retval.push_back (c); 217 retval.push_back (c);
193 else 218 else
194 { 219 {
225 { 250 {
226 Cell c = clsb.get ("SuperClasses").cell_value (); 251 Cell c = clsb.get ("SuperClasses").cell_value ();
227 252
228 for (int i = 0; ! error_state && ! retval && i < c.numel (); i++) 253 for (int i = 0; ! error_state && ! retval && i < c.numel (); i++)
229 { 254 {
230 cdef_class cls = lookup_class (c(i).string_value ()); 255 cdef_class cls = lookup_class (c(i));
231 256
232 if (! error_state) 257 if (! error_state)
233 retval = is_superclass (clsa, cls, true, 258 retval = is_superclass (clsa, cls, true,
234 max_depth < 0 ? max_depth : max_depth-1); 259 max_depth < 0 ? max_depth : max_depth-1);
235 } 260 }
581 606
582 static cdef_class 607 static cdef_class
583 make_class (const std::string& name, 608 make_class (const std::string& name,
584 const std::list<cdef_class>& super_list = std::list<cdef_class> ()) 609 const std::list<cdef_class>& super_list = std::list<cdef_class> ())
585 { 610 {
586 cdef_class cls ("meta.class", super_list); 611 cdef_class cls (name, super_list);
587 612
613 cls.set_class (cdef_class::meta_class ());
588 cls.put ("ConstructOnLoad", false); 614 cls.put ("ConstructOnLoad", false);
589 cls.put ("ContainingPackage", Matrix ()); 615 cls.put ("ContainingPackage", Matrix ());
590 cls.put ("Description", std::string ()); 616 cls.put ("Description", std::string ());
591 cls.put ("DetailedDescription", std::string ()); 617 cls.put ("DetailedDescription", std::string ());
592 cls.put ("Events", Cell ()); 618 cls.put ("Events", Cell ());
593 cls.put ("Hidden", false); 619 cls.put ("Hidden", false);
594 cls.put ("InferiorClasses", Cell ()); 620 cls.put ("InferiorClasses", Cell ());
595 cls.put ("Methods", Cell ()); 621 cls.put ("Methods", Cell ());
596 cls.put ("Name", name);
597 cls.put ("Properties", Cell ()); 622 cls.put ("Properties", Cell ());
598 cls.put ("Sealed", false); 623 cls.put ("Sealed", false);
599 624
600 if (name == "handle") 625 if (name == "handle")
601 { 626 {
650 const octave_value& set_method = Matrix (), 675 const octave_value& set_method = Matrix (),
651 const std::string& set_access = "public") 676 const std::string& set_access = "public")
652 { 677 {
653 // FIXME: what about default value? 678 // FIXME: what about default value?
654 679
655 cdef_property prop ("meta.property"); 680 cdef_property prop (name);
656 681
657 prop.put ("Name", name); 682 prop.set_class (cdef_class::meta_property ());
658 prop.put ("Description", std::string ()); 683 prop.put ("Description", std::string ());
659 prop.put ("DetailedDescription", std::string ()); 684 prop.put ("DetailedDescription", std::string ());
660 prop.put ("Abstract", false); 685 prop.put ("Abstract", false);
661 prop.put ("Constant", false); 686 prop.put ("Constant", false);
662 prop.put ("GetAccess", get_access); 687 prop.put ("GetAccess", get_access);
691 static cdef_method 716 static cdef_method
692 make_method (const cdef_class& cls, const std::string& name, 717 make_method (const cdef_class& cls, const std::string& name,
693 const octave_value& fcn,const std::string& m_access = "public", 718 const octave_value& fcn,const std::string& m_access = "public",
694 bool is_static = false) 719 bool is_static = false)
695 { 720 {
696 cdef_method meth ("meta.method"); 721 cdef_method meth (name);
697 722
723 meth.set_class (cdef_class::meta_method ());
698 meth.put ("Abstract", false); 724 meth.put ("Abstract", false);
699 meth.put ("Access", m_access); 725 meth.put ("Access", m_access);
700 meth.put ("DefiningClass", to_ov (cls)); 726 meth.put ("DefiningClass", to_ov (cls));
701 meth.put ("Description", std::string ()); 727 meth.put ("Description", std::string ());
702 meth.put ("DetailedDescription", std::string ()); 728 meth.put ("DetailedDescription", std::string ());
703 meth.put ("Hidden", false); 729 meth.put ("Hidden", false);
704 meth.put ("Name", name);
705 meth.put ("Sealed", true); 730 meth.put ("Sealed", true);
706 meth.put ("Static", is_static); 731 meth.put ("Static", is_static);
707 732
708 make_function_of_class (cls, fcn); 733 make_function_of_class (cls, fcn);
709 734
726 make_package (const std::string& nm, 751 make_package (const std::string& nm,
727 const std::string& parent = std::string ()) 752 const std::string& parent = std::string ())
728 { 753 {
729 cdef_package pack ("meta.package"); 754 cdef_package pack ("meta.package");
730 755
731 all_packages[nm] = pack; 756 pack.set_class (cdef_class::meta_package ());
732 pack.put ("Name", nm); 757 pack.put ("Name", nm);
733 pack.put ("ContainingPackage", to_ov (all_packages[parent])); 758 pack.put ("ContainingPackage", to_ov (all_packages[parent]));
759
760 all_packages[nm] = pack;
734 761
735 return pack; 762 return pack;
736 } 763 }
737 764
738 //---------------------------------------------------------------------------- 765 //----------------------------------------------------------------------------
979 octave_value_list args; 1006 octave_value_list args;
980 }; 1007 };
981 1008
982 //---------------------------------------------------------------------------- 1009 //----------------------------------------------------------------------------
983 1010
984 cdef_class
985 cdef_object_rep::get_class (void) const
986 {
987 cdef_class cls = lookup_class (class_name ());
988
989 return cls;
990 }
991
992 string_vector 1011 string_vector
993 cdef_object_rep::map_keys (void) const 1012 cdef_object_rep::map_keys (void) const
994 { 1013 {
995 cdef_class cls = get_class (); 1014 cdef_class cls = get_class ();
996 1015
999 1018
1000 return string_vector (); 1019 return string_vector ();
1001 } 1020 }
1002 1021
1003 octave_value_list 1022 octave_value_list
1004 cdef_object_rep::subsref (const std::string& type, 1023 cdef_object_scalar::subsref (const std::string& type,
1005 const std::list<octave_value_list>& idx, 1024 const std::list<octave_value_list>& idx,
1006 int nargout, size_t& skip, 1025 int nargout, size_t& skip,
1007 const cdef_class& context) 1026 const cdef_class& context)
1008 { 1027 {
1009 skip = 0; 1028 skip = 0;
1010 1029
1011 cdef_class cls = (context.ok () ? context : get_class ()); 1030 cdef_class cls = (context.ok () ? context : get_class ());
1012 1031
1082 1101
1083 return retval; 1102 return retval;
1084 } 1103 }
1085 1104
1086 octave_value 1105 octave_value
1087 cdef_object_rep::subsasgn (const std::string& type, 1106 cdef_object_scalar::subsasgn (const std::string& type,
1088 const std::list<octave_value_list>& idx, 1107 const std::list<octave_value_list>& idx,
1089 const octave_value& rhs) 1108 const octave_value& rhs)
1090 { 1109 {
1091 octave_value retval; 1110 octave_value retval;
1092 1111
1093 cdef_class cls = get_class (); 1112 cdef_class cls = get_class ();
1094 1113
1141 1160
1142 return retval; 1161 return retval;
1143 } 1162 }
1144 1163
1145 void 1164 void
1146 cdef_object_rep::mark_for_construction (const cdef_class& cls) 1165 cdef_object_scalar::mark_for_construction (const cdef_class& cls)
1147 { 1166 {
1148 std::string cls_name = cls.get_name (); 1167 std::string cls_name = cls.get_name ();
1149 1168
1150 Cell supcls = cls.get ("SuperClasses").cell_value (); 1169 Cell supcls = cls.get ("SuperClasses").cell_value ();
1151 1170
1152 if (! error_state) 1171 if (! error_state)
1153 { 1172 {
1154 std::list<std::string> supcls_names; 1173 std::list<cdef_class> supcls_list = lookup_classes (supcls);
1155
1156 for (int i = 0; ! error_state && i < supcls.numel (); i++)
1157 supcls_names.push_back (supcls(i).string_value ());
1158 1174
1159 if (! error_state) 1175 if (! error_state)
1160 ctor_list[cls_name] = supcls_names; 1176 ctor_list[cls] = supcls_list;
1161 } 1177 }
1178 }
1179
1180 bool cdef_object_scalar::is_constructed_for (const cdef_class& cls) const
1181 {
1182 return (is_constructed ()
1183 || ctor_list.find (cls) == ctor_list.end ());
1184 }
1185
1186 bool cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const
1187 {
1188 std::map< cdef_class, std::list<cdef_class> >::const_iterator it;
1189
1190 if (is_constructed ())
1191 return true;
1192 else if ((it = ctor_list.find (cls)) == ctor_list.end ()
1193 || it->second.empty ())
1194 return true;
1195
1196 for (std::list<cdef_class>::const_iterator lit = it->second.begin ();
1197 lit != it->second.end (); ++lit)
1198 if (! is_constructed_for (*lit))
1199 return false;
1200
1201 return true;
1162 } 1202 }
1163 1203
1164 handle_cdef_object::~handle_cdef_object (void) 1204 handle_cdef_object::~handle_cdef_object (void)
1165 { 1205 {
1166 gnulib::printf ("deleting %s object (handle)\n", cname.c_str ()); 1206 gnulib::printf ("deleting %s object (handle)\n",
1207 get_class ().get_name ().c_str ());
1167 } 1208 }
1168 1209
1169 value_cdef_object::~value_cdef_object (void) 1210 value_cdef_object::~value_cdef_object (void)
1170 { 1211 {
1171 gnulib::printf ("deleting %s object (value)\n", cname.c_str ()); 1212 gnulib::printf ("deleting %s object (value)\n",
1172 } 1213 get_class ().get_name ().c_str ());
1173 1214 }
1174 cdef_class::cdef_class_rep::cdef_class_rep (const std::string& nm, 1215
1175 const std::list<cdef_class>& superclasses) 1216 cdef_class::cdef_class_rep::cdef_class_rep (const std::list<cdef_class>& superclasses)
1176 : handle_cdef_object (nm), handle_class (false) 1217 : handle_cdef_object (), handle_class (false)
1177 { 1218 {
1178 for (std::list<cdef_class>::const_iterator it = superclasses.begin (); 1219 put ("SuperClasses", to_ov (superclasses));
1179 it != superclasses.end (); ++it) 1220 implicit_ctor_list = superclasses;
1180 implicit_ctor_list.push_back (it->get_name ());
1181
1182 put ("SuperClasses", Cell (implicit_ctor_list));
1183 } 1221 }
1184 1222
1185 cdef_method 1223 cdef_method
1186 cdef_class::cdef_class_rep::find_method (const std::string& nm, bool local) 1224 cdef_class::cdef_class_rep::find_method (const std::string& nm, bool local)
1187 { 1225 {
1207 1245
1208 Cell super_classes = get ("SuperClasses").cell_value (); 1246 Cell super_classes = get ("SuperClasses").cell_value ();
1209 1247
1210 for (int i = 0; i < super_classes.numel (); i++) 1248 for (int i = 0; i < super_classes.numel (); i++)
1211 { 1249 {
1212 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1250 cdef_class cls = lookup_class (super_classes(i));
1213 1251
1214 if (! error_state) 1252 if (! error_state)
1215 { 1253 {
1216 cdef_method meth = cls.find_method (nm); 1254 cdef_method meth = cls.find_method (nm);
1217 1255
1225 } 1263 }
1226 1264
1227 class ctor_analyzer : public tree_walker 1265 class ctor_analyzer : public tree_walker
1228 { 1266 {
1229 public: 1267 public:
1230 ctor_analyzer (const std::string& ctor, const std::string& obj, 1268 ctor_analyzer (const std::string& ctor, const std::string& obj)
1231 const std::list<std::string>& l) 1269 : tree_walker (), who (ctor), obj_name (obj) { }
1232 : tree_walker (), who (ctor), obj_name (obj), available_ctor_list (l) { }
1233 1270
1234 void visit_statement_list (tree_statement_list& t) 1271 void visit_statement_list (tree_statement_list& t)
1235 { 1272 {
1236 for (tree_statement_list::const_iterator it = t.begin (); 1273 for (tree_statement_list::const_iterator it = t.begin ();
1237 ! error_state && it != t.end (); ++it) 1274 ! error_state && it != t.end (); ++it)
1280 1317
1281 std::string ctor_name = (package_name.empty () 1318 std::string ctor_name = (package_name.empty ()
1282 ? class_name 1319 ? class_name
1283 : package_name + "." + class_name); 1320 : package_name + "." + class_name);
1284 1321
1285 if (std::find (available_ctor_list.begin (), 1322 cdef_class cls = lookup_class (ctor_name, false);
1286 available_ctor_list.end (), ctor_name) 1323
1287 == available_ctor_list.end ()) 1324 if (cls.ok ())
1288 ::error ("`%s' is not a direct superclass of `%s'", 1325 ctor_list.push_back (cls);
1289 ctor_name.c_str (), who.c_str ());
1290 else if (std::find (ctor_list.begin (), ctor_list.end (),
1291 ctor_name) != ctor_list.end ())
1292 ::error ("calling constructor `%s' more than once",
1293 ctor_name.c_str ());
1294
1295 ctor_list.push_back (ctor_name);
1296 } 1326 }
1297 } 1327 }
1298 } 1328 }
1299 } 1329 }
1300 } 1330 }
1301 1331
1302 std::list<std::string> get_constructor_list (void) const 1332 std::list<cdef_class> get_constructor_list (void) const
1303 { return ctor_list; } 1333 { return ctor_list; }
1304 1334
1305 // NO-OP 1335 // NO-OP
1306 void visit_anon_fcn_handle (tree_anon_fcn_handle&) { } 1336 void visit_anon_fcn_handle (tree_anon_fcn_handle&) { }
1307 void visit_argument_list (tree_argument_list&) { } 1337 void visit_argument_list (tree_argument_list&) { }
1346 1376
1347 /* The name of the first output argument of the constructor */ 1377 /* The name of the first output argument of the constructor */
1348 std::string obj_name; 1378 std::string obj_name;
1349 1379
1350 /* The list of superclass constructors that are explicitly called */ 1380 /* The list of superclass constructors that are explicitly called */
1351 std::list<std::string> ctor_list; 1381 std::list<cdef_class> ctor_list;
1352
1353 /* The list of possible superclass constructors */
1354 std::list<std::string> available_ctor_list;
1355 }; 1382 };
1356 1383
1357 void 1384 void
1358 cdef_class::cdef_class_rep::install_method (const cdef_method& meth) 1385 cdef_class::cdef_class_rep::install_method (const cdef_method& meth)
1359 { 1386 {
1376 tree_statement_list *body = uf->body (); 1403 tree_statement_list *body = uf->body ();
1377 1404
1378 if (ret_list && ret_list->size () == 1) 1405 if (ret_list && ret_list->size () == 1)
1379 { 1406 {
1380 std::string obj_name = ret_list->front ()->name (); 1407 std::string obj_name = ret_list->front ()->name ();
1381 ctor_analyzer a (meth.get_name (), obj_name, 1408 ctor_analyzer a (meth.get_name (), obj_name);
1382 implicit_ctor_list);
1383 1409
1384 body->accept (a); 1410 body->accept (a);
1385 if (! error_state) 1411 if (! error_state)
1386 { 1412 {
1387 std::list<std::string> explicit_ctor_list 1413 std::list<cdef_class> explicit_ctor_list
1388 = a.get_constructor_list (); 1414 = a.get_constructor_list ();
1389 1415
1390 for (std::list<std::string>::const_iterator it = explicit_ctor_list.begin (); 1416 for (std::list<cdef_class>::const_iterator it = explicit_ctor_list.begin ();
1391 ! error_state && it != explicit_ctor_list.end (); ++it) 1417 ! error_state && it != explicit_ctor_list.end (); ++it)
1392 { 1418 {
1393 gnulib::printf ("explicit superclass constructor: %s\n", 1419 gnulib::printf ("explicit superclass constructor: %s\n",
1394 it->c_str ()); 1420 it->get_name ().c_str ());
1395 implicit_ctor_list.remove (*it); 1421 implicit_ctor_list.remove (*it);
1396 } 1422 }
1397 } 1423 }
1398 } 1424 }
1399 else 1425 else
1469 1495
1470 Cell super_classes = get ("SuperClasses").cell_value (); 1496 Cell super_classes = get ("SuperClasses").cell_value ();
1471 1497
1472 for (int i = 0; i < super_classes.numel (); i++) 1498 for (int i = 0; i < super_classes.numel (); i++)
1473 { 1499 {
1474 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1500 cdef_class cls = lookup_class (super_classes(i));
1475 1501
1476 if (! error_state) 1502 if (! error_state)
1477 cls.get_rep ()->find_methods (meths, true); 1503 cls.get_rep ()->find_methods (meths, true);
1478 else 1504 else
1479 break; 1505 break;
1497 1523
1498 Cell super_classes = get ("SuperClasses").cell_value (); 1524 Cell super_classes = get ("SuperClasses").cell_value ();
1499 1525
1500 for (int i = 0; i < super_classes.numel (); i++) 1526 for (int i = 0; i < super_classes.numel (); i++)
1501 { 1527 {
1502 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1528 cdef_class cls = lookup_class (super_classes(i));
1503 1529
1504 if (! error_state) 1530 if (! error_state)
1505 { 1531 {
1506 cdef_property prop = cls.find_property (nm); 1532 cdef_property prop = cls.find_property (nm);
1507 1533
1572 1598
1573 Cell super_classes = get ("SuperClasses").cell_value (); 1599 Cell super_classes = get ("SuperClasses").cell_value ();
1574 1600
1575 for (int i = 0; ! error_state && i < super_classes.numel (); i++) 1601 for (int i = 0; ! error_state && i < super_classes.numel (); i++)
1576 { 1602 {
1577 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1603 cdef_class cls = lookup_class (super_classes(i));
1578 1604
1579 if (! error_state) 1605 if (! error_state)
1580 cls.get_rep ()->find_properties (props, true); 1606 cls.get_rep ()->find_properties (props, true);
1581 else 1607 else
1582 break; 1608 break;
1632 1658
1633 Cell super_classes = get ("SuperClasses").cell_value (); 1659 Cell super_classes = get ("SuperClasses").cell_value ();
1634 1660
1635 for (int i = 0; ! error_state && i < super_classes.numel (); i++) 1661 for (int i = 0; ! error_state && i < super_classes.numel (); i++)
1636 { 1662 {
1637 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1663 cdef_class cls = lookup_class (super_classes(i));
1638 1664
1639 if (! error_state) 1665 if (! error_state)
1640 cls.get_rep ()->find_names (names, all); 1666 cls.get_rep ()->find_names (names, all);
1641 else 1667 else
1642 break; 1668 break;
1670 { 1696 {
1671 method_iterator it = method_map.find ("delete"); 1697 method_iterator it = method_map.find ("delete");
1672 1698
1673 if (it != method_map.end ()) 1699 if (it != method_map.end ())
1674 { 1700 {
1675 std::string cls_name = obj.class_name (); 1701 cdef_class cls = obj.get_class ();
1676 1702
1677 obj.set_class_name (get ("Name").string_value ()); 1703 obj.set_class (wrap ());
1678 1704
1679 it->second.execute (obj, octave_value_list (), 0); 1705 it->second.execute (obj, octave_value_list (), 0);
1680 1706
1681 obj.set_class_name (cls_name); 1707 obj.set_class (cls);
1682 } 1708 }
1683 1709
1684 // FIXME: should we destroy corresponding properties here? 1710 // FIXME: should we destroy corresponding properties here?
1685 1711
1686 // Call "delete" in super classes 1712 // Call "delete" in super classes
1687 1713
1688 Cell super_classes = get ("SuperClasses").cell_value (); 1714 Cell super_classes = get ("SuperClasses").cell_value ();
1689 1715
1690 for (int i = 0; i < super_classes.numel (); i++) 1716 for (int i = 0; i < super_classes.numel (); i++)
1691 { 1717 {
1692 cdef_class cls = lookup_class (super_classes(i).string_value ()); 1718 cdef_class cls = lookup_class (super_classes(i));
1693 1719
1694 if (!error_state) 1720 if (!error_state)
1695 cls.delete_object (obj); 1721 cls.delete_object (obj);
1696 } 1722 }
1697 } 1723 }
1767 cdef_class::cdef_class_rep::run_constructor (cdef_object& obj, 1793 cdef_class::cdef_class_rep::run_constructor (cdef_object& obj,
1768 const octave_value_list& args) 1794 const octave_value_list& args)
1769 { 1795 {
1770 octave_value_list empty_args; 1796 octave_value_list empty_args;
1771 1797
1772 for (std::list<std::string>::const_iterator it = implicit_ctor_list.begin (); 1798 for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin ();
1773 ! error_state && it != implicit_ctor_list.end (); ++it) 1799 ! error_state && it != implicit_ctor_list.end (); ++it)
1774 { 1800 {
1775 cdef_class supcls = lookup_class (*it); 1801 cdef_class supcls = lookup_class (*it);
1776 1802
1777 if (! error_state) 1803 if (! error_state)
1805 return; 1831 return;
1806 } 1832 }
1807 } 1833 }
1808 } 1834 }
1809 1835
1810 obj.mark_as_constructed (cls_name); 1836 obj.mark_as_constructed (wrap ());
1811 } 1837 }
1812 1838
1813 octave_value 1839 octave_value
1814 cdef_class::cdef_class_rep::construct (const octave_value_list& args) 1840 cdef_class::cdef_class_rep::construct (const octave_value_list& args)
1815 { 1841 {
1816 cdef_object_rep *r; 1842 cdef_object_rep *r;
1817 1843
1818 if (is_handle_class ()) 1844 if (is_handle_class ())
1819 r = new handle_cdef_object (get_name ()); 1845 r = new handle_cdef_object ();
1820 else 1846 else
1821 r = new value_cdef_object (get_name ()); 1847 r = new value_cdef_object ();
1848 r->set_class (wrap ());
1822 1849
1823 cdef_object obj (r); 1850 cdef_object obj (r);
1824 1851
1825 initialize_object (obj); 1852 initialize_object (obj);
1826 1853
2069 2096
2070 if (! obj.is_constructed ()) 2097 if (! obj.is_constructed ())
2071 { 2098 {
2072 cdef_class cls (to_cdef (get ("DefiningClass"))); 2099 cdef_class cls (to_cdef (get ("DefiningClass")));
2073 2100
2074 if (! obj.is_partially_constructed_for (cls.get_name ())) 2101 if (! obj.is_partially_constructed_for (cls))
2075 { 2102 {
2076 ::error ("cannot reference properties of class `%s' for non-constructed object", 2103 ::error ("cannot reference properties of class `%s' for non-constructed object",
2077 cls.get_name ().c_str ()); 2104 cls.get_name ().c_str ());
2078 return retval; 2105 return retval;
2079 } 2106 }
2113 { 2140 {
2114 if (! obj.is_constructed ()) 2141 if (! obj.is_constructed ())
2115 { 2142 {
2116 cdef_class cls (to_cdef (get ("DefiningClass"))); 2143 cdef_class cls (to_cdef (get ("DefiningClass")));
2117 2144
2118 if (! obj.is_partially_constructed_for (cls.get_name ())) 2145 if (! obj.is_partially_constructed_for (cls))
2119 { 2146 {
2120 ::error ("cannot reference properties of class `%s' for non-constructed object", 2147 ::error ("cannot reference properties of class `%s' for non-constructed object",
2121 cls.get_name ().c_str ()); 2148 cls.get_name ().c_str ());
2122 return; 2149 return;
2123 } 2150 }
2387 2414
2388 Cell 2415 Cell
2389 cdef_package::cdef_package_rep::get_packages (void) const 2416 cdef_package::cdef_package_rep::get_packages (void) const
2390 { return map2Cell (package_map); } 2417 { return map2Cell (package_map); }
2391 2418
2419 cdef_class cdef_class::_meta_class = cdef_class ();
2420 cdef_class cdef_class::_meta_property = cdef_class ();
2421 cdef_class cdef_class::_meta_method = cdef_class ();
2422 cdef_class cdef_class::_meta_package = cdef_class ();
2423
2424 cdef_package cdef_package::_meta = cdef_package ();
2425
2392 void 2426 void
2393 install_classdef (void) 2427 install_classdef (void)
2394 { 2428 {
2395 octave_classdef::register_type (); 2429 octave_classdef::register_type ();
2396 2430
2431 /* bootstrap */
2432 cdef_class handle = make_class ("handle");
2433 cdef_class meta_class = cdef_class::_meta_class = make_class ("meta.class", handle);
2434 handle.set_class (meta_class);
2435 meta_class.set_class (meta_class);
2436
2397 /* meta classes */ 2437 /* meta classes */
2398 cdef_class handle = make_class ("handle"); 2438 cdef_class meta_property = cdef_class::_meta_property = make_class ("meta.property", handle);
2399 cdef_class meta_class = make_class ("meta.class", handle); 2439 cdef_class meta_method = cdef_class::_meta_method = make_class ("meta.method", handle);
2400 cdef_class meta_property = make_class ("meta.property", handle); 2440 cdef_class meta_package = cdef_class::_meta_package = make_class ("meta.package", handle);
2401 cdef_class meta_method = make_class ("meta.method", handle); 2441
2402 cdef_class meta_event = make_class ("meta.event", handle); 2442 cdef_class meta_event = make_class ("meta.event", handle);
2403 cdef_class meta_package = make_class ("meta.package", handle);
2404 cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", handle); 2443 cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", handle);
2405 2444
2406 /* meta classes are all sealed */ 2445 /* meta classes are all sealed */
2407 meta_class.put ("Sealed", true); 2446 meta_class.put ("Sealed", true);
2408 meta_property.put ("Sealed", true); 2447 meta_property.put ("Sealed", true);
2409 meta_method.put ("Sealed", true); 2448 meta_method.put ("Sealed", true);
2449 meta_package.put ("Sealed", true);
2410 meta_event.put ("Sealed", true); 2450 meta_event.put ("Sealed", true);
2411 meta_package.put ("Sealed", true);
2412 meta_dynproperty.put ("Sealed", true); 2451 meta_dynproperty.put ("Sealed", true);
2413 2452
2414 /* meta.class properties */ 2453 /* meta.class properties */
2415 meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad")); 2454 meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad"));
2416 meta_class.install_property (make_property (meta_class, "ContainingPackage")); 2455 meta_class.install_property (make_property (meta_class, "ContainingPackage"));
2530 "public", Matrix (), "private")); 2569 "public", Matrix (), "private"));
2531 meta_package.install_method (make_method (meta_package, "fromName", package_fromName, 2570 meta_package.install_method (make_method (meta_package, "fromName", package_fromName,
2532 "public", true)); 2571 "public", true));
2533 2572
2534 /* create "meta" package */ 2573 /* create "meta" package */
2535 cdef_package package_meta = make_package ("meta"); 2574 cdef_package package_meta = cdef_package::_meta = make_package ("meta");
2536 package_meta.install_class (meta_class, "class"); 2575 package_meta.install_class (meta_class, "class");
2537 package_meta.install_class (meta_property, "property"); 2576 package_meta.install_class (meta_property, "property");
2538 package_meta.install_class (meta_method, "method"); 2577 package_meta.install_class (meta_method, "method");
2539 package_meta.install_class (meta_package, "package"); 2578 package_meta.install_class (meta_package, "package");
2540 package_meta.install_class (meta_event, "event"); 2579 package_meta.install_class (meta_event, "event");