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
wantConstructorResults() const35 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 //===----------------------------------------------------------------------===//
Chunk(ChunkKind Kind,const char * Text)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
CreateText(const char * Text)158 CodeCompletionString::Chunk::CreateText(const char *Text) {
159 return Chunk(CK_Text, Text);
160 }
161
162 CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)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
CreatePlaceholder(const char * Placeholder)171 CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
172 return Chunk(CK_Placeholder, Placeholder);
173 }
174
175 CodeCompletionString::Chunk
CreateInformative(const char * Informative)176 CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
177 return Chunk(CK_Informative, Informative);
178 }
179
180 CodeCompletionString::Chunk
CreateResultType(const char * ResultType)181 CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
182 return Chunk(CK_ResultType, ResultType);
183 }
184
185 CodeCompletionString::Chunk
CreateCurrentParameter(const char * CurrentParameter)186 CodeCompletionString::Chunk::CreateCurrentParameter(
187 const char *CurrentParameter) {
188 return Chunk(CK_CurrentParameter, CurrentParameter);
189 }
190
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability)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
getAsString() const202 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
getTypedText() const223 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
CopyString(llvm::StringRef String)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
CopyString(llvm::Twine String)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
TakeString()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
getPriorityFromDecl(NamedDecl * ND)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 *
getFunction() const288 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 *
getFunctionType() const298 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
~CodeCompleteConsumer()318 CodeCompleteConsumer::~CodeCompleteConsumer() { }
319
320 void
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)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
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates)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
computeCursorKindAndAvailability()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.
getOrderedName(const CodeCompletionResult & R,std::string & Saved)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
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)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