# HG changeset patch # User Michael Goffioul # Date 1358296591 18000 # Node ID d8553705f8f0cc9bd91fc4ae37ec9582388a274b # Parent 837a4a9b50492c8bd0bf11a841038f09fd885896 Support calling static methods and getting constant properties. * libinterp/octave-value/ov-classdef.cc (cdef_object::cdef_object_rep::subsref): Get constant property value correctly. (cdef_class::cdef_class_rep::subsref_meta): Implement calling static methods and accessing constant properties. diff -r 837a4a9b5049 -r d8553705f8f0 libinterp/octave-value/ov-classdef.cc --- a/libinterp/octave-value/ov-classdef.cc Tue Jan 15 17:01:13 2013 -0500 +++ b/libinterp/octave-value/ov-classdef.cc Tue Jan 15 19:36:31 2013 -0500 @@ -1130,8 +1130,13 @@ { if (prop.check_get_access ()) { - refcount++; - retval(0) = prop.get_value (cdef_object (this)); + if (prop.is_constant ()) + retval(0) = prop.get_value (); + else + { + refcount++; + retval(0) = prop.get_value (cdef_object (this)); + } skip = 1; } @@ -1942,6 +1947,8 @@ const std::list& idx, int nargout) { + size_t skip = 1; + octave_value_list retval; switch (type[0]) @@ -1951,16 +1958,79 @@ gnulib::printf ("constructor\n"); retval(0) = construct (idx.front ()); break; + case '.': // Static method, constant (or property?) - gnulib::printf ("static method\n"); + gnulib::printf ("static method/property\n"); + if (idx.front ().length () == 1) + { + std::string nm = idx.front ()(0).string_value (); + + if (! error_state) + { + cdef_method meth = find_method (nm); + + if (meth.ok ()) + { + if (meth.is_static ()) + { + if (meth.check_access ()) + { + octave_value_list args; + + if (type.length () > 1 && idx.size () > 1 + && type[1] == '(') + { + args = *(++(idx.begin ())); + skip++; + } + + retval = meth.execute (args, (type.length () > skip + ? 1 : nargout)); + } + else + gripe_method_access ("meta.class", meth); + } + else + ::error ("method `%s' is not static", nm.c_str ()); + } + else + { + cdef_property prop = find_property (nm); + + if (prop.ok ()) + { + if (prop.is_constant ()) + { + if (prop.check_get_access ()) + retval(0) = prop.get_value (); + else + gripe_property_access ("meta.class", prop, false); + } + else + ::error ("property `%s' is not constant", + nm.c_str ()); + } + else + ::error ("no such method or property `%s'", nm.c_str ()); + } + } + else + ::error ("invalid meta.class indexing, expected a method or property name"); + } + else + ::error ("invalid meta.class indexing"); + break; + + default: + ::error ("invalid meta.class indexing"); break; } if (! error_state) { - if (type.length () > 1 && idx.size () > 1 && ! retval.empty ()) - retval = retval(0).next_subsref (nargout, type, idx); + if (type.length () > skip && idx.size () > skip && ! retval.empty ()) + retval = retval(0).next_subsref (nargout, type, idx, skip); } return retval;