//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
//
// 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 "CursorVisitor.h"
#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
#include "CXTranslationUnit.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/Support/Compiler.h"

using namespace clang;
using namespace cxcursor;
using namespace cxindex;

static void getTopOverriddenMethods(CXTranslationUnit TU,
                                    const Decl *D,
                                    SmallVectorImpl<const Decl *> &Methods) {
  if (!D)
    return;
  if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
    return;

  SmallVector<CXCursor, 8> Overridden;
  cxcursor::getOverriddenCursors(cxcursor::MakeCXCursor(D, TU), Overridden);
  
  if (Overridden.empty()) {
    Methods.push_back(D->getCanonicalDecl());
    return;
  }

  for (SmallVectorImpl<CXCursor>::iterator
         I = Overridden.begin(), E = Overridden.end(); I != E; ++I)
    getTopOverriddenMethods(TU, cxcursor::getCursorDecl(*I), Methods);
}

namespace {

struct FindFileIdRefVisitData {
  CXTranslationUnit TU;
  FileID FID;
  const Decl *Dcl;
  int SelectorIdIdx;
  CXCursorAndRangeVisitor visitor;

  typedef SmallVector<const Decl *, 8> TopMethodsTy;
  TopMethodsTy TopMethods;

  FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID,
                         const Decl *D, int selectorIdIdx,
                         CXCursorAndRangeVisitor visitor)
    : TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) {
    Dcl = getCanonical(D);
    getTopOverriddenMethods(TU, Dcl, TopMethods);
  }

  ASTContext &getASTContext() const {
    return cxtu::getASTUnit(TU)->getASTContext();
  }

  /// We are looking to find all semantically relevant identifiers,
  /// so the definition of "canonical" here is different than in the AST, e.g.
  ///
  /// \code
  ///   class C {
  ///     C() {}
  ///   };
  /// \endcode
  ///
  /// we consider the canonical decl of the constructor decl to be the class
  /// itself, so both 'C' can be highlighted.
  const Decl *getCanonical(const Decl *D) const {
    if (!D)
      return nullptr;

    D = D->getCanonicalDecl();

    if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) {
      if (ImplD->getClassInterface())
        return getCanonical(ImplD->getClassInterface());

    } else if (const CXXConstructorDecl *CXXCtorD =
                   dyn_cast<CXXConstructorDecl>(D)) {
      return getCanonical(CXXCtorD->getParent());
    }
    
    return D;
  }

  bool isHit(const Decl *D) const {
    if (!D)
      return false;

    D = getCanonical(D);
    if (D == Dcl)
      return true;

    if (isa<ObjCMethodDecl>(D) || isa<CXXMethodDecl>(D))
      return isOverriddingMethod(D);

    return false;
  }

private:
  bool isOverriddingMethod(const Decl *D) const {
    if (llvm::find(TopMethods, D) != TopMethods.end())
      return true;

    TopMethodsTy methods;
    getTopOverriddenMethods(TU, D, methods);
    for (TopMethodsTy::iterator
           I = methods.begin(), E = methods.end(); I != E; ++I) {
      if (llvm::find(TopMethods, *I) != TopMethods.end())
        return true;
    }

    return false;
  }
};

} // end anonymous namespace.

/// For a macro \arg Loc, returns the file spelling location and sets
/// to \arg isMacroArg whether the spelling resides inside a macro definition or
/// a macro argument.
static SourceLocation getFileSpellingLoc(SourceManager &SM,
                                         SourceLocation Loc,
                                         bool &isMacroArg) {
  assert(Loc.isMacroID());
  SourceLocation SpellLoc = SM.getImmediateSpellingLoc(Loc);
  if (SpellLoc.isMacroID())
    return getFileSpellingLoc(SM, SpellLoc, isMacroArg);
  
  isMacroArg = SM.isMacroArgExpansion(Loc);
  return SpellLoc;
}

