X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/c2ba7425955ae538e220cec79d9124756d1b4c8b..b9322dfb8efe37f6f88a899269bdf21015f4db9a:/src/find.h diff --git a/src/find.h b/src/find.h index 1876a1e..fec540f 100644 --- a/src/find.h +++ b/src/find.h @@ -18,6 +18,15 @@ opt find(const std::vector & ts, std::function f) return nullopt; } +template +opt findPtr(const std::vector & ts, std::function f) +{ + for (int i = 0; i < ts.size(); i++) + if (f(ts[i])) + return &((T *)ts.data())[i]; + return nullopt; +} + opt findFunction( const Program & p, const std::string & name, @@ -55,6 +64,43 @@ opt findFunction( return find(p.functions, [&](Function f) { return f.name == name; }); } +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--) + { + 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, @@ -69,6 +115,8 @@ opt findStruct( if (!n.has_value()) return nullopt; + + std::vector namespaces = { n.value() }; for (int i = 1; i < namespacePrefixes.size(); i++) { @@ -76,10 +124,57 @@ opt findStruct( 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; }); } +opt findStructPtr( + const Program & p, + const std::string & name, + const std::vector & namespacePrefixes) +{ + 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++) + { + 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 = 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, @@ -96,7 +191,7 @@ opt findVariable( return nullopt; } -opt findStructMethod( +opt> findStructMethod( const Program & p, const std::string & name, TypeInfo ti) @@ -108,8 +203,20 @@ opt findStructMethod( return nullopt; return find>(s.value().methods, [&](Function f) { return f.name == name; }); } +opt *> findStructMethodPtr( + const Program & p, + const std::string & name, + TypeInfo ti) +{ + 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; }); +} -opt findStructMember( +opt> findStructMember( const Program & p, TypeInfo ti, const std::string & name)