| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #include "lifetime_annotations/test/named_func_lifetimes.h" |
| |
| #include <algorithm> |
| #include <cassert> |
| #include <cstddef> |
| #include <optional> |
| #include <ostream> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "lifetime_annotations/function_lifetimes.h" |
| #include "lifetime_annotations/lifetime.h" |
| #include "lifetime_annotations/lifetime_symbol_table.h" |
| #include "llvm/ADT/StringRef.h" |
| |
| namespace clang { |
| namespace tidy { |
| namespace lifetimes { |
| |
| std::string NameLifetimes(const FunctionLifetimes& func_lifetimes) { |
| LifetimeSymbolTable symbol_table; |
| return func_lifetimes.DebugString([&symbol_table](Lifetime l) -> std::string { |
| if (l.IsLocal()) { |
| return "local"; |
| } |
| if (l == Lifetime::Static()) { |
| return "static"; |
| } |
| return symbol_table.LookupLifetimeAndMaybeDeclare(l).str(); |
| }); |
| } |
| |
| std::string NameLifetimes(const FunctionLifetimes& func_lifetimes, |
| const LifetimeSymbolTable& symbol_table) { |
| return func_lifetimes.DebugString([&symbol_table](Lifetime l) -> std::string { |
| if (l.IsLocal()) { |
| return "local"; |
| } |
| if (l == Lifetime::Static()) { |
| return "static"; |
| } |
| std::optional<llvm::StringRef> name = symbol_table.LookupLifetime(l); |
| assert(name.has_value()); |
| return name.value().str(); |
| }); |
| } |
| |
| std::optional<llvm::StringRef> NamedFuncLifetimes::Get( |
| llvm::StringRef func) const { |
| auto iter = lifetimes_.find(func); |
| if (iter == lifetimes_.end()) { |
| return std::nullopt; |
| } |
| return iter->second; |
| } |
| |
| std::vector<std::pair<llvm::StringRef, llvm::StringRef>> |
| NamedFuncLifetimes::Entries() const { |
| std::vector<std::pair<llvm::StringRef, llvm::StringRef>> entries; |
| for (const auto& entry : lifetimes_) { |
| entries.emplace_back(entry.getKey(), entry.getValue()); |
| } |
| std::sort(entries.begin(), entries.end()); |
| return entries; |
| } |
| |
| std::ostream& operator<<(std::ostream& os, |
| const NamedFuncLifetimes& lifetimes) { |
| std::vector<std::pair<llvm::StringRef, llvm::StringRef>> entries = |
| lifetimes.Entries(); |
| for (size_t i = 0; i < entries.size(); ++i) { |
| if (i > 0) { |
| os << "; "; |
| } |
| os << entries[i].first.str() << ": " << entries[i].second.str(); |
| } |
| |
| return os; |
| } |
| |
| class LifetimesAreMatcher { |
| public: |
| using is_gtest_matcher = void; |
| |
| explicit LifetimesAreMatcher(NamedFuncLifetimes expected) |
| : expected_(std::move(expected)) {} |
| |
| bool MatchAndExplain(const NamedFuncLifetimes& lifetimes, |
| std::ostream*) const { |
| return lifetimes == expected_; |
| } |
| |
| void DescribeTo(std::ostream* os) const { *os << "is " << expected_; } |
| |
| void DescribeNegationTo(std::ostream* os) const { |
| *os << "is not " << expected_; |
| } |
| |
| private: |
| NamedFuncLifetimes expected_; |
| }; |
| |
| testing::Matcher<NamedFuncLifetimes> LifetimesAre(NamedFuncLifetimes expected) { |
| return LifetimesAreMatcher(std::move(expected)); |
| } |
| |
| class LifetimesContainMatcher { |
| public: |
| using is_gtest_matcher = void; |
| |
| explicit LifetimesContainMatcher(NamedFuncLifetimes expected) |
| : expected_(std::move(expected)) {} |
| |
| bool MatchAndExplain(const NamedFuncLifetimes& lifetimes, |
| std::ostream*) const { |
| for (auto [func, expected_lifetimes] : expected_.Entries()) { |
| std::optional<llvm::StringRef> actual_lifetimes = lifetimes.Get(func); |
| if (!actual_lifetimes.has_value() || |
| *actual_lifetimes != expected_lifetimes) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| void DescribeTo(std::ostream* os) const { *os << "contains " << expected_; } |
| |
| void DescribeNegationTo(std::ostream* os) const { |
| *os << "does not contain " << expected_; |
| } |
| |
| private: |
| NamedFuncLifetimes expected_; |
| }; |
| |
| testing::Matcher<NamedFuncLifetimes> LifetimesContain( |
| NamedFuncLifetimes expected) { |
| return LifetimesContainMatcher(std::move(expected)); |
| } |
| |
| } // namespace lifetimes |
| } // namespace tidy |
| } // namespace clang |