diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-18 19:08:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-18 19:08:43 +0000 |
commit | 33ced0b8550f3e7169f326944731ee02e9338659 (patch) | |
tree | bf0f8e833f1101d048cec2758baff0e8c7c79e8a /lib/Sema/SemaCodeComplete.cpp | |
parent | 6d60ca9c5015a7e7eceab31bed24425aeb47db67 (diff) |
Implement code completion for Objective-C category names in @interface
and @implementation declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89223 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index eaa4f1514a..93aa08c4da 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -1933,7 +1933,7 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) { // Make sure that we ignore the class we're currently defining. NamedDecl *CurClass = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); - if (isa<ObjCInterfaceDecl>(CurClass)) + if (CurClass && isa<ObjCInterfaceDecl>(CurClass)) Results.Ignore(CurClass); // Add all classes. @@ -1955,3 +1955,69 @@ void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { Results.ExitScope(); HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); } + +void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, + IdentifierInfo *ClassName) { + typedef CodeCompleteConsumer::Result Result; + + ResultBuilder Results(*this); + + // Ignore any categories we find that have already been implemented by this + // interface. + llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; + NamedDecl *CurClass + = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); + if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) + for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category; + Category = Category->getNextClassCategory()) + CategoryNames.insert(Category->getIdentifier()); + + // Add all of the categories we know about. + Results.EnterNewScope(); + TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); + for (DeclContext::decl_iterator D = TU->decls_begin(), + DEnd = TU->decls_end(); + D != DEnd; ++D) + if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D)) + if (CategoryNames.insert(Category->getIdentifier())) + Results.MaybeAddResult(Result(Category, 0), CurContext); + Results.ExitScope(); + + HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); +} + +void Sema::CodeCompleteObjCImplementationCategory(Scope *S, + IdentifierInfo *ClassName) { + typedef CodeCompleteConsumer::Result Result; + + // Find the corresponding interface. If we couldn't find the interface, the + // program itself is ill-formed. However, we'll try to be helpful still by + // providing the list of all of the categories we know about. + NamedDecl *CurClass + = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); + ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass); + if (!Class) + return CodeCompleteObjCInterfaceCategory(S, ClassName); + + ResultBuilder Results(*this); + + // Add all of the categories that have have corresponding interface + // declarations in this class and any of its superclasses, except for + // already-implemented categories in the class itself. + llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; + Results.EnterNewScope(); + bool IgnoreImplemented = true; + while (Class) { + for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category; + Category = Category->getNextClassCategory()) + if ((!IgnoreImplemented || !Category->getImplementation()) && + CategoryNames.insert(Category->getIdentifier())) + Results.MaybeAddResult(Result(Category, 0), CurContext); + + Class = Class->getSuperClass(); + IgnoreImplemented = false; + } + Results.ExitScope(); + + HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); +} |