//===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CodeCompleteConsumer class.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Parse/Scope.h"
#include "clang/Lex/Preprocessor.h"
#include "clang-c/Index.h"
#include "Sema.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
#include <functional>

using namespace clang;
using llvm::StringRef;

//===----------------------------------------------------------------------===//
// Code completion string implementation
//===----------------------------------------------------------------------===//
CodeCompletionString::Chunk::Chunk(ChunkKind Kind, llvm::StringRef Text) 
  : Kind(Kind), Text("")
{
  switch (Kind) {
  case CK_TypedText:
  case CK_Text:
  case CK_Placeholder:
  case CK_Informative:
  case CK_CurrentParameter: {
    char *New = new char [Text.size() + 1];
    std::memcpy(New, Text.data(), Text.size());
    New[Text.size()] = '\0';
    this->Text = New;
    break;
  }

  case CK_Optional:
    llvm_unreachable("Optional strings cannot be created from text");
    break;
      
  case CK_LeftParen:
    this->Text = "(";
    break;

  case CK_RightParen:
    this->Text = ")";
    break;

  case CK_LeftBracket:
    this->Text = "[";
    break;
    
  case CK_RightBracket:
    this->Text = "]";
    break;
    
  case CK_LeftBrace:
    this->Text = "{";
    break;

  case CK_RightBrace:
    this->Text = "}";
    break;

  case CK_LeftAngle:
    this->Text = "<";
    break;
    
  case CK_RightAngle:
    this->Text = ">";
    break;
      
  case CK_Comma:
    this->Text = ", ";
    break;
  }
}

CodeCompletionString::Chunk
CodeCompletionString::Chunk::CreateText(StringRef Text) {
  return Chunk(CK_Text, Text);
}

CodeCompletionString::Chunk 
CodeCompletionString::Chunk::CreateOptional(
                                 std::auto_ptr<CodeCompletionString> Optional) {
  Chunk Result;
  Result.Kind = CK_Optional;
  Result.Optional = Optional.release();
  return Result;
}

CodeCompletionString::Chunk 
CodeCompletionString::Chunk::CreatePlaceholder(StringRef Placeholder) {
  return Chunk(CK_Placeholder, Placeholder);
}

CodeCompletionString::Chunk 
CodeCompletionString::Chunk::CreateInformative(StringRef Informative) {
  return Chunk(CK_Informative, Informative);
}

CodeCompletionString::Chunk 
CodeCompletionString::Chunk::CreateCurrentParameter(
                                                StringRef CurrentParameter) {
  return Chunk(CK_CurrentParameter, CurrentParameter);
}

CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
  switch (Kind) {
  case CK_TypedText:
  case CK_Text:
  case CK_Placeholder:
  case CK_Informative:
  case CK_CurrentParameter:
  case CK_LeftParen:
  case CK_RightParen:
  case CK_LeftBracket:
  case CK_RightBracket:
  case CK_LeftBrace:
  case CK_RightBrace:
  case CK_LeftAngle:
  case CK_RightAngle:
  case CK_Comma:
    return Chunk(Kind, Text);
      
  case CK_Optional: {
    std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
    return CreateOptional(Opt);
  }
  }

  // Silence GCC warning.
  return Chunk();
}

void
CodeCompletionString::Chunk::Destroy() {
  switch (Kind) {
  case CK_Optional: 
    delete Optional; 
    break;
      
  case CK_TypedText:
  case CK_Text: 
  case CK_Placeholder:
  case CK_Informative:
  case CK_CurrentParameter:
    delete [] Text;
    break;

  case CK_LeftParen:
  case CK_RightParen:
  case CK_LeftBracket:
  case CK_RightBracket:
  case CK_LeftBrace:
  case CK_RightBrace:
  case CK_LeftAngle:
  case CK_RightAngle:
  case CK_Comma:
    break;
  }
}

CodeCompletionString::~CodeCompletionString() {
  std::for_each(Chunks.begin(), Chunks.end(), 
                std::mem_fun_ref(&Chunk::Destroy));
}

std::string CodeCompletionString::getAsString() const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
                          
  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
    switch (C->Kind) {
    case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
    case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
    case CK_Informative: OS << "[#" << C->Text << "#]"; break;
    case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
    default: OS << C->Text; break;
    }
  }
  OS.flush();
  return Result;
}

const char *CodeCompletionString::getTypedText() const {
  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
    if (C->Kind == CK_TypedText)
      return C->Text;
  
  return 0;
}

CodeCompletionString *CodeCompletionString::Clone() const {
  CodeCompletionString *Result = new CodeCompletionString;
  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
    Result->AddChunk(C->Clone());
  return Result;
}

static void WriteUnsigned(llvm::raw_ostream &OS, unsigned Value) {
  OS.write((const char *)&Value, sizeof(unsigned));
}

