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