// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// A general interface for filtering and only acting on classes in Chromium C++
// code.

#include "ChromeClassTester.h"

#include <algorithm>

#include "clang/AST/AST.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"

#ifdef LLVM_ON_UNIX
#include <sys/param.h>
#endif

using namespace clang;
using chrome_checker::Options;

namespace {

bool ends_with(const std::string& one, const std::string& two) {
  if (two.size() > one.size())
    return false;

  return one.compare(one.size() - two.size(), two.size(), two) == 0;
}

}  // namespace

ChromeClassTester::ChromeClassTester(CompilerInstance& instance,
                                     const Options& options)
    : options_(options),
      instance_(instance),
      diagnostic_(instance.getDiagnostics()) {
  BuildBannedLists();
}

ChromeClassTester::~ChromeClassTester() {}

void ChromeClassTester::HandleTagDeclDefinition(TagDecl* tag) {
  pending_class_decls_.push_back(tag);
}

bool ChromeClassTester::HandleTopLevelDecl(DeclGroupRef group_ref) {
  for (size_t i = 0; i < pending_class_decls_.size(); ++i)
    CheckTag(pending_class_decls_[i]);
  pending_class_decls_.clear();

  return true;  // true means continue parsing.
}

void ChromeClassTester::CheckTag(TagDecl* tag) {
  // We handle class types here where we have semantic information. We can only
  // check structs/classes/enums here, but we get a bunch of nice semantic
  // information instead of just parsing information.

  if (CXXRecordDecl* record = dyn_cast<CXXRecordDecl>(tag)) {
    if (InBannedNamespace(record))
      return;

    SourceLocation record_location = record->getInnerLocStart();
    if (InBannedDirectory(record_location))
      return;

    // We sadly need to maintain a blacklist of types that violate these
    // rules, but do so for good reason or due to limitations of this
    // checker (i.e., we don't handle extern templates very well).
    std::string base_name = record->getNameAsString();
    if (IsIgnoredType(base_name))
      return;

    // We ignore all classes that end with "Matcher" because they're probably
    // GMock artifacts.
    if (ends_with(base_name, "Matcher"))
        return;

    CheckChromeClass(record_location, record);
  } else if (EnumDecl* enum_decl = dyn_cast<EnumDecl>(tag)) {
    SourceLocation enum_location = enum_decl->getInnerLocStart();
    if (InBannedDirectory(enum_location))
      return;

    std::string base_name = enum_decl->getNameAsString();
    if (IsIgnoredType(base_name))
      return;

    CheckChromeEnum(enum_location, enum_decl);
  }
}

void ChromeClassTester::emitWarning(SourceLocation loc,
                                    const char* raw_error) {
  FullSourceLoc full(loc, instance().getSourceManager());
  std::string err;
  err = "[chromium-style] ";
  err += raw_error;

  DiagnosticIDs::Level level = getErrorLevel() == DiagnosticsEngine::Error
      ? DiagnosticIDs::Error : DiagnosticIDs::Warning;

  unsigned id = diagnostic().getDiagnosticIDs()->getCustomDiagID(level, err);
  DiagnosticBuilder builder = diagnostic().Report(full, id);

}

bool ChromeClassTester::InBannedDirectory(SourceLocation loc) {
  if (instance().getSourceManager().isInSystemHeader(loc))
    return true;

  std::string filename;
  if (!GetFilename(loc, &filename)) {
    // If the filename cannot be determined, simply treat this as a banned
    // location, instead of going through the full lookup process.
    return true;
  }

  // We need to special case scratch space; which is where clang does its
  // macro expansion. We explicitly want to allow people to do otherwise bad
  // things through macros that were defined due to third party libraries.
  if (filename == "<scratch space>")
    return true;

  // Don't complain about autogenerated protobuf files.
  if (ends_with(filename, ".pb.h")) {
    return true;
  }

#if defined(LLVM_ON_UNIX)
  // Resolve the symlinktastic relative path and make it absolute.
  char resolvedPath[MAXPATHLEN];
  if (realpath(filename.c_str(), resolvedPath)) {
    filename = resolvedPath;
  }
#endif

#if defined(LLVM_ON_WIN32)
  std::replace(filename.begin(), filename.end(), '\\', '/');

  // On Posix, realpath() has made the path absolute.  On Windows, this isn't
  // necessarily true, so prepend a '/' to the path to make sure the
  // banned_directories_ loop below works correctly.
  // This turns e.g. "gen/dir/file.cc" to "/gen/dir/file.cc" which lets the
  // "/gen/" banned_dir work.
  // This seems simpler than converting to utf16, calling GetFullPathNameW(),
  // and converting back to utf8.
  filename.insert(filename.begin(), '/');
#endif

  for (const std::string& allowed_dir : allowed_directories_) {
    // If any of the allowed directories occur as a component in filename,
    // this file is allowed.
    assert(allowed_dir.front() == '/' && "Allowed dir must start with '/'");
    assert(allowed_dir.back() == '/' && "Allowed dir must end with '/'");

    if (filename.find(allowed_dir) != std::string::npos)
      return false;
  }

  for (const std::string& banned_dir : banned_directories_) {
    // If any of the banned directories occur as a component in filename,
    // this file is rejected.
    assert(banned_dir.front() == '/' && "Banned dir must start with '/'");
    assert(banned_dir.back() == '/' && "Banned dir must end with '/'");

    if (filename.find(banned_dir) != std::string::npos)
      return true;
  }

  return false;
}

