//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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 (SmallVector<CXCursor, 8>::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();
  }

  /// \brief 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 0;

    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 (std::find(TopMethods.begin(), TopMethods.end(), D) !=
          TopMethods.end())
      return true;

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

    return false;
  }
};

} // end anonymous namespace.

/// \brief 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 = 0;
  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 = 0;
  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(LLVM_FUNCTION_NAME);

  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) {
  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);

  if (!TU) {
    if (Log)
      *Log << "Null CXTranslationUnit";
    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 << 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 : 0 };
  return clang_findReferencesInFile(cursor, file, visitor);
}

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

} // end: extern "C"

