Home | History | Annotate | Download | only in Sema
      1 //===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file implements the CodeCompleteConsumer class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include "clang/Sema/CodeCompleteConsumer.h"
     14 #include "clang/Sema/Scope.h"
     15 #include "clang/Sema/Sema.h"
     16 #include "clang/AST/DeclCXX.h"
     17 #include "clang/AST/DeclObjC.h"
     18 #include "clang/AST/DeclTemplate.h"
     19 #include "clang/Lex/Preprocessor.h"
     20 #include "clang-c/Index.h"
     21 #include "llvm/ADT/STLExtras.h"
     22 #include "llvm/ADT/Twine.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 #include <algorithm>
     25 #include <cstring>
     26 #include <functional>
     27 
     28 using namespace clang;
     29 using llvm::StringRef;
     30 
     31 //===----------------------------------------------------------------------===//
     32 // Code completion context implementation
     33 //===----------------------------------------------------------------------===//
     34 
     35 bool CodeCompletionContext::wantConstructorResults() const {
     36   switch (Kind) {
     37   case CCC_Recovery:
     38   case CCC_Statement:
     39   case CCC_Expression:
     40   case CCC_ObjCMessageReceiver:
     41   case CCC_ParenthesizedExpression:
     42     return true;
     43 
     44   case CCC_TopLevel:
     45   case CCC_ObjCInterface:
     46   case CCC_ObjCImplementation:
     47   case CCC_ObjCIvarList:
     48   case CCC_ClassStructUnion:
     49   case CCC_DotMemberAccess:
     50   case CCC_ArrowMemberAccess:
     51   case CCC_ObjCPropertyAccess:
     52   case CCC_EnumTag:
     53   case CCC_UnionTag:
     54   case CCC_ClassOrStructTag:
     55   case CCC_ObjCProtocolName:
     56   case CCC_Namespace:
     57   case CCC_Type:
     58   case CCC_Name:
     59   case CCC_PotentiallyQualifiedName:
     60   case CCC_MacroName:
     61   case CCC_MacroNameUse:
     62   case CCC_PreprocessorExpression:
     63   case CCC_PreprocessorDirective:
     64   case CCC_NaturalLanguage:
     65   case CCC_SelectorName:
     66   case CCC_TypeQualifiers:
     67   case CCC_Other:
     68   case CCC_OtherWithMacros:
     69   case CCC_ObjCInstanceMessage:
     70   case CCC_ObjCClassMessage:
     71   case CCC_ObjCSuperclass:
     72   case CCC_ObjCCategoryName:
     73     return false;
     74   }
     75 
     76   return false;
     77 }
     78 
     79 //===----------------------------------------------------------------------===//
     80 // Code completion string implementation
     81 //===----------------------------------------------------------------------===//
     82 CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
     83   : Kind(Kind), Text("")
     84 {
     85   switch (Kind) {
     86   case CK_TypedText:
     87   case CK_Text:
     88   case CK_Placeholder:
     89   case CK_Informative:
     90   case CK_ResultType:
     91   case CK_CurrentParameter:
     92     this->Text = Text;
     93     break;
     94 
     95   case CK_Optional:
     96     llvm_unreachable("Optional strings cannot be created from text");
     97     break;
     98 
     99   case CK_LeftParen:
    100     this->Text = "(";
    101     break;
    102 
    103   case CK_RightParen:
    104     this->Text = ")";
    105     break;
    106 
    107   case CK_LeftBracket:
    108     this->Text = "[";
    109     break;
    110 
    111   case CK_RightBracket:
    112     this->Text = "]";
    113     break;
    114 
    115   case CK_LeftBrace:
    116     this->Text = "{";
    117     break;
    118 
    119   case CK_RightBrace:
    120     this->Text = "}";
    121     break;
    122 
    123   case CK_LeftAngle:
    124     this->Text = "<";
    125     break;
    126 
    127   case CK_RightAngle:
    128     this->Text = ">";
    129     break;
    130 
    131   case CK_Comma:
    132     this->Text = ", ";
    133     break;
    134 
    135   case CK_Colon:
    136     this->Text = ":";
    137     break;
    138 
    139   case CK_SemiColon:
    140     this->Text = ";";
    141     break;
    142 
    143   case CK_Equal:
    144     this->Text = " = ";
    145     break;
    146 
    147   case CK_HorizontalSpace:
    148     this->Text = " ";
    149     break;
    150 
    151   case CK_VerticalSpace:
    152     this->Text = "\n";
    153     break;
    154   }
    155 }
    156 
    157 CodeCompletionString::Chunk
    158 CodeCompletionString::Chunk::CreateText(const char *Text) {
    159   return Chunk(CK_Text, Text);
    160 }
    161 
    162 CodeCompletionString::Chunk
    163 CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
    164   Chunk Result;
    165   Result.Kind = CK_Optional;
    166   Result.Optional = Optional;
    167   return Result;
    168 }
    169 
    170 CodeCompletionString::Chunk
    171 CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
    172   return Chunk(CK_Placeholder, Placeholder);
    173 }
    174 
    175 CodeCompletionString::Chunk
    176 CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
    177   return Chunk(CK_Informative, Informative);
    178 }
    179 
    180 CodeCompletionString::Chunk
    181 CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
    182   return Chunk(CK_ResultType, ResultType);
    183 }
    184 
    185 CodeCompletionString::Chunk
    186 CodeCompletionString::Chunk::CreateCurrentParameter(
    187                                                 const char *CurrentParameter) {
    188   return Chunk(CK_CurrentParameter, CurrentParameter);
    189 }
    190 
    191 CodeCompletionString::CodeCompletionString(const Chunk *Chunks,
    192                                            unsigned NumChunks,
    193                                            unsigned Priority,
    194                                            CXAvailabilityKind Availability)
    195   : NumChunks(NumChunks), Priority(Priority), Availability(Availability)
    196 {
    197   Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
    198   for (unsigned I = 0; I != NumChunks; ++I)
    199     StoredChunks[I] = Chunks[I];
    200 }
    201 
    202 std::string CodeCompletionString::getAsString() const {
    203   std::string Result;
    204   llvm::raw_string_ostream OS(Result);
    205 
    206   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
    207     switch (C->Kind) {
    208     case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
    209     case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
    210 
    211     case CK_Informative:
    212     case CK_ResultType:
    213       OS << "[#" << C->Text << "#]";
    214       break;
    215 
    216     case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
    217     default: OS << C->Text; break;
    218     }
    219   }
    220   return OS.str();
    221 }
    222 
    223 const char *CodeCompletionString::getTypedText() const {
    224   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
    225     if (C->Kind == CK_TypedText)
    226       return C->Text;
    227 
    228   return 0;
    229 }
    230 
    231 const char *CodeCompletionAllocator::CopyString(llvm::StringRef String) {
    232   char *Mem = (char *)Allocate(String.size() + 1, 1);
    233   std::copy(String.begin(), String.end(), Mem);
    234   Mem[String.size()] = 0;
    235   return Mem;
    236 }
    237 
    238 const char *CodeCompletionAllocator::CopyString(llvm::Twine String) {
    239   // FIXME: It would be more efficient to teach Twine to tell us its size and
    240   // then add a routine there to fill in an allocated char* with the contents
    241   // of the string.
    242   llvm::SmallString<128> Data;
    243   return CopyString(String.toStringRef(Data));
    244 }
    245 
    246 CodeCompletionString *CodeCompletionBuilder::TakeString() {
    247   void *Mem = Allocator.Allocate(
    248                   sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size(),
    249                                  llvm::alignOf<CodeCompletionString>());
    250   CodeCompletionString *Result
    251     = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
    252                                Priority, Availability);
    253   Chunks.clear();
    254   return Result;
    255 }
    256 
    257 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
    258   if (!ND)
    259     return CCP_Unlikely;
    260 
    261   // Context-based decisions.
    262   DeclContext *DC = ND->getDeclContext()->getRedeclContext();
    263   if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) {
    264     // _cmd is relatively rare
    265     if (ImplicitParamDecl *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND))
    266       if (ImplicitParam->getIdentifier() &&
    267           ImplicitParam->getIdentifier()->isStr("_cmd"))
    268         return CCP_ObjC_cmd;
    269 
    270     return CCP_LocalDeclaration;
    271   }
    272   if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
    273     return CCP_MemberDeclaration;
    274 
    275   // Content-based decisions.
    276   if (isa<EnumConstantDecl>(ND))
    277     return CCP_Constant;
    278   if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
    279     return CCP_Type;
    280 
    281   return CCP_Declaration;
    282 }
    283 
    284 //===----------------------------------------------------------------------===//
    285 // Code completion overload candidate implementation
    286 //===----------------------------------------------------------------------===//
    287 FunctionDecl *
    288 CodeCompleteConsumer::OverloadCandidate::getFunction() const {
    289   if (getKind() == CK_Function)
    290     return Function;
    291   else if (getKind() == CK_FunctionTemplate)
    292     return FunctionTemplate->getTemplatedDecl();
    293   else
    294     return 0;
    295 }
    296 
    297 const FunctionType *
    298 CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
    299   switch (Kind) {
    300   case CK_Function:
    301     return Function->getType()->getAs<FunctionType>();
    302 
    303   case CK_FunctionTemplate:
    304     return FunctionTemplate->getTemplatedDecl()->getType()
    305              ->getAs<FunctionType>();
    306 
    307   case CK_FunctionType:
    308     return Type;
    309   }
    310 
    311   return 0;
    312 }
    313 
    314 //===----------------------------------------------------------------------===//
    315 // Code completion consumer implementation
    316 //===----------------------------------------------------------------------===//
    317 
    318 CodeCompleteConsumer::~CodeCompleteConsumer() { }
    319 
    320 void
    321 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
    322                                                  CodeCompletionContext Context,
    323                                                  CodeCompletionResult *Results,
    324                                                          unsigned NumResults) {
    325   std::stable_sort(Results, Results + NumResults);
    326 
    327   // Print the results.
    328   for (unsigned I = 0; I != NumResults; ++I) {
    329     OS << "COMPLETION: ";
    330     switch (Results[I].Kind) {
    331     case CodeCompletionResult::RK_Declaration:
    332       OS << Results[I].Declaration;
    333       if (Results[I].Hidden)
    334         OS << " (Hidden)";
    335       if (CodeCompletionString *CCS
    336             = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
    337         OS << " : " << CCS->getAsString();
    338       }
    339 
    340       OS << '\n';
    341       break;
    342 
    343     case CodeCompletionResult::RK_Keyword:
    344       OS << Results[I].Keyword << '\n';
    345       break;
    346 
    347     case CodeCompletionResult::RK_Macro: {
    348       OS << Results[I].Macro->getName();
    349       if (CodeCompletionString *CCS
    350             = Results[I].CreateCodeCompletionString(SemaRef, Allocator)) {
    351         OS << " : " << CCS->getAsString();
    352       }
    353       OS << '\n';
    354       break;
    355     }
    356 
    357     case CodeCompletionResult::RK_Pattern: {
    358       OS << "Pattern : "
    359          << Results[I].Pattern->getAsString() << '\n';
    360       break;
    361     }
    362     }
    363   }
    364 }
    365 
    366 void
    367 PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
    368                                                         unsigned CurrentArg,
    369                                               OverloadCandidate *Candidates,
    370                                                      unsigned NumCandidates) {
    371   for (unsigned I = 0; I != NumCandidates; ++I) {
    372     if (CodeCompletionString *CCS
    373           = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
    374                                                 Allocator)) {
    375       OS << "OVERLOAD: " << CCS->getAsString() << "\n";
    376     }
    377   }
    378 }
    379 
    380 void CodeCompletionResult::computeCursorKindAndAvailability() {
    381   switch (Kind) {
    382   case RK_Declaration:
    383     // Set the availability based on attributes.
    384     switch (Declaration->getAvailability()) {
    385     case AR_Available:
    386     case AR_NotYetIntroduced:
    387       Availability = CXAvailability_Available;
    388       break;
    389 
    390     case AR_Deprecated:
    391       Availability = CXAvailability_Deprecated;
    392       break;
    393 
    394     case AR_Unavailable:
    395       Availability = CXAvailability_NotAvailable;
    396       break;
    397     }
    398 
    399     if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
    400       if (Function->isDeleted())
    401         Availability = CXAvailability_NotAvailable;
    402 
    403     CursorKind = getCursorKindForDecl(Declaration);
    404     if (CursorKind == CXCursor_UnexposedDecl)
    405       CursorKind = CXCursor_NotImplemented;
    406     break;
    407 
    408   case RK_Macro:
    409     Availability = CXAvailability_Available;
    410     CursorKind = CXCursor_MacroDefinition;
    411     break;
    412 
    413   case RK_Keyword:
    414     Availability = CXAvailability_Available;
    415     CursorKind = CXCursor_NotImplemented;
    416     break;
    417 
    418   case RK_Pattern:
    419     // Do nothing: Patterns can come with cursor kinds!
    420     break;
    421   }
    422 }
    423 
    424 /// \brief Retrieve the name that should be used to order a result.
    425 ///
    426 /// If the name needs to be constructed as a string, that string will be
    427 /// saved into Saved and the returned StringRef will refer to it.
    428 static llvm::StringRef getOrderedName(const CodeCompletionResult &R,
    429                                     std::string &Saved) {
    430   switch (R.Kind) {
    431     case CodeCompletionResult::RK_Keyword:
    432       return R.Keyword;
    433 
    434     case CodeCompletionResult::RK_Pattern:
    435       return R.Pattern->getTypedText();
    436 
    437     case CodeCompletionResult::RK_Macro:
    438       return R.Macro->getName();
    439 
    440     case CodeCompletionResult::RK_Declaration:
    441       // Handle declarations below.
    442       break;
    443   }
    444 
    445   DeclarationName Name = R.Declaration->getDeclName();
    446 
    447   // If the name is a simple identifier (by far the common case), or a
    448   // zero-argument selector, just return a reference to that identifier.
    449   if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
    450     return Id->getName();
    451   if (Name.isObjCZeroArgSelector())
    452     if (IdentifierInfo *Id
    453         = Name.getObjCSelector().getIdentifierInfoForSlot(0))
    454       return Id->getName();
    455 
    456   Saved = Name.getAsString();
    457   return Saved;
    458 }
    459 
    460 bool clang::operator<(const CodeCompletionResult &X,
    461                       const CodeCompletionResult &Y) {
    462   std::string XSaved, YSaved;
    463   llvm::StringRef XStr = getOrderedName(X, XSaved);
    464   llvm::StringRef YStr = getOrderedName(Y, YSaved);
    465   int cmp = XStr.compare_lower(YStr);
    466   if (cmp)
    467     return cmp < 0;
    468 
    469   // If case-insensitive comparison fails, try case-sensitive comparison.
    470   cmp = XStr.compare(YStr);
    471   if (cmp)
    472     return cmp < 0;
    473 
    474   return false;
    475 }
    476