static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
                         unsigned &Value) {
  if (Memory + sizeof(unsigned) > MemoryEnd)
    return true;

  memmove(&Value, Memory, sizeof(unsigned));
  Memory += sizeof(unsigned);
  return false;
}

void CodeCompletionString::Serialize(llvm::raw_ostream &OS) const {
  // Write the number of chunks.
  WriteUnsigned(OS, size());

  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
    WriteUnsigned(OS, C->Kind);

    switch (C->Kind) {
    case CK_TypedText:
    case CK_Text:
    case CK_Placeholder:
    case CK_Informative:
    case CK_CurrentParameter: {
      const char *Text = C->Text;
      unsigned StrLen = strlen(Text);
      WriteUnsigned(OS, StrLen);
      OS.write(Text, StrLen);
      break;
    }

    case CK_Optional:
      C->Optional->Serialize(OS);
      break;

    case CK_LeftParen:
    case CK_RightParen:
    case CK_LeftBracket:
    case CK_RightBracket:
    case CK_LeftBrace:
    case CK_RightBrace:
    case CK_LeftAngle:
    case CK_RightAngle:
    case CK_Comma:
      break;
    }
  }
}

CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str,
                                                        const char *StrEnd) {
  if (Str == StrEnd || *Str == 0)
    return 0;

  CodeCompletionString *Result = new CodeCompletionString;
  unsigned NumBlocks;
  if (ReadUnsigned(Str, StrEnd, NumBlocks))
    return Result;

  for (unsigned I = 0; I != NumBlocks; ++I) {
    if (Str + 1 >= StrEnd)
      break;

    // Parse the next kind.
    unsigned KindValue;
    if (ReadUnsigned(Str, StrEnd, KindValue))
      return Result;

    switch (ChunkKind Kind = (ChunkKind)KindValue) {
    case CK_TypedText:
    case CK_Text:
    case CK_Placeholder:
    case CK_Informative:
    case CK_CurrentParameter: {
      unsigned StrLen;
      if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd))
        return Result;

      Result->AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
      Str += StrLen;
      break;
    }

    case CK_Optional: {
      std::auto_ptr<CodeCompletionString> Optional(Deserialize(Str, StrEnd));
      Result->AddOptionalChunk(Optional);
      break;
    }

    case CK_LeftParen:
    case CK_RightParen:
    case CK_LeftBracket:
    case CK_RightBracket:
    case CK_LeftBrace:
    case CK_RightBrace:
    case CK_LeftAngle:
    case CK_RightAngle:
    case CK_Comma:
      Result->AddChunk(Chunk(Kind));
      break;      
    }
  };
  
  return Result;
}

void CodeCompleteConsumer::Result::Destroy() {
  if (Kind == RK_Pattern) {
    delete Pattern;
    Pattern = 0;
  }
}

//===----------------------------------------------------------------------===//
// Code completion overload candidate implementation
//===----------------------------------------------------------------------===//
FunctionDecl *
CodeCompleteConsumer::OverloadCandidate::getFunction() const {
  if (getKind() == CK_Function)
    return Function;
  else if (getKind() == CK_FunctionTemplate)
    return FunctionTemplate->getTemplatedDecl();
  else
    return 0;
}

const FunctionType *
CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
  switch (Kind) {
  case CK_Function:
    return Function->getType()->getAs<FunctionType>();
      
  case CK_FunctionTemplate:
    return FunctionTemplate->getTemplatedDecl()->getType()
             ->getAs<FunctionType>();
      
  case CK_FunctionType:
    return Type;
  }
  
  return 0;
}

//===----------------------------------------------------------------------===//
// Code completion consumer implementation
//===----------------------------------------------------------------------===//

CodeCompleteConsumer::~CodeCompleteConsumer() { }

void 
PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
                                                         Result *Results, 
                                                         unsigned NumResults) {
  // Print the results.
  for (unsigned I = 0; I != NumResults; ++I) {
    OS << "COMPLETION: ";
    switch (Results[I].Kind) {
    case Result::RK_Declaration:
      OS << Results[I].Declaration->getNameAsString() << " : " 
         << Results[I].Rank;
      if (Results[I].Hidden)
        OS << " (Hidden)";
      if (CodeCompletionString *CCS 
            = Results[I].CreateCodeCompletionString(SemaRef)) {
        OS << " : " << CCS->getAsString();
        delete CCS;
      }
        
      OS << '\n';
      break;
      
    case Result::RK_Keyword:
      OS << Results[I].Keyword << " : " << Results[I].Rank << '\n';
      break;
        
    case Result::RK_Macro: {
      OS << Results[I].Macro->getName() << " : " << Results[I].Rank;
      if (CodeCompletionString *CCS 
          = Results[I].CreateCodeCompletionString(SemaRef)) {
        OS << " : " << CCS->getAsString();
        delete CCS;
      }
      OS << '\n';
      break;
    }
        
    case Result::RK_Pattern: {
      OS << "Pattern : " << Results[I].Rank << " : " 
         << Results[I].Pattern->getAsString() << '\n';
      break;
    }
    }
  }
  
  // Once we've printed the code-completion results, suppress remaining
  // diagnostics.
  // FIXME: Move this somewhere else!
  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
}

