GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
cdef-manager.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "cdef-manager.h"
31 #include "cdef-utils.h"
32 #include "interpreter.h"
33 #include "ov-classdef.h"
34 
36 
37 static octave_value
38 make_fcn_handle (octave_builtin::fcn ff, const std::string& nm)
39 {
40  octave_value fcn (new octave_builtin (ff, nm));
41 
42  return octave_value (new octave_fcn_handle (fcn));
43 }
44 
45 static octave_value_list
46 class_get_properties (const octave_value_list& args, int /* nargout */)
47 {
48  octave_value_list retval;
49 
50  if (args.length () == 1 && args(0).type_name () == "object")
51  {
52  cdef_class cls (to_cdef (args(0)));
53 
54  retval(0) = cls.get_properties ();
55  }
56 
57  return retval;
58 }
59 
60 static octave_value_list
61 class_get_methods (const octave_value_list& args, int /* nargout */)
62 {
63  octave_value_list retval;
64 
65  if (args.length () == 1 && args(0).type_name () == "object")
66  {
67  cdef_class cls (to_cdef (args(0)));
68 
69  retval(0) = cls.get_methods ();
70  }
71 
72  return retval;
73 }
74 
75 static octave_value_list
76 class_get_superclasses (const octave_value_list& args, int /* nargout */)
77 {
78  octave_value_list retval;
79 
80  if (args.length () == 1 && args(0).type_name () == "object"
81  && args(0).class_name () == "meta.class")
82  {
83  cdef_class cls (to_cdef (args(0)));
84 
85  Cell classes = cls.get ("SuperClasses").cell_value ();
86 
87  retval(0) = to_ov (lookup_classes (classes));
88  }
89 
90  return retval;
91 }
92 
93 static octave_value_list
94 class_get_inferiorclasses (const octave_value_list& args, int /* nargout */)
95 {
96  octave_value_list retval;
97 
98  if (args.length () == 1 && args(0).type_name () == "object"
99  && args(0).class_name () == "meta.class")
100  {
101  cdef_class cls (to_cdef (args(0)));
102 
103  Cell classes = cls.get ("InferiorClasses").cell_value ();
104 
105  retval(0) = to_ov (lookup_classes (classes));
106  }
107 
108  return retval;
109 }
110 
111 static octave_value_list
112 class_fromName (const octave_value_list& args, int /* nargout */)
113 {
114  octave_value_list retval;
115 
116  if (args.length () != 1)
117  error ("fromName: invalid number of parameters");
118 
119  std::string name = args(0).xstring_value ("fromName: CLASS_NAME must be a string");
120 
121  retval(0) = to_ov (lookup_class (name, false));
122 
123  return retval;
124 }
125 
126 static octave_value_list
127 class_fevalStatic (const octave_value_list& args, int nargout)
128 {
129  if (args.length () <= 1 || args(0).type_name () != "object")
130  error ("fevalStatic: first argument must be a meta.class object");
131 
132  cdef_class cls (to_cdef (args(0)));
133 
134  std::string meth_name = args(1).xstring_value ("fevalStatic: method name must be a string");
135 
136  cdef_method meth = cls.find_method (meth_name);
137 
138  if (! meth.ok ())
139  error ("fevalStatic: method not found: %s", meth_name.c_str ());
140 
141  if (! meth.is_static ())
142  error ("fevalStatic: method '%s' is not static", meth_name.c_str ());
143 
144  return meth.execute (args.splice (0, 2), nargout, true, "fevalStatic");
145 }
146 
147 static octave_value_list
148 class_getConstant (const octave_value_list& args, int /* nargout */)
149 {
150  octave_value_list retval;
151 
152  if (args.length () != 2 || args(0).type_name () != "object"
153  || args(0).class_name () != "meta.class")
154  error ("getConstant: first argument must be a meta.class object");
155 
156  cdef_class cls = to_cdef (args(0));
157 
158  std::string prop_name = args(1).xstring_value ("getConstant: property name must be a string");
159 
160  cdef_property prop = cls.find_property (prop_name);
161 
162  if (! prop.ok ())
163  error ("getConstant: property not found: %s",
164  prop_name.c_str ());
165 
166  if (! prop.is_constant ())
167  error ("getConstant: property '%s' is not constant",
168  prop_name.c_str ());
169 
170  retval(0) = prop.get_value (true, "getConstant");
171 
172  return retval;
173 }
174 
175 #define META_CLASS_CMP(OP, CLSA, CLSB, FCN) \
176  static octave_value_list \
177  class_ ## OP (const octave_value_list& args, int /* nargout */) \
178  { \
179  octave_value_list retval; \
180  \
181  if (args.length () != 2 \
182  || args(0).type_name () != "object" \
183  || args(1).type_name () != "object" \
184  || args(0).class_name () != "meta.class" \
185  || args(1).class_name () != "meta.class") \
186  error (#OP ": invalid arguments"); \
187  \
188  cdef_class clsa = to_cdef (args(0)); \
189  \
190  cdef_class clsb = to_cdef (args(1)); \
191  \
192  retval(0) = FCN (CLSA, CLSB); \
193  \
194  return retval; \
195  }
196 
197 META_CLASS_CMP (lt, clsb, clsa, is_strict_superclass)
198 META_CLASS_CMP (le, clsb, clsa, is_superclass)
199 META_CLASS_CMP (gt, clsa, clsb, is_strict_superclass)
200 META_CLASS_CMP (ge, clsa, clsb, is_superclass)
201 META_CLASS_CMP (eq, clsa, clsb, operator==)
202 META_CLASS_CMP (ne, clsa, clsb, operator!=)
203 
204 static octave_value_list
205 property_get_defaultvalue (const octave_value_list& args, int /* nargout */)
206 {
207  octave_value_list retval;
208 
209  if (args.length () == 1 && args(0).type_name () == "object")
210  {
211  cdef_property prop (to_cdef (args(0)));
212 
213  retval(0) = prop.get ("DefaultValue");
214 
215  if (! retval(0).is_defined ())
216  error_with_id ("Octave:class:NoDefaultDefined",
217  "no default value for property '%s'",
218  prop.get_name ().c_str ());
219  }
220 
221  return retval;
222 }
223 
224 static octave_value_list
225 handle_delete (const octave_value_list& /* args */, int /* nargout */)
226 {
227  octave_value_list retval;
228 
229  // FIXME: implement this. Wait, what is this supposed to do?
230 
231  return retval;
232 }
233 
234 static octave_value_list
235 package_get_classes (const octave_value_list& args, int /* nargout */)
236 {
237  octave_value_list retval (1, Matrix ());
238 
239  if (args.length () == 1 && args(0).type_name () == "object"
240  && args(0).class_name () == "meta.package")
241  {
242  cdef_package pack (to_cdef (args(0)));
243 
244  retval(0) = pack.get_classes ();
245  }
246 
247  return retval;
248 }
249 
250 static octave_value_list
251 package_get_functions (const octave_value_list& args, int /* nargout */)
252 {
253  octave_value_list retval (1, Matrix ());
254 
255  if (args.length () == 0 && args(0).type_name () == "object"
256  && args(0).class_name () == "meta.package")
257  {
258  cdef_package pack (to_cdef (args(0)));
259 
260  retval(0) = pack.get_functions ();
261  }
262 
263  return retval;
264 }
265 
266 static octave_value_list
267 package_get_packages (const octave_value_list& args, int /* nargout */)
268 {
269  octave_value_list retval (1, Matrix ());
270 
271  if (args.length () == 0 && args(0).type_name () == "object"
272  && args(0).class_name () == "meta.package")
273  {
274  cdef_package pack (to_cdef (args(0)));
275 
276  retval(0) = pack.get_packages ();
277  }
278 
279  return retval;
280 }
281 
282 static octave_value_list
283 package_getAllPackages (interpreter& interp,
284  const octave_value_list& /* args */,
285  int /* nargout */)
286 {
287  std::map<std::string, cdef_package> toplevel_packages;
288 
289  load_path& lp = interp.get_load_path ();
290 
291  std::list<std::string> names = lp.get_all_package_names ();
292 
293  cdef_manager& cdm = interp.get_cdef_manager ();
294 
295  toplevel_packages["meta"] = cdm.find_package ("meta", false, false);
296 
297  for (const auto& nm : names)
298  toplevel_packages[nm] = cdm.find_package (nm, false, true);
299 
300  Cell c (toplevel_packages.size (), 1);
301 
302  int i = 0;
303 
304  for (const auto& nm_pkg : toplevel_packages)
305  c(i++, 0) = to_ov (nm_pkg.second);
306 
307  return octave_value_list (octave_value (c));
308 }
309 
310 static octave_value_list
311 package_fromName (const octave_value_list& args, int /* nargout */)
312 {
313  octave_value_list retval;
314 
315  if (args.length () != 1)
316  error ("fromName: invalid number of parameters");
317 
318  std::string name = args(0).xstring_value ("fromName: PACKAGE_NAME must be a string");
319 
320  retval(0) = to_ov (lookup_package (name, false));
321 
322  return retval;
323 }
324 
326  : m_interpreter (interp), m_all_classes (), m_all_packages (),
327  m_meta_class (), m_meta_property (), m_meta_method (),
328  m_meta_package (), m_meta ()
329 {
330  type_info& ti = m_interpreter.get_type_info ();
331 
333 
334  // bootstrap
335  cdef_class tmp_handle = make_class ("handle");
336 
337  m_meta_class = make_meta_class ("meta.class", tmp_handle);
338 
339  tmp_handle.set_class (m_meta_class);
340  m_meta_class.set_class (m_meta_class);
341 
342  // meta classes
343  m_meta_property = make_meta_class ("meta.property", tmp_handle);
344 
345  m_meta_method = make_meta_class ("meta.method", tmp_handle);
346 
347  m_meta_package = make_meta_class ("meta.package", tmp_handle);
348 
349  cdef_class tmp_meta_event
350  = make_meta_class ("meta.event", tmp_handle);
351 
352  cdef_class tmp_meta_dynproperty
353  = make_meta_class ("meta.dynamicproperty", tmp_handle);
354 
355  // meta.class properties
356  m_meta_class.install_property
357  (make_attribute (m_meta_class, "Abstract"));
358 
359  m_meta_class.install_property
360  (make_attribute (m_meta_class, "ConstructOnLoad"));
361 
362  m_meta_class.install_property
363  (make_property (m_meta_class, "ContainingPackage"));
364 
365  m_meta_class.install_property
366  (make_property (m_meta_class, "Description"));
367 
368  m_meta_class.install_property
369  (make_property (m_meta_class, "DetailedDescription"));
370 
371  m_meta_class.install_property
372  (make_property (m_meta_class, "Events"));
373 
374  m_meta_class.install_property
375  (make_attribute (m_meta_class, "HandleCompatible"));
376 
377  m_meta_class.install_property
378  (make_attribute (m_meta_class, "Hidden"));
379 
380  m_meta_class.install_property
381  (make_property (m_meta_class, "InferiorClasses",
382  make_fcn_handle (class_get_inferiorclasses,
383  "meta.class>get.InferiorClasses"),
384  "public", Matrix (), "private"));
385 
386  m_meta_class.install_property
387  (make_property (m_meta_class, "Methods",
388  make_fcn_handle (class_get_methods,
389  "meta.class>get.Methods"),
390  "public", Matrix (), "private"));
391 
392  m_meta_class.install_property
393  (make_property (m_meta_class, "MethodList",
394  make_fcn_handle (class_get_methods,
395  "meta.class>get.MethodList"),
396  "public", Matrix (), "private"));
397 
398  m_meta_class.install_property (make_attribute (m_meta_class, "Name"));
399 
400  m_meta_class.install_property
401  (make_property (m_meta_class, "Properties",
402  make_fcn_handle (class_get_properties,
403  "meta.class>get.Properties"),
404  "public", Matrix (), "private"));
405 
406  m_meta_class.install_property
407  (make_property (m_meta_class, "PropertyList",
408  make_fcn_handle (class_get_properties,
409  "meta.class>get.PropertyList"),
410  "public", Matrix (), "private"));
411 
412  m_meta_class.install_property (make_attribute (m_meta_class, "Sealed"));
413 
414  m_meta_class.install_property
415  (make_property (m_meta_class, "SuperClasses",
416  make_fcn_handle (class_get_superclasses,
417  "meta.class>get.SuperClasses"),
418  "public", Matrix (), "private"));
419 
420  m_meta_class.install_property
421  (make_property (m_meta_class, "SuperclassList",
422  make_fcn_handle (class_get_superclasses,
423  "meta.class>get.SuperclassList"),
424  "public", Matrix (), "private"));
425 
426  // FIXME: Matlab supports this property under "SuperclassList".
427  // Octave, however, has supported this under "SuperClassList".
428  // Alias the property. Remove in Octave version 8.1.
429  m_meta_class.install_property
430  (make_property (m_meta_class, "SuperClassList",
431  make_fcn_handle (class_get_superclasses,
432  "meta.class>get.SuperclassList"),
433  "public", Matrix (), "private"));
434 
435  // meta.class methods
436  m_meta_class.install_method
437  (make_method (m_meta_class, "fromName", class_fromName, "public", true));
438 
439  m_meta_class.install_method
440  (make_method (m_meta_class, "fevalStatic", class_fevalStatic, "public",
441  false));
442 
443  m_meta_class.install_method
444  (make_method (m_meta_class, "getConstant", class_getConstant, "public",
445  false));
446 
447  m_meta_class.install_method (make_method (m_meta_class, "eq", class_eq));
448  m_meta_class.install_method (make_method (m_meta_class, "ne", class_ne));
449  m_meta_class.install_method (make_method (m_meta_class, "lt", class_lt));
450  m_meta_class.install_method (make_method (m_meta_class, "le", class_le));
451  m_meta_class.install_method (make_method (m_meta_class, "gt", class_gt));
452  m_meta_class.install_method (make_method (m_meta_class, "ge", class_ge));
453 
454  // meta.method properties
455  m_meta_method.install_property
456  (make_attribute (m_meta_method, "Abstract"));
457 
458  m_meta_method.install_property
459  (make_attribute (m_meta_method, "Access"));
460 
461  m_meta_method.install_property
462  (make_attribute (m_meta_method, "DefiningClass"));
463 
464  m_meta_method.install_property
465  (make_attribute (m_meta_method, "Description"));
466 
467  m_meta_method.install_property
468  (make_attribute (m_meta_method, "DetailedDescription"));
469 
470  m_meta_method.install_property
471  (make_attribute (m_meta_method, "Hidden"));
472 
473  m_meta_method.install_property
474  (make_attribute (m_meta_method, "Name"));
475 
476  m_meta_method.install_property
477  (make_attribute (m_meta_method, "Sealed"));
478 
479  m_meta_method.install_property
480  (make_attribute (m_meta_method, "Static"));
481 
482  // meta.property properties
483  m_meta_property.install_property
484  (make_attribute (m_meta_property, "Name"));
485 
486  m_meta_property.install_property
487  (make_attribute (m_meta_property, "Description"));
488 
489  m_meta_property.install_property
490  (make_attribute (m_meta_property, "DetailedDescription"));
491 
492  m_meta_property.install_property
493  (make_attribute (m_meta_property, "Abstract"));
494 
495  m_meta_property.install_property
496  (make_attribute (m_meta_property, "Constant"));
497 
498  m_meta_property.install_property
499  (make_attribute (m_meta_property, "GetAccess"));
500 
501  m_meta_property.install_property
502  (make_attribute (m_meta_property, "SetAccess"));
503 
504  m_meta_property.install_property
505  (make_attribute (m_meta_property, "Dependent"));
506 
507  m_meta_property.install_property
508  (make_attribute (m_meta_property, "Transient"));
509 
510  m_meta_property.install_property
511  (make_attribute (m_meta_property, "Hidden"));
512 
513  m_meta_property.install_property
514  (make_attribute (m_meta_property, "GetObservable"));
515 
516  m_meta_property.install_property
517  (make_attribute (m_meta_property, "SetObservable"));
518 
519  m_meta_property.install_property
520  (make_attribute (m_meta_property, "GetMethod"));
521 
522  m_meta_property.install_property
523  (make_attribute (m_meta_property, "SetMethod"));
524 
525  m_meta_property.install_property
526  (make_attribute (m_meta_property, "DefiningClass"));
527 
528  m_meta_property.install_property
529  (make_property (m_meta_property, "DefaultValue",
530  make_fcn_handle (property_get_defaultvalue,
531  "meta.property>get.DefaultValue"),
532  "public", Matrix (), "private"));
533 
534  m_meta_property.install_property
535  (make_attribute (m_meta_property, "HasDefault"));
536 
537  // meta.property events
538  // FIXME: add events
539 
540  // handle methods
541 
542  tmp_handle.install_method
543  (make_method (tmp_handle, "delete", handle_delete));
544 
545  // meta.package properties
546 
547  m_meta_package.install_property
548  (make_attribute (m_meta_package, "Name"));
549 
550  m_meta_package.install_property
551  (make_property (m_meta_package, "ContainingPackage"));
552 
553  m_meta_package.install_property
554  (make_property (m_meta_package, "ClassList",
555  make_fcn_handle (package_get_classes,
556  "meta.package>get.ClassList"),
557  "public", Matrix (), "private"));
558 
559  m_meta_package.install_property
560  (make_property (m_meta_package, "Classes",
561  make_fcn_handle (package_get_classes,
562  "meta.package>get.Classes"),
563  "public", Matrix (), "private"));
564 
565  m_meta_package.install_property
566  (make_property (m_meta_package, "FunctionList",
567  make_fcn_handle (package_get_functions,
568  "meta.package>get.FunctionList"),
569  "public", Matrix (), "private"));
570 
571  m_meta_package.install_property
572  (make_property (m_meta_package, "Functions",
573  make_fcn_handle (package_get_functions,
574  "meta.package>get.Functions"),
575  "public", Matrix (), "private"));
576 
577  m_meta_package.install_property
578  (make_property (m_meta_package, "PackageList",
579  make_fcn_handle (package_get_packages,
580  "meta.package>get.PackageList"),
581  "public", Matrix (), "private"));
582 
583  m_meta_package.install_property
584  (make_property (m_meta_package, "Packages",
585  make_fcn_handle (package_get_packages,
586  "meta.package>get.Packages"),
587  "public", Matrix (), "private"));
588 
589  m_meta_package.install_method
590  (make_method (m_meta_package, "fromName", package_fromName,
591  "public", true));
592 
593  m_meta_package.install_method
594  (make_method (m_meta_package, "getAllPackages", package_getAllPackages,
595  "public", true));
596 
597  // create "meta" package
598  cdef_package package_meta
599  = m_meta
600  = make_package ("meta");
601 
602  package_meta.install_class (m_meta_class, "class");
603  package_meta.install_class (m_meta_property, "property");
604  package_meta.install_class (m_meta_method, "method");
605  package_meta.install_class (m_meta_package, "package");
606  package_meta.install_class (tmp_meta_event, "event");
607  package_meta.install_class (tmp_meta_dynproperty, "dynproperty");
608 
609  symbol_table& symtab = m_interpreter.get_symbol_table ();
610 
611  // install built-in classes into the symbol table
613  ("meta.class", m_meta_class.get_constructor_function ());
614 
616  ("meta.method", m_meta_method.get_constructor_function ());
617 
619  ("meta.property", m_meta_property.get_constructor_function ());
620 
622  ("meta.package", m_meta_package.get_constructor_function ());
623 
624  // FIXME: meta.event and meta.dynproperty are not implemented
625  // and should not be installed into symbol table.
626 
627  // symtab.install_built_in_function
628  // ("meta.event", tmp_meta_event.get_constructor_function ());
629 
630  // symtab.install_built_in_function
631  // ("meta.dynproperty", tmp_meta_dynproperty.get_constructor_function ());
632 }
633 
635 cdef_manager::find_class (const std::string& name, bool error_if_not_found,
636  bool load_if_not_found)
637 {
638  auto it = m_all_classes.find (name);
639 
640  if (it == m_all_classes.end ())
641  {
642  if (load_if_not_found)
643  {
644  octave_value ov_cls;
645 
646  std::size_t pos = name.rfind ('.');
647 
648  if (pos == std::string::npos)
649  ov_cls = m_interpreter.find (name);
650  else
651  {
652  std::string pack_name = name.substr (0, pos);
653 
654  cdef_package pack = find_package (pack_name, false, true);
655 
656  if (pack.ok ())
657  ov_cls = pack.find (name.substr (pos+1));
658  }
659 
660  if (ov_cls.is_defined ())
661  it = m_all_classes.find (name);
662  }
663  }
664 
665  if (it == m_all_classes.end ())
666  {
667  if (error_if_not_found)
668  error ("class not found: %s", name.c_str ());
669  }
670  else
671  {
672  cdef_class cls = it->second;
673 
674  if (! cls.is_builtin ())
675  cls = lookup_class (cls);
676 
677  if (cls.ok ())
678  return cls;
679  else
680  m_all_classes.erase (it);
681  }
682 
683  return cdef_class ();
684 }
685 
687 cdef_manager::find_method_symbol (const std::string& method_name,
688  const std::string& class_name)
689 {
690  cdef_class cls = find_class (class_name, false, false);
691 
692  if (cls.ok ())
693  {
694  cdef_method meth = cls.find_method (method_name);
695 
696  if (meth.ok ())
697  return octave_value (new octave_classdef_meta (meth));
698  }
699 
700  return octave_value ();
701 }
702 
704 cdef_manager::find_package (const std::string& name, bool error_if_not_found,
705  bool load_if_not_found)
706 {
707  cdef_package retval;
708 
709  std::map<std::string, cdef_package>::const_iterator it
710  = m_all_packages.find (name);
711 
712  if (it != m_all_packages.end ())
713  {
714  retval = it->second;
715 
716  if (! retval.ok ())
717  error ("invalid package '%s'", name.c_str ());
718  }
719  else
720  {
721  load_path& lp = m_interpreter.get_load_path ();
722 
723  if (load_if_not_found && lp.find_package (name))
724  {
725  std::size_t pos = name.rfind ('.');
726 
727  if (pos == std::string::npos)
728  retval = make_package (name, "");
729  else
730  {
731  std::string parent_name = name.substr (0, pos);
732 
733  retval = make_package (name, parent_name);
734  }
735  }
736  else if (error_if_not_found)
737  error ("unknown package '%s'", name.c_str ());
738  }
739 
740  return retval;
741 }
742 
744 cdef_manager::find_package_symbol (const std::string& pack_name)
745 {
746  cdef_package pack = find_package (pack_name, false);
747 
748  if (pack.ok ())
749  return octave_value (new octave_classdef_meta (pack));
750 
751  return octave_value ();
752 }
753 
755 cdef_manager::make_class (const std::string& name,
756  const std::list<cdef_class>& super_list)
757 {
758  cdef_class cls (name, super_list);
759 
760  cls.set_class (meta_class ());
761 
762  cls.put ("Abstract", false);
763  cls.put ("ConstructOnLoad", false);
764  cls.put ("ContainingPackage", Matrix ());
765  cls.put ("Description", "");
766  cls.put ("DetailedDescription", "");
767  cls.put ("Events", Cell ());
768  cls.put ("Hidden", false);
769  cls.put ("InferiorClasses", Cell ());
770  cls.put ("Methods", Cell ());
771  cls.put ("Properties", Cell ());
772  cls.put ("Sealed", false);
773 
774  if (name == "handle")
775  {
776  cls.put ("HandleCompatible", true);
777  cls.mark_as_handle_class ();
778  }
779  else if (super_list.empty ())
780  {
781  cls.put ("HandleCompatible", false);
782  }
783  else
784  {
785  bool all_handle_compatible = true;
786  bool has_handle_class = false;
787 
788  for (const auto& cl : super_list)
789  {
790  all_handle_compatible = all_handle_compatible
791  && cl.get ("HandleCompatible").bool_value ();
792 
793  has_handle_class = has_handle_class || cl.is_handle_class ();
794  }
795 
796  if (has_handle_class && ! all_handle_compatible)
797  error ("%s: cannot mix handle and non-HandleCompatible classes",
798  name.c_str ());
799 
800  cls.put ("HandleCompatible", all_handle_compatible);
801  if (has_handle_class)
802  cls.mark_as_handle_class ();
803  }
804 
805  if (! name.empty ())
806  register_class (cls);
807 
808  return cls;
809 }
810 
812 cdef_manager::make_class (const std::string& name,
813  const cdef_class& super)
814 {
815  return make_class (name, std::list<cdef_class> (1, super));
816 }
817 
819 cdef_manager::make_meta_class (const std::string& name,
820  const cdef_class& super)
821 {
822  cdef_class cls = make_class (name, super);
823 
824  cls.put ("Sealed", true);
825  cls.mark_as_meta_class ();
826 
827  return cls;
828 }
829 
831 cdef_manager::make_property (const cdef_class& cls, const std::string& name,
832  const octave_value& get_method,
833  const std::string& get_access,
834  const octave_value& set_method,
835  const std::string& set_access)
836 {
837  cdef_property prop (name);
838 
839  prop.set_class (meta_property ());
840 
841  prop.put ("Description", "");
842  prop.put ("DetailedDescription", "");
843  prop.put ("Abstract", false);
844  prop.put ("Constant", false);
845  prop.put ("GetAccess", get_access);
846  prop.put ("SetAccess", set_access);
847  prop.put ("Dependent", false);
848  prop.put ("Transient", false);
849  prop.put ("Hidden", false);
850  prop.put ("GetObservable", false);
851  prop.put ("SetObservable", false);
852  prop.put ("GetMethod", get_method);
853  prop.put ("SetMethod", set_method);
854  prop.put ("DefiningClass", to_ov (cls));
855  prop.put ("DefaultValue", octave_value ());
856  prop.put ("HasDefault", false);
857 
858  std::string class_name = cls.get_name ();
859 
860  if (! get_method.isempty ())
861  make_function_of_class (class_name, get_method);
862  if (! set_method.isempty ())
863  make_function_of_class (class_name, set_method);
864 
865  return prop;
866 }
867 
869 cdef_manager::make_attribute (const cdef_class& cls, const std::string& name)
870 {
871  return make_property (cls, name, Matrix (), "public", Matrix (), "private");
872 }
873 
875 cdef_manager::make_method (const cdef_class& cls, const std::string& name,
876  const octave_value& fcn,
877  const std::string& m_access, bool is_static)
878 {
879  cdef_method meth (name);
880 
881  meth.set_class (meta_method ());
882 
883  meth.put ("Abstract", false);
884  meth.put ("Access", m_access);
885  meth.put ("DefiningClass", to_ov (cls));
886  meth.put ("Description", "");
887  meth.put ("DetailedDescription", "");
888  meth.put ("Hidden", false);
889  meth.put ("Sealed", true);
890  meth.put ("Static", is_static);
891 
892  if (fcn.is_defined ())
893  make_function_of_class (cls, fcn);
894 
895  meth.set_function (fcn);
896 
897  if (is_dummy_method (fcn))
898  meth.mark_as_external (cls.get_name ());
899 
900  return meth;
901 }
902 
904 cdef_manager::make_method (const cdef_class& cls, const std::string& name,
906  const std::string& m_access, bool is_static)
907 {
908  octave_value fcn (new octave_builtin (ff, name));
909 
910  return make_method (cls, name, fcn, m_access, is_static);
911 }
912 
914 cdef_manager::make_method (const cdef_class& cls, const std::string& name,
916  const std::string& m_access, bool is_static)
917 {
918  octave_value fcn (new octave_builtin (mm, name));
919 
920  return make_method (cls, name, fcn, m_access, is_static);
921 }
922 
924 cdef_manager::make_package (const std::string& nm, const std::string& parent)
925 {
926  cdef_package pack (nm);
927 
928  pack.set_class (meta_package ());
929 
930  if (parent.empty ())
931  pack.put ("ContainingPackage", Matrix ());
932  else
933  pack.put ("ContainingPackage", to_ov (find_package (parent)));
934 
935  if (! nm.empty ())
936  register_package (pack);
937 
938  return pack;
939 }
940 
942 cdef_manager::find_method (const std::string& class_name,
943  const std::string& name) const
944 {
945  cdef_class cls = lookup_class (class_name);
946 
947  return cls.get_method (name);
948 }
949 
950 OCTAVE_END_NAMESPACE(octave)
#define META_CLASS_CMP(OP, CLSA, CLSB, FCN)
bool is_superclass(const cdef_class &clsa, const cdef_class &clsb, bool allow_equal, int max_depth)
Definition: cdef-utils.cc:200
bool is_strict_superclass(const cdef_class &clsa, const cdef_class &clsb)
Definition: cdef-utils.cc:226
bool is_dummy_method(const octave_value &fcn)
Definition: cdef-utils.cc:179
cdef_object to_cdef(const octave_value &val)
Definition: cdef-utils.cc:143
std::list< cdef_class > lookup_classes(const Cell &cls_list)
Definition: cdef-utils.cc:113
cdef_class lookup_class(const std::string &name, bool error_if_not_found, bool load_if_not_found)
Definition: cdef-utils.cc:80
octave_value to_ov(const cdef_object &obj)
Definition: cdef-utils.cc:128
cdef_package lookup_package(const std::string &name, bool error_if_not_found, bool load_if_not_found)
Definition: cdef-utils.cc:238
void make_function_of_class(const std::string &class_name, const octave_value &fcn)
Definition: cdef-utils.cc:55
Definition: Cell.h:43
Definition: dMatrix.h:42
cdef_method find_method(const std::string &nm, bool local=false)
Definition: cdef-class.h:457
void mark_as_meta_class()
Definition: cdef-class.h:398
void install_property(const cdef_property &prop)
Definition: cdef-class.h:286
void mark_as_handle_class()
Definition: cdef-class.h:388
void install_method(const cdef_method &meth)
Definition: cdef-class.h:268
octave_value get_method(const std::string &nm) const
Definition: cdef-class.h:351
bool is_builtin() const
Definition: cdef-class.h:320
octave_value get_constructor_function()
Definition: cdef-class.h:363
std::string get_name() const
Definition: cdef-class.h:318
cdef_property find_property(const std::string &nm)
Definition: cdef-class.h:463
const cdef_class & meta_method() const
Definition: cdef-manager.h:91
cdef_class make_class(const std::string &name, const std::list< cdef_class > &super_list=std::list< cdef_class >())
cdef_property make_property(const cdef_class &cls, const std::string &name, const octave_value &get_method=Matrix(), const std::string &get_access="public", const octave_value &set_method=Matrix(), const std::string &set_access="public")
const cdef_class & meta_property() const
Definition: cdef-manager.h:90
octave_value find_method(const std::string &class_name, const std::string &name) const
cdef_package make_package(const std::string &nm, const std::string &parent="")
octave_value find_method_symbol(const std::string &method_name, const std::string &class_name)
cdef_package find_package(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
octave_value find_package_symbol(const std::string &pack_name)
void register_package(const cdef_package &pkg)
Definition: cdef-manager.h:79
const cdef_class & meta_class() const
Definition: cdef-manager.h:89
cdef_class find_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
cdef_manager(interpreter &interp)
void register_class(const cdef_class &cls)
Definition: cdef-manager.h:69
cdef_class make_meta_class(const std::string &name, const cdef_class &super)
cdef_method make_method(const cdef_class &cls, const std::string &name, const octave_value &fcn, const std::string &m_access="public", bool is_static=false)
const cdef_class & meta_package() const
Definition: cdef-manager.h:92
cdef_property make_attribute(const cdef_class &cls, const std::string &name)
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.h:164
bool is_static() const
Definition: cdef-method.h:184
void set_function(const octave_value &fcn)
Definition: cdef-method.h:186
void mark_as_external(const std::string &dtype)
Definition: cdef-method.h:213
void put(const std::string &pname, const octave_value &val)
Definition: cdef-object.h:263
bool ok() const
Definition: cdef-object.h:312
void set_class(const cdef_class &cls)
Definition: cdef-object.h:232
octave_value get(const std::string &pname) const
Definition: cdef-object.h:268
void install_class(const cdef_class &cls, const std::string &nm)
Definition: cdef-package.h:181
octave_value find(const std::string &nm)
Definition: cdef-package.h:213
std::string get_name() const
bool is_constant() const
octave_value get_value(const cdef_object &obj, bool do_check_access=true, const std::string &who="") const
octave_value find(const std::string &name)
cdef_manager & get_cdef_manager()
Definition: interpreter.h:318
type_info & get_type_info()
Definition: interpreter.h:293
symbol_table & get_symbol_table()
Definition: interpreter.h:298
load_path & get_load_path()
Definition: interpreter.h:283
bool find_package(const std::string &package_name) const
Definition: load-path.h:101
std::list< std::string > get_all_package_names(bool only_top_level=true) const
Definition: load-path.cc:561
static void register_type()
Definition: ov-base.cc:101
octave_value_list(* fcn)(const octave_value_list &, int)
Definition: ov-builtin.h:63
octave_value_list(* meth)(octave::interpreter &, const octave_value_list &, int)
Definition: ov-builtin.h:60
octave_value_list splice(octave_idx_type offset, octave_idx_type len, const octave_value_list &lst=octave_value_list()) const
Definition: ovl.cc:139
octave_idx_type length() const
Definition: ovl.h:113
bool is_defined() const
Definition: ov.h:592
bool isempty() const
Definition: ov.h:601
void install_built_in_function(const std::string &name, const octave_value &fcn)
Definition: symtab.cc:411
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1033
void() error(const char *fmt,...)
Definition: error.cc:988
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))