72 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 "ForbiddenSubclassingCheck.h"10#include "../utils/OptionsUtils.h"11#include "clang/AST/ASTContext.h"12#include "clang/ASTMatchers/ASTMatchFinder.h"13 14using namespace clang::ast_matchers;15 16namespace clang::tidy::objc {17 18namespace {19 20constexpr char DefaultForbiddenSuperClassNames[] =21 "ABNewPersonViewController;"22 "ABPeoplePickerNavigationController;"23 "ABPersonViewController;"24 "ABUnknownPersonViewController;"25 "NSHashTable;"26 "NSMapTable;"27 "NSPointerArray;"28 "NSPointerFunctions;"29 "NSTimer;"30 "UIActionSheet;"31 "UIAlertView;"32 "UIImagePickerController;"33 "UITextInputMode;"34 "UIWebView";35 36} // namespace37 38ForbiddenSubclassingCheck::ForbiddenSubclassingCheck(StringRef Name,39 ClangTidyContext *Context)40 : ClangTidyCheck(Name, Context),41 ForbiddenSuperClassNames(utils::options::parseStringList(42 Options.get("ClassNames", DefaultForbiddenSuperClassNames))) {}43 44void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) {45 Finder->addMatcher(46 objcInterfaceDecl(47 isDerivedFrom(objcInterfaceDecl(hasAnyName(ForbiddenSuperClassNames))48 .bind("superclass")))49 .bind("subclass"),50 this);51}52 53void ForbiddenSubclassingCheck::check(const MatchFinder::MatchResult &Result) {54 const auto *SubClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>("subclass");55 assert(SubClass != nullptr);56 const auto *SuperClass =57 Result.Nodes.getNodeAs<ObjCInterfaceDecl>("superclass");58 assert(SuperClass != nullptr);59 diag(SubClass->getLocation(),60 "Objective-C interface %0 subclasses %1, which is not "61 "intended to be subclassed")62 << SubClass << SuperClass;63}64 65void ForbiddenSubclassingCheck::storeOptions(66 ClangTidyOptions::OptionMap &Opts) {67 Options.store(Opts, "ForbiddenSuperClassNames",68 utils::options::serializeStringList(ForbiddenSuperClassNames));69}70 71} // namespace clang::tidy::objc72