blob: 72c00695435097793231fb9a5b641f2b992791b8 [file] [log] [blame]
// 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