59 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- MissingHashCheck.cpp - clang-tidy --------------------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "MissingHashCheck.h"
 | |
| #include "clang/AST/ASTContext.h"
 | |
| #include "clang/ASTMatchers/ASTMatchFinder.h"
 | |
| 
 | |
| using namespace clang::ast_matchers;
 | |
| 
 | |
| namespace clang {
 | |
| namespace tidy {
 | |
| namespace objc {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| AST_MATCHER_P(ObjCImplementationDecl, hasInterface,
 | |
|               ast_matchers::internal::Matcher<ObjCInterfaceDecl>, Base) {
 | |
|   const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface();
 | |
|   return Base.matches(*InterfaceDecl, Finder, Builder);
 | |
| }
 | |
| 
 | |
| AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod,
 | |
|               ast_matchers::internal::Matcher<ObjCMethodDecl>, Base) {
 | |
|   // Check each instance method against the provided matcher.
 | |
|   for (const auto *I : Node.instance_methods()) {
 | |
|     if (Base.matches(*I, Finder, Builder))
 | |
|       return true;
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| void MissingHashCheck::registerMatchers(MatchFinder *Finder) {
 | |
|   Finder->addMatcher(
 | |
|       objcMethodDecl(
 | |
|           hasName("isEqual:"), isInstanceMethod(),
 | |
|           hasDeclContext(objcImplementationDecl(
 | |
|                              hasInterface(isDirectlyDerivedFrom("NSObject")),
 | |
|                              unless(hasInstanceMethod(hasName("hash"))))
 | |
|                              .bind("impl"))),
 | |
|       this);
 | |
| }
 | |
| 
 | |
| void MissingHashCheck::check(const MatchFinder::MatchResult &Result) {
 | |
|   const auto *ID = Result.Nodes.getNodeAs<ObjCImplementationDecl>("impl");
 | |
|   diag(ID->getLocation(), "%0 implements -isEqual: without implementing -hash")
 | |
|       << ID;
 | |
| }
 | |
| 
 | |
| } // namespace objc
 | |
| } // namespace tidy
 | |
| } // namespace clang
 |