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