Mercurial > octave-nkf
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"); |