void 
PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
                                                        unsigned CurrentArg,
                                              OverloadCandidate *Candidates,
                                                     unsigned NumCandidates) {
  for (unsigned I = 0; I != NumCandidates; ++I) {
    if (CodeCompletionString *CCS
          = Candidates[I].CreateSignatureString(CurrentArg, SemaRef)) {
      OS << "OVERLOAD: " << CCS->getAsString() << "\n";
      delete CCS;
    }
  }

  // Once we've printed the code-completion results, suppress remaining
  // diagnostics.
  // FIXME: Move this somewhere else!
  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
}

void 
CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
                                                       Result *Results, 
                                                       unsigned NumResults) {
  // Print the results.
  for (unsigned I = 0; I != NumResults; ++I) {
    CXCursorKind Kind = CXCursor_NotImplemented;

    switch (Results[I].Kind) {
    case Result::RK_Declaration:
      switch (Results[I].Declaration->getKind()) {
      case Decl::Record:
      case Decl::CXXRecord:
      case Decl::ClassTemplateSpecialization: {
        RecordDecl *Record = cast<RecordDecl>(Results[I].Declaration);
        if (Record->isStruct())
          Kind = CXCursor_StructDecl;
        else if (Record->isUnion())
          Kind = CXCursor_UnionDecl;
        else
          Kind = CXCursor_ClassDecl;
        break;
      }
        
      case Decl::ObjCMethod: {
        ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Results[I].Declaration);
        if (Method->isInstanceMethod())
            Kind = CXCursor_ObjCInstanceMethodDecl;
        else
          Kind = CXCursor_ObjCClassMethodDecl;
        break;
      }
        
      case Decl::Typedef:
        Kind = CXCursor_TypedefDecl;
        break;
        
      case Decl::Enum:
        Kind = CXCursor_EnumDecl;
        break;
        
      case Decl::Field:
        Kind = CXCursor_FieldDecl;
        break;
        
      case Decl::EnumConstant:
        Kind = CXCursor_EnumConstantDecl;
        break;
        
      case Decl::Function:
      case Decl::CXXMethod:
      case Decl::CXXConstructor:
      case Decl::CXXDestructor:
      case Decl::CXXConversion:
        Kind = CXCursor_FunctionDecl;
        break;
        
      case Decl::Var:
        Kind = CXCursor_VarDecl;
        break;
        
      case Decl::ParmVar:
        Kind = CXCursor_ParmDecl;
        break;
        
      case Decl::ObjCInterface:
        Kind = CXCursor_ObjCInterfaceDecl;
        break;
        
      case Decl::ObjCCategory:
        Kind = CXCursor_ObjCCategoryDecl;
        break;
        
      case Decl::ObjCProtocol:
        Kind = CXCursor_ObjCProtocolDecl;
        break;
        
      case Decl::ObjCProperty:
        Kind = CXCursor_ObjCPropertyDecl;
        break;
        
      case Decl::ObjCIvar:
        Kind = CXCursor_ObjCIvarDecl;
        break;
        
      case Decl::ObjCImplementation:
        Kind = CXCursor_ObjCClassDefn;
        break;
        
      case Decl::ObjCCategoryImpl:
        Kind = CXCursor_ObjCCategoryDefn;
        break;
        
      default:
        break;
      }
      break;
        
    case Result::RK_Keyword:
    case Result::RK_Macro:
    case Result::RK_Pattern:
      Kind = CXCursor_NotImplemented;
      break;
    }

    WriteUnsigned(OS, Kind);
    CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
    assert(CCS && "No code-completion string?");
    CCS->Serialize(OS);
    delete CCS;
  }
  
  // Once we've printed the code-completion results, suppress remaining
  // diagnostics.
  // FIXME: Move this somewhere else!
  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
}

void 
CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
                                                      unsigned CurrentArg,
                                                OverloadCandidate *Candidates,
                                                       unsigned NumCandidates) {
  for (unsigned I = 0; I != NumCandidates; ++I) {
    WriteUnsigned(OS, CXCursor_NotImplemented);
    CodeCompletionString *CCS
      = Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
    assert(CCS && "No code-completion string?");
    CCS->Serialize(OS);
    delete CCS;
  }
  
  // Once we've printed the code-completion results, suppress remaining
  // diagnostics.
  // FIXME: Move this somewhere else!
  SemaRef.PP.getDiagnostics().setSuppressAllDiagnostics();
}
