1 | // RUN: %check_clang_tidy -std=c++17 %s abseil-string-find-startswith %t -- \ |
2 | // RUN: -config="{CheckOptions: \ |
3 | // RUN: {abseil-string-find-startswith.StringLikeClasses: \ |
4 | // RUN: '::std::basic_string;::std::basic_string_view;::basic_string'}}" \ |
5 | // RUN: -- -isystem %clang_tidy_headers |
6 | |
7 | #include <string> |
8 | |
9 | using size_t = decltype(sizeof(int)); |
10 | |
11 | namespace std { |
12 | struct cxx_string { |
13 | int find(const char *s, int pos = 0); |
14 | int rfind(const char *s, int pos = npos); |
15 | static constexpr size_t npos = -1; |
16 | }; |
17 | } // namespace std |
18 | |
19 | struct basic_string : public std::cxx_string { |
20 | basic_string(); |
21 | }; |
22 | typedef basic_string global_string; |
23 | |
24 | std::string foo(std::string); |
25 | std::string bar(); |
26 | |
27 | #define A_MACRO(x, y) ((x) == (y)) |
28 | |
29 | void tests(std::string s, global_string s2, std::string_view sv) { |
30 | s.find(s: "a" ) == 0; |
31 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of find() == 0 [abseil-string-find-startswith] |
32 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}} |
33 | |
34 | s.find(str: s) == 0; |
35 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith |
36 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, s);{{$}} |
37 | |
38 | s.find(s: "aaa" ) != 0; |
39 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
40 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "aaa");{{$}} |
41 | |
42 | s.find(str: foo(foo(bar()))) != 0; |
43 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
44 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, foo(foo(bar())));{{$}} |
45 | |
46 | if (s.find(s: "...." ) == 0) { /* do something */ } |
47 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use absl::StartsWith |
48 | // CHECK-FIXES: {{^[[:space:]]*}}if (absl::StartsWith(s, "....")) { /* do something */ }{{$}} |
49 | |
50 | 0 != s.find(s: "a" ); |
51 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
52 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "a");{{$}} |
53 | |
54 | s2.find(s: "a" ) == 0; |
55 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith |
56 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}} |
57 | |
58 | s.rfind(s: "a" , pos: 0) == 0; |
59 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of rfind() == 0 [abseil-string-find-startswith] |
60 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}} |
61 | |
62 | s.rfind(str: s, pos: 0) == 0; |
63 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith |
64 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, s);{{$}} |
65 | |
66 | s.rfind(s: "aaa" , pos: 0) != 0; |
67 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
68 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "aaa");{{$}} |
69 | |
70 | s.rfind(str: foo(foo(bar())), pos: 0) != 0; |
71 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
72 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, foo(foo(bar())));{{$}} |
73 | |
74 | if (s.rfind(s: "...." , pos: 0) == 0) { /* do something */ } |
75 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use absl::StartsWith |
76 | // CHECK-FIXES: {{^[[:space:]]*}}if (absl::StartsWith(s, "....")) { /* do something */ }{{$}} |
77 | |
78 | 0 != s.rfind(s: "a" , pos: 0); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
80 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "a");{{$}} |
81 | |
82 | s2.rfind(s: "a" , pos: 0) == 0; |
83 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith |
84 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}} |
85 | |
86 | sv.find(str: "a" ) == 0; |
87 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith |
88 | // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(sv, "a");{{$}} |
89 | |
90 | sv.rfind(str: "a" , pos: 0) != 0; |
91 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith |
92 | // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(sv, "a");{{$}} |
93 | |
94 | // expressions that don't trigger the check are here. |
95 | A_MACRO(s.find("a" ), 0); |
96 | A_MACRO(s.rfind("a" , 0), 0); |
97 | s.find(s: "a" , pos: 1) == 0; |
98 | s.find(s: "a" , pos: 1) == 1; |
99 | s.find(s: "a" ) == 1; |
100 | s.rfind(s: "a" , pos: 1) == 0; |
101 | s.rfind(s: "a" , pos: 1) == 1; |
102 | s.rfind(s: "a" ) == 0; |
103 | s.rfind(s: "a" ) == 1; |
104 | } |
105 | |