CodeCompleteConsumer.cpp revision 212904
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/Support/raw_ostream.h"
23#include <algorithm>
24#include <cstring>
25#include <functional>
26
27using namespace clang;
28using llvm::StringRef;
29
30//===----------------------------------------------------------------------===//
31// Code completion string implementation
32//===----------------------------------------------------------------------===//
33CodeCompletionString::Chunk::Chunk(ChunkKind Kind, llvm::StringRef Text)
34  : Kind(Kind), Text("")
35{
36  switch (Kind) {
37  case CK_TypedText:
38  case CK_Text:
39  case CK_Placeholder:
40  case CK_Informative:
41  case CK_ResultType:
42  case CK_CurrentParameter: {
43    char *New = new char [Text.size() + 1];
44    std::memcpy(New, Text.data(), Text.size());
45    New[Text.size()] = '\0';
46    this->Text = New;
47    break;
48  }
49
50  case CK_Optional:
51    llvm_unreachable("Optional strings cannot be created from text");
52    break;
53
54  case CK_LeftParen:
55    this->Text = "(";
56    break;
57
58  case CK_RightParen:
59    this->Text = ")";
60    break;
61
62  case CK_LeftBracket:
63    this->Text = "[";
64    break;
65
66  case CK_RightBracket:
67    this->Text = "]";
68    break;
69
70  case CK_LeftBrace:
71    this->Text = "{";
72    break;
73
74  case CK_RightBrace:
75    this->Text = "}";
76    break;
77
78  case CK_LeftAngle:
79    this->Text = "<";
80    break;
81
82  case CK_RightAngle:
83    this->Text = ">";
84    break;
85
86  case CK_Comma:
87    this->Text = ", ";
88    break;
89
90  case CK_Colon:
91    this->Text = ":";
92    break;
93
94  case CK_SemiColon:
95    this->Text = ";";
96    break;
97
98  case CK_Equal:
99    this->Text = " = ";
100    break;
101
102  case CK_HorizontalSpace:
103    this->Text = " ";
104    break;
105
106  case CK_VerticalSpace:
107    this->Text = "\n";
108    break;
109  }
110}
111
112CodeCompletionString::Chunk
113CodeCompletionString::Chunk::CreateText(StringRef Text) {
114  return Chunk(CK_Text, Text);
115}
116
117CodeCompletionString::Chunk
118CodeCompletionString::Chunk::CreateOptional(
119                                 std::auto_ptr<CodeCompletionString> Optional) {
120  Chunk Result;
121  Result.Kind = CK_Optional;
122  Result.Optional = Optional.release();
123  return Result;
124}
125
126CodeCompletionString::Chunk
127CodeCompletionString::Chunk::CreatePlaceholder(StringRef Placeholder) {
128  return Chunk(CK_Placeholder, Placeholder);
129}
130
131CodeCompletionString::Chunk
132CodeCompletionString::Chunk::CreateInformative(StringRef Informative) {
133  return Chunk(CK_Informative, Informative);
134}
135
136CodeCompletionString::Chunk
137CodeCompletionString::Chunk::CreateResultType(StringRef ResultType) {
138  return Chunk(CK_ResultType, ResultType);
139}
140
141CodeCompletionString::Chunk
142CodeCompletionString::Chunk::CreateCurrentParameter(
143                                                StringRef CurrentParameter) {
144  return Chunk(CK_CurrentParameter, CurrentParameter);
145}
146
147CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
148  switch (Kind) {
149  case CK_TypedText:
150  case CK_Text:
151  case CK_Placeholder:
152  case CK_Informative:
153  case CK_ResultType:
154  case CK_CurrentParameter:
155  case CK_LeftParen:
156  case CK_RightParen:
157  case CK_LeftBracket:
158  case CK_RightBracket:
159  case CK_LeftBrace:
160  case CK_RightBrace:
161  case CK_LeftAngle:
162  case CK_RightAngle:
163  case CK_Comma:
164  case CK_Colon:
165  case CK_SemiColon:
166  case CK_Equal:
167  case CK_HorizontalSpace:
168  case CK_VerticalSpace:
169    return Chunk(Kind, Text);
170
171  case CK_Optional: {
172    std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
173    return CreateOptional(Opt);
174  }
175  }
176
177  // Silence GCC warning.
178  return Chunk();
179}
180
181void
182CodeCompletionString::Chunk::Destroy() {
183  switch (Kind) {
184  case CK_Optional:
185    delete Optional;
186    break;
187
188  case CK_TypedText:
189  case CK_Text:
190  case CK_Placeholder:
191  case CK_Informative:
192  case CK_ResultType:
193  case CK_CurrentParameter:
194    delete [] Text;
195    break;
196
197  case CK_LeftParen:
198  case CK_RightParen:
199  case CK_LeftBracket:
200  case CK_RightBracket:
201  case CK_LeftBrace:
202  case CK_RightBrace:
203  case CK_LeftAngle:
204  case CK_RightAngle:
205  case CK_Comma:
206  case CK_Colon:
207  case CK_SemiColon:
208  case CK_Equal:
209  case CK_HorizontalSpace:
210  case CK_VerticalSpace:
211    break;
212  }
213}
214
215void CodeCompletionString::clear() {
216  std::for_each(Chunks.begin(), Chunks.end(),
217                std::mem_fun_ref(&Chunk::Destroy));
218  Chunks.clear();
219}
220
221std::string CodeCompletionString::getAsString() const {
222  std::string Result;
223  llvm::raw_string_ostream OS(Result);
224
225  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
226    switch (C->Kind) {
227    case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
228    case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
229
230    case CK_Informative:
231    case CK_ResultType:
232      OS << "[#" << C->Text << "#]";
233      break;
234
235    case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
236    default: OS << C->Text; break;
237    }
238  }
239  return OS.str();
240}
241
242const char *CodeCompletionString::getTypedText() const {
243  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
244    if (C->Kind == CK_TypedText)
245      return C->Text;
246
247  return 0;
248}
249
250CodeCompletionString *
251CodeCompletionString::Clone(CodeCompletionString *Result) const {
252  if (!Result)
253    Result = new CodeCompletionString;
254  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
255    Result->AddChunk(C->Clone());
256  return Result;
257}
258
259static void WriteUnsigned(llvm::raw_ostream &OS, unsigned Value) {
260  OS.write((const char *)&Value, sizeof(unsigned));
261}
262
263static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
264                         unsigned &Value) {
265  if (Memory + sizeof(unsigned) > MemoryEnd)
266    return true;
267
268  memmove(&Value, Memory, sizeof(unsigned));
269  Memory += sizeof(unsigned);
270  return false;
271}
272
273void CodeCompletionString::Serialize(llvm::raw_ostream &OS) const {
274  // Write the number of chunks.
275  WriteUnsigned(OS, size());
276
277  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
278    WriteUnsigned(OS, C->Kind);
279
280    switch (C->Kind) {
281    case CK_TypedText:
282    case CK_Text:
283    case CK_Placeholder:
284    case CK_Informative:
285    case CK_ResultType:
286    case CK_CurrentParameter: {
287      const char *Text = C->Text;
288      unsigned StrLen = strlen(Text);
289      WriteUnsigned(OS, StrLen);
290      OS.write(Text, StrLen);
291      break;
292    }
293
294    case CK_Optional:
295      C->Optional->Serialize(OS);
296      break;
297
298    case CK_LeftParen:
299    case CK_RightParen:
300    case CK_LeftBracket:
301    case CK_RightBracket:
302    case CK_LeftBrace:
303    case CK_RightBrace:
304    case CK_LeftAngle:
305    case CK_RightAngle:
306    case CK_Comma:
307    case CK_Colon:
308    case CK_SemiColon:
309    case CK_Equal:
310    case CK_HorizontalSpace:
311    case CK_VerticalSpace:
312      break;
313    }
314  }
315}
316
317bool CodeCompletionString::Deserialize(const char *&Str, const char *StrEnd) {
318  if (Str == StrEnd || *Str == 0)
319    return false;
320
321  unsigned NumBlocks;
322  if (ReadUnsigned(Str, StrEnd, NumBlocks))
323    return false;
324
325  for (unsigned I = 0; I != NumBlocks; ++I) {
326    if (Str + 1 >= StrEnd)
327      break;
328
329    // Parse the next kind.
330    unsigned KindValue;
331    if (ReadUnsigned(Str, StrEnd, KindValue))
332      return false;
333
334    switch (ChunkKind Kind = (ChunkKind)KindValue) {
335    case CK_TypedText:
336    case CK_Text:
337    case CK_Placeholder:
338    case CK_Informative:
339    case CK_ResultType:
340    case CK_CurrentParameter: {
341      unsigned StrLen;
342      if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd))
343        return false;
344
345      AddChunk(Chunk(Kind, StringRef(Str, StrLen)));
346      Str += StrLen;
347      break;
348    }
349
350    case CK_Optional: {
351      std::auto_ptr<CodeCompletionString> Optional(new CodeCompletionString());
352      if (Optional->Deserialize(Str, StrEnd))
353        AddOptionalChunk(Optional);
354      break;
355    }
356
357    case CK_LeftParen:
358    case CK_RightParen:
359    case CK_LeftBracket:
360    case CK_RightBracket:
361    case CK_LeftBrace:
362    case CK_RightBrace:
363    case CK_LeftAngle:
364    case CK_RightAngle:
365    case CK_Comma:
366    case CK_Colon:
367    case CK_SemiColon:
368    case CK_Equal:
369    case CK_HorizontalSpace:
370    case CK_VerticalSpace:
371      AddChunk(Chunk(Kind));
372      break;
373    }
374  };
375
376  return true;
377}
378
379void CodeCompletionResult::Destroy() {
380  if (Kind == RK_Pattern) {
381    delete Pattern;
382    Pattern = 0;
383  }
384}
385
386unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
387  if (!ND)
388    return CCP_Unlikely;
389
390  // Context-based decisions.
391  DeclContext *DC = ND->getDeclContext()->getRedeclContext();
392  if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC))
393    return CCP_LocalDeclaration;
394  if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
395    return CCP_MemberDeclaration;
396
397  // Content-based decisions.
398  if (isa<EnumConstantDecl>(ND))
399    return CCP_Constant;
400  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
401    return CCP_Type;
402  return CCP_Declaration;
403}
404
405//===----------------------------------------------------------------------===//
406// Code completion overload candidate implementation
407//===----------------------------------------------------------------------===//
408FunctionDecl *
409CodeCompleteConsumer::OverloadCandidate::getFunction() const {
410  if (getKind() == CK_Function)
411    return Function;
412  else if (getKind() == CK_FunctionTemplate)
413    return FunctionTemplate->getTemplatedDecl();
414  else
415    return 0;
416}
417
418const FunctionType *
419CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
420  switch (Kind) {
421  case CK_Function:
422    return Function->getType()->getAs<FunctionType>();
423
424  case CK_FunctionTemplate:
425    return FunctionTemplate->getTemplatedDecl()->getType()
426             ->getAs<FunctionType>();
427
428  case CK_FunctionType:
429    return Type;
430  }
431
432  return 0;
433}
434
435//===----------------------------------------------------------------------===//
436// Code completion consumer implementation
437//===----------------------------------------------------------------------===//
438
439CodeCompleteConsumer::~CodeCompleteConsumer() { }
440
441void
442PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
443                                                 CodeCompletionContext Context,
444                                                 CodeCompletionResult *Results,
445                                                         unsigned NumResults) {
446  std::stable_sort(Results, Results + NumResults);
447
448  // Print the results.
449  for (unsigned I = 0; I != NumResults; ++I) {
450    OS << "COMPLETION: ";
451    switch (Results[I].Kind) {
452    case CodeCompletionResult::RK_Declaration:
453      OS << Results[I].Declaration;
454      if (Results[I].Hidden)
455        OS << " (Hidden)";
456      if (CodeCompletionString *CCS
457            = Results[I].CreateCodeCompletionString(SemaRef)) {
458        OS << " : " << CCS->getAsString();
459        delete CCS;
460      }
461
462      OS << '\n';
463      break;
464
465    case CodeCompletionResult::RK_Keyword:
466      OS << Results[I].Keyword << '\n';
467      break;
468
469    case CodeCompletionResult::RK_Macro: {
470      OS << Results[I].Macro->getName();
471      if (CodeCompletionString *CCS
472            = Results[I].CreateCodeCompletionString(SemaRef)) {
473        OS << " : " << CCS->getAsString();
474        delete CCS;
475      }
476      OS << '\n';
477      break;
478    }
479
480    case CodeCompletionResult::RK_Pattern: {
481      OS << "Pattern : "
482         << Results[I].Pattern->getAsString() << '\n';
483      break;
484    }
485    }
486  }
487}
488
489void
490PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
491                                                        unsigned CurrentArg,
492                                              OverloadCandidate *Candidates,
493                                                     unsigned NumCandidates) {
494  for (unsigned I = 0; I != NumCandidates; ++I) {
495    if (CodeCompletionString *CCS
496          = Candidates[I].CreateSignatureString(CurrentArg, SemaRef)) {
497      OS << "OVERLOAD: " << CCS->getAsString() << "\n";
498      delete CCS;
499    }
500  }
501}
502
503void CodeCompletionResult::computeCursorKindAndAvailability() {
504  switch (Kind) {
505  case RK_Declaration:
506    // Set the availability based on attributes.
507    Availability = CXAvailability_Available;
508    if (Declaration->getAttr<UnavailableAttr>())
509      Availability = CXAvailability_NotAvailable;
510    else if (Declaration->getAttr<DeprecatedAttr>())
511      Availability = CXAvailability_Deprecated;
512
513    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
514      if (Function->isDeleted())
515        Availability = CXAvailability_NotAvailable;
516
517    CursorKind = getCursorKindForDecl(Declaration);
518    if (CursorKind == CXCursor_UnexposedDecl)
519      CursorKind = CXCursor_NotImplemented;
520    break;
521
522  case RK_Macro:
523    Availability = CXAvailability_Available;
524    CursorKind = CXCursor_MacroDefinition;
525    break;
526
527  case RK_Keyword:
528    Availability = CXAvailability_Available;
529    CursorKind = CXCursor_NotImplemented;
530    break;
531
532  case RK_Pattern:
533    // Do nothing: Patterns can come with cursor kinds!
534    break;
535  }
536}
537
538/// \brief Retrieve the name that should be used to order a result.
539///
540/// If the name needs to be constructed as a string, that string will be
541/// saved into Saved and the returned StringRef will refer to it.
542static llvm::StringRef getOrderedName(const CodeCompletionResult &R,
543                                    std::string &Saved) {
544  switch (R.Kind) {
545    case CodeCompletionResult::RK_Keyword:
546      return R.Keyword;
547
548    case CodeCompletionResult::RK_Pattern:
549      return R.Pattern->getTypedText();
550
551    case CodeCompletionResult::RK_Macro:
552      return R.Macro->getName();
553
554    case CodeCompletionResult::RK_Declaration:
555      // Handle declarations below.
556      break;
557  }
558
559  DeclarationName Name = R.Declaration->getDeclName();
560
561  // If the name is a simple identifier (by far the common case), or a
562  // zero-argument selector, just return a reference to that identifier.
563  if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
564    return Id->getName();
565  if (Name.isObjCZeroArgSelector())
566    if (IdentifierInfo *Id
567        = Name.getObjCSelector().getIdentifierInfoForSlot(0))
568      return Id->getName();
569
570  Saved = Name.getAsString();
571  return Saved;
572}
573
574bool clang::operator<(const CodeCompletionResult &X,
575                      const CodeCompletionResult &Y) {
576  std::string XSaved, YSaved;
577  llvm::StringRef XStr = getOrderedName(X, XSaved);
578  llvm::StringRef YStr = getOrderedName(Y, YSaved);
579  int cmp = XStr.compare_lower(YStr);
580  if (cmp)
581    return cmp < 0;
582
583  // If case-insensitive comparison fails, try case-sensitive comparison.
584  cmp = XStr.compare(YStr);
585  if (cmp)
586    return cmp < 0;
587
588  return false;
589}
590
591void
592CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
593                                                 CodeCompletionContext Context,
594                                                 CodeCompletionResult *Results,
595                                                       unsigned NumResults) {
596  // Print the results.
597  for (unsigned I = 0; I != NumResults; ++I) {
598    WriteUnsigned(OS, Results[I].CursorKind);
599    WriteUnsigned(OS, Results[I].Priority);
600    WriteUnsigned(OS, Results[I].Availability);
601    CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
602    assert(CCS && "No code-completion string?");
603    CCS->Serialize(OS);
604    delete CCS;
605  }
606}
607
608void
609CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
610                                                      unsigned CurrentArg,
611                                                OverloadCandidate *Candidates,
612                                                       unsigned NumCandidates) {
613  for (unsigned I = 0; I != NumCandidates; ++I) {
614    WriteUnsigned(OS, CXCursor_NotImplemented);
615    WriteUnsigned(OS, /*Priority=*/I);
616    WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
617    CodeCompletionString *CCS
618      = Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
619    assert(CCS && "No code-completion string?");
620    CCS->Serialize(OS);
621    delete CCS;
622  }
623}
624