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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user