CodeCompleteConsumer.cpp revision 224145
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
28using namespace clang;
29using llvm::StringRef;
30
31//===----------------------------------------------------------------------===//
32// Code completion context implementation
33//===----------------------------------------------------------------------===//
34
35bool 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//===----------------------------------------------------------------------===//
82CodeCompletionString::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
157CodeCompletionString::Chunk
158CodeCompletionString::Chunk::CreateText(const char *Text) {
159  return Chunk(CK_Text, Text);
160}
161
162CodeCompletionString::Chunk
163CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
164  Chunk Result;
165  Result.Kind = CK_Optional;
166  Result.Optional = Optional;
167  return Result;
168}
169
170CodeCompletionString::Chunk
171CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
172  return Chunk(CK_Placeholder, Placeholder);
173}
174
175CodeCompletionString::Chunk
176CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
177  return Chunk(CK_Informative, Informative);
178}
179
180CodeCompletionString::Chunk
181CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
182  return Chunk(CK_ResultType, ResultType);
183}
184
185CodeCompletionString::Chunk
186CodeCompletionString::Chunk::CreateCurrentParameter(
187                                                const char *CurrentParameter) {
188  return Chunk(CK_CurrentParameter, CurrentParameter);
189}
190
191CodeCompletionString::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
202std::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
223const 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
231const 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
238const 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
246CodeCompletionString *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
257unsigned 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//===----------------------------------------------------------------------===//
287FunctionDecl *
288CodeCompleteConsumer::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
297const FunctionType *
298CodeCompleteConsumer::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
318CodeCompleteConsumer::~CodeCompleteConsumer() { }
319
320void
321PrintingCodeCompleteConsumer::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
366void
367PrintingCodeCompleteConsumer::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
380void 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.
428static 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
460bool 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