55 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "MissingHashCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::objc {16 17namespace {18 19AST_MATCHER_P(ObjCImplementationDecl, hasInterface,20 ast_matchers::internal::Matcher<ObjCInterfaceDecl>, Base) {21 const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface();22 return Base.matches(*InterfaceDecl, Finder, Builder);23}24 25AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod,26 ast_matchers::internal::Matcher<ObjCMethodDecl>, Base) {27 // Check each instance method against the provided matcher.28 for (const auto *I : Node.instance_methods()) {29 if (Base.matches(*I, Finder, Builder))30 return true;31 }32 return false;33}34 35} // namespace36 37void MissingHashCheck::registerMatchers(MatchFinder *Finder) {38 Finder->addMatcher(39 objcMethodDecl(40 hasName("isEqual:"), isInstanceMethod(),41 hasDeclContext(objcImplementationDecl(42 hasInterface(isDirectlyDerivedFrom("NSObject")),43 unless(hasInstanceMethod(hasName("hash"))))44 .bind("impl"))),45 this);46}47 48void MissingHashCheck::check(const MatchFinder::MatchResult &Result) {49 const auto *ID = Result.Nodes.getNodeAs<ObjCImplementationDecl>("impl");50 diag(ID->getLocation(), "%0 implements -isEqual: without implementing -hash")51 << ID;52}53 54} // namespace clang::tidy::objc55