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