X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/17860defa84c6d8bc0e8bc088a7e09361f17db07..c4231c6faf4e1b4650b075c641b0bb8c053739e4:/src/find.h?ds=sidebyside diff --git a/src/find.h b/src/find.h index ea3ae22..3342536 100644 --- a/src/find.h +++ b/src/find.h @@ -27,98 +27,136 @@ opt findPtr(const std::vector & ts, std::function f) return nullopt; } -bool checkNamespace(std::shared_ptr ctx, const std::vector & namespacePrefix) +std::optional< + std::tuple< + std::shared_ptr, + std::vector>> +getContext(std::shared_ptr ctx, const std::vector & namespacePrefix) { - - bool prefixMatches = true; + auto result = ctx; - auto nIt = ctx; - for (int i = namespacePrefix.size() - 1; i >= 0; i--) + for (auto name : namespacePrefix) + { + auto newResult = find(result->namespaces, [&](Namespace n) { return n.name == name; }); + if (newResult.has_value()) + { + result = newResult->ctx; + } + else { - const std::string & prefix = namespacePrefix[i]; - if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix) - { - prefixMatches = false; - break; - } - nIt = nIt->parent; + return nullopt; } + } + + std::vector namespaces; + for (auto it = result; it != nullptr; it = it->parent) + { + if (it->name.has_value()) + { + namespaces.insert(namespaces.begin(), it->name.value()); + } + else if (it->parent != nullptr) + { + namespaces.clear(); + break; + } + } - return prefixMatches; + return std::make_tuple(result, namespaces); } -opt findFunction( +opt>> findFunction( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto f = find(it->functions, [&](Function f) { return f.name == name; }); - if (f.has_value() && checkNamespace(it, namespacePrefix)) - return f; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findFunctionPtr( +opt>> findFunctionPtr( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto f = findPtr(it->functions, [&](Function f) { return f.name == name; }); - if (f.has_value() && checkNamespace(it, namespacePrefix)) - return f; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->functions, [&](Function _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findStruct( +opt>> findStruct( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto s = find(it->structs, [&](Struct s) { return s.name == name; }); - if (s.has_value() && checkNamespace(it, namespacePrefix)) - return s; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findStructPtr( +opt>> findStructPtr( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto s = findPtr(it->structs, [&](Struct s) { return s.name == name; }); - if (s.has_value() && checkNamespace(it, namespacePrefix)) - return s; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = findPtr(std::get<0>(*n)->structs, [&](Struct _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; } -opt findVariable( +opt>> findVariable( const std::string & name, const std::vector & namespacePrefix, std::shared_ptr ctx) { for (auto it = ctx; it != nullptr; it = it->parent) { - auto v = find(it->variables, [&](Variable v) { return v.name == name; }); - if (v.has_value() && checkNamespace(it, namespacePrefix)) - return v; + auto n = getContext(it, namespacePrefix); + if (n.has_value()) + { + auto x = find(std::get<0>(*n)->variables, [&](Variable _) { return _.name == name; }); + if (x.has_value()) + return std::make_tuple(x.value(), std::get<1>(*n)); + } } return nullopt; }