//===--- ForbiddenSubclassingCheck.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 "ForbiddenSubclassingCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "../utils/OptionsUtils.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace objc {

namespace {

constexpr char DefaultForbiddenSuperClassNames[] =
    "ABNewPersonViewController;"
    "ABPeoplePickerNavigationController;"
    "ABPersonViewController;"
    "ABUnknownPersonViewController;"
    "NSHashTable;"
    "NSMapTable;"
    "NSPointerArray;"
    "NSPointerFunctions;"
    "NSTimer;"
    "UIActionSheet;"
    "UIAlertView;"
    "UIImagePickerController;"
    "UITextInputMode;"
    "UIWebView";

/// \brief Matches Objective-C classes that directly or indirectly
/// have a superclass matching \c Base.
///
/// Note that a class is not considered to be a subclass of itself.
///
/// Example matches Y, Z
/// (matcher = objcInterfaceDecl(hasName("X")))
/// \code
///   @interface X
///   @end
///   @interface Y : X  // directly derived
///   @end
///   @interface Z : Y  // indirectly derived
///   @end
/// \endcode
AST_MATCHER_P(ObjCInterfaceDecl, isSubclassOf,
              ast_matchers::internal::Matcher<ObjCInterfaceDecl>, Base) {
  for (const auto *SuperClass = Node.getSuperClass();
       SuperClass != nullptr;
       SuperClass = SuperClass->getSuperClass()) {
    if (Base.matches(*SuperClass, Finder, Builder)) {
      return true;
    }
  }
  return false;
}

} // namespace

ForbiddenSubclassingCheck::ForbiddenSubclassingCheck(
    StringRef Name,
    ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      ForbiddenSuperClassNames(
          utils::options::parseStringList(
              Options.get("ClassNames", DefaultForbiddenSuperClassNames))) {
}

void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) {
  // this check should only be applied to ObjC sources.
  if (!getLangOpts().ObjC)
    return;

  Finder->addMatcher(
      objcInterfaceDecl(
          isSubclassOf(
              objcInterfaceDecl(
                  hasAnyName(
                      std::vector<StringRef>(
                          ForbiddenSuperClassNames.begin(),
                          ForbiddenSuperClassNames.end())))
              .bind("superclass")))
      .bind("subclass"),
      this);
}

void ForbiddenSubclassingCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *SubClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
      "subclass");
  assert(SubClass != nullptr);
  const auto *SuperClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
      "superclass");
  assert(SuperClass != nullptr);
  diag(SubClass->getLocation(),
       "Objective-C interface %0 subclasses %1, which is not "
       "intended to be subclassed")
      << SubClass
      << SuperClass;
}

void ForbiddenSubclassingCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(
      Opts,
      "ForbiddenSuperClassNames",
      utils::options::serializeStringList(ForbiddenSuperClassNames));
}

} // namespace objc
} // namespace tidy
} // namespace clang
