Skip to content

Commit 9514714

Browse files
committed
When providing code completions for an Objective-C property access,
also include methods with zero-argument selectors. Implements <rdar://problem/9048332>. llvm-svn: 130922
1 parent d3da57f commit 9514714

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

clang/include/clang/Sema/CodeCompleteConsumer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ enum {
8888

8989
/// \brief Adjustment for KVC code pattern priorities when it doesn't look
9090
/// like the
91-
CCD_ProbablyNotObjCCollection = 15
91+
CCD_ProbablyNotObjCCollection = 15,
92+
93+
/// \brief An Objective-C method being used as a property.
94+
CCD_MethodAsProperty = 2
9295
};
9396

9497
/// \brief Priority value factors by which we will divide or multiply the

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3078,6 +3078,7 @@ typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
30783078

30793079
static void AddObjCProperties(ObjCContainerDecl *Container,
30803080
bool AllowCategories,
3081+
bool AllowNullaryMethods,
30813082
DeclContext *CurContext,
30823083
AddedPropertiesSet &AddedProperties,
30833084
ResultBuilder &Results) {
@@ -3092,41 +3093,84 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
30923093
Results.MaybeAddResult(Result(*P, 0), CurContext);
30933094
}
30943095

3096+
// Add nullary methods
3097+
if (AllowNullaryMethods) {
3098+
ASTContext &Context = Container->getASTContext();
3099+
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3100+
MEnd = Container->meth_end();
3101+
M != MEnd; ++M) {
3102+
if (M->getSelector().isUnarySelector())
3103+
if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
3104+
if (AddedProperties.insert(Name)) {
3105+
CodeCompletionBuilder Builder(Results.getAllocator());
3106+
AddResultTypeChunk(Context, *M, Builder);
3107+
Builder.AddTypedTextChunk(
3108+
Results.getAllocator().CopyString(Name->getName()));
3109+
3110+
CXAvailabilityKind Availability = CXAvailability_Available;
3111+
switch (M->getAvailability()) {
3112+
case AR_Available:
3113+
case AR_NotYetIntroduced:
3114+
Availability = CXAvailability_Available;
3115+
break;
3116+
3117+
case AR_Deprecated:
3118+
Availability = CXAvailability_Deprecated;
3119+
break;
3120+
3121+
case AR_Unavailable:
3122+
Availability = CXAvailability_NotAvailable;
3123+
break;
3124+
}
3125+
3126+
Results.MaybeAddResult(Result(Builder.TakeString(),
3127+
CCP_MemberDeclaration + CCD_MethodAsProperty,
3128+
M->isInstanceMethod()
3129+
? CXCursor_ObjCInstanceMethodDecl
3130+
: CXCursor_ObjCClassMethodDecl,
3131+
Availability),
3132+
CurContext);
3133+
}
3134+
}
3135+
}
3136+
3137+
30953138
// Add properties in referenced protocols.
30963139
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
30973140
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
30983141
PEnd = Protocol->protocol_end();
30993142
P != PEnd; ++P)
3100-
AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
3101-
Results);
3143+
AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3144+
AddedProperties, Results);
31023145
} else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
31033146
if (AllowCategories) {
31043147
// Look through categories.
31053148
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
31063149
Category; Category = Category->getNextClassCategory())
3107-
AddObjCProperties(Category, AllowCategories, CurContext,
3108-
AddedProperties, Results);
3150+
AddObjCProperties(Category, AllowCategories, AllowNullaryMethods,
3151+
CurContext, AddedProperties, Results);
31093152
}
31103153

31113154
// Look through protocols.
31123155
for (ObjCInterfaceDecl::all_protocol_iterator
31133156
I = IFace->all_referenced_protocol_begin(),
31143157
E = IFace->all_referenced_protocol_end(); I != E; ++I)
3115-
AddObjCProperties(*I, AllowCategories, CurContext, AddedProperties,
3116-
Results);
3158+
AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
3159+
AddedProperties, Results);
31173160

