clang-tools 22.0.0git
AssertEqualsCheck.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "AssertEqualsCheck.h"
10#include "llvm/ADT/StringMap.h"
11
12#include <string>
13
14using namespace clang::ast_matchers;
15
17
18// Mapping from `XCTAssert*Equal` to `XCTAssert*EqualObjects` name.
19static const llvm::StringMap<StringRef> NameMap{
20 {"XCTAssertEqual", "XCTAssertEqualObjects"},
21 {"XCTAssertNotEqual", "XCTAssertNotEqualObjects"},
22};
23
24void AssertEqualsCheck::registerMatchers(MatchFinder *Finder) {
25 for (const auto &[CurrName, _] : NameMap) {
26 Finder->addMatcher(
27 binaryOperator(anyOf(hasOperatorName("!="), hasOperatorName("==")),
28 isExpandedFromMacro(std::string(CurrName)),
29 anyOf(hasLHS(hasType(qualType(
30 hasCanonicalType(asString("NSString *"))))),
31 hasRHS(hasType(qualType(
32 hasCanonicalType(asString("NSString *")))))))
33 .bind(CurrName),
34 this);
35 }
36}
37
39 const ast_matchers::MatchFinder::MatchResult &Result) {
40 for (const auto &[CurrName, TargetName] : NameMap) {
41 if (const auto *Root = Result.Nodes.getNodeAs<BinaryOperator>(CurrName)) {
42 const SourceManager *Sm = Result.SourceManager;
43 // The macros are nested two levels, so going up twice.
44 auto MacroCallsite = Sm->getImmediateMacroCallerLoc(
45 Sm->getImmediateMacroCallerLoc(Root->getBeginLoc()));
46 diag(MacroCallsite,
47 (Twine("use ") + TargetName + " for comparing objects").str())
48 << FixItHint::CreateReplacement(
49 clang::CharSourceRange::getCharRange(
50 MacroCallsite,
51 MacroCallsite.getLocWithOffset(CurrName.size())),
52 TargetName);
53 }
54 }
55}
56
57} // namespace clang::tidy::objc
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
static const llvm::StringMap< StringRef > NameMap