diff options
author | Alex Lorenz <arphaman@gmail.com> | 2016-11-09 13:43:18 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2016-11-09 13:43:18 +0000 |
commit | baef802f367cc95194bbe4019faddc31e712d85c (patch) | |
tree | e7c0b7daa4f55fc07b3b97088abf63c252adf096 /clang/lib/Sema/SemaCodeComplete.cpp | |
parent | e127fe7083895d8ec5a44bbfd0b6ee75769ca45c (diff) | |
download | llvm-baef802f367cc95194bbe4019faddc31e712d85c.zip llvm-baef802f367cc95194bbe4019faddc31e712d85c.tar.gz llvm-baef802f367cc95194bbe4019faddc31e712d85c.tar.bz2 |
[CodeCompletion] Show block invocation results for block property setters
This commit changes the code completion results for block property setters:
The default block property result is now a block invocation rather than a simple
property reference.
rdar://28846196
Differential Revision: https://reviews.llvm.org/D26071
llvm-svn: 286363
Diffstat (limited to 'clang/lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 125 |
1 files changed, 91 insertions, 34 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 445b8b4..9f770ce 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -3612,6 +3612,44 @@ static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) { return Container; } +/// \brief Adds a block invocation code completion result for the given block +/// declaration \p BD. +static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy, + CodeCompletionBuilder &Builder, + const NamedDecl *BD, + const FunctionTypeLoc &BlockLoc, + const FunctionProtoTypeLoc &BlockProtoLoc) { + Builder.AddResultTypeChunk( + GetCompletionTypeString(BlockLoc.getReturnLoc().getType(), Context, + Policy, Builder.getAllocator())); + + AddTypedNameChunk(Context, Policy, BD, Builder); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + + if (BlockProtoLoc && BlockProtoLoc.getTypePtr()->isVariadic()) { + Builder.AddPlaceholderChunk("..."); + } else { + for (unsigned I = 0, N = BlockLoc.getNumParams(); I != N; ++I) { + if (I) + Builder.AddChunk(CodeCompletionString::CK_Comma); + + // Format the placeholder string. + std::string PlaceholderStr = + FormatFunctionParameter(Policy, BlockLoc.getParam(I)); + + if (I == N - 1 && BlockProtoLoc && + BlockProtoLoc.getTypePtr()->isVariadic()) + PlaceholderStr += ", ..."; + + // Add the placeholder string. + Builder.AddPlaceholderChunk( + Builder.getAllocator().CopyString(PlaceholderStr)); + } + } + + Builder.AddChunk(CodeCompletionString::CK_RightParen); +} + static void AddObjCProperties(const CodeCompletionContext &CCContext, ObjCContainerDecl *Container, bool AllowCategories, bool AllowNullaryMethods, @@ -3629,42 +3667,61 @@ static void AddObjCProperties(const CodeCompletionContext &CCContext, if (!AddedProperties.insert(P->getIdentifier()).second) continue; - Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), - CurContext); + // FIXME: Provide block invocation completion for non-statement + // expressions. + if (!P->getType().getTypePtr()->isBlockPointerType() || + !IsBaseExprStatement) { + Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), + CurContext); + continue; + } + + // Block setter and invocation completion is provided only when we are able + // to find the FunctionProtoTypeLoc with parameter names for the block. + FunctionTypeLoc BlockLoc; + FunctionProtoTypeLoc BlockProtoLoc; + findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc, + BlockProtoLoc); + if (!BlockLoc) { + Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), + CurContext); + continue; + } + + // The default completion result for block properties should be the block + // invocation completion when the base expression is a statement. + CodeCompletionBuilder Builder(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + AddObjCBlockCall(Container->getASTContext(), + getCompletionPrintingPolicy(Results.getSema()), Builder, P, + BlockLoc, BlockProtoLoc); + Results.MaybeAddResult( + Result(Builder.TakeString(), P, Results.getBasePriority(P)), + CurContext); // Provide additional block setter completion iff the base expression is a - // statement. - if (!P->isReadOnly() && IsBaseExprStatement && - P->getType().getTypePtr()->isBlockPointerType()) { - FunctionTypeLoc BlockLoc; - FunctionProtoTypeLoc BlockProtoLoc; - findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc, - BlockProtoLoc); - - // Provide block setter completion only when we are able to find - // the FunctionProtoTypeLoc with parameter names for the block. - if (BlockLoc) { - CodeCompletionBuilder Builder(Results.getAllocator(), - Results.getCodeCompletionTUInfo()); - AddResultTypeChunk(Container->getASTContext(), - getCompletionPrintingPolicy(Results.getSema()), P, - CCContext.getBaseType(), Builder); - Builder.AddTypedTextChunk( - Results.getAllocator().CopyString(P->getName())); - Builder.AddChunk(CodeCompletionString::CK_Equal); - - std::string PlaceholderStr = formatBlockPlaceholder( - getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc, - BlockProtoLoc, /*SuppressBlockName=*/true); - // Add the placeholder string. - Builder.AddPlaceholderChunk( - Builder.getAllocator().CopyString(PlaceholderStr)); - - Results.MaybeAddResult( - Result(Builder.TakeString(), P, - Results.getBasePriority(P) + CCD_BlockPropertySetter), - CurContext); - } + // statement and the block property is mutable. + if (!P->isReadOnly()) { + CodeCompletionBuilder Builder(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + AddResultTypeChunk(Container->getASTContext(), + getCompletionPrintingPolicy(Results.getSema()), P, + CCContext.getBaseType(), Builder); + Builder.AddTypedTextChunk( + Results.getAllocator().CopyString(P->getName())); + Builder.AddChunk(CodeCompletionString::CK_Equal); + + std::string PlaceholderStr = formatBlockPlaceholder( + getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc, + BlockProtoLoc, /*SuppressBlockName=*/true); + // Add the placeholder string. + Builder.AddPlaceholderChunk( + Builder.getAllocator().CopyString(PlaceholderStr)); + + Results.MaybeAddResult( + Result(Builder.TakeString(), P, + Results.getBasePriority(P) + CCD_BlockPropertySetter), + CurContext); } } |