When providing code completions for an Objective-C property access,

also include methods with zero-argument selectors. Implements
<rdar://problem/9048332>.

llvm-svn: 130922
This commit is contained in:
Douglas Gregor
2011-05-05 15:50:42 +00:00
parent d3da57f99b
commit 951471482c
3 changed files with 82 additions and 14 deletions

View File

@@ -3078,6 +3078,7 @@ typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
static void AddObjCProperties(ObjCContainerDecl *Container,
bool AllowCategories,
bool AllowNullaryMethods,
DeclContext *CurContext,
AddedPropertiesSet &AddedProperties,
ResultBuilder &Results) {
@@ -3092,32 +3093,75 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
Results.MaybeAddResult(Result(*P, 0), CurContext);
}
// Add nullary methods
if (AllowNullaryMethods) {
ASTContext &Context = Container->getASTContext();
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
MEnd = Container->meth_end();
M != MEnd; ++M) {
if (M->getSelector().isUnarySelector())
if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
if (AddedProperties.insert(Name)) {
CodeCompletionBuilder Builder(Results.getAllocator());
AddResultTypeChunk(Context, *M, Builder);
Builder.AddTypedTextChunk(
Results.getAllocator().CopyString(Name->getName()));
CXAvailabilityKind Availability = CXAvailability_Available;
switch (M->getAvailability()) {
case AR_Available:
case AR_NotYetIntroduced:
Availability = CXAvailability_Available;
break;
case AR_Deprecated:
Availability = CXAvailability_Deprecated;
break;
case AR_Unavailable:
Availability = CXAvailability_NotAvailable;
break;
}
Results.MaybeAddResult(Result(Builder.TakeString(),
CCP_MemberDeclaration + CCD_MethodAsProperty,
M->isInstanceMethod()
? CXCursor_ObjCInstanceMethodDecl
: CXCursor_ObjCClassMethodDecl,
Availability),
CurContext);
}
}
}
// Add properties in referenced protocols.
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
PEnd = Protocol->protocol_end();
P != PEnd; ++P)
AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
Results);
AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
AddedProperties, Results);
} else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
if (AllowCategories) {
// Look through categories.
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
Category; Category = Category->getNextClassCategory())
AddObjCProperties(Category, AllowCategories, CurContext,
AddedProperties, Results);
AddObjCProperties(Category, AllowCategories, AllowNullaryMethods,
CurContext, AddedProperties, Results);
}
// Look through protocols.
for (ObjCInterfaceDecl::all_protocol_iterator
I = IFace->all_referenced_protocol_begin(),
E = IFace->all_referenced_protocol_end(); I != E; ++I)
AddObjCProperties(*I, AllowCategories, CurContext, AddedProperties,
Results);
AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
AddedProperties, Results);
// Look in the superclass.
if (IFace->getSuperClass())
AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
AddObjCProperties(IFace->getSuperClass(), AllowCategories,
AllowNullaryMethods, CurContext,
AddedProperties, Results);
} else if (const ObjCCategoryDecl *Category
= dyn_cast<ObjCCategoryDecl>(Container)) {
@@ -3125,8 +3169,8 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
PEnd = Category->protocol_end();
P != PEnd; ++P)
AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
Results);
AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
AddedProperties, Results);
}
}
@@ -3192,14 +3236,16 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
const ObjCObjectPointerType *ObjCPtr
= BaseType->getAsObjCInterfacePointerType();
assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext,
AddObjCProperties(ObjCPtr->getInterfaceDecl(), true,
/*AllowNullaryMethods=*/true, CurContext,
AddedProperties, Results);
// Add properties from the protocols in a qualified interface.
for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
E = ObjCPtr->qual_end();
I != E; ++I)
AddObjCProperties(*I, true, CurContext, AddedProperties, Results);
AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext,
AddedProperties, Results);
} else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
(!IsArrow && BaseType->isObjCObjectType())) {
// Objective-C instance variable access.
@@ -5334,11 +5380,13 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
Results.EnterNewScope();
if (ObjCImplementationDecl *ClassImpl
= dyn_cast<ObjCImplementationDecl>(Container))
AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
AddObjCProperties(ClassImpl->getClassInterface(), false,
/*AllowNullaryMethods=*/false, CurContext,
AddedProperties, Results);
else
AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
false, CurContext, AddedProperties, Results);
false, /*AllowNullaryMethods=*/false, CurContext,
AddedProperties, Results);
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter,