]> granicus.if.org Git - clang/commitdiff
Implement support for code completion of an Objective-C message send to
authorDouglas Gregor <dgregor@apple.com>
Tue, 6 Apr 2010 16:40:00 +0000 (16:40 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 6 Apr 2010 16:40:00 +0000 (16:40 +0000)
"id" or an expression of type "id". In these cases, we produce a list
of all of the (class or instance) methods, respectively, that we know about.

Note that this implementation does not yet work well with precompiled
headers; that's coming soon.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100528 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCodeComplete.cpp
test/Index/complete-objc-message.m

index df14aa7fc5a476006959beebbb84d93d8a9042e2..d29cab4ca17276cc140e9eaf2aabf2c12b4bcb45 100644 (file)
@@ -2970,8 +2970,33 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
   // superclasses, categories, implementation, etc.
   ResultBuilder Results(*this);
   Results.EnterNewScope();
-  AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
-                 Results);  
+
+  if (CDecl) 
+    AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
+                   Results);  
+  else if (FName->isStr("id")) {
+    // We're messaging "id" as a type; provide all class/factory methods.
+
+    // FIXME: Load the entire class method pool from the PCH file
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           M = FactoryMethodPool.begin(),
+           MEnd = FactoryMethodPool.end();
+         M != MEnd;
+         ++M) {
+      for (ObjCMethodList *MethList = &M->second; MethList; 
+           MethList = MethList->Next) {
+        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
+                                    NumSelIdents))
+          continue;
+
+        Result R(MethList->Method, 0);
+        R.StartParameter = NumSelIdents;
+        R.AllParametersAreInformative = false;
+        Results.MaybeAddResult(R, CurContext);
+      }
+    }
+  }
+
   Results.ExitScope();
   
   // This also suppresses remaining diagnostics.
@@ -2990,12 +3015,6 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
   DefaultFunctionArrayLvalueConversion(RecExpr);
   QualType ReceiverType = RecExpr->getType();
   
-  if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
-    // FIXME: We're messaging 'id'. Do we actually want to look up every method
-    // in the universe?
-    return;
-  }
-  
   // Build the set of methods we can see.
   ResultBuilder Results(*this);
   Results.EnterNewScope();
@@ -3035,7 +3054,28 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
       AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext, 
                      Results);
   }
-  
+  // Handle messages to "id".
+  else if (ReceiverType->isObjCIdType()) {
+    // FIXME: Load the entire instance method pool from the PCH file
+    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
+           M = InstanceMethodPool.begin(),
+           MEnd = InstanceMethodPool.end();
+         M != MEnd;
+         ++M) {
+      for (ObjCMethodList *MethList = &M->second; MethList; 
+           MethList = MethList->Next) {
+        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
+                                    NumSelIdents))
+          continue;
+
+        Result R(MethList->Method, 0);
+        R.StartParameter = NumSelIdents;
+        R.AllParametersAreInformative = false;
+        Results.MaybeAddResult(R, CurContext);
+      }
+    }
+  }
+
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
 }
index b9e8f08f5128cd2363c2c661ca7ddeede4f422b4..e65a056e36c33d9bf126fe32f4afbb901602b581 100644 (file)
@@ -116,6 +116,12 @@ void test_overload2(void) {
   [Overload2 Method:1 Arg1:1 OtherArg:ovl];
 }
 
+void msg_id(id x) {
+  [x Method:1 Arg1:1 OtherArg:ovl];
+  [[x blarg] Method:1 Arg1:1 OtherArg:ovl];
+  [id Method:1 Arg1:1 OtherArg:ovl];
+}
+
 // RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: {TypedText categoryClassMethod}
 // CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace  }{Text withKeyword:}{Placeholder (int)b}
@@ -192,3 +198,36 @@ void test_overload2(void) {
 // CHECK-CCF: TypedefDecl:{TypedText SEL}
 // CHECK-CCF: {ResultType Class}{TypedText self}
 // CHECK-CCF: {TypedText super}
+// RUN: c-index-test -code-completion-at=%s:120:6 %s | FileCheck -check-prefix=CHECK-CCG %s
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText categoryInstanceMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod1}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace  }{Text second:}{Placeholder (id)y}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod:}{Placeholder (id)obj}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText secondProtocolInstanceMethod}
+// RUN: c-index-test -code-completion-at=%s:121:14 %s | FileCheck -check-prefix=CHECK-CCG %s
+// RUN: c-index-test -code-completion-at=%s:122:7 %s | FileCheck -check-prefix=CHECK-CCH %s
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText categoryClassMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace  }{Text withKeyword:}{Placeholder (int)b}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType void}{TypedText classMethod2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace  }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace  }{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)obj}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MySubClassMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText MySubPrivateMethod}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText new}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace  }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace  }{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText protocolClassMethod}
+