[index] Fixes for locations and relations in Objective C categories and getters/setters
- Add entries for protocols on categories - Add relation between categories and class they extend - Add relation between getters/setters and their corresponding property - Use category name location as the location of category decls/defs if it has one llvm-svn: 285120
This commit is contained in:
parent
83fb4019f7
commit
806faaf42b
|
@ -88,8 +88,10 @@ enum class SymbolRole : uint16_t {
|
|||
RelationOverrideOf = 1 << 11,
|
||||
RelationReceivedBy = 1 << 12,
|
||||
RelationCalledBy = 1 << 13,
|
||||
RelationExtendedBy = 1 << 14,
|
||||
RelationAccessorOf = 1 << 15,
|
||||
};
|
||||
static const unsigned SymbolRoleBitNum = 14;
|
||||
static const unsigned SymbolRoleBitNum = 16;
|
||||
typedef unsigned SymbolRoleSet;
|
||||
|
||||
/// Represents a relation to another symbol for a symbol occurrence.
|
||||
|
|
|
@ -75,8 +75,21 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool handleObjCMethod(const ObjCMethodDecl *D) {
|
||||
if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic))
|
||||
bool handleObjCMethod(const ObjCMethodDecl *D,
|
||||
const ObjCPropertyDecl *AssociatedProp = nullptr) {
|
||||
SmallVector<SymbolRelation, 4> Relations;
|
||||
SmallVector<const ObjCMethodDecl*, 4> Overriden;
|
||||
|
||||
D->getOverriddenMethods(Overriden);
|
||||
for(auto overridden: Overriden) {
|
||||
Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
|
||||
overridden);
|
||||
}
|
||||
if (AssociatedProp)
|
||||
Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
|
||||
AssociatedProp);
|
||||
|
||||
if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations))
|
||||
return false;
|
||||
IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
|
||||
for (const auto *I : D->parameters())
|
||||
|
@ -269,9 +282,18 @@ public:
|
|||
}
|
||||
|
||||
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
|
||||
if (!IndexCtx.handleDecl(D))
|
||||
return false;
|
||||
IndexCtx.indexDeclContext(D);
|
||||
const ObjCInterfaceDecl *C = D->getClassInterface();
|
||||
if (C)
|
||||
TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
|
||||
SymbolRoleSet(), SymbolRelation{
|
||||
(unsigned)SymbolRole::RelationExtendedBy, D
|
||||
}));
|
||||
SourceLocation CategoryLoc = D->getCategoryNameLoc();
|
||||
if (!CategoryLoc.isValid())
|
||||
CategoryLoc = D->getLocation();
|
||||
TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
|
||||
TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
|
||||
TRY_TO(IndexCtx.indexDeclContext(D));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -279,8 +301,14 @@ public:
|
|||
const ObjCCategoryDecl *Cat = D->getCategoryDecl();
|
||||
if (!Cat)
|
||||
return true;
|
||||
|
||||
if (!IndexCtx.handleDecl(D))
|
||||
const ObjCInterfaceDecl *C = D->getClassInterface();
|
||||
if (C)
|
||||
TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
|
||||
SymbolRoleSet()));
|
||||
SourceLocation CategoryLoc = D->getCategoryNameLoc();
|
||||
if (!CategoryLoc.isValid())
|
||||
CategoryLoc = D->getLocation();
|
||||
if (!IndexCtx.handleDecl(D, CategoryLoc))
|
||||
return false;
|
||||
IndexCtx.indexDeclContext(D);
|
||||
return true;
|
||||
|
@ -299,10 +327,10 @@ public:
|
|||
bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
|
||||
if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
|
||||
if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
|
||||
handleObjCMethod(MD);
|
||||
handleObjCMethod(MD, D);
|
||||
if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
|
||||
if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
|
||||
handleObjCMethod(MD);
|
||||
handleObjCMethod(MD, D);
|
||||
if (!IndexCtx.handleDecl(D))
|
||||
return false;
|
||||
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
|
||||
|
|
|
@ -262,6 +262,8 @@ void index::applyForEachSymbolRole(SymbolRoleSet Roles,
|
|||
APPLY_FOR_ROLE(RelationOverrideOf);
|
||||
APPLY_FOR_ROLE(RelationReceivedBy);
|
||||
APPLY_FOR_ROLE(RelationCalledBy);
|
||||
APPLY_FOR_ROLE(RelationExtendedBy);
|
||||
APPLY_FOR_ROLE(RelationAccessorOf);
|
||||
|
||||
#undef APPLY_FOR_ROLE
|
||||
}
|
||||
|
@ -288,6 +290,8 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
|
|||
case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
|
||||
case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
|
||||
case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
|
||||
case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
|
||||
case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -95,13 +95,37 @@ extern int setjmp(jmp_buf);
|
|||
|
||||
@interface I3
|
||||
@property (readwrite) id prop;
|
||||
// CHECK: [[@LINE+3]]:1 | instance-method/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
|
||||
// CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
|
||||
// CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
|
||||
-(id)prop;
|
||||
// CHECK: [[@LINE+3]]:1 | instance-method/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Decl,Dyn,RelChild,RelAcc | rel: 2
|
||||
// CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
|
||||
// CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
|
||||
-(void)setProp:(id)p;
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+1]]:17 | class/ObjC | I3 | c:objc(cs)I3 | <no-cgname> | Def | rel: 0
|
||||
@implementation I3
|
||||
// CHECK: [[@LINE+3]]:13 | instance-property/ObjC | prop | c:objc(cs)I3(py)prop | <no-cgname> | Ref | rel: 0
|
||||
// CHECK: [[@LINE+2]]:13 | instance-method/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Def,RelChild | rel: 1
|
||||
// CHECK: [[@LINE+1]]:13 | instance-method/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Def,RelChild | rel: 1
|
||||
@synthesize prop = _prop;
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+5]]:12 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelExt | rel: 1
|
||||
// CHECK-NEXT: RelExt | bar | c:objc(cy)I3@bar
|
||||
// CHECK: [[@LINE+3]]:15 | extension/ObjC | bar | c:objc(cy)I3@bar | <no-cgname> | Decl | rel: 0
|
||||
// CHECK: [[@LINE+2]]:21 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase | rel: 1
|
||||
// CHECK-NEXT: RelBase | bar | c:objc(cy)I3@bar
|
||||
@interface I3(bar) <Prot1>
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref | rel: 0
|
||||
// CHECK: [[@LINE+1]]:20 | extension/ObjC | I3 | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
|
||||
@implementation I3(bar)
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+1]]:12 | extension/ObjC | <no-name> | <no-usr> | <no-cgname> | Decl | rel: 0
|
||||
@interface NonExistent()
|
||||
@end
|
||||
|
|
|
@ -26,10 +26,13 @@
|
|||
-(void)testIt2 {}
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+1]]:12 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
|
||||
// CHECK: [[@LINE+3]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelExt | rel: 1
|
||||
// CHECK-NEXT: RelExt | cat | c:objc(cy)MyTestCase@cat
|
||||
// CHECK: [[@LINE+1]]:23 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
|
||||
@interface MyTestCase(cat)
|
||||
@end
|
||||
// CHECK: [[@LINE+1]]:17 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
|
||||
// CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref | rel: 0
|
||||
// CHECK: [[@LINE+1]]:28 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
|
||||
@implementation MyTestCase(cat)
|
||||
// CHECK: [[@LINE+1]]:1 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
|
||||
- (void)testInCat {}
|
||||
|
@ -38,7 +41,8 @@
|
|||
|
||||
@class NSButton;
|
||||
@interface IBCls
|
||||
// CHECK: [[@LINE+2]]:34 | instance-method/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,RelChild | rel: 1
|
||||
|
||||
// CHECK: [[@LINE+2]]:34 | instance-method/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
|
||||
// CHECK: [[@LINE+1]]:34 | instance-property(IB)/ObjC | prop | c:objc(cs)IBCls(py)prop | <no-cgname> | Decl,RelChild | rel: 1
|
||||
@property (readonly) IBOutlet id prop;
|
||||
// CHECK: [[@LINE+1]]:54 | instance-property(IB,IBColl)/ObjC | propColl | c:objc(cs)IBCls(py)propColl | <no-cgname> | Decl,RelChild | rel: 1
|
||||
|
|
Loading…
Reference in New Issue