X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/3715a3f575b615f66e8ea7e57f83849e8bae4deb..17860defa84c6d8bc0e8bc088a7e09361f17db07:/src/find.h diff --git a/src/find.h b/src/find.h index fec540f..ea3ae22 100644 --- a/src/find.h +++ b/src/find.h @@ -27,202 +27,127 @@ opt findPtr(const std::vector & ts, std::function f) return nullopt; } -opt findFunction( - const Program & p, - const std::string & name, - const std::vector & namespacePrefixes) +bool checkNamespace(std::shared_ptr ctx, const std::vector & namespacePrefix) { - if (namespacePrefixes.empty()) - { - return find(p.functions, [&](Function f) { return f.name == name; }); - } - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - std::vector namespaces = { n.value() }; + bool prefixMatches = true; + + auto nIt = ctx; + for (int i = namespacePrefix.size() - 1; i >= 0; i--) + { + const std::string & prefix = namespacePrefix[i]; + if (nIt == nullptr || ! nIt->name.has_value() || nIt->name.value() != prefix) + { + prefixMatches = false; + break; + } + nIt = nIt->parent; + } + + return prefixMatches; +} - for (int i = 1; i < namespacePrefixes.size(); i++) - { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; - namespaces.push_back(n.value()); - } - for (int i = namespaces.size()-1; i >= 0; i--) +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(namespaces[i].functions, [&](Function f) { return f.name == name; }); - if (f.has_value()) - return f.value(); + auto f = find(it->functions, [&](Function f) { return f.name == name; }); + if (f.has_value() && checkNamespace(it, namespacePrefix)) + return f; } - - return find(p.functions, [&](Function f) { return f.name == name; }); + return nullopt; } opt findFunctionPtr( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - if (namespacePrefixes.empty()) + for (auto it = ctx; it != nullptr; it = it->parent) { - return findPtr(p.functions, [&](Function f) { return f.name == name; }); - } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - std::vector namespaces = { n.value() }; - - for (int i = 1; i < namespacePrefixes.size(); i++) - { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; - - namespaces.push_back(n.value()); + auto f = findPtr(it->functions, [&](Function f) { return f.name == name; }); + if (f.has_value() && checkNamespace(it, namespacePrefix)) + return f; } + return nullopt; +} - for (int i = namespaces.size()-1; i >= 0; i--) - { - auto f = findPtr(namespaces[i].functions, [&](Function f) { return f.name == name; }); - if (f.has_value()) - return f.value(); - } - return findPtr(p.functions, [&](Function f) { return f.name == name; }); -} opt findStruct( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - if (namespacePrefixes.empty()) + for (auto it = ctx; it != nullptr; it = it->parent) { - return find(p.structs, [&](Struct s) { return s.name == name; }); + auto s = find(it->structs, [&](Struct s) { return s.name == name; }); + if (s.has_value() && checkNamespace(it, namespacePrefix)) + return s; } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - std::vector namespaces = { n.value() }; - - for (int i = 1; i < namespacePrefixes.size(); i++) - { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; - - namespaces.push_back(n.value()); - } - - for (int i = namespaces.size()-1; i >= 0; i--) - { - auto f = find(namespaces[i].structs, [&](Struct f) { return f.name == name; }); - if (f.has_value()) - return f.value(); - } - - return find(n.value().structs, [&](Struct s) { return s.name == name; }); + return nullopt; } opt findStructPtr( - const Program & p, const std::string & name, - const std::vector & namespacePrefixes) + const std::vector & namespacePrefix, + std::shared_ptr ctx) { - if (namespacePrefixes.empty()) - { - return findPtr(p.structs, [&](Struct s) { return s.name == name; }); - } - - auto n = find(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; }); - - if (!n.has_value()) - return nullopt; - - std::vector namespaces = { n.value() }; - - for (int i = 1; i < namespacePrefixes.size(); i++) + for (auto it = ctx; it != nullptr; it = it->parent) { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) - return nullopt; - - namespaces.push_back(n.value()); + auto s = findPtr(it->structs, [&](Struct s) { return s.name == name; }); + if (s.has_value() && checkNamespace(it, namespacePrefix)) + return s; } + return nullopt; +} - for (int i = namespaces.size()-1; i >= 0; i--) - { - auto f = findPtr(namespaces[i].structs, [&](Struct f) { return f.name == name; }); - if (f.has_value()) - return f.value(); - } - return findPtr(n.value().structs, [&](Struct s) { return s.name == name; }); -} opt findVariable( - const Program & p, const std::string & name, + const std::vector & namespacePrefix, std::shared_ptr ctx) { - auto it = ctx; - while (it != nullptr) + for (auto it = ctx; it != nullptr; it = it->parent) { auto v = find(it->variables, [&](Variable v) { return v.name == name; }); - if (v.has_value()) + if (v.has_value() && checkNamespace(it, namespacePrefix)) return v; - it = it->parent; } return nullopt; } + + opt> findStructMethod( - const Program & p, const std::string & name, - TypeInfo ti) + const Struct & s) { - if (!ti.isStruct) - return nullopt; - auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes); - if (!s.has_value()) - return nullopt; - return find>(s.value().methods, [&](Function f) { return f.name == name; }); + return find>(s.methods, [&](Function f) { return f.name == name; }); } opt *> findStructMethodPtr( - const Program & p, const std::string & name, - TypeInfo ti) + const Struct & s) { - if (!ti.isStruct) - return nullopt; - auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes); - if (!s.has_value()) - return nullopt; - return findPtr>(s.value().methods, [&](Function f) { return f.name == name; }); + return findPtr>(s.methods, [&](Function f) { return f.name == name; }); } opt> findStructMember( - const Program & p, - TypeInfo ti, - const std::string & name) + const std::string & name, + const Struct & s) +{ + return find>(s.members, [&](Variable v) { return v.name == name; }); +} + +opt *> findStructMemberPtr( + const std::string & name, + const Struct & s) { - auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes); - if (!s.has_value()) - return nullopt; - return find>(s.value().members, [&](Variable v) { return v.name == name; }); + return findPtr>(s.members, [&](Variable v) { return v.name == name; }); } \ No newline at end of file