//===--- extra/module-map-checker/ModuleMapChecker.cpp -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a tool that validates a module map by checking that
// all headers in the corresponding directories are accounted for.
//
// Usage:   module-map-checker [(module-map-checker options)]
//            (module-map-file) [(front end options)]
//
// Options:
//
//    -I(include path)      Look at headers only in this directory tree.
//                          Must be a path relative to the module.map file.
//                          There can be multiple -I options, for when the
//                          module map covers multiple directories, and
//                          excludes higher or sibling directories not
//                          specified. If this option is omitted, the
//                          directory containing the module-map-file is
//                          the root of the header tree to be searched for
//                          headers.
//
//    -dump-module-map      Dump the module map object during the check.
//                          This displays the modules and headers.
//
//    (front end options)   In the case of use of an umbrella header, this can
//                          be used to pass options to the compiler front end
//                          preprocessor, such as -D or -I options.
//
// This program uses the Clang ModuleMap class to read and parse the module
// map file.  Starting at the module map file directory, or just the include
// paths, if specified, it will collect the names of all the files it
// considers headers (no extension, .h, or .inc--if you need more, modify the
// isHeader function).  It then compares the headers against those referenced
// in the module map, either explicitly named, or implicitly named via an
// umbrella directory or umbrella file, as parsed by the ModuleMap object.
// If headers are found which are not referenced or covered by an umbrella
// directory or file, warning messages will be produced, and this program
// will return an error code of 1.  Other errors result in an error code of 2.
// If no problems are found, an error code of 0 is returned.
//
// Note that in the case of umbrella headers, this tool invokes the compiler
// to preprocess the file, and uses a callback to collect the header files
// included by the umbrella header or any of its nested includes.  If any
// front end options are needed for these compiler invocations, these
// can be included on the command line after the module map file argument.
//
// Warning message have the form:
//
//  warning: module.map does not account for file: Level3A.h
//
// Note that for the case of the module map referencing a file that does
// not exist, the module map parser in Clang will (at the time of this
// writing) display an error message.
//
// Potential problems with this program:
//
// 1. Might need a better header matching mechanism, or extensions to the
//    canonical file format used.
//
// 2. It might need to support additional header file extensions.
//
// Future directions:
//
// 1. Add an option to fix the problems found, writing a new module map.
//    Include an extra option to add unaccounted-for headers as excluded.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "ModuleMapChecker.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace clang::driver;
using namespace clang::driver::options;
using namespace clang::tooling;
using namespace llvm;
using namespace llvm::opt;
using namespace llvm::sys;

// Option for include paths.
static cl::list<std::string>
IncludePaths("I", cl::desc("Include path."
                           " Must be relative to module.map file."),
             cl::ZeroOrMore, cl::value_desc("path"));

// Option for dumping the parsed module map.
static cl::opt<bool>
DumpModuleMap("dump-module-map", cl::init(false),
              cl::desc("Dump the parsed module map information."));

// Option for module.map path.
static cl::opt<std::string>
ModuleMapPath(cl::Positional, cl::init("module.map"),
              cl::desc("<The module.map file path."
                       " Uses module.map in current directory if omitted.>"));

// Collect all other arguments, which will be passed to the front end.
static cl::list<std::string>
CC1Arguments(cl::ConsumeAfter, cl::desc("<arguments to be passed to front end "
                                        "for parsing umbrella headers>..."));

int main(int Argc, const char **Argv) {

  // Parse command line.
  cl::ParseCommandLineOptions(Argc, Argv, "module-map-checker.\n");

  // Create checker object.
  std::unique_ptr<ModuleMapChecker> Checker(
      ModuleMapChecker::createModuleMapChecker(ModuleMapPath, IncludePaths,
                                               DumpModuleMap, CC1Arguments));

  // Do the checks.  The return value is the program return code,
  // 0 for okay, 1 for module map warnings produced, 2 for any other error.
  std::error_code ReturnCode = Checker->doChecks();

  if (ReturnCode == std::error_code(1, std::generic_category()))
    return 1; // Module map warnings were issued.
  else if (ReturnCode == std::error_code(2, std::generic_category()))
    return 2; // Some other error occurred.
  else
    return 0; // No errors or warnings.
}

