blob: 80c25f1549802171820332144f1dce8c80880a2d [file] [log] [blame]
Googler2aac9832021-11-26 14:20:34 +00001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#include "lifetime_annotations/test/named_func_lifetimes.h"
6
7#include <algorithm>
Googler32c6ddf2021-11-30 11:46:44 +00008#include <optional>
Googler2aac9832021-11-26 14:20:34 +00009#include <string>
10
Lukasz Anforowiczcec7a8a2022-04-27 10:24:51 -070011#include "llvm/ADT/DenseMap.h"
Googler2aac9832021-11-26 14:20:34 +000012
Martin Brænne1a207c52022-04-19 00:05:38 -070013namespace clang {
14namespace tidy {
15namespace lifetimes {
Googler2aac9832021-11-26 14:20:34 +000016
Googler32c6ddf2021-11-30 11:46:44 +000017std::string NameLifetimes(const FunctionLifetimes& func_lifetimes) {
18 LifetimeSymbolTable symbol_table;
19 return func_lifetimes.DebugString([&symbol_table](Lifetime l) -> std::string {
Googler2aac9832021-11-26 14:20:34 +000020 if (l.IsLocal()) {
21 return "local";
22 }
23 if (l == Lifetime::Static()) {
24 return "static";
25 }
Googler32c6ddf2021-11-30 11:46:44 +000026 return symbol_table.LookupLifetimeAndMaybeDeclare(l).str();
27 });
28}
29
30std::string NameLifetimes(const FunctionLifetimes& func_lifetimes,
31 const LifetimeSymbolTable& symbol_table) {
32 return func_lifetimes.DebugString([&symbol_table](Lifetime l) -> std::string {
33 if (l.IsLocal()) {
34 return "local";
Googler2aac9832021-11-26 14:20:34 +000035 }
Googler32c6ddf2021-11-30 11:46:44 +000036 if (l == Lifetime::Static()) {
37 return "static";
38 }
39 std::optional<llvm::StringRef> name = symbol_table.LookupLifetime(l);
40 assert(name.has_value());
41 return name.value().str();
42 });
Googler2aac9832021-11-26 14:20:34 +000043}
44
45std::optional<llvm::StringRef> NamedFuncLifetimes::Get(
46 llvm::StringRef func) const {
47 auto iter = lifetimes_.find(func);
48 if (iter == lifetimes_.end()) {
49 return std::nullopt;
50 }
51 return iter->second;
52}
53
54std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
55NamedFuncLifetimes::Entries() const {
56 std::vector<std::pair<llvm::StringRef, llvm::StringRef>> entries;
57 for (const auto& entry : lifetimes_) {
58 entries.emplace_back(entry.getKey(), entry.getValue());
59 }
60 std::sort(entries.begin(), entries.end());
61 return entries;
62}
63
64std::ostream& operator<<(std::ostream& os,
65 const NamedFuncLifetimes& lifetimes) {
66 std::vector<std::pair<llvm::StringRef, llvm::StringRef>> entries =
67 lifetimes.Entries();
68 for (size_t i = 0; i < entries.size(); ++i) {
69 if (i > 0) {
70 os << "; ";
71 }
72 os << entries[i].first.str() << ": " << entries[i].second.str();
73 }
74
75 return os;
76}
77
78class LifetimesAreMatcher {
79 public:
80 using is_gtest_matcher = void;
81
82 explicit LifetimesAreMatcher(NamedFuncLifetimes expected)
83 : expected_(std::move(expected)) {}
84
85 bool MatchAndExplain(const NamedFuncLifetimes& lifetimes,
86 std::ostream*) const {
87 return lifetimes == expected_;
88 }
89
90 void DescribeTo(std::ostream* os) const { *os << "is " << expected_; }
91
92 void DescribeNegationTo(std::ostream* os) const {
93 *os << "is not " << expected_;
94 }
95
96 private:
97 NamedFuncLifetimes expected_;
98};
99
100testing::Matcher<NamedFuncLifetimes> LifetimesAre(NamedFuncLifetimes expected) {
101 return LifetimesAreMatcher(std::move(expected));
102}
103
104class LifetimesContainMatcher {
105 public:
106 using is_gtest_matcher = void;
107
108 explicit LifetimesContainMatcher(NamedFuncLifetimes expected)
109 : expected_(std::move(expected)) {}
110
111 bool MatchAndExplain(const NamedFuncLifetimes& lifetimes,
112 std::ostream*) const {
113 for (auto [func, expected_lifetimes] : expected_.Entries()) {
114 std::optional<llvm::StringRef> actual_lifetimes = lifetimes.Get(func);
115 if (!actual_lifetimes.has_value() ||
116 *actual_lifetimes != expected_lifetimes) {
117 return false;
118 }
119 }
120 return true;
121 }
122
123 void DescribeTo(std::ostream* os) const { *os << "contains " << expected_; }
124
125 void DescribeNegationTo(std::ostream* os) const {
126 *os << "does not contain " << expected_;
127 }
128
129 private:
130 NamedFuncLifetimes expected_;
131};
132
133testing::Matcher<NamedFuncLifetimes> LifetimesContain(
134 NamedFuncLifetimes expected) {
135 return LifetimesContainMatcher(std::move(expected));
136}
137
Martin Brænne1a207c52022-04-19 00:05:38 -0700138} // namespace lifetimes
139} // namespace tidy
140} // namespace clang