//===--- MultipleInheritanceCheck.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 "MultipleInheritanceCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang;
using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace fuchsia {

namespace {
AST_MATCHER(CXXRecordDecl, hasBases) {
  if (Node.hasDefinition())
    return Node.getNumBases() > 0;
  return false;
}
} // namespace

// Adds a node (by name) to the interface map, if it was not present in the map
// previously.
void MultipleInheritanceCheck::addNodeToInterfaceMap(const CXXRecordDecl *Node,
                                                     bool IsInterface) {
  assert(Node->getIdentifier());
  StringRef Name = Node->getIdentifier()->getName();
  InterfaceMap.insert(std::make_pair(Name, IsInterface));
}

// Returns "true" if the boolean "isInterface" has been set to the
// interface status of the current Node. Return "false" if the
// interface status for the current node is not yet known.
bool MultipleInheritanceCheck::getInterfaceStatus(const CXXRecordDecl *Node,
                                                  bool &IsInterface) const {
  assert(Node->getIdentifier());
  StringRef Name = Node->getIdentifier()->getName();
  llvm::StringMapConstIterator<bool> Pair = InterfaceMap.find(Name);
  if (Pair == InterfaceMap.end())
    return false;
  IsInterface = Pair->second;
  return true;
}

bool MultipleInheritanceCheck::isCurrentClassInterface(
    const CXXRecordDecl *Node) const {
  // Interfaces should have no fields.
  if (!Node->field_empty()) return false;

  // Interfaces should have exclusively pure methods.
  return llvm::none_of(Node->methods(), [](const CXXMethodDecl *M) {
    return M->isUserProvided() && !M->isPure() && !M->isStatic();
  });
}

bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
  if (!Node->getIdentifier())
    return false;

  // Short circuit the lookup if we have analyzed this record before.
  bool PreviousIsInterfaceResult;
  if (getInterfaceStatus(Node, PreviousIsInterfaceResult))
    return PreviousIsInterfaceResult;

  // To be an interface, all base classes must be interfaces as well.
  for (const auto &I : Node->bases()) {
    if (I.isVirtual()) continue;
    const auto *Ty = I.getType()->getAs<RecordType>();
    if (!Ty) continue;
    const RecordDecl *D = Ty->getDecl()->getDefinition();
    if (!D) continue;
    const auto *Base = cast<CXXRecordDecl>(D);
    if (!isInterface(Base)) {
      addNodeToInterfaceMap(Node, false);
      return false;
    }
  }

  bool CurrentClassIsInterface = isCurrentClassInterface(Node);
  addNodeToInterfaceMap(Node, CurrentClassIsInterface);
  return CurrentClassIsInterface;
}

void MultipleInheritanceCheck::registerMatchers(MatchFinder *Finder) {
  // Match declarations which have bases.
  Finder->addMatcher(
      cxxRecordDecl(allOf(hasBases(), isDefinition())).bind("decl"), this);
}

void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *D = Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) {
    // Check against map to see if if the class inherits from multiple
    // concrete classes
    unsigned NumConcrete = 0;
    for (const auto &I : D->bases()) {
      if (I.isVirtual()) continue;
      const auto *Ty = I.getType()->getAs<RecordType>();
      if (!Ty) continue;
      const auto *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
      if (!isInterface(Base)) NumConcrete++;
    }
    
    // Check virtual bases to see if there is more than one concrete 
    // non-virtual base.
    for (const auto &V : D->vbases()) {
      const auto *Ty = V.getType()->getAs<RecordType>();
      if (!Ty) continue;
      const auto *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
      if (!isInterface(Base)) NumConcrete++;
    }

    if (NumConcrete > 1) {
      diag(D->getBeginLoc(), "inheriting multiple classes that aren't "
                             "pure virtual is discouraged");
    }
  }
}

}  // namespace fuchsia
}  // namespace tidy
}  // namespace clang