31183161
// Look in the superclass.
31193162
if (IFace->getSuperClass())
3120-
AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
3163+
AddObjCProperties(IFace->getSuperClass(), AllowCategories,
3164+
AllowNullaryMethods, CurContext,
31213165
AddedProperties, Results);
31223166
} else if (const ObjCCategoryDecl *Category
31233167
= dyn_cast<ObjCCategoryDecl>(Container)) {
31243168
// Look through protocols.
31253169
for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
31263170
PEnd = Category->protocol_end();
31273171
P != PEnd; ++P)
3128-
AddObjCProperties(*P, AllowCategories, CurContext, AddedProperties,
3129-
Results);
3172+
AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3173+
AddedProperties, Results);
31303174
}
31313175
}
31323176

@@ -3192,14 +3236,16 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
31923236
const ObjCObjectPointerType *ObjCPtr
31933237
= BaseType->getAsObjCInterfacePointerType();
31943238
assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
3195-
AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext,
3239+
AddObjCProperties(ObjCPtr->getInterfaceDecl(), true,
3240+
/*AllowNullaryMethods=*/true, CurContext,
31963241
AddedProperties, Results);
31973242

31983243
// Add properties from the protocols in a qualified interface.
31993244
for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
32003245
E = ObjCPtr->qual_end();
32013246
I != E; ++I)
3202-
AddObjCProperties(*I, true, CurContext, AddedProperties, Results);
3247+
AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext,
3248+
AddedProperties, Results);
32033249
} else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
32043250
(!IsArrow && BaseType->isObjCObjectType())) {
32053251
// Objective-C instance variable access.
@@ -5334,11 +5380,13 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
53345380
Results.EnterNewScope();
53355381
if (ObjCImplementationDecl *ClassImpl
53365382
= dyn_cast<ObjCImplementationDecl>(Container))
5337-
AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
5383+
AddObjCProperties(ClassImpl->getClassInterface(), false,
5384+
/*AllowNullaryMethods=*/false, CurContext,
53385385
AddedProperties, Results);
53395386
else
53405387
AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
5341-
false, CurContext, AddedProperties, Results);
5388+
false, /*AllowNullaryMethods=*/false, CurContext,
5389+
AddedProperties, Results);
53425390
Results.ExitScope();
53435391

53445392
HandleCodeCompleteResults(this, CodeCompleter,

clang/test/Index/complete-member-access.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,26 @@ void test_props(Int* ptr) {
2222
ptr->IVar = 0;
2323
}
2424

25+
@interface Sub : Int
26+
@property int myProp;
27+
28+
- (int)myProp;
29+
- (int)myOtherPropLikeThing;
30+
- (int)myOtherNonPropThing:(int)value;
31+
@end
32+
33+
int test_more_props(Sub *s) {
34+
return s.myOtherPropLikeThing;
35+
}
36+
2537
// RUN: c-index-test -code-completion-at=%s:21:7 %s | FileCheck -check-prefix=CHECK-CC1 %s
2638
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText prop1}
2739
// CHECK-CC1: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp}
2840
// RUN: c-index-test -code-completion-at=%s:22:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
2941
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText IVar} (35)
3042
// CHECK-CC2: ObjCIvarDecl:{ResultType int}{TypedText SuperIVar} (37)
43+
// RUN: c-index-test -code-completion-at=%s:34:12 %s | FileCheck -check-prefix=CHECK-CC3 %s
44+
// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType int}{TypedText myOtherPropLikeThing} (37)
45+
// CHECK-CC3: ObjCPropertyDecl:{ResultType int}{TypedText myProp} (35)
46+
// CHECK-CC3: ObjCPropertyDecl:{ResultType int}{TypedText prop1} (35)
47+
// CHECK-CC3: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp} (35)

0 commit comments

Comments
 (0)