AssertEquals.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. //===--- AssertEquals.cpp - clang-tidy --------------------------*- C++ -*-===//
  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. #include "AssertEquals.h"
  9. #include <map>
  10. #include <string>
  11. using namespace clang::ast_matchers;
  12. namespace clang::tidy::objc {
  13. // Mapping from `XCTAssert*Equal` to `XCTAssert*EqualObjects` name.
  14. static const std::map<std::string, std::string> &NameMap() {
  15. static std::map<std::string, std::string> map{
  16. {"XCTAssertEqual", "XCTAssertEqualObjects"},
  17. {"XCTAssertNotEqual", "XCTAssertNotEqualObjects"},
  18. };
  19. return map;
  20. }
  21. void AssertEquals::registerMatchers(MatchFinder *finder) {
  22. for (const auto &pair : NameMap()) {
  23. finder->addMatcher(
  24. binaryOperator(anyOf(hasOperatorName("!="), hasOperatorName("==")),
  25. isExpandedFromMacro(pair.first),
  26. anyOf(hasLHS(hasType(qualType(
  27. hasCanonicalType(asString("NSString *"))))),
  28. hasRHS(hasType(qualType(
  29. hasCanonicalType(asString("NSString *"))))))
  30. )
  31. .bind(pair.first),
  32. this);
  33. }
  34. }
  35. void AssertEquals::check(const ast_matchers::MatchFinder::MatchResult &result) {
  36. for (const auto &pair : NameMap()) {
  37. if (const auto *root = result.Nodes.getNodeAs<BinaryOperator>(pair.first)) {
  38. SourceManager *sm = result.SourceManager;
  39. // The macros are nested two levels, so going up twice.
  40. auto macro_callsite = sm->getImmediateMacroCallerLoc(
  41. sm->getImmediateMacroCallerLoc(root->getBeginLoc()));
  42. diag(macro_callsite, "use " + pair.second + " for comparing objects")
  43. << FixItHint::CreateReplacement(
  44. clang::CharSourceRange::getCharRange(
  45. macro_callsite,
  46. macro_callsite.getLocWithOffset(pair.first.length())),
  47. pair.second);
  48. }
  49. }
  50. }
  51. } // namespace clang::tidy::objc