// Preprocessor callbacks.
// We basically just collect include files.
class ModuleMapCheckerCallbacks : public PPCallbacks {
public:
  ModuleMapCheckerCallbacks(ModuleMapChecker &Checker) : Checker(Checker) {}
  ~ModuleMapCheckerCallbacks() {}

  // Include directive callback.
  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                          StringRef FileName, bool IsAngled,
                          CharSourceRange FilenameRange, const FileEntry *File,
                          StringRef SearchPath, StringRef RelativePath,
                          const Module *Imported) {
    Checker.collectUmbrellaHeaderHeader(File->getName());
  }

private:
  ModuleMapChecker &Checker;
};

// Frontend action stuff:

// Consumer is responsible for setting up the callbacks.
class ModuleMapCheckerConsumer : public ASTConsumer {
public:
  ModuleMapCheckerConsumer(ModuleMapChecker &Checker, Preprocessor &PP) {
    // PP takes ownership.
    PP.addPPCallbacks(new ModuleMapCheckerCallbacks(Checker));
  }
};

class ModuleMapCheckerAction : public SyntaxOnlyAction {
public:
  ModuleMapCheckerAction(ModuleMapChecker &Checker) : Checker(Checker) {}

protected:
  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                         StringRef InFile) {
    return new ModuleMapCheckerConsumer(Checker, CI.getPreprocessor());
  }

private:
  ModuleMapChecker &Checker;
};

class ModuleMapCheckerFrontendActionFactory : public FrontendActionFactory {
public:
  ModuleMapCheckerFrontendActionFactory(ModuleMapChecker &Checker)
      : Checker(Checker) {}

  virtual ModuleMapCheckerAction *create() {
    return new ModuleMapCheckerAction(Checker);
  }

private:
  ModuleMapChecker &Checker;
};

// ModuleMapChecker class implementation.

