Qore Programming Language  0.9.4.6
QoreNamespaceIntern.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreNamespaceIntern.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2020 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_QORENAMESPACEINTERN_H
33 #define _QORE_QORENAMESPACEINTERN_H
34 
35 #include "qore/intern/QoreClassList.h"
36 #include "qore/intern/HashDeclList.h"
37 #include "qore/intern/QoreNamespaceList.h"
38 #include "qore/intern/ConstantList.h"
39 #include "qore/intern/FunctionList.h"
40 #include "qore/intern/GlobalVariableList.h"
41 #include "qore/intern/typed_hash_decl_private.h"
42 #include "qore/vector_map"
43 
44 #include <map>
45 #include <vector>
46 #include <list>
47 
48 class qore_root_ns_private;
49 class qore_ns_private;
50 
51 typedef std::list<const qore_ns_private*> nslist_t;
52 
53 class qore_ns_private {
54 private:
55  // not implemented
56  DLLLOCAL qore_ns_private(const qore_ns_private&) = delete;
57  // not implemented
58  DLLLOCAL qore_ns_private& operator=(const qore_ns_private&) = delete;
59 
60 protected:
61  // called from the root namespace constructor only
62  DLLLOCAL qore_ns_private(QoreNamespace* n_ns) : constant(this), depth(0), root(true), pub(true), builtin(true), parent(0), class_handler(0), ns(n_ns) {
63  }
64 
65 public:
66  const QoreProgramLocation* loc;
67  std::string name;
68 
69  QoreClassList classList; // class map
70  HashDeclList hashDeclList; // hashdecl map
71  ConstantList constant; // constant map
72  QoreNamespaceList nsl; // namespace map
73  FunctionList func_list; // function map
74  GlobalVariableList var_list; // global variable map
75  gvblist_t pend_gvblist; // global variable declaration list
76 
77  // 0 = root namespace, ...
78  unsigned depth = 0;
79 
80  bool root = false, // is this the root namespace?
81  pub, // is this namespace public (inherited by child programs or programs importing user modules)
82  builtin, // is this namespace builtin?
83  imported = false; // was this namespace imported?
84 
85  const qore_ns_private* parent = nullptr; // pointer to parent namespace (0 if this is the root namespace or an unattached namespace)
86  q_ns_class_handler_t class_handler = nullptr;
87  QoreNamespace* ns;
88 
89  // used with builtin namespaces
90  DLLLOCAL qore_ns_private(QoreNamespace* n_ns, const char* n) : name(n), constant(this), pub(true), builtin(true), ns(n_ns) {
91  }
92 
93  // called when assimilating
94  DLLLOCAL qore_ns_private(const char* n, bool pub) : name(n), constant(this), pub(pub), builtin(false), ns(new QoreNamespace(this)) {
95  }
96 
97  // called when parsing
98  DLLLOCAL qore_ns_private(const QoreProgramLocation* loc);
99 
100  DLLLOCAL qore_ns_private(const qore_ns_private& old, int64 po)
101  : name(old.name),
102  classList(old.classList, po, this),
103  hashDeclList(old.hashDeclList, po, this),
104  constant(old.constant, po, this),
105  nsl(old.nsl, po, *this),
106  func_list(old.func_list, this, po),
107  var_list(old.var_list, po),
108  depth(old.depth),
109  root(old.root),
110  pub(old.builtin ? true : false),
111  builtin(old.builtin),
112  imported(old.imported),
113  parent(nullptr), class_handler(old.class_handler), ns(nullptr) {
114  }
115 
116  DLLLOCAL ~qore_ns_private() {
117  }
118 
119  DLLLOCAL void getPath(std::string& str, bool anchored = false) const {
120  const qore_ns_private* w = parent;
121  while (w && (anchored || w->parent)) {
122  //printd(5, "qore_ns_private::getPath() this: %p name: '%s' parent: %p root: %d\n", w, w->name.c_str(), parent, root);
123  str.insert(0, "::");
124  str.insert(0, w->name);
125  w = w->parent;
126  }
127 
128  // append this namespace's name
129  str += name;
130  }
131 
132  DLLLOCAL void getNsList(nslist_t& nsl) const {
133  //printd(5, "qore_ns_private::getNsList() this: %p '%s::' root: %d\n", this, name.c_str(), root);
134  if (root)
135  return;
136 
137  const qore_ns_private* w = this;
138  while (w && w->parent) {
139  nsl.push_front(w);
140  w = w->parent;
141  }
142  }
143 
144  DLLLOCAL static QoreNamespace* newNamespace(const qore_ns_private& old, int64 po) {
145  qore_ns_private* p = new qore_ns_private(old, po);
146  return new QoreNamespace(p);
147  }
148 
149  // destroys the object and frees all associated memory
150  DLLLOCAL void purge() {
151  constant.reset();
152 
153  classList.reset();
154 
155  hashDeclList.reset();
156 
157  nsl.reset();
158  }
159 
160  DLLLOCAL qore_root_ns_private* getRoot() {
161  qore_ns_private* w = this;
162  while (w->parent)
163  w = (qore_ns_private*)w->parent;
164 
165  return w->root ? reinterpret_cast<qore_root_ns_private*>(w) : 0;
166  }
167 
168  DLLLOCAL void setClassHandler(q_ns_class_handler_t n_class_handler);
169 
170  // finds a local class in the committed class list, if not found executes the class handler
171  DLLLOCAL QoreClass* findLoadClass(const char* cname) {
172  //printd(5, "qore_ns_private::findLoadClass('%s') this: %p ('%s') class_handler: %p found: %d\n", cname, this, name.c_str(), class_handler, classList.find(cname));
173  QoreClass* qc = classList.find(cname);
174  if (!qc && class_handler)
175  qc = class_handler(ns, cname);
176  return qc;
177  }
178 
179  DLLLOCAL void getGlobalVars(QoreHashNode& h) const {
180  std::string path;
181  getPath(path);
182  var_list.getGlobalVars(path, h);
183  nsl.getGlobalVars(h);
184  }
185 
186  DLLLOCAL void clearConstants(QoreListNode& l);
187  DLLLOCAL void clearData(ExceptionSink* xsink);
188  DLLLOCAL void deleteData(bool deref_vars, ExceptionSink* xsink);
189  //DLLLOCAL void deleteClearData(ExceptionSink* xsink);
190 
191  DLLLOCAL void parseAssimilate(QoreNamespace* ns);
192  DLLLOCAL void runtimeAssimilate(QoreNamespace* ns);
193 
194  DLLLOCAL void updateDepthRecursive(unsigned ndepth);
195 
196  DLLLOCAL int parseAddPendingClass(const QoreProgramLocation* loc, const NamedScope& n, QoreClass* oc);
197  DLLLOCAL int parseAddPendingClass(const QoreProgramLocation* loc, QoreClass* oc);
198 
199  DLLLOCAL int parseAddPendingHashDecl(const QoreProgramLocation* loc, const NamedScope& n, TypedHashDecl* hashdecl);
200  DLLLOCAL int parseAddPendingHashDecl(const QoreProgramLocation* loc, TypedHashDecl* hashdecl);
201 
202  DLLLOCAL bool addGlobalVars(qore_root_ns_private& rns);
203 
204  DLLLOCAL cnemap_t::iterator parseAddConstant(const QoreProgramLocation* loc, const char* name, QoreValue value, bool pub);
205 
206  DLLLOCAL void parseAddConstant(const QoreProgramLocation* loc, const NamedScope& name, QoreValue value, bool pub);
207 
208  DLLLOCAL int parseAddMethodToClass(const QoreProgramLocation* loc, const NamedScope& name, MethodVariantBase* qcmethod, bool static_flag);
209 
210  DLLLOCAL int checkImportFunction(const char* name, ExceptionSink* xsink) {
211  //printd(5, "qore_ns_private::checkImportFunction(%s) this: %p\n", name, this);
212 
213  if (func_list.findNode(name)) {
214  xsink->raiseException("FUNCTION-IMPORT-ERROR", "function '%s' already exists in this namespace", name);
215  return -1;
216  }
217 
218  return 0;
219  }
220 
221  DLLLOCAL FunctionEntry* runtimeImportFunction(ExceptionSink* xsink, QoreFunction* u, const char* new_name = nullptr, bool inject = false) {
222  const char* fn = new_name ? new_name : u->getName();
223  if (checkImportFunction(fn, xsink))
224  return 0;
225 
226  return func_list.import(fn, u, this, inject);
227  }
228 
229  DLLLOCAL int checkImportClass(const char* cname, ExceptionSink* xsink) {
230  //printd(5, "qore_ns_private::checkImportClass(%s) this: %p\n", name, this);
231 
232  if (classList.find(cname)) {
233  xsink->raiseException("CLASS-IMPORT-ERROR", "class '%s' already exists in namespace '%s'", cname, name.c_str());
234  return -1;
235  }
236  if (hashDeclList.find(cname)) {
237  xsink->raiseException("CLASS-IMPORT-ERROR", "hashdecl '%s' already exists in namespace '%s'", cname, name.c_str());
238  return -1;
239  }
240  if (nsl.find(cname)) {
241  xsink->raiseException("CLASS-IMPORT-ERROR", "a subnamespace named '%s' already exists in namespace '%s'", cname, name.c_str());
242  return -1;
243  }
244 
245  return 0;
246  }
247 
248  DLLLOCAL int checkImportHashDecl(const char* hdname, ExceptionSink* xsink) {
249  //printd(5, "qore_ns_private::checkImportHashDecl(%s) this: %p\n", hdname, this);
250 
251  if (hashDeclList.find(hdname)) {
252  xsink->raiseException("HASHDECL-IMPORT-ERROR", "hashdecl '%s' already exists in namespace '%s'", hdname, name.c_str());
253  return -1;
254  }
255  if (classList.find(hdname)) {
256  xsink->raiseException("HASHDECL-IMPORT-ERROR", "class '%s' already exists in namespace '%s'", hdname, name.c_str());
257  return -1;
258  }
259 
260  return 0;
261  }
262 
263  DLLLOCAL QoreClass* runtimeImportClass(ExceptionSink* xsink, const QoreClass* c, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = nullptr, bool inject = false, const qore_class_private* injectedClass = nullptr);
264 
265  DLLLOCAL TypedHashDecl* runtimeImportHashDecl(ExceptionSink* xsink, const TypedHashDecl* hd, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = nullptr);
266 
267  DLLLOCAL const FunctionEntry* runtimeFindFunctionEntry(const char* name) {
268  return func_list.findNode(name, true);
269  }
270 
271  DLLLOCAL const QoreFunction* runtimeFindFunction(const char* name) {
272  return func_list.find(name, true);
273  }
274 
275  DLLLOCAL const QoreFunction* findAnyFunction(const char* name) {
276  return func_list.find(name, false);
277  }
278 
279  DLLLOCAL QoreNamespace* findCreateNamespace(const char* nme, bool user, bool& is_new, qore_root_ns_private* rns);
280  DLLLOCAL QoreNamespace* findCreateNamespacePath(const nslist_t& nsl, bool user, bool& is_new);
281  DLLLOCAL QoreNamespace* findCreateNamespacePath(const NamedScope& nspath, bool pub, bool user, bool& is_new);
282 
283  DLLLOCAL TypedHashDecl* parseFindLocalHashDecl(const char* name) {
284  return hashDeclList.find(name);
285  }
286 
287  DLLLOCAL QoreValue getConstantValue(const char* name, const QoreTypeInfo*& typeInfo, bool& found);
288  DLLLOCAL QoreClass* parseFindLocalClass(const char* name);
289  DLLLOCAL qore_ns_private* parseAddNamespace(QoreNamespace* nns);
290 
291  DLLLOCAL void addModuleNamespace(qore_ns_private* nns, QoreModuleContext& qmc);
292  DLLLOCAL void addCommitNamespaceIntern(qore_ns_private* nns);
293  DLLLOCAL void addNamespace(qore_ns_private* nns);
294 
295  DLLLOCAL void parseInit();
296  DLLLOCAL void parseResolveHierarchy();
297  DLLLOCAL void parseResolveClassMembers();
298  DLLLOCAL void parseResolveAbstract();
299  DLLLOCAL void parseInitConstants();
300  DLLLOCAL void parseRollback(ExceptionSink* xsink);
301  DLLLOCAL void parseCommit();
302  DLLLOCAL void parseCommitRuntimeInit(ExceptionSink* xsink);
303 
304  DLLLOCAL Var* runtimeMatchGlobalVar(const NamedScope& nscope, const qore_ns_private*& rns) const;
305  DLLLOCAL const ConstantEntry* runtimeMatchNamespaceConstant(const NamedScope& nscope, const qore_ns_private*& rns) const;
306  DLLLOCAL const QoreClass* runtimeMatchScopedClassWithMethod(const NamedScope& nscope) const;
307  DLLLOCAL const QoreClass* runtimeMatchClass(const NamedScope& nscope, const qore_ns_private*& rns) const;
308  DLLLOCAL const qore_ns_private* runtimeMatchNamespace(const NamedScope& nscope, int offset = 0) const;
309  DLLLOCAL const qore_ns_private* runtimeMatchAddClass(const NamedScope& nscope, bool& fnd) const;
310 
311  DLLLOCAL const TypedHashDecl* runtimeMatchHashDecl(const NamedScope& nscope, const qore_ns_private*& rns) const;
312 
313  DLLLOCAL const FunctionEntry* runtimeMatchFunctionEntry(const NamedScope& nscope) const;
314  DLLLOCAL const qore_ns_private* runtimeMatchAddFunction(const NamedScope& nscope, bool& fnd) const;
315 
316  //DLLLOCAL const QoreFunction* parseMatchFunction(const NamedScope& nscope, unsigned& match) const;
317 
318  DLLLOCAL const FunctionEntry* parseMatchFunctionEntry(const NamedScope& nscope, unsigned& match) const;
319 
320  DLLLOCAL QoreNamespace* resolveNameScope(const QoreProgramLocation* loc, const NamedScope& name) const;
321  DLLLOCAL QoreNamespace* parseMatchNamespace(const NamedScope& nscope, unsigned& matched) const;
322 
323  DLLLOCAL TypedHashDecl* parseMatchScopedHashDecl(const NamedScope& name, unsigned& matched);
324 
325  DLLLOCAL QoreClass* parseMatchScopedClass(const NamedScope& name, unsigned& matched);
326  DLLLOCAL QoreClass* parseMatchScopedClassWithMethod(const NamedScope& nscope, unsigned& matched);
327 
328  DLLLOCAL QoreValue parseCheckScopedReference(const QoreProgramLocation* loc, const NamedScope& ns, unsigned& m, const QoreTypeInfo*& typeInfo, bool& found, bool abr) const;
329 
330  DLLLOCAL QoreValue parseFindLocalConstantValue(const QoreProgramLocation* loc, const NamedScope& ns, unsigned& m, const QoreTypeInfo*& typeInfo, bool& found, bool abr) const;
331 
332  DLLLOCAL QoreValue parseFindLocalConstantValue(const char* cname, const QoreTypeInfo*& typeInfo, bool& found);
333  DLLLOCAL QoreNamespace* parseFindLocalNamespace(const char* nname);
334 
335  DLLLOCAL QoreValue parseMatchScopedConstantValue(const NamedScope& name, unsigned& matched, const QoreTypeInfo*& typeInfo, bool& found);
336 
337  DLLLOCAL FunctionEntry* addPendingVariantIntern(const char* fname, AbstractQoreFunctionVariant* v, bool& new_func);
338 
339  DLLLOCAL void addBuiltinVariant(const char* name, AbstractQoreFunctionVariant* v);
340  DLLLOCAL void addBuiltinModuleVariant(const char* name, AbstractQoreFunctionVariant* v, QoreModuleContext& qmc);
341  DLLLOCAL void addBuiltinVariantIntern(const char* name, AbstractQoreFunctionVariant* v);
342 
343  template <typename T, class B>
344  DLLLOCAL void addBuiltinVariant(const char* name, T f, int64 flags, int64 functional_domain, const QoreTypeInfo* returnTypeInfo, unsigned num_params, va_list args) {
345  //printd(5, "qore_ns_private::addBuiltinVariant('%s', %p, flags=%lld) BEFORE\n", name, f, flags);
346  type_vec_t typeList;
347  arg_vec_t defaultArgList;
348  name_vec_t nameList;
349  if (num_params)
350  qore_process_params(num_params, typeList, defaultArgList, nameList, args);
351 
352  //printd(5, "qore_ns_private::addBuiltinVariant('%s', %p, flags=%lld, domain=%lld, ret=%s, num_params=%d, ...)\n", name, f, flags, functional_domain, QoreTypeInfo::getName(returnTypeInfo), num_params);
353  addBuiltinVariant(name, new B(f, flags, functional_domain, returnTypeInfo, typeList, defaultArgList, nameList));
354  }
355 
356  DLLLOCAL void scanMergeCommittedNamespace(const qore_ns_private& mns, QoreModuleContext& qmc) const;
357  DLLLOCAL void copyMergeCommittedNamespace(const qore_ns_private& mns);
358 
359  DLLLOCAL void parseInitGlobalVars();
360 
361  DLLLOCAL void checkGlobalVarDecl(Var* v, const NamedScope& vname);
362  DLLLOCAL void parseAddGlobalVarDecl(const QoreProgramLocation* loc, char* name, const QoreTypeInfo* typeInfo, QoreParseTypeInfo* parseTypeInfo, bool pub);
363 
364  DLLLOCAL void setPublic();
365 
366  DLLLOCAL void runtimeImportSystemClasses(const qore_ns_private& source, qore_root_ns_private& rns, ExceptionSink* xsink);
367  DLLLOCAL void runtimeImportSystemHashDecls(const qore_ns_private& source, qore_root_ns_private& rns, ExceptionSink* xsink);
368  DLLLOCAL void runtimeImportSystemConstants(const qore_ns_private& source, qore_root_ns_private& rns, ExceptionSink* xsink);
369  DLLLOCAL void runtimeImportSystemFunctions(const qore_ns_private& source, qore_root_ns_private& rns, ExceptionSink* xsink);
370 
371  DLLLOCAL static void addNamespace(QoreNamespace& ns, QoreNamespace* nns) {
372  ns.priv->addNamespace(nns->priv);
373  }
374 
375  DLLLOCAL static QoreValue parseResolveReferencedClassConstant(const QoreProgramLocation* loc, QoreClass* qc, const char* name, const QoreTypeInfo*& typeInfo, bool& found);
376 
377  DLLLOCAL static ConstantList& getConstantList(const QoreNamespace* ns) {
378  return ns->priv->constant;
379  }
380 
381  DLLLOCAL static const QoreFunction* runtimeFindFunction(QoreNamespace& ns, const char* name) {
382  return ns.priv->runtimeFindFunction(name);
383  }
384 
385  DLLLOCAL static const FunctionEntry* runtimeFindFunctionEntry(QoreNamespace& ns, const char* name) {
386  return ns.priv->runtimeFindFunctionEntry(name);
387  }
388 
389  DLLLOCAL static QoreListNode* getUserFunctionList(QoreNamespace& ns) {
390  return ns.priv->func_list.getList();
391  }
392 
393  DLLLOCAL static void parseAddPendingClass(QoreNamespace& ns, const QoreProgramLocation* loc, const NamedScope& n, QoreClass* oc) {
394  ns.priv->parseAddPendingClass(loc, n, oc);
395  }
396 
397  DLLLOCAL static void parseAddNamespace(QoreNamespace& ns, QoreNamespace* nns) {
398  ns.priv->parseAddNamespace(nns);
399  }
400 
401  DLLLOCAL static void parseAddConstant(QoreNamespace& ns, const QoreProgramLocation* loc, const NamedScope& name, QoreValue value, bool pub) {
402  ns.priv->parseAddConstant(loc, name, value, pub);
403  }
404 
405  DLLLOCAL static void parseCommit(QoreNamespace& ns) {
406  ns.priv->parseCommit();
407  }
408 
409  DLLLOCAL static void purge(QoreNamespace& ns) {
410  ns.priv->purge();
411  }
412 
413  DLLLOCAL static qore_ns_private* get(QoreNamespace& ns) {
414  return ns.priv;
415  }
416 
417  DLLLOCAL static const qore_ns_private* get(const QoreNamespace& ns) {
418  return ns.priv;
419  }
420 
421  DLLLOCAL static bool isPublic(const QoreNamespace& ns) {
422  return ns.priv->pub;
423  }
424 
425  DLLLOCAL static bool isUserPublic(const QoreNamespace& ns) {
426  return ns.priv->pub && !ns.priv->builtin;
427  }
428 };
429 
430 hashdecl namespace_iterator_element {
431  qore_ns_private* ns;
432  nsmap_t::iterator i;
433 
434  DLLLOCAL namespace_iterator_element(qore_ns_private* ns) : ns(ns) {
435  assert(ns);
436 
437  i = ns->nsl.nsmap.begin();
438  }
439 
440  DLLLOCAL bool atEnd() const {
441  return i == ns->nsl.nsmap.end();
442  }
443 
444  DLLLOCAL QoreNamespace* next() {
445  ++i;
446  if (atEnd()) {
447  return nullptr;
448  }
449  return i->second;
450  }
451 };
452 
453 class QorePrivateNamespaceIterator {
454 protected:
455  typedef std::vector<namespace_iterator_element> nsv_t;
456  nsv_t nsv; // stack of namespaces
457  qore_ns_private* root; // for starting over when done
458 
459  DLLLOCAL void set(qore_ns_private* rns) {
460  nsv.push_back(namespace_iterator_element(rns));
461 
462  //printd(5, "QorePrivateNamespaceIterator::set() %p:%s committed: %d\n", rns, rns->name.c_str(), committed);
463  while (!(rns->nsl.empty())) {
464  rns = qore_ns_private::get(*((rns->nsl.nsmap.begin()->second)));
465  //printd(5, "QorePrivateNamespaceIterator::set() -> %p:%s committed: %d\n", rns, rns->name.c_str(), committed);
466  nsv.push_back(namespace_iterator_element(rns));
467  }
468  }
469 
470 public:
471  DLLLOCAL QorePrivateNamespaceIterator(qore_ns_private* rns) : root(rns) {
472  assert(rns);
473  }
474 
475  DLLLOCAL bool next() {
476  // reset when starting over
477  if (nsv.empty()) {
478  set(root);
479  return true;
480  }
481 
482  namespace_iterator_element* nie = &(nsv.back());
483 
484  // if the last element of the current namespace list has been iterated, take it off the stack
485  if (nie->atEnd()) {
486  nsv.pop_back();
487  if (nsv.empty())
488  return false;
489 
490  nie = &(nsv.back());
491  }
492 
493  QoreNamespace* next = nie->next();
494  if (next)
495  set(qore_ns_private::get(*next));
496 
497  return true;
498  }
499 
500  DLLLOCAL qore_ns_private* operator->() {
501  return nsv.back().ns;
502  }
503 
504  DLLLOCAL qore_ns_private* operator*() {
505  return nsv.back().ns;
506  }
507 
508  DLLLOCAL qore_ns_private* get() {
509  return nsv.back().ns;
510  }
511 };
512 
513 hashdecl NSOInfoBase {
514  qore_ns_private* ns = nullptr;
515 
516  DLLLOCAL NSOInfoBase() {
517  }
518 
519  DLLLOCAL NSOInfoBase(qore_ns_private* n_ns) : ns(n_ns) {
520  }
521 
522  DLLLOCAL unsigned depth() const {
523  return ns->depth;
524  }
525 };
526 
527 template <typename T>
528 hashdecl NSOInfo : public NSOInfoBase {
529  // object
530  T* obj = nullptr;
531 
532  DLLLOCAL NSOInfo() {
533  }
534 
535  DLLLOCAL NSOInfo(qore_ns_private* n_ns, T* n_obj) : NSOInfoBase(n_ns), obj(n_obj) {
536  }
537 
538  DLLLOCAL void assign(qore_ns_private* n_ns, T* n_obj) {
539  ns = n_ns;
540  obj = n_obj;
541  }
542 };
543 
544 // cannot use vector_map here for performance reasons
545 template <typename T>
546 class RootMap : public std::map<const std::string, NSOInfo<T>> {
547 private:
548  // not implemented
549  DLLLOCAL RootMap(const RootMap& old);
550  // not implemented
551  DLLLOCAL RootMap& operator=(const RootMap& m);
552 
553 public:
554  typedef NSOInfo<T> info_t;
555  typedef std::map<const std::string, NSOInfo<T>> map_t;
556 
557  DLLLOCAL RootMap() {
558  }
559 
560  DLLLOCAL void update(const std::string& name, qore_ns_private* ns, T* obj) {
561  // get current lookup map entry for this object
562  typename map_t::iterator i = this->lower_bound(name);
563  if (i == this->end() || i->first != name) {
564  this->insert(i, typename map_t::value_type(name, info_t(ns, obj)));
565  } else { // if the old depth is > the new depth, then replace
566  if (i->second.depth() > ns->depth) {
567  i->second.assign(ns, obj);
568  }
569  }
570  }
571 
572  DLLLOCAL void update(typename map_t::const_iterator ni) {
573  // get current lookup map entry for this object
574  typename map_t::iterator i = this->lower_bound(ni->first);
575  if (i == this->end() || i->first != ni->first) {
576  //printd(5, "RootMap::update(iterator) inserting '%s' new depth: %d\n", ni->first, ni->second.depth());
577  this->insert(i, typename map_t::value_type(ni->first, ni->second));
578  } else {
579  // if the old depth is > the new depth, then replace
580  if (i->second.depth() > ni->second.depth()) {
581  //printd(5, "RootMap::update(iterator) replacing '%s' current depth: %d new depth: %d\n", ni->first, i->second.depth(), ni->second.depth());
582  i->second = ni->second;
583  }
584  //else
585  //printd(5, "RootMap::update(iterator) ignoring '%s' current depth: %d new depth: %d\n", ni->first, i->second.depth(), ni->second.depth());
586  }
587  }
588 
589  T* findObj(const std::string& name) {
590  typename map_t::iterator i = this->find(name);
591  return i == this->end() ? nullptr : i->second.obj;
592  }
593 };
594 
595 hashdecl FunctionEntryInfo {
596  FunctionEntry* obj = nullptr;
597 
598  DLLLOCAL FunctionEntryInfo() {
599  }
600 
601  DLLLOCAL FunctionEntryInfo(FunctionEntry* o) : obj(o) {
602  }
603 
604  DLLLOCAL unsigned depth() const {
605  return getNamespace()->depth;
606  }
607 
608  DLLLOCAL qore_ns_private* getNamespace() const {
609  return obj->getNamespace();
610  }
611 
612  DLLLOCAL void assign(FunctionEntry* n_obj) {
613  obj = n_obj;
614  }
615 };
616 
617 // cannot use vector_map here for performance reasons
618 typedef std::map<const char*, FunctionEntryInfo, ltstr> femap_t;
619 class FunctionEntryRootMap : public femap_t {
620 private:
621  // not implemented
622  DLLLOCAL FunctionEntryRootMap(const FunctionEntryRootMap& old);
623  // not implemented
624  DLLLOCAL FunctionEntryRootMap& operator=(const FunctionEntryRootMap& m);
625 
626 public:
627  DLLLOCAL FunctionEntryRootMap() {
628  }
629 
630  DLLLOCAL void update(const char* name, FunctionEntry* obj) {
631  // get current lookup map entry for this object
632  femap_t::iterator i = find(name);
633  if (i == end())
634  insert(femap_t::value_type(name, FunctionEntryInfo(obj)));
635  else // if the old depth is > the new depth, then replace
636  if (i->second.depth() > obj->getNamespace()->depth)
637  i->second.assign(obj);
638  }
639 
640  DLLLOCAL void update(femap_t::const_iterator ni) {
641  // get current lookup map entry for this object
642  femap_t::iterator i = find(ni->first);
643  if (i == end()) {
644  //printd(5, "FunctionEntryRootMap::update(iterator) inserting '%s' new depth: %d\n", ni->first, ni->second.depth());
645  insert(femap_t::value_type(ni->first, ni->second));
646  }
647  else {
648  // if the old depth is > the new depth, then replace
649  if (i->second.depth() > ni->second.depth()) {
650  //printd(5, "FunctionEntryRootMap::update(iterator) replacing '%s' current depth: %d new depth: %d\n", ni->first, i->second.depth(), ni->second.depth());
651  i->second = ni->second;
652  }
653  //else
654  //printd(5, "FunctionEntryRootMap::update(iterator) ignoring '%s' current depth: %d new depth: %d\n", ni->first, i->second.depth(), ni->second.depth());
655  }
656  }
657 
658  FunctionEntry* findObj(const char* name) {
659  femap_t::iterator i = find(name);
660  return i == end() ? 0 : i->second.obj;
661  }
662 };
663 
664 class NamespaceDepthList {
665  friend class NamespaceDepthListIterator;
666 protected:
667  // map from depth to namespace
668  typedef std::multimap<unsigned, qore_ns_private*> nsdmap_t;
669  nsdmap_t nsdmap;
670 
671 public:
672  DLLLOCAL NamespaceDepthList() {
673  }
674 
675  DLLLOCAL void add(qore_ns_private* ns) {
676  nsdmap.insert(nsdmap_t::value_type(ns->depth, ns));
677  }
678 
679  DLLLOCAL void clear() {
680  nsdmap.clear();
681  }
682 };
683 
684 class NamespaceDepthListIterator {
685  NamespaceDepthList::nsdmap_t::iterator i, e;
686 public:
687  DLLLOCAL NamespaceDepthListIterator(NamespaceDepthList& m) : i(m.nsdmap.begin()), e(m.nsdmap.end()) {
688  }
689 
690  DLLLOCAL bool next() {
691  if (i == e)
692  return false;
693  ++i;
694  return i != e;
695  }
696 
697  DLLLOCAL qore_ns_private* get() const {
698  assert(i->second);
699  return i->second;
700  }
701 };
702 
703 class NamespaceMap {
704  friend class NamespaceMapIterator;
705  friend class ConstNamespaceMapIterator;
706  friend class ConstAllNamespacesIterator;
707 
708 protected:
709  // map from depth to namespace
710  typedef std::multimap<unsigned, qore_ns_private*> nsdmap_t;
711  // map from name to depth map
712  //typedef std::map<const char*, nsdmap_t, ltstr> nsmap_t;
713  typedef vector_map_t<const char*, nsdmap_t> nsmap_t;
714  // map from namespace to depth for reindexing
715  //typedef std::map<qore_ns_private*, unsigned> nsrmap_t;
716  typedef vector_map_t<qore_ns_private*, unsigned> nsrmap_t;
717 
718  nsmap_t nsmap; // name to depth to namespace map
719  nsrmap_t nsrmap; // namespace to depth map (for fast reindexing)
720 
721  // not implemented
722  DLLLOCAL NamespaceMap(const NamespaceMap& old);
723  // not implemented
724  DLLLOCAL NamespaceMap& operator=(const NamespaceMap& m);
725 
726 public:
727  DLLLOCAL NamespaceMap() {
728  }
729 
730  DLLLOCAL void update(qore_ns_private* ns) {
731  // if this namespace is already indexed, then reindex
732  nsrmap_t::iterator ri = nsrmap.find(ns);
733  if (ri != nsrmap.end()) {
734  // if the depth is the same, then do nothing
735  if (ns->depth == ri->second)
736  return;
737 
738  // otherwise get the depth -> namespace map under this name
739  nsmap_t::iterator i = nsmap.find(ns->name.c_str());
740  assert(i != nsmap.end());
741 
742  // now get the namespace entry
743  nsdmap_t::iterator di = i->second.find(ri->second);
744  assert(di != i->second.end());
745 
746  // remove from depth -> namespace map
747  i->second.erase(di);
748 
749  // remove from reverse map
750  nsrmap.erase(ri);
751 
752  // add new entry to depth -> namespace map
753  i->second.insert(nsdmap_t::value_type(ns->depth, ns));
754 
755  return;
756  }
757  else {
758  // insert depth -> ns map entry
759  nsmap_t::iterator i = nsmap.find(ns->name.c_str());
760  if (i == nsmap.end())
761  i = nsmap.insert(nsmap_t::value_type(ns->name.c_str(), nsdmap_t())).first;
762 
763  i->second.insert(nsdmap_t::value_type(ns->depth, ns));
764  }
765 
766  // add new entry to reverse map
767  nsrmap.insert(nsrmap_t::value_type(ns, ns->depth));
768  }
769 
770  DLLLOCAL void commit(NamespaceMap& pend) {
771  // commit entries
772  for (nsrmap_t::iterator i = pend.nsrmap.begin(), e = pend.nsrmap.end(); i != e; ++i)
773  update(i->first);
774  pend.clear();
775  }
776 
777  DLLLOCAL void clear() {
778  nsmap.clear();
779  nsrmap.clear();
780  }
781 
782  // find the first namespace with the given name
783  DLLLOCAL QoreNamespace* findFirst(const char* name) {
784  nsmap_t::iterator mi = nsmap.find(name);
785  if (mi != nsmap.end()) {
786  nsdmap_t::iterator i = mi->second.begin();
787  if (i != mi->second.end()) {
788  return i->second->ns;
789  }
790  }
791  return nullptr;
792  }
793 };
794 
795 class NamespaceMapIterator {
796 protected:
797  NamespaceMap::nsmap_t::iterator mi;
798  NamespaceMap::nsdmap_t::iterator i;
799  bool valid;
800 
801 public:
802  DLLLOCAL NamespaceMapIterator(NamespaceMap& nsm, const char* name) : mi(nsm.nsmap.find(name)), valid(mi != nsm.nsmap.end()) {
803  if (valid)
804  i = mi->second.end();
805  }
806 
807  DLLLOCAL bool next() {
808  if (!valid)
809  return false;
810 
811  if (i == mi->second.end())
812  i = mi->second.begin();
813  else
814  ++i;
815 
816  return i != mi->second.end();
817  }
818 
819  DLLLOCAL qore_ns_private* get() {
820  return i->second;
821  }
822 };
823 
824 class ConstNamespaceMapIterator {
825 protected:
826  NamespaceMap::nsmap_t::const_iterator mi;
827  NamespaceMap::nsdmap_t::const_iterator i;
828  bool valid;
829 
830 public:
831  DLLLOCAL ConstNamespaceMapIterator(const NamespaceMap& nsm, const char* name) : mi(nsm.nsmap.find(name)), valid(mi != nsm.nsmap.end()) {
832  if (valid)
833  i = mi->second.end();
834  }
835 
836  DLLLOCAL bool next() {
837  if (!valid)
838  return false;
839 
840  if (i == mi->second.end())
841  i = mi->second.begin();
842  else
843  ++i;
844 
845  return i != mi->second.end();
846  }
847 
848  DLLLOCAL const qore_ns_private* get() {
849  return i->second;
850  }
851 };
852 
853 class ConstAllNamespacesIterator {
854 public:
855  DLLLOCAL ConstAllNamespacesIterator(const NamespaceMap& nsmap) : nsrmap(nsmap.nsrmap), i(nsmap.nsrmap.end()) {
856  }
857 
858  DLLLOCAL bool next() {
859  if (i == nsrmap.end()) {
860  i = nsrmap.begin();
861  }
862  else {
863  ++i;
864  }
865 
866  return i != nsrmap.end();
867  }
868 
869  DLLLOCAL const QoreNamespace* get() const {
870  assert(i != nsrmap.end());
871  return i->first->ns;
872  }
873 
874 private:
875  const NamespaceMap::nsrmap_t& nsrmap;
876  NamespaceMap::nsrmap_t::const_iterator i;
877 };
878 
879 typedef FunctionEntryRootMap fmap_t;
880 
881 typedef RootMap<ConstantEntry> cnmap_t;
882 
883 typedef RootMap<QoreClass> clmap_t;
884 
885 typedef RootMap<TypedHashDecl> thdmap_t;
886 
887 typedef RootMap<Var> varmap_t;
888 
889 hashdecl deferred_new_check_t {
890  const qore_class_private* qc;
891  const QoreProgramLocation* loc;
892 
893  DLLLOCAL deferred_new_check_t(const qore_class_private* qc, const QoreProgramLocation* loc) : qc(qc), loc(loc) {
894  }
895 };
896 
897 class qore_root_ns_private : public qore_ns_private {
898  friend class qore_ns_private;
899  friend class QoreNamespace;
900 
901 protected:
902  typedef std::vector<deferred_new_check_t> deferred_new_check_vec_t;
903  deferred_new_check_vec_t deferred_new_check_vec;
904 
905  DLLLOCAL int addPendingVariantIntern(qore_ns_private& ns, const char* name, AbstractQoreFunctionVariant* v) {
906  // try to add function variant to given namespace
907  bool new_func = false;
908  FunctionEntry* fe = ns.addPendingVariantIntern(name, v, new_func);
909  if (!fe)
910  return -1;
911 
912  assert(fe->getNamespace() == &ns);
913 
914  if (new_func) {
915  fmap_t::iterator i = fmap.find(fe->getName());
916  // only add to pending map if either not in the committed map or the depth is higher in the committed map
917  if (i == fmap.end() || i->second.depth() > ns.depth)
918  pend_fmap.update(fe->getName(), fe);
919  }
920 
921  return 0;
922  }
923 
924  DLLLOCAL int addPendingVariantIntern(qore_ns_private& ns, const NamedScope& nscope, AbstractQoreFunctionVariant* v) {
925  assert(nscope.size() > 1);
927 
928  QoreNamespace* fns = ns.ns;
929  for (unsigned i = 0; i < nscope.size() - 1; ++i) {
930  fns = fns->priv->parseFindLocalNamespace(nscope[i]);
931  if (!fns) {
932  parse_error(*v->getUserVariantBase()->getUserSignature()->getParseLocation(), "cannot find namespace '%s::' in '%s()' as a child of namespace '%s::'", nscope[i], nscope.ostr, ns.name.c_str());
933  return -1;
934  }
935  }
936 
937  return addPendingVariantIntern(*fns->priv, nscope.getIdentifier(), vh.release());
938  }
939 
940  // performed at runtime
941  DLLLOCAL int runtimeImportClass(ExceptionSink* xsink, qore_ns_private& ns, const QoreClass* c, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = nullptr, bool inject = false, const qore_class_private* injectedClass = nullptr) {
942  QoreClass* nc = ns.runtimeImportClass(xsink, c, spgm, set_pub, new_name, inject, injectedClass);
943  if (!nc)
944  return -1;
945 
946  //printd(5, "qore_root_ns_private::runtimeImportClass() this: %p ns: %p '%s' (depth %d) class: %p %s\n", this, &ns, ns.name.c_str(), ns.depth, nc, nc->getName());
947 
948  clmap.update(nc->getName(), &ns, nc);
949  return 0;
950  }
951 
952  // performed at runtime
953  DLLLOCAL int runtimeImportHashDecl(ExceptionSink* xsink, qore_ns_private& ns, const TypedHashDecl* hd, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = nullptr) {
954  TypedHashDecl* nhd = ns.runtimeImportHashDecl(xsink, hd, spgm, set_pub, new_name);
955  if (!nhd)
956  return -1;
957 
958  //printd(5, "qore_root_ns_private::thdmap() this: %p ns: %p '%s' (depth %d) hashdecl: %p %s\n", this, &ns, ns.name.c_str(), ns.depth, nc, nc->getName());
959 
960  thdmap.update(nhd->getName(), &ns, nhd);
961  return 0;
962  }
963 
964  // performed at runtime
965  DLLLOCAL int runtimeImportFunction(ExceptionSink* xsink, qore_ns_private& ns, QoreFunction* u, const char* new_name = nullptr, bool inject = false) {
966  FunctionEntry* fe = ns.runtimeImportFunction(xsink, u, new_name, inject);
967  if (!fe)
968  return -1;
969 
970  assert(fe->getNamespace() == &ns);
971 
972  //printd(5, "qore_root_ns_private::runtimeImportFunction() this: %p ns: %p '%s' (depth %d) func: %p %s\n", this, &ns, ns.name.c_str(), ns.depth, u, fe->getName());
973 
974  fmap.update(fe->getName(), fe);
975  return 0;
976  }
977 
978  DLLLOCAL bool runtimeExistsFunctionIntern(const char* name) {
979  return fmap.find(name) != fmap.end();
980  }
981 
982  DLLLOCAL const QoreClass* runtimeFindClassIntern(const char* name, const qore_ns_private*& ns) const {
983  clmap_t::const_iterator i = clmap.find(name);
984 
985  if (i != clmap.end()) {
986  ns = i->second.ns;
987  //printd(5, "qore_root_ns_private::runtimeFindClassIntern() this: %p %s found in ns: '%s' depth: %d\n", this, name, ns->name.c_str(), ns->depth);
988  return i->second.obj;
989  }
990 
991  return nullptr;
992  }
993 
994  DLLLOCAL const QoreClass* runtimeFindClassIntern(const NamedScope& name, const qore_ns_private*& ns) const;
995 
996  DLLLOCAL const TypedHashDecl* runtimeFindHashDeclIntern(const char* name, const qore_ns_private*& ns) {
997  thdmap_t::iterator i = thdmap.find(name);
998 
999  if (i != thdmap.end()) {
1000  ns = i->second.ns;
1001  //printd(5, "qore_root_ns_private::runtimeFindHashDeclIntern() this: %p %s found in ns: '%s' depth: %d\n", this, name, ns->name.c_str(), ns->depth);
1002  return i->second.obj;
1003  }
1004 
1005  return nullptr;
1006  }
1007 
1008  DLLLOCAL const FunctionEntry* runtimeFindFunctionEntryIntern(const char* name) {
1009  fmap_t::const_iterator i = fmap.find(name);
1010  return i != fmap.end() ? i->second.obj : nullptr;
1011  }
1012 
1013  DLLLOCAL const FunctionEntry* runtimeFindFunctionEntryIntern(const NamedScope& name);
1014 
1015  DLLLOCAL FunctionEntry* parseFindFunctionEntryIntern(const char* name) {
1016  {
1017  // try to check in current namespace first
1018  qore_ns_private* nscx = parse_get_ns();
1019  if (nscx) {
1020  FunctionEntry* fe = nscx->func_list.findNode(name);
1021  if (fe)
1022  return fe;
1023  }
1024  }
1025 
1026  fmap_t::iterator i = fmap.find(name);
1027  fmap_t::iterator ip = pend_fmap.find(name);
1028 
1029  if (i != fmap.end()) {
1030  if (ip != pend_fmap.end()) {
1031  if (i->second.depth() < ip->second.depth())
1032  return i->second.obj;
1033 
1034  return ip->second.obj;
1035  }
1036 
1037  return i->second.obj;
1038  }
1039 
1040  if (ip != pend_fmap.end())
1041  return ip->second.obj;
1042 
1043  return 0;
1044  }
1045 
1046  DLLLOCAL QoreFunction* parseFindFunctionIntern(const char* name) {
1047  FunctionEntry* fe = parseFindFunctionEntryIntern(name);
1048  return !fe ? 0 : fe->getFunction();
1049  }
1050 
1051  DLLLOCAL const FunctionEntry* parseResolveFunctionEntryIntern(const QoreProgramLocation* loc, const char* fname) {
1052  QORE_TRACE("qore_root_ns_private::parseResolveFunctionEntryIntern()");
1053 
1054  const FunctionEntry* f = parseFindFunctionEntryIntern(fname);
1055  if (!f)
1056  // cannot find function, throw exception
1057  parse_error(*loc, "function '%s()' cannot be found", fname);
1058 
1059  return f;
1060  }
1061 
1062  // called during parsing (plock already grabbed)
1063  DLLLOCAL AbstractCallReferenceNode* parseResolveCallReferenceIntern(UnresolvedProgramCallReferenceNode* fr);
1064 
1065  DLLLOCAL void parseCommit() {
1066  // commit pending function lookup entries
1067  for (fmap_t::iterator i = pend_fmap.begin(), e = pend_fmap.end(); i != e; ++i)
1068  fmap.update(i);
1069  pend_fmap.clear();
1070 
1071  qore_ns_private::parseCommit();
1072  // exceptions can be through thrown when performing runtime initialization
1073  qore_ns_private::parseCommitRuntimeInit(getProgram()->getParseExceptionSink());
1074  }
1075 
1076  DLLLOCAL ConstantEntry* parseFindOnlyConstantEntryIntern(const char* cname, qore_ns_private*& ns) {
1077  {
1078  // first try to look in current namespace context
1079  qore_ns_private* nscx = parse_get_ns();
1080  if (nscx) {
1081  ConstantEntry* ce = nscx->constant.findEntry(cname);
1082  if (ce) {
1083  ns = nscx;
1084  return ce;
1085  }
1086  }
1087  }
1088 
1089  // look up in global constant map
1090  cnmap_t::iterator i = cnmap.find(cname);
1091 
1092  if (i != cnmap.end()) {
1093  ns = i->second.ns;
1094  return i->second.obj;;
1095  }
1096 
1097  return 0;
1098  }
1099 
1100  DLLLOCAL QoreValue parseFindOnlyConstantValueIntern(const QoreProgramLocation* loc, const char* cname, const QoreTypeInfo*& typeInfo, bool& found) {
1101  assert(!found);
1102  qore_ns_private* ns;
1103  ConstantEntry* ce = parseFindOnlyConstantEntryIntern(cname, ns);
1104  if (!ce)
1105  return QoreValue();
1106 
1107  //printd(5, "qore_root_ns_private::parseFindOnlyConstantValueIntern() const: %s ns: %p %s\n", cname, ns, ns->name.c_str());
1108 
1109  found = true;
1110  NamespaceParseContextHelper nspch(ns);
1111  return ce->get(loc, typeInfo, ns);
1112  }
1113 
1114  DLLLOCAL QoreValue parseFindConstantValueIntern(const QoreProgramLocation* loc, const char* cname, const QoreTypeInfo*& typeInfo, bool& found, bool error) {
1115  assert(!found);
1116  // look up class constants first
1117  QoreClass* pc = parse_get_class();
1118  if (pc) {
1119  QoreValue rv = qore_class_private::parseFindConstantValue(pc, cname, typeInfo, found, pc ? qore_class_private::get(*pc) : nullptr);
1120  if (found) {
1121  return rv;
1122  }
1123  }
1124 
1125  QoreValue rv = parseFindOnlyConstantValueIntern(loc, cname, typeInfo, found);
1126  if (found) {
1127  return rv;
1128  }
1129 
1130  if (error) {
1131  parse_error(*loc, "constant '%s' cannot be resolved in any namespace", cname);
1132  }
1133 
1134  return QoreValue();
1135  }
1136 
1137  DLLLOCAL ResolvedCallReferenceNode* runtimeGetCallReference(const char* fname, ExceptionSink* xsink) {
1138  fmap_t::iterator i = fmap.find(fname);
1139  if (i == fmap.end()) {
1140  xsink->raiseException("NO-SUCH-FUNCTION", "callback function '%s()' does not exist", fname);
1141  return 0;
1142  }
1143 
1144  return i->second.obj->makeCallReference(get_runtime_location());
1145  }
1146 
1147  DLLLOCAL TypedHashDecl* parseFindScopedHashDeclIntern(const NamedScope& nscope, unsigned& matched);
1148 
1149  DLLLOCAL TypedHashDecl* parseFindHashDeclIntern(const char* hdname) {
1150  {
1151  // try to check in current namespace first
1152  qore_ns_private* nscx = parse_get_ns();
1153  if (nscx) {
1154  TypedHashDecl* hd = nscx->parseFindLocalHashDecl(hdname);
1155  if (hd)
1156  return hd;
1157  }
1158  }
1159 
1160  thdmap_t::iterator i = thdmap.find(hdname);
1161 
1162  if (i != thdmap.end()) {
1163  return i->second.obj;
1164  }
1165 
1166  //printd(5, "qore_root_ns_private::parseFindHashDeclIntern() this: %p '%s' not found\n", this, cname);
1167  return nullptr;
1168  }
1169 
1170  DLLLOCAL QoreClass* parseFindScopedClassIntern(const QoreProgramLocation* loc, const NamedScope& name);
1171  DLLLOCAL QoreClass* parseFindScopedClassIntern(const NamedScope& name, unsigned& matched);
1172  DLLLOCAL QoreClass* parseFindScopedClassWithMethodInternError(const QoreProgramLocation* loc, const NamedScope& name, bool error);
1173  DLLLOCAL QoreClass* parseFindScopedClassWithMethodIntern(const NamedScope& name, unsigned& matched);
1174 
1175  DLLLOCAL QoreClass* parseFindClassIntern(const char* cname) {
1176  assert(cname);
1177  {
1178  // try to check in current namespace first
1179  qore_ns_private* nscx = parse_get_ns();
1180  if (nscx) {
1181  QoreClass* qc = nscx->parseFindLocalClass(cname);
1182  if (qc)
1183  return qc;
1184  }
1185  }
1186 
1187  clmap_t::iterator i = clmap.find(cname);
1188 
1189  if (i != clmap.end()) {
1190  return i->second.obj;
1191  }
1192 
1193  // now check all namespaces with class handlers
1194  NamespaceDepthListIterator nhi(nshlist);
1195  while (nhi.next()) {
1196  QoreClass* qc = nhi.get()->findLoadClass(cname);
1197  if (qc)
1198  return qc;
1199  }
1200 
1201  //printd(5, "qore_root_ns_private::parseFindClassIntern() this: %p '%s' not found\n", this, cname);
1202  return nullptr;
1203  }
1204 
1205  DLLLOCAL const QoreClass* runtimeFindClass(const char* name) const {
1206  clmap_t::const_iterator i = clmap.find(name);
1207  return i != clmap.end() ? i->second.obj : nullptr;
1208  }
1209 
1210  DLLLOCAL QoreNamespace* runtimeFindNamespaceForAddFunction(const NamedScope& name, ExceptionSink* xsink) {
1211  //printd(5, "QoreNamespaceIntern::runtimeFindNamespaceForAddFunction() this: %p name: %s (%s)\n", this, name.ostr, name[0]);
1212  bool fnd = false;
1213 
1214  // iterate all namespaces with the initial name and look for the match
1215  NamespaceMapIterator nmi(nsmap, name[0]);
1216  while (nmi.next()) {
1217  const qore_ns_private* rv = nmi.get()->runtimeMatchAddFunction(name, fnd);
1218  //printd(5, "QoreNamespaceIntern::runtimeFindNamespaceForAddFunction() this: %p name: %s ns: %p '%s' rv: %p fnd: %d\n", this, name.ostr, nmi.get(), nmi.get()->name.c_str(), rv, fnd);
1219  if (rv)
1220  return const_cast<QoreNamespace*>(rv->ns);
1221  }
1222 
1223  if (fnd)
1224  xsink->raiseException("FUNCTION-IMPORT-ERROR", "target function '%s' already exists in the given namespace", name.ostr);
1225  else
1226  xsink->raiseException("FUNCTION-IMPORT-ERROR", "target namespace in '%s' does not exist", name.ostr);
1227  return 0;
1228  }
1229 
1230  DLLLOCAL QoreNamespace* runtimeFindNamespaceForAddClass(const NamedScope& name, ExceptionSink* xsink) {
1231  bool fnd = false;
1232 
1233  // iterate all namespaces with the initial name and look for the match
1234  NamespaceMapIterator nmi(nsmap, name.get(0));
1235  while (nmi.next()) {
1236  const qore_ns_private* rv = nmi.get()->runtimeMatchAddClass(name, fnd);
1237  if (rv)
1238  return const_cast<QoreNamespace*>(rv->ns);
1239  }
1240 
1241  if (fnd)
1242  xsink->raiseException("CLASS-IMPORT-ERROR", "target class '%s' already exists in the given namespace", name.ostr);
1243  else
1244  xsink->raiseException("CLASS-IMPORT-ERROR", "target namespace in '%s' does not exist", name.ostr);
1245  return 0;
1246  }
1247 
1248  DLLLOCAL void addConstant(qore_ns_private& ns, const char* cname, QoreValue value, const QoreTypeInfo* typeInfo);
1249 
1250  DLLLOCAL QoreValue parseFindReferencedConstantValueIntern(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo*& typeInfo, bool& found, bool error);
1251 
1252  DLLLOCAL QoreValue parseResolveBarewordIntern(const QoreProgramLocation* loc, const char* bword, const QoreTypeInfo*& typeInfo, bool& found);
1253 
1254  DLLLOCAL QoreValue parseResolveReferencedScopedReferenceIntern(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo*& typeInfo, bool& found);
1255 
1256  DLLLOCAL void parseAddConstantIntern(const QoreProgramLocation* loc, QoreNamespace& ns, const NamedScope& name, QoreValue value, bool pub);
1257 
1258  DLLLOCAL void parseAddClassIntern(const QoreProgramLocation* loc, const NamedScope& name, QoreClass* oc);
1259 
1260  DLLLOCAL void parseAddHashDeclIntern(const QoreProgramLocation* loc, const NamedScope& name, TypedHashDecl* hd);
1261 
1262  DLLLOCAL qore_ns_private* parseResolveNamespaceIntern(const QoreProgramLocation* loc, const NamedScope& nscope, qore_ns_private* sns);
1263  DLLLOCAL qore_ns_private* parseResolveNamespace(const QoreProgramLocation* loc, const NamedScope& nscope, qore_ns_private* sns);
1264  DLLLOCAL qore_ns_private* parseResolveNamespace(const QoreProgramLocation* loc, const NamedScope& nscope);
1265 
1266  DLLLOCAL const FunctionEntry* parseResolveFunctionEntryIntern(const NamedScope& nscope);
1267 
1268  DLLLOCAL Var* parseAddResolvedGlobalVarDefIntern(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo* typeInfo);
1269  DLLLOCAL Var* parseAddGlobalVarDefIntern(const QoreProgramLocation* loc, const NamedScope& name, QoreParseTypeInfo* typeInfo);
1270 
1271  DLLLOCAL Var* parseCheckImplicitGlobalVarIntern(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo* typeInfo);
1272 
1273  DLLLOCAL Var* parseFindGlobalVarIntern(const NamedScope& vname) {
1274  assert(vname.size() > 1);
1275 
1276  Var* rv = 0;
1277  unsigned match = 0;
1278 
1279  {
1280  // try to check in current namespace first
1281  qore_ns_private* nscx = parse_get_ns();
1282  if (nscx && nscx->name == vname[0]) {
1283  QoreNamespace* vns = nscx->parseMatchNamespace(vname, match);
1284  if (vns && (rv = vns->priv->var_list.parseFindVar(vname.getIdentifier())))
1285  return rv;
1286  }
1287  }
1288 
1289  // iterate all namespaces with the initial name and look for the match
1290  {
1291  NamespaceMapIterator nmi(nsmap, vname[0]);
1292  while (nmi.next()) {
1293  QoreNamespace* vns = nmi.get()->parseMatchNamespace(vname, match);
1294  if (vns && (rv = vns->priv->var_list.parseFindVar(vname.getIdentifier())))
1295  return rv;
1296  }
1297  }
1298 
1299  return rv;
1300  }
1301 
1302  DLLLOCAL Var* parseFindGlobalVarIntern(const char* vname) {
1303  {
1304  // try to check in current namespace first
1305  qore_ns_private* nscx = parse_get_ns();
1306  if (nscx) {
1307  Var* v = nscx->var_list.parseFindVar(vname);
1308  if (v)
1309  return v;
1310  }
1311 
1312  //printd(5, "qore_root_ns_private::parseFindGlobalVarIntern() this: %p '%s' nscx: %p ('%s') varmap: %d pend_varmap: %d\n", this, vname, nscx, nscx ? nscx->name.c_str() : "n/a", varmap.find(vname) != varmap.end(), pend_varmap.find(vname) != pend_varmap.end());
1313  }
1314 
1315  varmap_t::iterator i = varmap.find(vname);
1316 
1317  if (i != varmap.end()) {
1318  return i->second.obj;
1319  }
1320 
1321  return nullptr;
1322  }
1323 
1324  DLLLOCAL Var* runtimeFindGlobalVar(const NamedScope& nscope, const qore_ns_private*& vns) const;
1325 
1326  DLLLOCAL Var* runtimeFindGlobalVar(const char* vname, const qore_ns_private*& vns) const {
1327  if (strstr(vname, "::")) {
1328  NamedScope nscope(vname);
1329  return runtimeFindGlobalVar(nscope, vns);
1330  }
1331 
1332  varmap_t::const_iterator i = varmap.find(vname);
1333  if (i != varmap.end()) {
1334  assert(i->second.ns);
1335  vns = i->second.ns;
1336  return i->second.obj;
1337  }
1338  return nullptr;
1339  }
1340 
1341  DLLLOCAL const ConstantEntry* runtimeFindNamespaceConstant(const NamedScope& nscope, const qore_ns_private*& cns) const;
1342 
1343  DLLLOCAL const ConstantEntry* runtimeFindNamespaceConstant(const char* cname, const qore_ns_private*& cns) const {
1344  if (strstr(cname, "::")) {
1345  NamedScope nscope(cname);
1346  return runtimeFindNamespaceConstant(nscope, cns);
1347  }
1348 
1349  cnmap_t::const_iterator i = cnmap.find(cname);
1350  if (i != cnmap.end()) {
1351  assert(i->second.ns);
1352  cns = i->second.ns;
1353  return i->second.obj;
1354  }
1355  return nullptr;
1356  }
1357 
1358  DLLLOCAL void runtimeImportGlobalVariable(qore_ns_private& tns, Var* v, bool readonly, ExceptionSink* xsink) {
1359  Var* var = tns.var_list.import(v, xsink, readonly);
1360  if (!var)
1361  return;
1362 
1363  varmap.update(var->getName(), &tns, var);
1364  }
1365 
1366  DLLLOCAL Var* runtimeCreateVar(qore_ns_private& vns, const char* vname, const QoreTypeInfo* typeInfo, bool builtin) {
1367  Var* v = vns.var_list.runtimeCreateVar(vname, typeInfo, builtin);
1368 
1369  if (v)
1370  varmap.update(v->getName(), &vns, v);
1371  return v;
1372  }
1373 
1374  DLLLOCAL bool parseResolveGlobalVarsAndClassHierarchiesIntern();
1375 
1376  // returns 0 for success, non-zero for error
1377  DLLLOCAL int parseAddMethodToClassIntern(const QoreProgramLocation* loc, const NamedScope& name, MethodVariantBase* qcmethod, bool static_flag);
1378 
1379  DLLLOCAL static void rebuildConstantIndexes(cnmap_t& cnmap, ConstantList& cl, qore_ns_private* ns) {
1380  ConstantListIterator cli(cl);
1381  while (cli.next())
1382  cnmap.update(cli.getName().c_str(), ns, cli.getEntry());
1383  }
1384 
1385  DLLLOCAL static void rebuildClassIndexes(clmap_t& clmap, QoreClassList& cl, qore_ns_private* ns) {
1386  ClassListIterator cli(cl);
1387  while (cli.next())
1388  clmap.update(cli.getName(), ns, cli.get());
1389  }
1390 
1391  DLLLOCAL static void rebuildHashDeclIndexes(thdmap_t& thdmap, HashDeclList& hdl, qore_ns_private* ns) {
1392  HashDeclListIterator hdli(hdl);
1393  while (hdli.next())
1394  thdmap.update(hdli.getName(), ns, hdli.get());
1395  }
1396 
1397  DLLLOCAL static void rebuildFunctionIndexes(fmap_t& fmap, fl_map_t& flmap, qore_ns_private* ns) {
1398  for (fl_map_t::iterator i = flmap.begin(), e = flmap.end(); i != e; ++i) {
1399  assert(i->second->getNamespace() == ns);
1400  fmap.update(i->first, i->second);
1401  //printd(5, "qore_root_ns_private::rebuildFunctionIndexes() this: %p ns: %p func %s\n", this, ns, i->first);
1402  }
1403  }
1404 
1405  DLLLOCAL void rebuildIndexes(qore_ns_private* ns) {
1406  // process function indexes
1407  rebuildFunctionIndexes(fmap, ns->func_list, ns);
1408 
1409  // process variable indexes
1410  for (map_var_t::iterator i = ns->var_list.vmap.begin(), e = ns->var_list.vmap.end(); i != e; ++i)
1411  varmap.update(i->first, ns, i->second);
1412 
1413  // process constant indexes
1414  rebuildConstantIndexes(cnmap, ns->constant, ns);
1415 
1416  // process class indexes
1417  rebuildClassIndexes(clmap, ns->classList, ns);
1418 
1419  // process hashdecl indexes
1420  rebuildHashDeclIndexes(thdmap, ns->hashDeclList, ns);
1421 
1422  // reindex namespace
1423  nsmap.update(ns);
1424 
1425  // inserts into depth list
1426  nshlist.add(ns);
1427  }
1428 
1429  DLLLOCAL void parseRebuildIndexes(qore_ns_private* ns) {
1430  //printd(5, "qore_root_ns_private::parseRebuildIndexes() this: %p ns: %p (%s) depth %d\n", this, ns, ns->name.c_str(), ns->depth);
1431 
1432  // process function indexes
1433  for (fl_map_t::iterator i = ns->func_list.begin(), e = ns->func_list.end(); i != e; ++i) {
1434  assert(i->second->getNamespace() == ns);
1435  pend_fmap.update(i->first, i->second);
1436  }
1437 
1438  // process variable indexes
1439  for (map_var_t::iterator i = ns->var_list.vmap.begin(), e = ns->var_list.vmap.end(); i != e; ++i)
1440  varmap.update(i->first, ns, i->second);
1441 
1442  // process constant indexes
1443  rebuildConstantIndexes(cnmap, ns->constant, ns);
1444 
1445  // process class indexes
1446  rebuildClassIndexes(clmap, ns->classList, ns);
1447 
1448  // process hashdecl indexes
1449  rebuildHashDeclIndexes(thdmap, ns->hashDeclList, ns);
1450 
1451  // reindex namespace
1452  nsmap.update(ns);
1453  }
1454 
1455  DLLLOCAL void parseAddNamespaceIntern(QoreNamespace* nns);
1456 
1457 public:
1458  RootQoreNamespace* rns;
1459  QoreNamespace* qoreNS;
1460 
1461  fmap_t fmap, // root function map
1462  pend_fmap; // root pending function map (only used during parsing)
1463 
1464  cnmap_t cnmap; // root constant map
1465 
1466  clmap_t clmap; // root class map
1467 
1468  thdmap_t thdmap; // root hashdecl map
1469 
1470  varmap_t varmap; // root variable map
1471 
1472  NamespaceMap nsmap; // root namespace map
1473 
1474  NamespaceDepthList nshlist; // root namespace with handler map
1475 
1476  // unresolved pending global variable list - only used in the 1st stage of parsing (data read in to tree)
1477  gvlist_t pend_gvlist;
1478 
1479  DLLLOCAL qore_root_ns_private(RootQoreNamespace* n_rns) : qore_ns_private(n_rns), rns(n_rns), qoreNS(0) {
1480  assert(root);
1481  assert(pub);
1482  // add initial namespace to committed map
1483  nsmap.update(this);
1484  }
1485 
1486  DLLLOCAL qore_root_ns_private(const qore_root_ns_private& old, int64 po) : qore_ns_private(old, po) {
1487  if ((po & PO_NO_API) == PO_NO_API) {
1488  // create empty Qore namespace
1489  qoreNS = new QoreNamespace("Qore");
1490  nsl.nsmap.insert(nsmap_t::value_type("Qore", qoreNS));
1491  qoreNS->priv->nsl.nsmap.insert(nsmap_t::value_type("Option", new QoreNamespace("Option")));
1492  } else
1493  qoreNS = nsl.find("Qore");
1494  assert(qoreNS);
1495 
1496  // always set the module public flag to true in the root namespace
1497  pub = true;
1498 
1499  // rebuild root indexes - only for committed objects
1500  rebuildAllIndexes();
1501  }
1502 
1503  DLLLOCAL ~qore_root_ns_private() {
1504  }
1505 
1506  DLLLOCAL RootQoreNamespace* copy(int64 po) {
1507  qore_root_ns_private* p = new qore_root_ns_private(*this, po);
1508  RootQoreNamespace* rv = new RootQoreNamespace(p);
1509  return rv;
1510  }
1511 
1512  DLLLOCAL void rebuildAllIndexes() {
1513  // clear depth list
1514  nshlist.clear();
1515 
1516  // rebuild root indexes
1517  QorePrivateNamespaceIterator qpni(this);
1518  while (qpni.next())
1519  rebuildIndexes(qpni.get());
1520  }
1521 
1522  DLLLOCAL void deferParseCheckAbstractNew(const qore_class_private* qc, const QoreProgramLocation* loc) {
1523  deferred_new_check_vec.push_back(deferred_new_check_t(qc, loc));
1524  }
1525 
1526  DLLLOCAL QoreNamespace* runtimeFindNamespace(const NamedScope& name) {
1527  // iterate all namespaces with the initial name and look for the match
1528  NamespaceMapIterator nmi(nsmap, name[0]);
1529  while (nmi.next()) {
1530  const qore_ns_private* rv = nmi.get()->runtimeMatchNamespace(name);
1531  if (rv) {
1532  return const_cast<QoreNamespace*>(rv->ns);
1533  }
1534  }
1535 
1536  return nullptr;
1537  }
1538 
1539  DLLLOCAL QoreNamespace* runtimeFindNamespace(const QoreString& name) {
1540  if (name.bindex("::", 0) != -1) {
1541  NamedScope scope(name.c_str());
1542  return runtimeFindNamespace(scope);
1543  }
1544 
1545  return nsmap.findFirst(name.c_str());
1546  }
1547 
1548  DLLLOCAL const QoreClass* runtimeFindScopedClassWithMethod(const NamedScope& name) const;
1549  DLLLOCAL const QoreClass* runtimeFindScopedClassWithMethodIntern(const NamedScope& name) const;
1550 
1551  /*
1552  DLLLOCAL void deleteClearData(ExceptionSink* xsink) {
1553  }
1554  */
1555 
1556  DLLLOCAL qore_ns_private* getQore() {
1557  return qoreNS->priv;
1558  }
1559 
1560  DLLLOCAL const qore_ns_private* getQore() const {
1561  return qoreNS->priv;
1562  }
1563 
1564  DLLLOCAL QoreHashNode* getGlobalVars() const {
1565  QoreHashNode* rv = new QoreHashNode(autoTypeInfo);
1566  qore_ns_private::getGlobalVars(*rv);
1567  return rv;
1568  }
1569 
1570  DLLLOCAL void commitModule(QoreModuleContext& qmc) {
1571  for (unsigned j = 0; j < qmc.mcnl.size(); ++j) {
1572  ModuleContextNamespaceCommit& mc = qmc.mcnl[j];
1573  mc.parent->addCommitNamespaceIntern(mc.nns);
1574  }
1575 
1576  for (unsigned j = 0; j < qmc.mcfl.size(); ++j) {
1577  ModuleContextFunctionCommit& mc = qmc.mcfl[j];
1578  mc.parent->addBuiltinVariantIntern(mc.name, mc.v);
1579  }
1580 
1581  // issue #3461: must rebuild all indexes here or symbols will appear missing
1582  if (qmc.mcnl.size() || qmc.mcfl.size()) {
1583  rebuildAllIndexes();
1584  }
1585  }
1586 
1587  DLLLOCAL void parseRollback(ExceptionSink* xsink) {
1588  // roll back pending lookup entries
1589  pend_fmap.clear();
1590  cnmap.clear();
1591 
1592  varmap.clear();
1593  nsmap.clear();
1594 
1595  // roll back pending global variables
1596  pend_gvlist.clear();
1597 
1598  clmap.clear();
1599  thdmap.clear();
1600 
1601  // delete any deferred new object checks for classes with abstract members
1602  deferred_new_check_vec.clear();
1603 
1604  qore_ns_private::parseRollback(xsink);
1605  }
1606 
1607  DLLLOCAL TypedHashDecl* parseFindHashDecl(const QoreProgramLocation* loc, const NamedScope& name);
1608 
1609  DLLLOCAL const TypedHashDecl* runtimeFindHashDeclIntern(const NamedScope& name, const qore_ns_private*& ns);
1610 
1611  DLLLOCAL QoreNamespace* runtimeFindCreateNamespacePath(const NamedScope& nspath, bool pub, bool user) {
1612  assert(nspath.size());
1613  bool is_new = false;
1614  QoreNamespace* nns = findCreateNamespacePath(nspath, pub, user, is_new);
1615  if (is_new) // add namespace index
1616  nsmap.update(nns->priv);
1617  return nns;
1618  }
1619 
1620  DLLLOCAL QoreNamespace* runtimeFindCreateNamespacePath(const qore_ns_private& ns, bool user) {
1621  // get a list of namespaces from after the root (not including the root) to the current
1622  nslist_t nsl;
1623  ns.getNsList(nsl);
1624 
1625  printd(5, "qore_root_ns_private::runtimeFindCreateNamespacePath() this: %p ns: '%s'\n", this, ns.name.c_str());
1626 
1627  bool is_new = false;
1628  QoreNamespace* nns = findCreateNamespacePath(nsl, user, is_new);
1629  assert(ns.name == nns->getName());
1630  if (is_new) // add namespace index
1631  nsmap.update(nns->priv);
1632  return nns;
1633  }
1634 
1635  DLLLOCAL void runtimeRebuildConstantIndexes(qore_ns_private* ns) {
1636  rebuildConstantIndexes(cnmap, ns->constant, ns);
1637  }
1638 
1639  DLLLOCAL void runtimeRebuildClassIndexes(qore_ns_private* ns) {
1640  rebuildClassIndexes(clmap, ns->classList, ns);
1641  }
1642 
1643  DLLLOCAL void runtimeRebuildHashDeclIndexes(qore_ns_private* ns) {
1644  rebuildHashDeclIndexes(thdmap, ns->hashDeclList, ns);
1645  }
1646 
1647  DLLLOCAL void runtimeRebuildFunctionIndexes(qore_ns_private* ns) {
1648  rebuildFunctionIndexes(fmap, ns->func_list, ns);
1649  }
1650 
1651  DLLLOCAL const AbstractQoreFunctionVariant* runtimeFindCall(const char* name, const QoreListNode* params, ExceptionSink* xsink);
1652 
1653  DLLLOCAL QoreListNode* runtimeFindCallVariants(const char* name, ExceptionSink* xsink);
1654 
1655  DLLLOCAL void parseInit();
1656 
1657  DLLLOCAL class_vec_t runtimeFindAllClassesRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1658 
1659  DLLLOCAL hashdecl_vec_t runtimeFindAllHashDeclsRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1660 
1661  DLLLOCAL func_vec_t runtimeFindAllFunctionsRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1662 
1663  DLLLOCAL ns_vec_t runtimeFindAllNamespacesRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1664 
1665  DLLLOCAL gvar_vec_t runtimeFindAllGlobalVarsRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1666 
1667  DLLLOCAL const_vec_t runtimeFindAllNamespaceConstantsRegex(const QoreString& pattern, int re_opts, ExceptionSink* xsink) const;
1668 
1669  DLLLOCAL static QoreHashNode* getGlobalVars(RootQoreNamespace& rns) {
1670  return rns.rpriv->getGlobalVars();
1671  }
1672 
1673  DLLLOCAL static void runtimeImportSystemClasses(RootQoreNamespace& rns, const RootQoreNamespace& source, ExceptionSink* xsink) {
1674  rns.priv->runtimeImportSystemClasses(*source.priv, *rns.rpriv, xsink);
1675  }
1676 
1677  DLLLOCAL static void runtimeImportSystemHashDecls(RootQoreNamespace& rns, const RootQoreNamespace& source, ExceptionSink* xsink) {
1678  rns.priv->runtimeImportSystemHashDecls(*source.priv, *rns.rpriv, xsink);
1679  }
1680 
1681  DLLLOCAL static void runtimeImportSystemConstants(RootQoreNamespace& rns, const RootQoreNamespace& source, ExceptionSink* xsink) {
1682  rns.priv->runtimeImportSystemConstants(*source.priv, *rns.rpriv, xsink);
1683  }
1684 
1685  DLLLOCAL static void runtimeImportSystemFunctions(RootQoreNamespace& rns, const RootQoreNamespace& source, ExceptionSink* xsink) {
1686  rns.priv->runtimeImportSystemFunctions(*source.priv, *rns.rpriv, xsink);
1687  }
1688 
1689  DLLLOCAL static QoreNamespace* runtimeFindCreateNamespacePath(const RootQoreNamespace& rns, const qore_ns_private& ns, bool user) {
1690  return rns.rpriv->runtimeFindCreateNamespacePath(ns, user);
1691  }
1692 
1693  DLLLOCAL static QoreNamespace* runtimeFindCreateNamespacePath(const RootQoreNamespace& rns, const NamedScope& nspath, bool pub, bool user) {
1694  return rns.rpriv->runtimeFindCreateNamespacePath(nspath, pub, user);
1695  }
1696 
1697  DLLLOCAL static RootQoreNamespace* copy(const RootQoreNamespace& rns, int64 po) {
1698  return rns.rpriv->copy(po);
1699  }
1700 
1701  DLLLOCAL static int addPendingVariant(qore_ns_private& nsp, const char* name, AbstractQoreFunctionVariant* v) {
1702  return getRootNS()->rpriv->addPendingVariantIntern(nsp, name, v);
1703  }
1704 
1705  DLLLOCAL static int addPendingVariant(qore_ns_private& nsp, const NamedScope& name, AbstractQoreFunctionVariant* v) {
1706  return getRootNS()->rpriv->addPendingVariantIntern(nsp, name, v);
1707  }
1708 
1709  DLLLOCAL static int runtimeImportFunction(RootQoreNamespace& rns, ExceptionSink* xsink, QoreNamespace& ns, QoreFunction* u, const char* new_name = nullptr, bool inject = false) {
1710  return rns.rpriv->runtimeImportFunction(xsink, *ns.priv, u, new_name, inject);
1711  }
1712 
1713  DLLLOCAL static int runtimeImportClass(RootQoreNamespace& rns, ExceptionSink* xsink, QoreNamespace& ns, const QoreClass* c, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = 0, bool inject = false, const qore_class_private* injectedClass = nullptr) {
1714  return rns.rpriv->runtimeImportClass(xsink, *ns.priv, c, spgm, set_pub, new_name, inject, injectedClass);
1715  }
1716 
1717  DLLLOCAL static int runtimeImportHashDecl(RootQoreNamespace& rns, ExceptionSink* xsink, QoreNamespace& ns, const TypedHashDecl* c, QoreProgram* spgm, q_setpub_t set_pub, const char* new_name = nullptr) {
1718  return rns.rpriv->runtimeImportHashDecl(xsink, *ns.priv, c, spgm, set_pub, new_name);
1719  }
1720 
1721  DLLLOCAL static const QoreClass* runtimeFindClass(RootQoreNamespace& rns, const char* name, const qore_ns_private*& ns) {
1722  if (strstr(name, "::")) {
1723  NamedScope nscope(name);
1724  return rns.rpriv->runtimeFindClassIntern(nscope, ns);
1725  }
1726  return rns.rpriv->runtimeFindClassIntern(name, ns);
1727  }
1728 
1729  DLLLOCAL static const TypedHashDecl* runtimeFindHashDecl(RootQoreNamespace& rns, const char* name, const qore_ns_private*& ns) {
1730  if (strstr(name, "::")) {
1731  NamedScope nscope(name);
1732  return rns.rpriv->runtimeFindHashDeclIntern(nscope, ns);
1733  }
1734  return rns.rpriv->runtimeFindHashDeclIntern(name, ns);
1735  }
1736 
1737  DLLLOCAL static const QoreFunction* runtimeFindFunction(RootQoreNamespace& rns, const char* name, const qore_ns_private*& ns) {
1738  const FunctionEntry* fe = runtimeFindFunctionEntry(rns, name);
1739  if (fe) {
1740  ns = fe->getNamespace();
1741  return fe->getFunction();
1742  }
1743  return nullptr;
1744  }
1745 
1746  DLLLOCAL static const FunctionEntry* runtimeFindFunctionEntry(RootQoreNamespace& rns, const char* name) {
1747  if (strstr(name, "::")) {
1748  NamedScope nscope(name);
1749  return rns.rpriv->runtimeFindFunctionEntryIntern(nscope);
1750  }
1751  return rns.rpriv->runtimeFindFunctionEntryIntern(name);
1752  }
1753 
1754  DLLLOCAL static bool runtimeExistsFunction(RootQoreNamespace& rns, const char* name) {
1755  return rns.rpriv->runtimeExistsFunctionIntern(name);
1756  }
1757 
1758  DLLLOCAL static void addConstant(qore_root_ns_private& rns, qore_ns_private& ns, const char* cname, QoreValue value, const QoreTypeInfo* typeInfo) {
1759  rns.addConstant(ns, cname, value, typeInfo);
1760  }
1761 
1762  DLLLOCAL static const QoreFunction* parseResolveFunction(const QoreProgramLocation* loc, const char* fname) {
1763  const FunctionEntry* fe = getRootNS()->rpriv->parseResolveFunctionEntryIntern(loc, fname);
1764  return fe ? fe->getFunction() : nullptr;
1765  }
1766 
1767  DLLLOCAL static const FunctionEntry* parseResolveFunctionEntry(const QoreProgramLocation* loc, const char* fname) {
1768  return getRootNS()->rpriv->parseResolveFunctionEntryIntern(loc, fname);
1769  }
1770 
1771  // called during parsing (plock already grabbed)
1772  DLLLOCAL static AbstractCallReferenceNode* parseResolveCallReference(UnresolvedProgramCallReferenceNode* fr) {
1773  return getRootNS()->rpriv->parseResolveCallReferenceIntern(fr);
1774  }
1775 
1776  DLLLOCAL static bool parseResolveGlobalVarsAndClassHierarchies() {
1777  return getRootNS()->rpriv->parseResolveGlobalVarsAndClassHierarchiesIntern();
1778  }
1779 
1780  DLLLOCAL static void parseCommit(RootQoreNamespace& rns) {
1781  rns.rpriv->parseCommit();
1782  }
1783 
1784  DLLLOCAL static QoreValue parseFindConstantValue(const QoreProgramLocation* loc, const char* name, const QoreTypeInfo*& typeInfo, bool& found, bool error) {
1785  found = false;
1786  return getRootNS()->rpriv->parseFindConstantValueIntern(loc, name, typeInfo, found, error);
1787  }
1788 
1789  DLLLOCAL static QoreValue parseFindReferencedConstantValue(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo*& typeInfo, bool& found, bool error) {
1790  found = false;
1791  return getRootNS()->rpriv->parseFindReferencedConstantValueIntern(loc, name, typeInfo, found, error);
1792  }
1793 
1794  DLLLOCAL static QoreValue parseResolveBareword(const QoreProgramLocation* loc, const char* bword, const QoreTypeInfo*& typeInfo, bool& found) {
1795  found = false;
1796  return getRootNS()->rpriv->parseResolveBarewordIntern(loc, bword, typeInfo, found);
1797  }
1798 
1799  DLLLOCAL static QoreValue parseResolveReferencedScopedReference(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo*& typeInfo, bool& found) {
1800  found = false;
1801  return getRootNS()->rpriv->parseResolveReferencedScopedReferenceIntern(loc, name, typeInfo, found);
1802  }
1803 
1804  DLLLOCAL static QoreClass* parseFindClass(const QoreProgramLocation* loc, const char* name) {
1805  QoreClass* qc = getRootNS()->rpriv->parseFindClassIntern(name);
1806  if (!qc)
1807  parse_error(*loc, "reference to undefined class '%s'", name);
1808  return qc;
1809  }
1810 
1811  DLLLOCAL static QoreClass* parseFindScopedClass(const QoreProgramLocation* loc, const NamedScope& name) {
1812  return getRootNS()->rpriv->parseFindScopedClassIntern(loc, name);
1813  }
1814 
1815  DLLLOCAL static QoreClass* parseFindScopedClassWithMethod(const QoreProgramLocation* loc, const NamedScope& name, bool error) {
1816  return getRootNS()->rpriv->parseFindScopedClassWithMethodInternError(loc, name, error);
1817  }
1818 
1819  DLLLOCAL static void parseAddConstant(const QoreProgramLocation* loc, QoreNamespace& ns, const NamedScope& name, QoreValue value, bool pub) {
1820  getRootNS()->rpriv->parseAddConstantIntern(loc, ns, name, value, pub);
1821  }
1822 
1823  // returns 0 for success, non-zero for error
1824  DLLLOCAL static int parseAddMethodToClass(const QoreProgramLocation* loc, const NamedScope& name, MethodVariantBase* qcmethod, bool static_flag) {
1825  return getRootNS()->rpriv->parseAddMethodToClassIntern(loc, name, qcmethod, static_flag);
1826  }
1827 
1828  DLLLOCAL static void parseAddClass(const QoreProgramLocation* loc, const NamedScope& name, QoreClass* oc) {
1829  getRootNS()->rpriv->parseAddClassIntern(loc, name, oc);
1830  }
1831 
1832  DLLLOCAL static void parseAddHashDecl(const QoreProgramLocation* loc, const NamedScope& name, TypedHashDecl* hd) {
1833  getRootNS()->rpriv->parseAddHashDeclIntern(loc, name, hd);
1834  }
1835 
1836  DLLLOCAL static void parseAddNamespace(QoreNamespace* nns) {
1837  getRootNS()->rpriv->parseAddNamespaceIntern(nns);
1838  }
1839 
1840  DLLLOCAL static const QoreFunction* parseResolveFunction(const NamedScope& nscope) {
1841  const FunctionEntry* fe = getRootNS()->rpriv->parseResolveFunctionEntryIntern(nscope);
1842  return fe ? fe->getFunction() : nullptr;
1843  }
1844 
1845  DLLLOCAL static const FunctionEntry* parseResolveFunctionEntry(const NamedScope& nscope) {
1846  return getRootNS()->rpriv->parseResolveFunctionEntryIntern(nscope);
1847  }
1848 
1849  DLLLOCAL const QoreClass* runtimeFindScopedClass(const NamedScope& name) const;
1850 
1851  DLLLOCAL static ResolvedCallReferenceNode* runtimeGetCallReference(RootQoreNamespace& rns, const char* name, ExceptionSink* xsink) {
1852  return rns.rpriv->runtimeGetCallReference(name, xsink);
1853  }
1854 
1855  DLLLOCAL static Var* parseAddResolvedGlobalVarDef(const QoreProgramLocation* loc, const NamedScope& vname, const QoreTypeInfo* typeInfo) {
1856  return getRootNS()->rpriv->parseAddResolvedGlobalVarDefIntern(loc, vname, typeInfo);
1857  }
1858 
1859  DLLLOCAL static Var* parseAddGlobalVarDef(const QoreProgramLocation* loc, const NamedScope& vname, QoreParseTypeInfo* typeInfo) {
1860  return getRootNS()->rpriv->parseAddGlobalVarDefIntern(loc, vname, typeInfo);
1861  }
1862 
1863  DLLLOCAL static Var* parseCheckImplicitGlobalVar(const QoreProgramLocation* loc, const NamedScope& name, const QoreTypeInfo* typeInfo) {
1864  return getRootNS()->rpriv->parseCheckImplicitGlobalVarIntern(loc, name, typeInfo);
1865  }
1866 
1867  DLLLOCAL static Var* parseFindGlobalVar(const char* vname) {
1868  return getRootNS()->rpriv->parseFindGlobalVarIntern(vname);
1869  }
1870 
1871  DLLLOCAL static Var* parseFindGlobalVar(const NamedScope& nscope) {
1872  return getRootNS()->rpriv->parseFindGlobalVarIntern(nscope);
1873  }
1874 
1875  DLLLOCAL static void scanMergeCommittedNamespace(const RootQoreNamespace& ns, const RootQoreNamespace& mns, QoreModuleContext& qmc) {
1876  ns.priv->scanMergeCommittedNamespace(*(mns.priv), qmc);
1877  }
1878 
1879  DLLLOCAL static void copyMergeCommittedNamespace(RootQoreNamespace& ns, const RootQoreNamespace& mns) {
1880  ns.priv->copyMergeCommittedNamespace(*(mns.priv));
1881 
1882  // rebuild root indexes - only for committed objects
1883  ns.rpriv->rebuildAllIndexes();
1884  }
1885 
1886  DLLLOCAL static Var* runtimeFindGlobalVar(const RootQoreNamespace& rns, const char* vname, const qore_ns_private*& vns) {
1887  return rns.rpriv->runtimeFindGlobalVar(vname, vns);
1888  }
1889 
1890  DLLLOCAL static Var* runtimeCreateVar(RootQoreNamespace& rns, QoreNamespace& vns, const char* vname, const QoreTypeInfo* typeInfo, bool builtin = false) {
1891  return rns.rpriv->runtimeCreateVar(*vns.priv, vname, typeInfo, builtin);
1892  }
1893 
1894  DLLLOCAL static void runtimeImportGlobalVariable(RootQoreNamespace& rns, QoreNamespace& tns, Var* v, bool readonly, ExceptionSink* xsink) {
1895  return rns.rpriv->runtimeImportGlobalVariable(*tns.priv, v, readonly, xsink);
1896  }
1897 
1898  /*
1899  DLLLOCAL static void runtimeModuleRebuildIndexes(RootQoreNamespace& rns) {
1900  // rebuild root indexes
1901  QorePrivateNamespaceIterator qpni(rns.priv, true);
1902  while (qpni.next())
1903  rns.rpriv->rebuildIndexes(qpni.get());
1904  }
1905  */
1906 
1907  DLLLOCAL static const QoreClass* runtimeFindClass(RootQoreNamespace& rns, const char* name) {
1908  return rns.rpriv->runtimeFindClass(name);
1909  }
1910 
1911  DLLLOCAL static const ConstantEntry* runtimeFindNamespaceConstant(const RootQoreNamespace& rns, const char* cname, const qore_ns_private*& cns) {
1912  return rns.rpriv->runtimeFindNamespaceConstant(cname, cns);
1913  }
1914 
1915  DLLLOCAL static QoreNamespace* runtimeFindNamespaceForAddFunction(RootQoreNamespace& rns, const NamedScope& name, ExceptionSink* xsink) {
1916  return rns.rpriv->runtimeFindNamespaceForAddFunction(name, xsink);
1917  }
1918 
1919  DLLLOCAL static QoreNamespace* runtimeFindNamespaceForAddClass(RootQoreNamespace& rns, const NamedScope& name, ExceptionSink* xsink) {
1920  return rns.rpriv->runtimeFindNamespaceForAddClass(name, xsink);
1921  }
1922 
1923  DLLLOCAL static qore_root_ns_private* get(RootQoreNamespace& rns) {
1924  return rns.rpriv;
1925  }
1926 
1927  DLLLOCAL static const qore_root_ns_private* get(const RootQoreNamespace& rns) {
1928  return rns.rpriv;
1929  }
1930 
1931  DLLLOCAL static qore_ns_private* getQore(RootQoreNamespace& rns) {
1932  return rns.rpriv->qoreNS->priv;
1933  }
1934 
1935  DLLLOCAL static const qore_ns_private* getQore(const RootQoreNamespace& rns) {
1936  return rns.rpriv->qoreNS->priv;
1937  }
1938 
1939  DLLLOCAL static void clearConstants(RootQoreNamespace& ns, QoreListNode& l) {
1940  ns.priv->clearConstants(l);
1941  ns.rpriv->cnmap.clear();
1942  }
1943 
1944  DLLLOCAL static void clearData(RootQoreNamespace& ns, ExceptionSink* xsink) {
1945  ns.priv->clearData(xsink);
1946  }
1947 };
1948 
1949 #endif
DLLEXPORT const char * c_str() const
returns the string&#39;s buffer; this data should not be changed
DLLEXPORT qore_offset_t bindex(const QoreString &needle, qore_offset_t pos) const
returns the byte position of a substring within the string or -1 if not found
DLLEXPORT const char * getName() const
returns the name of the typed hash
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
#define PO_NO_API
an alias of PO_INHERITANCE_OPTIONS
Definition: Restrictions.h:153
contains constants, classes, and subnamespaces in QoreProgram objects
Definition: QoreNamespace.h:64
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
base class for call references, reference-counted, dynamically allocated only
Definition: CallReferenceNode.h:39
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:81
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
the root namespace of a QoreProgram object
Definition: QoreNamespace.h:286
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
DLLEXPORT QoreNamespace(const char *n)
creates a namespace with the given name
defines a Qore-language class
Definition: QoreClass.h:239
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only ...
Definition: QoreProgram.h:126
DLLEXPORT QoreNamespace * findCreateNamespacePath(const char *nspath)
finds a Namespace based on the argument; creates it (or the whole path) if necessary ...
static unsigned num_params(const QoreListNode *n)
returns the number of arguments passed to the function
Definition: params.h:54
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
DLLEXPORT const char * getName() const
returns the name of the namespace
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257
manages a reference count of a pointer to a class that takes a simple "deref()" call with no argument...
Definition: ReferenceHolder.h:118
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
std::vector< QoreValue > arg_vec_t
vector of value information for default argument lists
Definition: common.h:254
DLLEXPORT void addConstant(const char *name, QoreValue value)
adds a constant definition to the namespace
an unresolved call reference, only present temporarily in the parse tree
Definition: CallReferenceNode.h:68
typed hash declaration
Definition: TypedHashDecl.h:44
base class for resolved call references
Definition: CallReferenceNode.h:105
DLLEXPORT QoreNamespace * copy(int po) const
returns a deep copy of the namespace; DEPRECATED: use copy(int64) instead
std::vector< const QoreTypeInfo * > type_vec_t
vector of type information for parameter lists
Definition: common.h:251
DLLEXPORT const char * getName() const
returns the class name