bool ChromeClassTester::InBannedNamespace(const Decl* record) {
  std::string n = GetNamespace(record);
  if (!n.empty()) {
    return std::find(banned_namespaces_.begin(), banned_namespaces_.end(), n)
        != banned_namespaces_.end();
  }

  return false;
}

std::string ChromeClassTester::GetNamespace(const Decl* record) {
  return GetNamespaceImpl(record->getDeclContext(), "");
}

bool ChromeClassTester::InImplementationFile(SourceLocation record_location) {
  std::string filename;
  if (!GetFilename(record_location, &filename))
    return false;

  if (ends_with(filename, ".cc") || ends_with(filename, ".cpp") ||
      ends_with(filename, ".mm")) {
    return true;
  }

  return false;
}

void ChromeClassTester::BuildBannedLists() {
  banned_namespaces_.emplace("std");
  banned_namespaces_.emplace("__gnu_cxx");

  if (!options_.enforce_overriding_blink) {
    banned_namespaces_.emplace("blink");
    banned_namespaces_.emplace("WTF");
  }

  if (options_.enforce_in_thirdparty_webkit) {
    allowed_directories_.emplace("/third_party/WebKit/");
  }

  banned_directories_.emplace("/third_party/");
  banned_directories_.emplace("/native_client/");
  banned_directories_.emplace("/breakpad/");
  banned_directories_.emplace("/courgette/");
  banned_directories_.emplace("/pdf/");
  banned_directories_.emplace("/ppapi/");
  banned_directories_.emplace("/usr/include/");
  banned_directories_.emplace("/usr/lib/");
  banned_directories_.emplace("/usr/local/include/");
  banned_directories_.emplace("/usr/local/lib/");
  banned_directories_.emplace("/testing/");
  banned_directories_.emplace("/v8/");
  banned_directories_.emplace("/dart/");
  banned_directories_.emplace("/sdch/");
  banned_directories_.emplace("/icu4c/");
  banned_directories_.emplace("/frameworks/");

  // Don't check autogenerated headers.
  // Make puts them below $(builddir_name)/.../gen and geni.
  // Ninja puts them below OUTPUT_DIR/.../gen
  // Xcode has a fixed output directory for everything.
  banned_directories_.emplace("/gen/");
  banned_directories_.emplace("/geni/");
  banned_directories_.emplace("/xcodebuild/");

  // Used in really low level threading code that probably shouldn't be out of
  // lined.
  ignored_record_names_.emplace("ThreadLocalBoolean");

  // A complicated pickle derived struct that is all packed integers.
  ignored_record_names_.emplace("Header");

  // Part of the GPU system that uses multiple included header
  // weirdness. Never getting this right.
  ignored_record_names_.emplace("Validators");

  // Has a UNIT_TEST only constructor. Isn't *terribly* complex...
  ignored_record_names_.emplace("AutocompleteController");
  ignored_record_names_.emplace("HistoryURLProvider");

  // Used over in the net unittests. A large enough bundle of integers with 1
  // non-pod class member. Probably harmless.
  ignored_record_names_.emplace("MockTransaction");

  // Enum type with _LAST members where _LAST doesn't mean last enum value.
  ignored_record_names_.emplace("ServerFieldType");

  // Used heavily in ui_base_unittests and once in views_unittests. Fixing this
  // isn't worth the overhead of an additional library.
  ignored_record_names_.emplace("TestAnimationDelegate");

  // Part of our public interface that nacl and friends use. (Arguably, this
  // should mean that this is a higher priority but fixing this looks hard.)
  ignored_record_names_.emplace("PluginVersionInfo");

  // Measured performance improvement on cc_perftests. See
  // https://codereview.chromium.org/11299290/
  ignored_record_names_.emplace("QuadF");

  // Enum type with _LAST members where _LAST doesn't mean last enum value.
  ignored_record_names_.emplace("ViewID");
}

std::string ChromeClassTester::GetNamespaceImpl(const DeclContext* context,
                                                const std::string& candidate) {
  switch (context->getDeclKind()) {
    case Decl::TranslationUnit: {
      return candidate;
    }
    case Decl::Namespace: {
      const NamespaceDecl* decl = dyn_cast<NamespaceDecl>(context);
      std::string name_str;
      llvm::raw_string_ostream OS(name_str);
      if (decl->isAnonymousNamespace())
        OS << "<anonymous namespace>";
      else
        OS << *decl;
      return GetNamespaceImpl(context->getParent(),
                              OS.str());
    }
    default: {
      return GetNamespaceImpl(context->getParent(), candidate);
    }
  }
}

bool ChromeClassTester::IsIgnoredType(const std::string& base_name) {
  return ignored_record_names_.find(base_name) != ignored_record_names_.end();
}

bool ChromeClassTester::GetFilename(SourceLocation loc,
                                    std::string* filename) {
  const SourceManager& source_manager = instance_.getSourceManager();
  SourceLocation spelling_location = source_manager.getSpellingLoc(loc);
  PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location);
  if (ploc.isInvalid()) {
    // If we're in an invalid location, we're looking at things that aren't
    // actually stated in the source.
    return false;
  }

  *filename = ploc.getFilename();
  return true;
}

DiagnosticsEngine::Level ChromeClassTester::getErrorLevel() {
  if (options_.warn_only)
    return DiagnosticsEngine::Warning;

  return diagnostic().getWarningsAsErrors() ? DiagnosticsEngine::Error
                                            : DiagnosticsEngine::Warning;
}