static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
                                                  CXCursor parent,
                                                  CXClientData client_data) {
  CXCursor declCursor = clang_getCursorReferenced(cursor);
  if (!clang_isDeclaration(declCursor.kind))
    return CXChildVisit_Recurse;

  const Decl *D = cxcursor::getCursorDecl(declCursor);
  if (!D)
    return CXChildVisit_Continue;

  FindFileIdRefVisitData *data = (FindFileIdRefVisitData *)client_data;
  if (data->isHit(D)) {
    cursor = cxcursor::getSelectorIdentifierCursor(data->SelectorIdIdx, cursor);

    // We are looking for identifiers to highlight so for objc methods (and
    // not a parameter) we can only highlight the selector identifiers.
    if ((cursor.kind == CXCursor_ObjCClassMethodDecl ||
         cursor.kind == CXCursor_ObjCInstanceMethodDecl) &&
         cxcursor::getSelectorIdentifierIndex(cursor) == -1)
      return CXChildVisit_Recurse;

    if (clang_isExpression(cursor.kind)) {
      if (cursor.kind == CXCursor_DeclRefExpr ||
          cursor.kind == CXCursor_MemberRefExpr) {
        // continue..

      } else if (cursor.kind == CXCursor_ObjCMessageExpr &&
                 cxcursor::getSelectorIdentifierIndex(cursor) != -1) {
        // continue..
                
      } else
        return CXChildVisit_Recurse;
    }

    SourceLocation
      Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
    SourceLocation SelIdLoc = cxcursor::getSelectorIdentifierLoc(cursor);
    if (SelIdLoc.isValid())
      Loc = SelIdLoc;

    ASTContext &Ctx = data->getASTContext();
    SourceManager &SM = Ctx.getSourceManager();
    bool isInMacroDef = false;
    if (Loc.isMacroID()) {
      bool isMacroArg;
      Loc = getFileSpellingLoc(SM, Loc, isMacroArg);
      isInMacroDef = !isMacroArg;
    }

    // We are looking for identifiers in a specific file.
    std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
    if (LocInfo.first != data->FID)
      return CXChildVisit_Recurse;

    if (isInMacroDef) {
      // FIXME: For a macro definition make sure that all expansions
      // of it expand to the same reference before allowing to point to it.
      return CXChildVisit_Recurse;
    }

    if (data->visitor.visit(data->visitor.context, cursor,
                        cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
      return CXChildVisit_Break;
  }
  return CXChildVisit_Recurse;
}

static bool findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
                             const FileEntry *File,
                             CXCursorAndRangeVisitor Visitor) {
  assert(clang_isDeclaration(declCursor.kind));
  SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();

  FileID FID = SM.translateFile(File);
  const Decl *Dcl = cxcursor::getCursorDecl(declCursor);
  if (!Dcl)
    return false;

  FindFileIdRefVisitData data(TU, FID, Dcl,
                              cxcursor::getSelectorIdentifierIndex(declCursor),
                              Visitor);

  if (const DeclContext *DC = Dcl->getParentFunctionOrMethod()) {
    return clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU),
                               findFileIdRefVisit, &data);
  }

  SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
  CursorVisitor FindIdRefsVisitor(TU,
                                  findFileIdRefVisit, &data,
                                  /*VisitPreprocessorLast=*/true,
                                  /*VisitIncludedEntities=*/false,
                                  Range,
                                  /*VisitDeclsOnly=*/true);
  return FindIdRefsVisitor.visitFileRegion();
}

namespace {

struct FindFileMacroRefVisitData {
  ASTUnit &Unit;
  const FileEntry *File;
  const IdentifierInfo *Macro;
  CXCursorAndRangeVisitor visitor;

  FindFileMacroRefVisitData(ASTUnit &Unit, const FileEntry *File,
                            const IdentifierInfo *Macro,
                            CXCursorAndRangeVisitor visitor)
    : Unit(Unit), File(File), Macro(Macro), visitor(visitor) { }

  ASTContext &getASTContext() const {
    return Unit.getASTContext();
  }
};

} // anonymous namespace

