From a2f29f7c81a466a15dc70580a81664ceba37e008 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 24 Jan 2017 14:15:08 +0000 Subject: [CodeCompletion] Ensure that ObjC root class completes instance methods from protocols and categories as well Code completion results for class methods already include instance methods from Objective-C root classes. This commit ensures that the results also include instance methods from protocols that the root class implements and root class categories as well. rdar://28012953 Differential Revision: https://reviews.llvm.org/D27257 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@292932 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCodeComplete.cpp | 58 +++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'lib/Sema/SemaCodeComplete.cpp') diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 94cfc4baca..85343cde2b 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -5230,24 +5230,22 @@ namespace { /// when it has the same number of parameters as we have selector identifiers. /// /// \param Results the structure into which we'll add results. -static void AddObjCMethods(ObjCContainerDecl *Container, - bool WantInstanceMethods, - ObjCMethodKind WantKind, +static void AddObjCMethods(ObjCContainerDecl *Container, + bool WantInstanceMethods, ObjCMethodKind WantKind, ArrayRef SelIdents, DeclContext *CurContext, - VisitedSelectorSet &Selectors, - bool AllowSameLength, - ResultBuilder &Results, - bool InOriginalClass = true) { + VisitedSelectorSet &Selectors, bool AllowSameLength, + ResultBuilder &Results, bool InOriginalClass = true, + bool IsRootClass = false) { typedef CodeCompletionResult Result; Container = getContainerDef(Container); ObjCInterfaceDecl *IFace = dyn_cast(Container); - bool isRootClass = IFace && !IFace->getSuperClass(); + IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass()); for (auto *M : Container->methods()) { // The instance methods on the root class can be messaged via the // metaclass. if (M->isInstanceMethod() == WantInstanceMethods || - (isRootClass && !WantInstanceMethods)) { + (IsRootClass && !WantInstanceMethods)) { // Check whether the selector identifiers we've been given are a // subset of the identifiers for this particular method. if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength)) @@ -5273,8 +5271,8 @@ static void AddObjCMethods(ObjCContainerDecl *Container, for (ObjCList::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) - AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, Results, false); + AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext, + Selectors, AllowSameLength, Results, false, IsRootClass); } } @@ -5283,43 +5281,43 @@ static void AddObjCMethods(ObjCContainerDecl *Container, // Add methods in protocols. for (auto *I : IFace->protocols()) - AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, Results, false); - + AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext, + Selectors, AllowSameLength, Results, false, IsRootClass); + // Add methods in categories. for (auto *CatDecl : IFace->known_categories()) { AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, - Results, InOriginalClass); - + CurContext, Selectors, AllowSameLength, Results, + InOriginalClass, IsRootClass); + // Add a categories protocol methods. const ObjCList &Protocols = CatDecl->getReferencedProtocols(); for (ObjCList::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) - AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, - Results, false); - + AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext, + Selectors, AllowSameLength, Results, false, IsRootClass); + // Add methods in category implementations. if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation()) - AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, - Results, InOriginalClass); + AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext, + Selectors, AllowSameLength, Results, InOriginalClass, + IsRootClass); } // Add methods in superclass. + // Avoid passing in IsRootClass since root classes won't have super classes. if (IFace->getSuperClass()) - AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, - SelIdents, CurContext, Selectors, - AllowSameLength, Results, false); + AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, + SelIdents, CurContext, Selectors, AllowSameLength, Results, + /*IsRootClass=*/false); // Add methods in our implementation, if any. if (ObjCImplementationDecl *Impl = IFace->getImplementation()) - AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, - CurContext, Selectors, AllowSameLength, - Results, InOriginalClass); + AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext, + Selectors, AllowSameLength, Results, InOriginalClass, + IsRootClass); } -- cgit v1.2.1