//===--- USRFinder.cpp - Clang refactoring library ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
/// point.
///
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "llvm/ADT/SmallVector.h"

using namespace llvm;

namespace clang {
namespace tooling {

namespace {

/// Recursively visits each AST node to find the symbol underneath the cursor.
class NamedDeclOccurrenceFindingVisitor
    : public RecursiveSymbolVisitor<NamedDeclOccurrenceFindingVisitor> {
public:
  // \brief Finds the NamedDecl at a point in the source.
  // \param Point the location in the source to search for the NamedDecl.
  explicit NamedDeclOccurrenceFindingVisitor(const SourceLocation Point,
                                             const ASTContext &Context)
      : RecursiveSymbolVisitor(Context.getSourceManager(),
                               Context.getLangOpts()),
        Point(Point), Context(Context) {}

  bool visitSymbolOccurrence(const NamedDecl *ND,
                             ArrayRef<SourceRange> NameRanges) {
    if (!ND)
      return true;
    for (const auto &Range : NameRanges) {
      SourceLocation Start = Range.getBegin();
      SourceLocation End = Range.getEnd();
      if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
          !End.isFileID() || !isPointWithin(Start, End))
        return true;
    }
    Result = ND;
    return false;
  }

  const NamedDecl *getNamedDecl() const { return Result; }

private:
  // \brief Determines if the Point is within Start and End.
  bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
    // FIXME: Add tests for Point == End.
    return Point == Start || Point == End ||
           (Context.getSourceManager().isBeforeInTranslationUnit(Start,
                                                                 Point) &&
            Context.getSourceManager().isBeforeInTranslationUnit(Point, End));
  }

  const NamedDecl *Result = nullptr;
  const SourceLocation Point; // The location to find the NamedDecl.
  const ASTContext &Context;
};

} // end anonymous namespace

const NamedDecl *getNamedDeclAt(const ASTContext &Context,
                                const SourceLocation Point) {
  const SourceManager &SM = Context.getSourceManager();
  NamedDeclOccurrenceFindingVisitor Visitor(Point, Context);

  // Try to be clever about pruning down the number of top-level declarations we
  // see. If both start and end is either before or after the point we're
  // looking for the point cannot be inside of this decl. Don't even look at it.
  for (auto *CurrDecl : Context.getTranslationUnitDecl()->decls()) {
    SourceLocation StartLoc = CurrDecl->getLocStart();
    SourceLocation EndLoc = CurrDecl->getLocEnd();
    if (StartLoc.isValid() && EndLoc.isValid() &&
        SM.isBeforeInTranslationUnit(StartLoc, Point) !=
            SM.isBeforeInTranslationUnit(EndLoc, Point))
      Visitor.TraverseDecl(CurrDecl);
  }

  return Visitor.getNamedDecl();
}

namespace {

/// Recursively visits each NamedDecl node to find the declaration with a
/// specific name.
class NamedDeclFindingVisitor
    : public RecursiveASTVisitor<NamedDeclFindingVisitor> {
public:
  explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}

  // We don't have to traverse the uses to find some declaration with a
  // specific name, so just visit the named declarations.
  bool VisitNamedDecl(const NamedDecl *ND) {
    if (!ND)
      return true;
    // Fully qualified name is used to find the declaration.
    if (Name != ND->getQualifiedNameAsString() &&
        Name != "::" + ND->getQualifiedNameAsString())
      return true;
    Result = ND;
    return false;
  }

  const NamedDecl *getNamedDecl() const { return Result; }

private:
  const NamedDecl *Result = nullptr;
  StringRef Name;
};

} // end anonymous namespace

const NamedDecl *getNamedDeclFor(const ASTContext &Context,
                                 const std::string &Name) {
  NamedDeclFindingVisitor Visitor(Name);
  Visitor.TraverseDecl(Context.getTranslationUnitDecl());
  return Visitor.getNamedDecl();
}

std::string getUSRForDecl(const Decl *Decl) {
  llvm::SmallVector<char, 128> Buff;

  // FIXME: Add test for the nullptr case.
  if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
    return "";

  return std::string(Buff.data(), Buff.size());
}

} // end namespace tooling
} // end namespace clang
