xref: /llvm-project/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.cpp (revision 7d2ea6c422d3f5712b7253407005e1a465a76946)
1e010406eSHaojian Wu //===--- ForbiddenSubclassingCheck.cpp - clang-tidy -----------------------===//
2e010406eSHaojian Wu //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e010406eSHaojian Wu //
7e010406eSHaojian Wu //===----------------------------------------------------------------------===//
8e010406eSHaojian Wu 
9e010406eSHaojian Wu #include "ForbiddenSubclassingCheck.h"
10ab2d3ce4SAlexander Kornienko #include "../utils/OptionsUtils.h"
11e010406eSHaojian Wu #include "clang/AST/ASTContext.h"
12e010406eSHaojian Wu #include "clang/ASTMatchers/ASTMatchFinder.h"
13e010406eSHaojian Wu #include "llvm/ADT/Hashing.h"
14e010406eSHaojian Wu #include "llvm/ADT/SmallVector.h"
15e010406eSHaojian Wu 
16e010406eSHaojian Wu using namespace clang::ast_matchers;
17e010406eSHaojian Wu 
18*7d2ea6c4SCarlos Galvez namespace clang::tidy::objc {
19e010406eSHaojian Wu 
20e010406eSHaojian Wu namespace {
21e010406eSHaojian Wu 
22e010406eSHaojian Wu constexpr char DefaultForbiddenSuperClassNames[] =
23e010406eSHaojian Wu     "ABNewPersonViewController;"
24e010406eSHaojian Wu     "ABPeoplePickerNavigationController;"
25e010406eSHaojian Wu     "ABPersonViewController;"
26e010406eSHaojian Wu     "ABUnknownPersonViewController;"
27e010406eSHaojian Wu     "NSHashTable;"
28e010406eSHaojian Wu     "NSMapTable;"
29e010406eSHaojian Wu     "NSPointerArray;"
30e010406eSHaojian Wu     "NSPointerFunctions;"
31e010406eSHaojian Wu     "NSTimer;"
32e010406eSHaojian Wu     "UIActionSheet;"
33e010406eSHaojian Wu     "UIAlertView;"
34e010406eSHaojian Wu     "UIImagePickerController;"
35e010406eSHaojian Wu     "UITextInputMode;"
36e010406eSHaojian Wu     "UIWebView";
37e010406eSHaojian Wu 
38e010406eSHaojian Wu } // namespace
39e010406eSHaojian Wu 
ForbiddenSubclassingCheck(StringRef Name,ClangTidyContext * Context)40e010406eSHaojian Wu ForbiddenSubclassingCheck::ForbiddenSubclassingCheck(
41e010406eSHaojian Wu     StringRef Name,
42e010406eSHaojian Wu     ClangTidyContext *Context)
43e010406eSHaojian Wu     : ClangTidyCheck(Name, Context),
44e010406eSHaojian Wu       ForbiddenSuperClassNames(
45e010406eSHaojian Wu           utils::options::parseStringList(
46e010406eSHaojian Wu               Options.get("ClassNames", DefaultForbiddenSuperClassNames))) {
47e010406eSHaojian Wu }
48e010406eSHaojian Wu 
registerMatchers(MatchFinder * Finder)49e010406eSHaojian Wu void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) {
50e010406eSHaojian Wu   Finder->addMatcher(
51e010406eSHaojian Wu       objcInterfaceDecl(
5212cb5405SNathan James           isDerivedFrom(objcInterfaceDecl(hasAnyName(ForbiddenSuperClassNames))
53e010406eSHaojian Wu                             .bind("superclass")))
54e010406eSHaojian Wu           .bind("subclass"),
55e010406eSHaojian Wu       this);
56e010406eSHaojian Wu }
57e010406eSHaojian Wu 
check(const MatchFinder::MatchResult & Result)58e010406eSHaojian Wu void ForbiddenSubclassingCheck::check(
59e010406eSHaojian Wu     const MatchFinder::MatchResult &Result) {
60e010406eSHaojian Wu   const auto *SubClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
61e010406eSHaojian Wu       "subclass");
62e010406eSHaojian Wu   assert(SubClass != nullptr);
63e010406eSHaojian Wu   const auto *SuperClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
64e010406eSHaojian Wu       "superclass");
65e010406eSHaojian Wu   assert(SuperClass != nullptr);
66e010406eSHaojian Wu   diag(SubClass->getLocation(),
67e010406eSHaojian Wu        "Objective-C interface %0 subclasses %1, which is not "
68e010406eSHaojian Wu        "intended to be subclassed")
69e010406eSHaojian Wu       << SubClass
70e010406eSHaojian Wu       << SuperClass;
71e010406eSHaojian Wu }
72e010406eSHaojian Wu 
storeOptions(ClangTidyOptions::OptionMap & Opts)73e010406eSHaojian Wu void ForbiddenSubclassingCheck::storeOptions(
74e010406eSHaojian Wu     ClangTidyOptions::OptionMap &Opts) {
75e010406eSHaojian Wu   Options.store(
76e010406eSHaojian Wu       Opts,
77e010406eSHaojian Wu       "ForbiddenSuperClassNames",
78e010406eSHaojian Wu       utils::options::serializeStringList(ForbiddenSuperClassNames));
79e010406eSHaojian Wu }
80e010406eSHaojian Wu 
81*7d2ea6c4SCarlos Galvez } // namespace clang::tidy::objc
82