diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-07 00:00:49 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-07 00:00:49 +0000 |
commit | 0c8296dfb495f41d6f0de6fe1d03014ffd063674 (patch) | |
tree | 0d9bfd8e8a4b996ec6fcd402bc052fc00e978514 /lib/Sema/SemaCodeComplete.cpp | |
parent | 9e7e3c6c47f2819bce456950617a966d26839eb4 (diff) |
Various improvements to Clang's code-completion infrastructure:
- Introduce more code-completion string "chunk" kinds that describe
symbols, the actual text that the user is expected to type, etc.
- Make the generation of macro results optional, since it can be
slow
- Make code-completion accessible through the C API, marshalling the
code-completion results through a temporary file (ick) to maintain
process separation.
The last doesn't have tests yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 113 |
1 files changed, 68 insertions, 45 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index e9df17d6a1..9963fc3d45 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -187,8 +187,7 @@ getRequiredQualification(ASTContext &Context, Context.getTypeDeclType(TD).getTypePtr()); else assert(Parent->isTranslationUnit()); - } - + } return Result; } @@ -674,6 +673,8 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank, static void AddFunctionParameterChunks(ASTContext &Context, FunctionDecl *Function, CodeCompletionString *Result) { + typedef CodeCompletionString::Chunk Chunk; + CodeCompletionString *CCStr = Result; for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) { @@ -688,7 +689,7 @@ static void AddFunctionParameterChunks(ASTContext &Context, } if (P != 0) - CCStr->AddTextChunk(", "); + CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma)); // Format the placeholder string. std::string PlaceholderStr; @@ -713,6 +714,8 @@ static void AddTemplateParameterChunks(ASTContext &Context, TemplateDecl *Template, CodeCompletionString *Result, unsigned MaxParameters = 0) { + typedef CodeCompletionString::Chunk Chunk; + CodeCompletionString *CCStr = Result; bool FirstParameter = true; @@ -768,7 +771,7 @@ static void AddTemplateParameterChunks(ASTContext &Context, if (FirstParameter) FirstParameter = false; else - CCStr->AddTextChunk(", "); + CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma)); // Add the placeholder string. CCStr->AddPlaceholderChunk(PlaceholderStr.c_str()); @@ -803,6 +806,8 @@ void AddQualifierToCompletionString(CodeCompletionString *Result, /// result is all that is needed. CodeCompletionString * CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { + typedef CodeCompletionString::Chunk Chunk; + if (Kind == RK_Keyword) return 0; @@ -813,12 +818,12 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { // Format a function-like macro with placeholders for the arguments. CodeCompletionString *Result = new CodeCompletionString; - Result->AddTextChunk(Macro->getName().str().c_str()); - Result->AddTextChunk("("); + Result->AddTypedTextChunk(Macro->getName().str().c_str()); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end(); A != AEnd; ++A) { if (A != MI->arg_begin()) - Result->AddTextChunk(", "); + Result->AddChunk(Chunk(CodeCompletionString::CK_Comma)); if (!MI->isVariadic() || A != AEnd - 1) { // Non-variadic argument. @@ -837,21 +842,28 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { Result->AddPlaceholderChunk(Arg.c_str()); } } - Result->AddTextChunk(")"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result; } assert(Kind == RK_Declaration && "Missed a macro kind?"); NamedDecl *ND = Declaration; + if (StartsNestedNameSpecifier) { + CodeCompletionString *Result = new CodeCompletionString; + Result->AddTypedTextChunk(ND->getNameAsString().c_str()); + Result->AddTextChunk("::"); + return Result; + } + if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { CodeCompletionString *Result = new CodeCompletionString; AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, S.Context); - Result->AddTextChunk(Function->getNameAsString().c_str()); - Result->AddTextChunk("("); + Result->AddTypedTextChunk(Function->getNameAsString().c_str()); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); AddFunctionParameterChunks(S.Context, Function, Result); - Result->AddTextChunk(")"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result; } @@ -860,7 +872,7 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, S.Context); FunctionDecl *Function = FunTmpl->getTemplatedDecl(); - Result->AddTextChunk(Function->getNameAsString().c_str()); + Result->AddTypedTextChunk(Function->getNameAsString().c_str()); // Figure out which template parameters are deduced (or have default // arguments). @@ -884,7 +896,7 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { else { assert(isa<TemplateTemplateParmDecl>(Param)); HasDefaultArg - = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); + = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); } if (!HasDefaultArg) @@ -896,16 +908,16 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { // Some of the function template arguments cannot be deduced from a // function call, so we introduce an explicit template argument list // containing all of the arguments up to the first deducible argument. - Result->AddTextChunk("<"); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle)); AddTemplateParameterChunks(S.Context, FunTmpl, Result, LastDeducibleArgument); - Result->AddTextChunk(">"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle)); } // Add the function parameters - Result->AddTextChunk("("); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); AddFunctionParameterChunks(S.Context, Function, Result); - Result->AddTextChunk(")"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result; } @@ -913,20 +925,18 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { CodeCompletionString *Result = new CodeCompletionString; AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, S.Context); - Result->AddTextChunk(Template->getNameAsString().c_str()); - Result->AddTextChunk("<"); + Result->AddTypedTextChunk(Template->getNameAsString().c_str()); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle)); AddTemplateParameterChunks(S.Context, Template, Result); - Result->AddTextChunk(">"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle)); return Result; } - if (Qualifier || StartsNestedNameSpecifier) { + if (Qualifier) { CodeCompletionString *Result = new CodeCompletionString; AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, S.Context); - Result->AddTextChunk(ND->getNameAsString().c_str()); - if (StartsNestedNameSpecifier) - Result->AddTextChunk("::"); + Result->AddTypedTextChunk(ND->getNameAsString().c_str()); return Result; } @@ -937,6 +947,8 @@ CodeCompletionString * CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( unsigned CurrentArg, Sema &S) const { + typedef CodeCompletionString::Chunk Chunk; + CodeCompletionString *Result = new CodeCompletionString; FunctionDecl *FDecl = getFunction(); const FunctionProtoType *Proto @@ -947,9 +959,9 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( const FunctionType *FT = getFunctionType(); Result->AddTextChunk( FT->getResultType().getAsString(S.Context.PrintingPolicy).c_str()); - Result->AddTextChunk("("); - Result->AddPlaceholderChunk("..."); - Result->AddTextChunk("("); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); + Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "...")); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result; } @@ -959,11 +971,11 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( Result->AddTextChunk( Proto->getResultType().getAsString(S.Context.PrintingPolicy).c_str()); - Result->AddTextChunk("("); + Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs(); for (unsigned I = 0; I != NumParams; ++I) { if (I) - Result->AddTextChunk(", "); + Result->AddChunk(Chunk(CodeCompletionString::CK_Comma)); std::string ArgString; QualType ArgType; @@ -978,19 +990,20 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy); if (I == CurrentArg) - Result->AddPlaceholderChunk(ArgString.c_str()); + Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, + ArgString.c_str())); else Result->AddTextChunk(ArgString.c_str()); } if (Proto && Proto->isVariadic()) { - Result->AddTextChunk(", "); + Result->AddChunk(Chunk(CodeCompletionString::CK_Comma)); if (CurrentArg < NumParams) Result->AddTextChunk("..."); else - Result->AddPlaceholderChunk("..."); + Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "...")); } - Result->AddTextChunk(")"); + Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result; } @@ -1049,11 +1062,11 @@ namespace { }; } -// Add all of the known macros as code-completion results. static void AddMacroResults(Preprocessor &PP, unsigned Rank, ResultBuilder &Results) { Results.EnterNewScope(); - for (Preprocessor::macro_iterator M = PP.macro_begin(), MEnd = PP.macro_end(); + for (Preprocessor::macro_iterator M = PP.macro_begin(), + MEnd = PP.macro_end(); M != MEnd; ++M) Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank)); Results.ExitScope(); @@ -1073,7 +1086,8 @@ void Sema::CodeCompleteOrdinaryName(Scope *S) { ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName); unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(), 0, CurContext, Results); - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1130,7 +1144,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE, } // Add macros - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); // Hand off the results found for code completion. HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); @@ -1177,7 +1192,8 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { NextRank, CurContext, Results); } - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1255,7 +1271,8 @@ void Sema::CodeCompleteCase(Scope *S) { } Results.ExitScope(); - AddMacroResults(PP, 1, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, 1, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1350,7 +1367,8 @@ void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS, if (!Results.empty() && NNS->isDependent()) Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank)); - AddMacroResults(PP, NextRank + 1, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank + 1, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1371,7 +1389,8 @@ void Sema::CodeCompleteUsing(Scope *S) { 0, CurContext, Results); Results.ExitScope(); - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1386,7 +1405,8 @@ void Sema::CodeCompleteUsingDirective(Scope *S) { unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(), 0, CurContext, Results); Results.ExitScope(); - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1421,7 +1441,8 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { Results.ExitScope(); } - AddMacroResults(PP, 1, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, 1, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1433,7 +1454,8 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias); unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(), 0, CurContext, Results); - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } @@ -1464,7 +1486,8 @@ void Sema::CodeCompleteOperatorName(Scope *S) { NextRank + 1, CurContext, Results); Results.ExitScope(); - AddMacroResults(PP, NextRank, Results); + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, NextRank, Results); HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size()); } |