X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/b9322dfb8efe37f6f88a899269bdf21015f4db9a..c4231c6faf4e1b4650b075c641b0bb8c053739e4:/src/find.h?ds=inline diff --git a/src/find.h b/src/find.h index fec540f..3342536 100644 --- a/src/find.h +++ b/src/find.h @@ -27,202 +27,165 @@ opt findPtr(const std::vector & ts, std::function f) return nullopt; } -opt findFunction( - const Program & p, - const std::string & name, - const std::vector & namespacePrefixes) +std::optional< + std::tuple< + std::shared_ptr, + std::vector>> +getContext(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; + auto result = ctx; - std::vector namespaces = { n.value() }; - - for (int i = 1; i < namespacePrefixes.size(); i++) + for (auto name : namespacePrefix) { - n = find(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; }); - - if (!n.has_value()) + auto newResult = find(result->namespaces, [&](Namespace n) { return n.name == name; }); + if (newResult.has_value()) + { + result = newResult->ctx; + } + else + { return nullopt; - - namespaces.push_back(n.value()); + } } - for (int i = namespaces.size()-1; i >= 0; i--) + std::vector namespaces; + for (auto it = result; it != nullptr; it = it->parent) { - auto f = find(namespaces[i].functions, [&](Function f) { return f.name == name; }); - if (f.has_value()) - return f.value(); + if (it->name.has_value()) + { + namespaces.insert(namespaces.begin(), it->name.value()); + } + else if (it->parent != nullptr) + { + namespaces.clear(); + break; + } } - return find(p.functions, [&](Function f) { return f.name == name; }); + return std::make_tuple(result, namespaces); } -opt findFunctionPtr( - const Program & p, - const std::string & name, - const std::vector & namespacePrefixes) -{ - if (namespacePrefixes.empty()) - { - 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()); - } - - 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 = findPtr(namespaces[i].functions, [&](Function f) { return f.name == name; }); - if (f.has_value()) - return f.value(); + 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 findPtr(p.functions, [&](Function f) { return f.name == name; }); + return nullopt; } -opt findStruct( - const Program & p, +opt>> findFunctionPtr( 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 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)); + } } - - 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]; }); + return nullopt; +} - if (!n.has_value()) - return nullopt; - namespaces.push_back(n.value()); - } - for (int i = namespaces.size()-1; i >= 0; i--) +opt>> findStruct( + 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].structs, [&](Struct f) { return f.name == name; }); - if (f.has_value()) - return f.value(); + 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 find(n.value().structs, [&](Struct s) { return s.name == name; }); + return nullopt; } -opt findStructPtr( - const Program & p, +opt>> findStructPtr( 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 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; +} - 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, +opt>> findVariable( 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()) - return v; - it = it->parent; + 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; } + + 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