changeset 15956:d8553705f8f0 classdef

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.
author Michael Goffioul <michael.goffioul@gmail.com>
date Tue, 15 Jan 2013 19:36:31 -0500
parents 837a4a9b5049
children db6371b97fed
files libinterp/octave-value/ov-classdef.cc
diffstat 1 files changed, 75 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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<octave_value_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;