// Constructor.
ModuleMapChecker::ModuleMapChecker(StringRef ModuleMapPath,
                                   std::vector<std::string> &IncludePaths,
                                   bool DumpModuleMap,
                                   ArrayRef<std::string> CommandLine)
    : ModuleMapPath(ModuleMapPath), IncludePaths(IncludePaths),
      DumpModuleMap(DumpModuleMap), CommandLine(CommandLine),
      LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
      DiagnosticOpts(new DiagnosticOptions()),
      DC(errs(), DiagnosticOpts.get()),
      Diagnostics(
          new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
      TargetOpts(new ModuleMapTargetOptions()),
      Target(TargetInfo::CreateTargetInfo(*Diagnostics, TargetOpts)),
      FileMgr(new FileManager(FileSystemOpts)),
      SourceMgr(new SourceManager(*Diagnostics, *FileMgr, false)),
      HeaderSearchOpts(new HeaderSearchOptions()),
      HeaderInfo(new HeaderSearch(HeaderSearchOpts, *SourceMgr, *Diagnostics,
                                  *LangOpts, Target.get())),
      ModMap(new ModuleMap(*SourceMgr, *Diagnostics, *LangOpts, Target.get(),
                           *HeaderInfo)) {}

// Create instance of ModuleMapChecker, to simplify setting up
// subordinate objects.
ModuleMapChecker *ModuleMapChecker::createModuleMapChecker(
    StringRef ModuleMapPath, std::vector<std::string> &IncludePaths,
    bool DumpModuleMap, ArrayRef<std::string> CommandLine) {

  return new ModuleMapChecker(ModuleMapPath, IncludePaths, DumpModuleMap,
                              CommandLine);
}

// Do checks.
// Starting from the directory of the module.map file,
// Find all header files, optionally looking only at files
// covered by the include path options, and compare against
// the headers referenced by the module.map file.
// Display warnings for unaccounted-for header files.
// Returns error_code of 0 if there were no errors or warnings, 1 if there
//   were warnings, 2 if any other problem, such as if a bad
//   module map path argument was specified.
std::error_code ModuleMapChecker::doChecks() {
  std::error_code returnValue;

  // Load the module map.
  if (!loadModuleMap())
    return std::error_code(2, std::generic_category());

  // Collect the headers referenced in the modules.
  collectModuleHeaders();

  // Collect the file system headers.
  if (!collectFileSystemHeaders())
    return std::error_code(2, std::generic_category());

  // Do the checks.  These save the problematic file names.
  findUnaccountedForHeaders();

  // Check for warnings.
  if (UnaccountedForHeaders.size())
    returnValue = std::error_code(1, std::generic_category());

  // Dump module map if requested.
  if (DumpModuleMap) {
    errs() << "\nDump of module map:\n\n";
    ModMap->dump();
  }

  return returnValue;
}

// The following functions are called by doChecks.

// Load module map.
// Returns true if module.map file loaded successfully.
bool ModuleMapChecker::loadModuleMap() {
  // Get file entry for module.map file.
  const FileEntry *ModuleMapEntry =
      SourceMgr->getFileManager().getFile(ModuleMapPath);

  // return error if not found.
  if (!ModuleMapEntry) {
    errs() << "error: File \"" << ModuleMapPath << "\" not found.\n";
    return false;
  }

  // Because the module map parser uses a ForwardingDiagnosticConsumer,
  // which doesn't forward the BeginSourceFile call, we do it explicitly here.
  DC.BeginSourceFile(*LangOpts, nullptr);

  // Parse module.map file into module map.
  if (ModMap->parseModuleMapFile(ModuleMapEntry, false))
    return false;

  // Do matching end call.
  DC.EndSourceFile();

  return true;
}

// Collect module headers.
// Walks the modules and collects referenced headers into
// ModuleMapHeadersSet.
void ModuleMapChecker::collectModuleHeaders() {
  for (ModuleMap::module_iterator I = ModMap->module_begin(),
                                  E = ModMap->module_end();
       I != E; ++I) {
    collectModuleHeaders(*I->second);
  }
}

// Collect referenced headers from one module.
// Collects the headers referenced in the given module into
// ModuleMapHeadersSet.
// FIXME: Doesn't collect files from umbrella header.
bool ModuleMapChecker::collectModuleHeaders(const Module &Mod) {

  if (const FileEntry *UmbrellaHeader = Mod.getUmbrellaHeader()) {
    // Collect umbrella header.
    ModuleMapHeadersSet.insert(getCanonicalPath(UmbrellaHeader->getName()));
    // Preprocess umbrella header and collect the headers it references.
    if (!collectUmbrellaHeaderHeaders(UmbrellaHeader->getName()))
      return false;
  } else if (const DirectoryEntry *UmbrellaDir = Mod.getUmbrellaDir()) {
    // Collect headers in umbrella directory.
    if (!collectUmbrellaHeaders(UmbrellaDir->getName()))
      return false;
  }

  for (unsigned I = 0, N = Mod.NormalHeaders.size(); I != N; ++I) {
    ModuleMapHeadersSet.insert(
        getCanonicalPath(Mod.NormalHeaders[I]->getName()));
  }

  for (unsigned I = 0, N = Mod.ExcludedHeaders.size(); I != N; ++I) {
    ModuleMapHeadersSet.insert(
        getCanonicalPath(Mod.ExcludedHeaders[I]->getName()));
  }

  for (unsigned I = 0, N = Mod.PrivateHeaders.size(); I != N; ++I) {
    ModuleMapHeadersSet.insert(
        getCanonicalPath(Mod.PrivateHeaders[I]->getName()));
  }

  for (Module::submodule_const_iterator MI = Mod.submodule_begin(),
                                        MIEnd = Mod.submodule_end();
       MI != MIEnd; ++MI)
    collectModuleHeaders(**MI);

  return true;
}

// Collect headers from an umbrella directory.
bool ModuleMapChecker::collectUmbrellaHeaders(StringRef UmbrellaDirName) {
  // Initialize directory name.
  SmallString<256> Directory(ModuleMapDirectory);
  if (UmbrellaDirName.size())
    sys::path::append(Directory, UmbrellaDirName);
  if (Directory.size() == 0)
    Directory = ".";
  // Walk the directory.
  std::error_code EC;
  fs::file_status Status;
  for (fs::directory_iterator I(Directory.str(), EC), E; I != E;
       I.increment(EC)) {
    if (EC)
      return false;
    std::string File(I->path());
    I->status(Status);
    fs::file_type Type = Status.type();
    // If the file is a directory, ignore the name.
    if (Type == fs::file_type::directory_file)
      continue;
    // If the file does not have a common header extension, ignore it.
    if (!isHeader(File))
      continue;
    // Save header name.
    ModuleMapHeadersSet.insert(getCanonicalPath(File));
  }
  return true;
}

// Collect headers rferenced from an umbrella file.
bool
ModuleMapChecker::collectUmbrellaHeaderHeaders(StringRef UmbrellaHeaderName) {

  SmallString<256> PathBuf(ModuleMapDirectory);

  // If directory is empty, it's the current directory.
  if (ModuleMapDirectory.length() == 0)
    sys::fs::current_path(PathBuf);

  // Create the compilation database.
  std::unique_ptr<CompilationDatabase> Compilations;
  Compilations.reset(new FixedCompilationDatabase(Twine(PathBuf), CommandLine));

  std::vector<std::string> HeaderPath;
  HeaderPath.push_back(UmbrellaHeaderName);

  // Create the tool and run the compilation.
  ClangTool Tool(*Compilations, HeaderPath);
  int HadErrors = Tool.run(new ModuleMapCheckerFrontendActionFactory(*this));

  // If we had errors, exit early.
  return HadErrors ? false : true;
}

// Called from ModuleMapCheckerCallbacks to track a header included
// from an umbrella header.
void ModuleMapChecker::collectUmbrellaHeaderHeader(StringRef HeaderName) {

  SmallString<256> PathBuf(ModuleMapDirectory);
  // If directory is empty, it's the current directory.
  if (ModuleMapDirectory.length() == 0)
    sys::fs::current_path(PathBuf);
  // HeaderName will have an absolute path, so if it's the module map
  // directory, we remove it, also skipping trailing separator.
  if (HeaderName.startswith(PathBuf))
    HeaderName = HeaderName.substr(PathBuf.size() + 1);
  // Save header name.
  ModuleMapHeadersSet.insert(getCanonicalPath(HeaderName));
}

// Collect file system header files.
// This function scans the file system for header files,
// starting at the directory of the module.map file,
// optionally filtering out all but the files covered by
// the include path options.
// Returns true if no errors.
bool ModuleMapChecker::collectFileSystemHeaders() {

  // Get directory containing the module.map file.
  // Might be relative to current directory, absolute, or empty.
  ModuleMapDirectory = getDirectoryFromPath(ModuleMapPath);

  // If no include paths specified, we do the whole tree starting
  // at the module.map directory.
  if (IncludePaths.size() == 0) {
    if (!collectFileSystemHeaders(StringRef("")))
      return false;
  } else {
    // Otherwise we only look at the sub-trees specified by the
    // include paths.
    for (std::vector<std::string>::const_iterator I = IncludePaths.begin(),
                                                  E = IncludePaths.end();
         I != E; ++I) {
      if (!collectFileSystemHeaders(*I))
        return false;
    }
  }

  // Sort it, because different file systems might order the file differently.
  std::sort(FileSystemHeaders.begin(), FileSystemHeaders.end());

  return true;
}

// Collect file system header files from the given path.
// This function scans the file system for header files,
// starting at the given directory, which is assumed to be
// relative to the directory of the module.map file.
// \returns True if no errors.
bool ModuleMapChecker::collectFileSystemHeaders(StringRef IncludePath) {

  // Initialize directory name.
  SmallString<256> Directory(ModuleMapDirectory);
  if (IncludePath.size())
    sys::path::append(Directory, IncludePath);
  if (Directory.size() == 0)
    Directory = ".";
  if (IncludePath.startswith("/") || IncludePath.startswith("\\") ||
      ((IncludePath.size() >= 2) && (IncludePath[1] == ':'))) {
    errs() << "error: Include path \"" << IncludePath
           << "\" is not relative to the module map file.\n";
    return false;
  }

  // Recursively walk the directory tree.
  std::error_code EC;
  fs::file_status Status;
  int Count = 0;
  for (fs::recursive_directory_iterator I(Directory.str(), EC), E; I != E;
       I.increment(EC)) {
    if (EC)
      return false;
    std::string file(I->path());
    I->status(Status);
    fs::file_type type = Status.type();
    // If the file is a directory, ignore the name (but still recurses).
    if (type == fs::file_type::directory_file)
      continue;
    // If the file does not have a common header extension, ignore it.
    if (!isHeader(file))
      continue;
    // Save header name.
    FileSystemHeaders.push_back(getCanonicalPath(file));
    Count++;
  }
  if (Count == 0) {
    errs() << "warning: No headers found in include path: \"" << IncludePath
           << "\"\n";
  }
  return true;
}

// Find headers unaccounted-for in module map.
// This function compares the list of collected header files
// against those referenced in the module map.  Display
// warnings for unaccounted-for header files.
// Save unaccounted-for file list for possible.
// fixing action.
// FIXME: There probably needs to be some canonalization
// of file names so that header path can be correctly
// matched.  Also, a map could be used for the headers
// referenced in the module, but
void ModuleMapChecker::findUnaccountedForHeaders() {
  // Walk over file system headers.
  for (std::vector<std::string>::const_iterator I = FileSystemHeaders.begin(),
                                                E = FileSystemHeaders.end();
       I != E; ++I) {
    // Look for header in module map.
    if (ModuleMapHeadersSet.insert(*I)) {
      UnaccountedForHeaders.push_back(*I);
      errs() << "warning: " << ModuleMapPath
             << " does not account for file: " << *I << "\n";
    }
  }
}

// Utility functions.

// Get directory path component from file path.
// \returns the component of the given path, which will be
// relative if the given path is relative, absolute if the
// given path is absolute, or "." if the path has no leading
// path component.
std::string ModuleMapChecker::getDirectoryFromPath(StringRef Path) {
  SmallString<256> Directory(Path);
  sys::path::remove_filename(Directory);
  if (Directory.size() == 0)
    return ".";
  return Directory.str();
}

// Convert header path to canonical form.
// The canonical form is basically just use forward slashes, and remove "./".
// \param FilePath The file path, relative to the module map directory.
// \returns The file path in canonical form.
std::string ModuleMapChecker::getCanonicalPath(StringRef FilePath) {
  std::string Tmp(FilePath);
  std::replace(Tmp.begin(), Tmp.end(), '\\', '/');
  StringRef Result(Tmp);
  if (Result.startswith("./"))
    Result = Result.substr(2);
  return Result;
}

// Check for header file extension.
// If the file extension is .h, .inc, or missing, it's
// assumed to be a header.
// \param FileName The file name.  Must not be a directory.
// \returns true if it has a header extension or no extension.
bool ModuleMapChecker::isHeader(StringRef FileName) {
  StringRef Extension = sys::path::extension(FileName);
  if (Extension.size() == 0)
    return false;
  if (Extension.equals_lower(".h"))
    return true;
  if (Extension.equals_lower(".inc"))
    return true;
  return false;
}
