diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-06 16:40:00 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-06 16:40:00 +0000 |
commit | 13438f9b9c8fdf08998c843dd307d2a9eda05b32 (patch) | |
tree | ea5c2455c1b7a06c3f5e600d46e18ac0de0393e2 /lib/Sema/SemaCodeComplete.cpp | |
parent | 85372b93d175385b0aacbc1bd8f28e73abfba834 (diff) |
Implement support for code completion of an Objective-C message send to
"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
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index df14aa7fc5..d29cab4ca1 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -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()); } |