r286363 - [CodeCompletion] Show block invocation results for block property setters
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 9 05:43:19 PST 2016
Author: arphaman
Date: Wed Nov 9 07:43:18 2016
New Revision: 286363
URL: http://llvm.org/viewvc/llvm-project?rev=286363&view=rev
Log:
[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
Added:
cfe/trunk/test/Index/complete-block-properties.m
Modified:
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-block-property-assignment.m
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=286363&r1=286362&r2=286363&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Nov 9 07:43:18 2016
@@ -3612,6 +3612,44 @@ static ObjCContainerDecl *getContainerDe
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 Code
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);
}
}
Added: cfe/trunk/test/Index/complete-block-properties.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-block-properties.m?rev=286363&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-block-properties.m (added)
+++ cfe/trunk/test/Index/complete-block-properties.m Wed Nov 9 07:43:18 2016
@@ -0,0 +1,53 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+// Block invocations should be presented when completing properties in
+// standalone statements.
+// rdar://28846196
+
+typedef int Foo;
+typedef void (^FooBlock)(Foo *someParameter);
+typedef int (^BarBlock)(int *);
+
+ at interface Obj
+
+ at property (readwrite, nonatomic, copy) void (^block)();
+ at property (readonly, nonatomic, copy) int (^performA)();
+ at property (readonly, nonatomic, copy) int (^performB)(int x, int y);
+ at property (readwrite, nonatomic, copy) Foo (^blocker)(int x, Foo y, FooBlock foo);
+
+ at end
+
+
+ at interface Test : Obj
+
+ at property (readonly, nonatomic, copy) FooBlock fooBlock;
+ at property (readonly, nonatomic, copy) BarBlock barBlock;
+ at property (readonly, nonatomic, copy) Test * (^getObject)(int index);
+ at property (readwrite, nonatomic) int foo;
+
+ at end
+
+ at implementation Test
+
+- (void)test {
+ self.foo = 2;
+ int x = self.performA(); self.foo = 2;
+ self.getObject(0).foo = 2;
+}
+
+// RUN: c-index-test -code-completion-at=%s:34:8 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:35:33 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:36:21 %s | FileCheck -check-prefix=CHECK-CC1 %s
+//CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText barBlock}{LeftParen (}{Placeholder int *}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText block}{LeftParen (}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText block}{Equal = }{Placeholder ^(void)} (38)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo}{TypedText blocker}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder Foo y}{Comma , }{Placeholder ^(Foo *someParameter)foo}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo (^)(int, Foo, FooBlock)}{TypedText blocker}{Equal = }{Placeholder ^Foo(int x, Foo y, FooBlock foo)} (38)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText fooBlock}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Test *}{TypedText getObject}{LeftParen (}{Placeholder int index}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performA}{LeftParen (}{RightParen )} (35)
+//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performB}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder int y}{RightParen )} (35)
+
+ at end
Modified: cfe/trunk/test/Index/complete-block-property-assignment.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-block-property-assignment.m?rev=286363&r1=286362&r2=286363&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-block-property-assignment.m (original)
+++ cfe/trunk/test/Index/complete-block-property-assignment.m Wed Nov 9 07:43:18 2016
@@ -35,11 +35,11 @@ typedef void (^FooBlock)(Foo *someParame
// RUN: c-index-test -code-completion-at=%s:29:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
-// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onAction}{LeftParen (}{Placeholder Obj *object}{RightParen )} (35)
// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction}{Equal = }{Placeholder ^(Obj *object)} (38)
-// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onEventHandler}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35)
// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler}{Equal = }{Placeholder ^(Foo *someParameter)} (38)
-// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onReadonly}{LeftParen (}{Placeholder int *someParameter}{RightParen )} (35)
- (void) takeInt:(int)x { }
More information about the cfe-commits
mailing list