static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
                                                     CXCursor parent,
                                                     CXClientData client_data) {
  const IdentifierInfo *Macro = nullptr;
  if (cursor.kind == CXCursor_MacroDefinition)
    Macro = getCursorMacroDefinition(cursor)->getName();
  else if (cursor.kind == CXCursor_MacroExpansion)
    Macro = getCursorMacroExpansion(cursor).getName();
  if (!Macro)
    return CXChildVisit_Continue;

  FindFileMacroRefVisitData *data = (FindFileMacroRefVisitData *)client_data;
  if (data->Macro != Macro)
    return CXChildVisit_Continue;

  SourceLocation
    Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));

  ASTContext &Ctx = data->getASTContext();
  SourceManager &SM = Ctx.getSourceManager();
  bool isInMacroDef = false;
  if (Loc.isMacroID()) {
    bool isMacroArg;
    Loc = getFileSpellingLoc(SM, Loc, isMacroArg);
    isInMacroDef = !isMacroArg;
  }

  // We are looking for identifiers in a specific file.
  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
  if (SM.getFileEntryForID(LocInfo.first) != data->File)
    return CXChildVisit_Continue;

  if (isInMacroDef) {
    // FIXME: For a macro definition make sure that all expansions
    // of it expand to the same reference before allowing to point to it.
    return CXChildVisit_Continue;
  }

  if (data->visitor.visit(data->visitor.context, cursor,
                        cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
    return CXChildVisit_Break;
  return CXChildVisit_Continue;
}

static bool findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
                                const FileEntry *File,
                                CXCursorAndRangeVisitor Visitor) {
  if (Cursor.kind != CXCursor_MacroDefinition &&
      Cursor.kind != CXCursor_MacroExpansion)
    return false;

  ASTUnit *Unit = cxtu::getASTUnit(TU);
  SourceManager &SM = Unit->getSourceManager();

  FileID FID = SM.translateFile(File);
  const IdentifierInfo *Macro = nullptr;
  if (Cursor.kind == CXCursor_MacroDefinition)
    Macro = getCursorMacroDefinition(Cursor)->getName();
  else
    Macro = getCursorMacroExpansion(Cursor).getName();
  if (!Macro)
    return false;

  FindFileMacroRefVisitData data(*Unit, File, Macro, Visitor);

  SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
  CursorVisitor FindMacroRefsVisitor(TU,
                                  findFileMacroRefVisit, &data,
                                  /*VisitPreprocessorLast=*/false,
                                  /*VisitIncludedEntities=*/false,
                                  Range);
  return FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
}

namespace {

struct FindFileIncludesVisitor {
  ASTUnit &Unit;
  const FileEntry *File;
  CXCursorAndRangeVisitor visitor;

  FindFileIncludesVisitor(ASTUnit &Unit, const FileEntry *File,
                          CXCursorAndRangeVisitor visitor)
    : Unit(Unit), File(File), visitor(visitor) { }

  ASTContext &getASTContext() const {
    return Unit.getASTContext();
  }

  enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
    if (cursor.kind != CXCursor_InclusionDirective)
      return CXChildVisit_Continue;

    SourceLocation
      Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));

    ASTContext &Ctx = getASTContext();
    SourceManager &SM = Ctx.getSourceManager();

    // We are looking for includes in a specific file.
    std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
    if (SM.getFileEntryForID(LocInfo.first) != File)
      return CXChildVisit_Continue;

    if (visitor.visit(visitor.context, cursor,
                      cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
      return CXChildVisit_Break;
    return CXChildVisit_Continue;
  }

  static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent,
                                       CXClientData client_data) {
    return static_cast<FindFileIncludesVisitor*>(client_data)->
                                                          visit(cursor, parent);
  }
};

} // anonymous namespace

static bool findIncludesInFile(CXTranslationUnit TU, const FileEntry *File,
                               CXCursorAndRangeVisitor Visitor) {
  assert(TU && File && Visitor.visit);

  ASTUnit *Unit = cxtu::getASTUnit(TU);
  SourceManager &SM = Unit->getSourceManager();

  FileID FID = SM.translateFile(File);

  FindFileIncludesVisitor IncludesVisitor(*Unit, File, Visitor);

  SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
  CursorVisitor InclusionCursorsVisitor(TU,
                                        FindFileIncludesVisitor::visit,
                                        &IncludesVisitor,
                                        /*VisitPreprocessorLast=*/false,
                                        /*VisitIncludedEntities=*/false,
                                        Range);
  return InclusionCursorsVisitor.visitPreprocessedEntitiesInRegion();
}


