arphaman created this revision.
arphaman added a reviewer: akyrtzi.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch implements a heuristic that I mentioned in 
https://reviews.llvm.org/D25520. When completing blocks properties that return 
void the default property completion result shows up before the setter, 
otherwise the setter completion now shows up before the default property 
completion. We normally want to use the result of the block call, so one 
typically wouldn't call a block that returns a non-void type in a standalone 
statement.


Repository:
  rL LLVM

https://reviews.llvm.org/D26034

Files:
  lib/Sema/SemaCodeComplete.cpp
  test/Index/complete-block-property-assignment.m


Index: test/Index/complete-block-property-assignment.m
===================================================================
--- test/Index/complete-block-property-assignment.m
+++ test/Index/complete-block-property-assignment.m
@@ -15,6 +15,7 @@
 @interface Test : Obj
 @property (readwrite, nonatomic, copy) FooBlock onEventHandler;
 @property (readonly, nonatomic, copy) void (^onReadonly)(int *someParameter);
+@property (readwrite, nonatomic, copy) int (^processEvent)(int eventCode);
 @property (readonly, nonatomic, strong) Obj *obj;
 @end
 
@@ -29,17 +30,19 @@
   SELFY.foo = 2
 }
 
-// RUN: c-index-test -code-completion-at=%s:26:8 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:27:27 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:28:22 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:29:9 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:27:8 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:28:27 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:29:22 %s | FileCheck 
-check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:30: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 (^)(Obj *)}{TypedText 
onAction}{Equal  = }{Placeholder ^(Obj *object)} (38)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText 
onEventHandler} (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 int (^)(int)}{TypedText 
processEvent} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText 
processEvent}{Equal  = }{Placeholder ^int(int eventCode)} (32)
 
 - (void) takeInt:(int)x { }
 
@@ -53,16 +56,17 @@
   return self.foo;
 }
 
-// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck 
-check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:48:16 %s | FileCheck 
-check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:49:23 %s | FileCheck 
-check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:50:12 %s | FileCheck 
-check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:51:15 %s | FileCheck 
-check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:53:15 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:50:9 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:51:16 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck 
-check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck 
-check-prefix=CHECK-NO %s
 // CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText 
onAction} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText 
onEventHandler} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText 
onReadonly} (35)
+// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText 
processEvent} (35)
 
 @end
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -3659,9 +3659,17 @@
         Builder.AddPlaceholderChunk(
             Builder.getAllocator().CopyString(PlaceholderStr));
 
+        // When completing blocks properties that return void the default
+        // property completion result should show up before the setter,
+        // otherwise the setter completion should show up before the default
+        // property completion, as we normally want to use the result of the
+        // call.
         Results.MaybeAddResult(
             Result(Builder.TakeString(), P,
-                   Results.getBasePriority(P) + CCD_BlockPropertySetter),
+                   Results.getBasePriority(P) +
+                       (BlockLoc.getTypePtr()->getReturnType()->isVoidType()
+                            ? CCD_BlockPropertySetter
+                            : -CCD_BlockPropertySetter)),
             CurContext);
       }
     }


Index: test/Index/complete-block-property-assignment.m
===================================================================
--- test/Index/complete-block-property-assignment.m
+++ test/Index/complete-block-property-assignment.m
@@ -15,6 +15,7 @@
 @interface Test : Obj
 @property (readwrite, nonatomic, copy) FooBlock onEventHandler;
 @property (readonly, nonatomic, copy) void (^onReadonly)(int *someParameter);
+@property (readwrite, nonatomic, copy) int (^processEvent)(int eventCode);
 @property (readonly, nonatomic, strong) Obj *obj;
 @end
 
@@ -29,17 +30,19 @@
   SELFY.foo = 2
 }
 
-// RUN: c-index-test -code-completion-at=%s:26:8 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:27:27 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:28:22 %s | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: c-index-test -code-completion-at=%s:29:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:27:8 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:28:27 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:29:22 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: c-index-test -code-completion-at=%s:30: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 (^)(Obj *)}{TypedText onAction}{Equal  = }{Placeholder ^(Obj *object)} (38)
 // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (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 int (^)(int)}{TypedText processEvent} (35)
+// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent}{Equal  = }{Placeholder ^int(int eventCode)} (32)
 
 - (void) takeInt:(int)x { }
 
@@ -53,16 +56,17 @@
   return self.foo;
 }
 
-// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:48:16 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:49:23 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:50:12 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:51:15 %s | FileCheck -check-prefix=CHECK-NO %s
-// RUN: c-index-test -code-completion-at=%s:53:15 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:50:9 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:51:16 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO %s
+// RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck -check-prefix=CHECK-NO %s
 // CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35)
 // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35)
+// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35)
 
 @end
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -3659,9 +3659,17 @@
         Builder.AddPlaceholderChunk(
             Builder.getAllocator().CopyString(PlaceholderStr));
 
+        // When completing blocks properties that return void the default
+        // property completion result should show up before the setter,
+        // otherwise the setter completion should show up before the default
+        // property completion, as we normally want to use the result of the
+        // call.
         Results.MaybeAddResult(
             Result(Builder.TakeString(), P,
-                   Results.getBasePriority(P) + CCD_BlockPropertySetter),
+                   Results.getBasePriority(P) +
+                       (BlockLoc.getTypePtr()->getReturnType()->isVoidType()
+                            ? CCD_BlockPropertySetter
+                            : -CCD_BlockPropertySetter)),
             CurContext);
       }
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to