GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
cdef-method.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2021 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 <algorithm>
31 #include <iomanip>
32 
33 #include "cdef-class.h"
34 #include "cdef-manager.h"
35 #include "cdef-utils.h"
36 #include "errwarn.h"
37 #include "interpreter-private.h"
38 #include "interpreter.h"
39 #include "load-path.h"
40 #include "ov-builtin.h"
41 #include "ov-classdef.h"
42 #include "ov-fcn-handle.h"
43 #include "ov-usr-fcn.h"
44 #include "parse.h"
45 #include "pt-assign.h"
46 #include "pt-classdef.h"
47 #include "pt-idx.h"
48 #include "pt-misc.h"
49 #include "pt-stmt.h"
50 #include "pt-walk.h"
51 
52 namespace octave
53 {
54  OCTAVE_NORETURN static
55  void
56  err_method_access (const std::string& from, const cdef_method& meth)
57  {
58  octave_value acc = meth.get ("Access");
59  std::string acc_s;
60 
61  if (acc.is_string ())
62  acc_s = acc.string_value ();
63  else
64  acc_s = "class-restricted";
65 
66  error ("%s: method '%s' has %s access and cannot be run in this context",
67  from.c_str (), meth.get_name ().c_str (), acc_s.c_str ());
68  }
69 
70  void
72  {
73  if (is_external ())
74  {
75  if (is_dummy_method (function))
76  {
77  load_path& lp
78  = __get_load_path__ ("cdef_method::cdef_method_rep::check_method");
79 
80  std::string name = get_name ();
81  std::string cls_name = dispatch_type;
82  std::string pack_name;
83 
84  size_t pos = cls_name.rfind ('.');
85 
86  if (pos != std::string::npos)
87  {
88  pack_name = cls_name.substr (0, pos);
89  cls_name = cls_name.substr (pos + 1);
90  }
91 
92  std::string dir_name;
93  std::string file_name = lp.find_method (cls_name, name,
94  dir_name, pack_name);
95 
96  if (! file_name.empty ())
97  {
98  octave_value ov_fcn
99  = load_fcn_from_file (file_name, dir_name,
100  dispatch_type, pack_name);
101 
102  if (ov_fcn.is_defined ())
103  {
104  function = ov_fcn;
105 
107  }
108  }
109  }
110  else
111  {
112  // FIXME: check out-of-date status
113  }
114 
115  if (is_dummy_method (function))
116  error ("no definition found for method '%s' of class '%s'",
117  get_name ().c_str (), dispatch_type.c_str ());
118  }
119  }
120 
123  int nargout, bool do_check_access,
124  const std::string& who)
125  {
127 
128  if (do_check_access && ! check_access ())
129  err_method_access (who, wrap ());
130 
131  if (get ("Abstract").bool_value ())
132  error ("%s: cannot execute abstract method",
133  get ("Name").string_value ().c_str ());
134 
135  check_method ();
136 
137  if (function.is_defined ())
138  retval = feval (function, args, nargout);
139 
140  return retval;
141  }
142 
145  const octave_value_list& args,
146  int nargout, bool do_check_access,
147  const std::string& who)
148  {
150 
151  if (do_check_access && ! check_access ())
152  err_method_access (who, wrap ());
153 
154  if (get ("Abstract").bool_value ())
155  error ("%s: cannot execute abstract method",
156  get ("Name").string_value ().c_str ());
157 
158  check_method ();
159 
160  if (function.is_defined ())
161  {
162  octave_value_list new_args;
163 
164  new_args.resize (args.length () + 1);
165 
166  new_args(0) = to_ov (obj);
167  for (int i = 0; i < args.length (); i++)
168  new_args(i+1) = args(i);
169 
170  retval = feval (function, new_args, nargout);
171  }
172 
173  return retval;
174  }
175 
176  bool
178  {
179  if (function.is_function())
180  return function.function_value ()->is_classdef_constructor ();
181 
182  return false;
183  }
184 
185  bool
186  cdef_method::cdef_method_rep::is_defined_in_class (const std::string &cname) const
187  {
188  return (function.is_function ()
189  ? function.function_value ()->dispatch_class () == cname
190  : false);
191  }
192 
193  std::string
195  {
196  check_method ();
197 
198  octave_function *fcn = function.function_value ();
199 
200  return fcn ? fcn->doc_string () : "";
201  }
202 
203  bool
205  {
206  cdef_class cls (to_cdef (get ("DefiningClass")));
207 
208  return octave::check_access (cls, get ("Access"), get_name ());
209  }
210 
213  (const std::string& type, const std::list<octave_value_list>& idx,
214  int nargout)
215  {
217 
218  switch (type[0])
219  {
220  case '(':
221  retval = (execute (idx.front (), type.length () > 1 ? 1 : nargout, true));
222  break;
223 
224  default:
225  error ("invalid meta.method indexing");
226  break;
227  }
228 
229  if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
230  retval = retval(0).next_subsref (nargout, type, idx, 1);
231 
232  return retval;
233  }
234 }
std::string get_name(void) const
Definition: cdef-method.h:66
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.cc:122
bool is_defined_in_class(const std::string &cname) const
Definition: cdef-method.cc:186
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
Definition: cdef-method.cc:213
bool check_access(void) const
Definition: cdef-method.h:179
std::string get_name(void) const
Definition: cdef-method.h:181
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.h:163
octave_value get(const std::string &pname) const
Definition: cdef-object.h:261
std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, const std::string &pack_name="")
Definition: load-path.h:79
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:873
virtual std::string doc_string(const std::string &="") const
Definition: ov-fcn.h:227
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
octave_idx_type length(void) const
Definition: ovl.h:113
bool is_string(void) const
Definition: ov.h:593
bool is_defined(void) const
Definition: ov.h:551
std::string string_value(bool force=false) const
Definition: ov.h:927
void error(const char *fmt,...)
Definition: error.cc:968
QString name
octave_value load_fcn_from_file(const std::string &file_name, const std::string &dir_name, const std::string &dispatch_type, const std::string &package_name, const std::string &fcn_name, bool autoload)
Definition: oct-parse.cc:9321
void make_function_of_class(const std::string &class_name, const octave_value &fcn)
Definition: cdef-utils.cc:55
bool is_dummy_method(const octave_value &fcn)
Definition: cdef-utils.cc:179
octave_value to_ov(const cdef_object &obj)
Definition: cdef-utils.cc:128
cdef_object to_cdef(const octave_value &val)
Definition: cdef-utils.cc:143
bool check_access(const cdef_class &cls, const octave_value &acc, const std::string &meth_name, const std::string &prop_name, bool is_prop_set)
Definition: cdef-utils.cc:294
static OCTAVE_NORETURN void err_method_access(const std::string &from, const cdef_method &meth)
Definition: cdef-method.cc:56
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:9580
load_path & __get_load_path__(const std::string &who)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811