11 #include "../utils/OptionsUtils.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/ASTMatchers/ASTMatchers.h"
14 #include "clang/Frontend/CompilerInstance.h"
15 #include "clang/Tooling/Transformer/RewriteRule.h"
16 #include "clang/Tooling/Transformer/Stencil.h"
27 using ::clang::transformer::applyFirst;
28 using ::clang::transformer::cat;
29 using ::clang::transformer::change;
30 using ::clang::transformer::makeRule;
31 using ::clang::transformer::node;
34 "::std::basic_string_view;"
35 "::absl::string_view";
38 static llvm::Optional<transformer::RewriteRule>
48 const std::vector<std::string> StringLikeClassNames =
51 const std::string AbseilStringsMatchHeader =
54 auto StringLikeClass = cxxRecordDecl(hasAnyName(SmallVector<StringRef, 4>(
55 StringLikeClassNames.begin(), StringLikeClassNames.end())));
57 hasUnqualifiedDesugaredType(recordType(hasDeclaration(StringLikeClass)));
59 hasUnqualifiedDesugaredType(pointerType(pointee(isAnyCharacter())));
60 auto StringNpos = declRefExpr(
61 to(varDecl(hasName(
"npos"), hasDeclContext(StringLikeClass))));
62 auto StringFind = cxxMemberCallExpr(
65 hasParameter(0, parmVarDecl(anyOf(hasType(StringType),
66 hasType(CharStarType)))))),
67 on(hasType(StringType)), hasArgument(0, expr().bind(
"parameter_to_find")),
68 anyOf(hasArgument(1, integerLiteral(equals(0))),
69 hasArgument(1, cxxDefaultArgExpr())),
70 onImplicitObjectArgument(expr().bind(
"string_being_searched")));
72 tooling::RewriteRule rule = applyFirst(
73 {makeRule(binaryOperator(hasOperatorName(
"=="),
74 hasOperands(ignoringParenImpCasts(StringNpos),
75 ignoringParenImpCasts(StringFind))),
76 change(cat(
"!absl::StrContains(", node(
"string_being_searched"),
77 ", ", node(
"parameter_to_find"),
")")),
78 cat(
"use !absl::StrContains instead of find() == npos")),
79 makeRule(binaryOperator(hasOperatorName(
"!="),
80 hasOperands(ignoringParenImpCasts(StringNpos),
81 ignoringParenImpCasts(StringFind))),
82 change(cat(
"absl::StrContains(", node(
"string_being_searched"),
83 ", ", node(
"parameter_to_find"),
")")),
84 cat(
"use absl::StrContains instead of find() != npos"))});
85 addInclude(rule, AbseilStringsMatchHeader);
89 StringFindStrContainsCheck::StringFindStrContainsCheck(
94 AbseilStringsMatchHeaderOption(Options.get(
98 const LangOptions &LangOpts)
const {
99 return LangOpts.CPlusPlus11;
104 TransformerClangTidyCheck::storeOptions(Opts);
108 AbseilStringsMatchHeaderOption);