//===----------------------------------------------------------------------===//
// libclang public APIs.
//===----------------------------------------------------------------------===//

extern "C" {

CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
                                    CXCursorAndRangeVisitor visitor) {
  LogRef Log = Logger::make(__func__);

  if (clang_Cursor_isNull(cursor)) {
    if (Log)
      *Log << "Null cursor";
    return CXResult_Invalid;
  }
  if (cursor.kind == CXCursor_NoDeclFound) {
    if (Log)
      *Log << "Got CXCursor_NoDeclFound";
    return CXResult_Invalid;
  }
  if (!file) {
    if (Log)
      *Log << "Null file";
    return CXResult_Invalid;
  }
  if (!visitor.visit) {
    if (Log)
      *Log << "Null visitor";
    return CXResult_Invalid;
  }

  if (Log)
    *Log << cursor << " @" << static_cast<const FileEntry *>(file);

  ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
  if (!CXXUnit)
    return CXResult_Invalid;

  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  if (cursor.kind == CXCursor_MacroDefinition ||
      cursor.kind == CXCursor_MacroExpansion) {
    if (findMacroRefsInFile(cxcursor::getCursorTU(cursor),
                            cursor,
                            static_cast<const FileEntry *>(file),
                            visitor))
      return CXResult_VisitBreak;
    return CXResult_Success;
  }

  // We are interested in semantics of identifiers so for C++ constructor exprs
  // prefer type references, e.g.:
  //
  //  return MyStruct();
  //
  // for 'MyStruct' we'll have a cursor pointing at the constructor decl but
  // we are actually interested in the type declaration.
  cursor = cxcursor::getTypeRefCursor(cursor);

  CXCursor refCursor = clang_getCursorReferenced(cursor);

  if (!clang_isDeclaration(refCursor.kind)) {
    if (Log)
      *Log << "cursor is not referencing a declaration";
    return CXResult_Invalid;
  }

  if (findIdRefsInFile(cxcursor::getCursorTU(cursor),
                       refCursor,
                       static_cast<const FileEntry *>(file),
                       visitor))
    return CXResult_VisitBreak;
  return CXResult_Success;
}

CXResult clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
                             CXCursorAndRangeVisitor visitor) {
  if (cxtu::isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return CXResult_Invalid;
  }

  LogRef Log = Logger::make(__func__);
  if (!file) {
    if (Log)
      *Log << "Null file";
    return CXResult_Invalid;
  }
  if (!visitor.visit) {
    if (Log)
      *Log << "Null visitor";
    return CXResult_Invalid;
  }

  if (Log)
    *Log << TU << " @" << static_cast<const FileEntry *>(file);

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return CXResult_Invalid;

  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  if (findIncludesInFile(TU, static_cast<const FileEntry *>(file), visitor))
    return CXResult_VisitBreak;
  return CXResult_Success;
}

static enum CXVisitorResult _visitCursorAndRange(void *context,
                                                 CXCursor cursor,
                                                 CXSourceRange range) {
  CXCursorAndRangeVisitorBlock block = (CXCursorAndRangeVisitorBlock)context;
  return INVOKE_BLOCK2(block, cursor, range);
}

CXResult clang_findReferencesInFileWithBlock(CXCursor cursor,
                                             CXFile file,
                                           CXCursorAndRangeVisitorBlock block) {
  CXCursorAndRangeVisitor visitor = { block,
                                      block ? _visitCursorAndRange : nullptr };
  return clang_findReferencesInFile(cursor, file, visitor);
}

CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit TU,
                                           CXFile file,
                                           CXCursorAndRangeVisitorBlock block) {
  CXCursorAndRangeVisitor visitor = { block,
                                      block ? _visitCursorAndRange : nullptr };
  return clang_findIncludesInFile(TU, file, visitor);
}

} // end: extern "C"
