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