[index] For extensions, relate the symbol reference that gets extended and base references with the extension symbol.

They were getting related with the original extended symbol, which was incorrect.
This commit is contained in:
Argyrios Kyrtzidis
2017-02-19 18:19:39 -08:00
parent dba747642e
commit a13289835e
4 changed files with 50 additions and 26 deletions

View File

@@ -45,7 +45,7 @@ inline SymbolPropertySet &operator|=(SymbolPropertySet &SKSet, SymbolProperty SK
} }
struct IndexRelation { struct IndexRelation {
const ValueDecl *decl; const Decl *decl;
SymbolInfo symInfo; SymbolInfo symInfo;
SymbolRoleSet roles = SymbolRoleSet(0); SymbolRoleSet roles = SymbolRoleSet(0);
@@ -55,7 +55,7 @@ struct IndexRelation {
StringRef USR; // USR may be safely compared by pointer. StringRef USR; // USR may be safely compared by pointer.
StringRef group; StringRef group;
IndexRelation(SymbolRoleSet Roles, const ValueDecl *Sym, SymbolInfo SymInfo, StringRef Name, StringRef USR) IndexRelation(SymbolRoleSet Roles, const Decl *Sym, SymbolInfo SymInfo, StringRef Name, StringRef USR)
: decl(Sym), symInfo(SymInfo), roles(Roles), name(Name), USR(USR) {} : decl(Sym), symInfo(SymInfo), roles(Roles), name(Name), USR(USR) {}
IndexRelation() = default; IndexRelation() = default;

View File

@@ -189,15 +189,21 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
return false; return false;
} }
bool addRelation(IndexSymbol &Info, SymbolRoleSet RelationRoles, ValueDecl *D) { bool addRelation(IndexSymbol &Info, SymbolRoleSet RelationRoles, Decl *D) {
assert(D); assert(D);
StringRef Name, USR; StringRef Name, USR;
SymbolInfo SymInfo = getSymbolInfoForDecl(D); SymbolInfo SymInfo = getSymbolInfoForDecl(D);
if (SymInfo.Kind == SymbolKind::Unknown) if (SymInfo.Kind == SymbolKind::Unknown)
return true; return true;
if (getNameAndUSR(D, /*ExtD=*/nullptr, Name, USR)) if (auto *ExtD = dyn_cast<ExtensionDecl>(D)) {
NominalTypeDecl *NTD = ExtD->getExtendedType()->getAnyNominal();
if (getNameAndUSR(NTD, ExtD, Name, USR))
return true; return true;
} else {
if (getNameAndUSR(cast<ValueDecl>(D), /*ExtD=*/nullptr, Name, USR))
return true;
}
Info.Relations.push_back(IndexRelation(RelationRoles, D, SymInfo, Name, USR)); Info.Relations.push_back(IndexRelation(RelationRoles, D, SymInfo, Name, USR));
Info.roles |= RelationRoles; Info.roles |= RelationRoles;
@@ -339,9 +345,9 @@ private:
bool startEntity(Decl *D, IndexSymbol &Info); bool startEntity(Decl *D, IndexSymbol &Info);
bool startEntityDecl(ValueDecl *D); bool startEntityDecl(ValueDecl *D);
bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, ValueDecl *Related); bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, Decl *Related);
bool reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, ValueDecl *Related); bool reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related);
bool reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, ValueDecl *Inheritee); bool reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, Decl *Inheritee);
NominalTypeDecl *getTypeLocAsNominalTypeDecl(const TypeLoc &Ty); NominalTypeDecl *getTypeLocAsNominalTypeDecl(const TypeLoc &Ty);
bool reportPseudoGetterDecl(VarDecl *D) { bool reportPseudoGetterDecl(VarDecl *D) {
@@ -609,7 +615,7 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
return startEntity(D, Info); return startEntity(D, Info);
} }
bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, ValueDecl *Related) { bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, Decl *Related) {
if (!shouldIndex(D)) if (!shouldIndex(D))
return true; return true;
@@ -628,7 +634,7 @@ bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRo
return !Cancelled; return !Cancelled;
} }
bool IndexSwiftASTWalker::reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, ValueDecl *Inheritee) { bool IndexSwiftASTWalker::reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, Decl *Inheritee) {
for (auto Base : Inherited) { for (auto Base : Inherited) {
if(!reportRelatedTypeRef(Base, (SymbolRoleSet) SymbolRole::RelationBaseOf, Inheritee)) if(!reportRelatedTypeRef(Base, (SymbolRoleSet) SymbolRole::RelationBaseOf, Inheritee))
return false; return false;
@@ -636,7 +642,7 @@ bool IndexSwiftASTWalker::reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, V
return true; return true;
} }
bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, ValueDecl *Related) { bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related) {
if (IdentTypeRepr *T = dyn_cast_or_null<IdentTypeRepr>(Ty.getTypeRepr())) { if (IdentTypeRepr *T = dyn_cast_or_null<IdentTypeRepr>(Ty.getTypeRepr())) {
auto Comps = T->getComponentRange(); auto Comps = T->getComponentRange();
@@ -718,7 +724,10 @@ IndexSwiftASTWalker::getTypeLocAsNominalTypeDecl(const TypeLoc &Ty) {
} }
bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) { bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
SourceLoc Loc = D->getExtendedTypeLoc().getSourceRange().Start; // Use the 'End' token of the range, in case it is a compound name, e.g.
// extension A.B {}
// we want the location of 'B' token.
SourceLoc Loc = D->getExtendedTypeLoc().getSourceRange().End;
if (!D->getExtendedType()) if (!D->getExtendedType())
return true; return true;
NominalTypeDecl *NTD = D->getExtendedType()->getAnyNominal(); NominalTypeDecl *NTD = D->getExtendedType()->getAnyNominal();
@@ -734,11 +743,10 @@ bool IndexSwiftASTWalker::reportExtension(ExtensionDecl *D) {
if (!startEntity(D, Info)) if (!startEntity(D, Info))
return false; return false;
// FIXME: make extensions their own entity
if (!reportRelatedRef(NTD, Loc, (SymbolRoleSet)SymbolRole::RelationExtendedBy, if (!reportRelatedRef(NTD, Loc, (SymbolRoleSet)SymbolRole::RelationExtendedBy,
NTD)) D))
return false; return false;
if (!reportInheritedTypeRefs(D->getInherited(), NTD)) if (!reportInheritedTypeRefs(D->getInherited(), D))
return false; return false;
return true; return true;

View File

@@ -123,24 +123,24 @@ protocol AProtocol {
// Extension // Extension
extension AnEnumeration { func extFn() {} } extension AnEnumeration { func extFn() {} }
// CHECK: [[@LINE-1]]:11 | extension/ext-enum/Swift | AnEnumeration | s:e:s:14swift_ide_test13AnEnumerationO5extFnyyF | Def | rel: 0 // CHECK: [[@LINE-1]]:11 | extension/ext-enum/Swift | AnEnumeration | [[EXT_AnEnumeration_USR:s:e:s:14swift_ide_test13AnEnumerationO5extFnyyF]] | Def | rel: 0
// CHECK: [[@LINE-2]]:11 | enum/Swift | AnEnumeration | s:14swift_ide_test13AnEnumerationO | Ref,RelExt | rel: 1 // CHECK: [[@LINE-2]]:11 | enum/Swift | AnEnumeration | s:14swift_ide_test13AnEnumerationO | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | AnEnumeration | s:14swift_ide_test13AnEnumerationO // CHECK-NEXT: RelExt | AnEnumeration | [[EXT_AnEnumeration_USR]]
extension AStruct { func extFn() {} } extension AStruct { func extFn() {} }
// CHECK: [[@LINE-1]]:11 | extension/ext-struct/Swift | AStruct | s:e:s:14swift_ide_test7AStructV5extFnyyF | Def | rel: 0 // CHECK: [[@LINE-1]]:11 | extension/ext-struct/Swift | AStruct | [[EXT_AStruct_USR:s:e:s:14swift_ide_test7AStructV5extFnyyF]] | Def | rel: 0
// CHECK: [[@LINE-2]]:11 | struct/Swift | AStruct | s:14swift_ide_test7AStructV | Ref,RelExt | rel: 1 // CHECK: [[@LINE-2]]:11 | struct/Swift | AStruct | s:14swift_ide_test7AStructV | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | AStruct | s:14swift_ide_test7AStructV // CHECK-NEXT: RelExt | AStruct | [[EXT_AStruct_USR]]
extension AClass { func extFn() {} } extension AClass { func extFn() {} }
// CHECK: [[@LINE-1]]:11 | extension/ext-class/Swift | AClass | s:e:s:14swift_ide_test6AClassC5extFnyyF | Def | rel: 0 // CHECK: [[@LINE-1]]:11 | extension/ext-class/Swift | AClass | [[EXT_AClass_USR:s:e:s:14swift_ide_test6AClassC5extFnyyF]] | Def | rel: 0
// CHECK: [[@LINE-2]]:11 | class/Swift | AClass | s:14swift_ide_test6AClassC | Ref,RelExt | rel: 1 // CHECK: [[@LINE-2]]:11 | class/Swift | AClass | s:14swift_ide_test6AClassC | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | AClass | s:14swift_ide_test6AClassC // CHECK-NEXT: RelExt | AClass | [[EXT_AClass_USR]]
extension AProtocol { func extFn() } extension AProtocol { func extFn() }
// CHECK: [[@LINE-1]]:11 | extension/ext-protocol/Swift | AProtocol | s:e:s:14swift_ide_test9AProtocolPAAE5extFnyyF | Def | rel: 0 // CHECK: [[@LINE-1]]:11 | extension/ext-protocol/Swift | AProtocol | [[EXT_AProtocol_USR:s:e:s:14swift_ide_test9AProtocolPAAE5extFnyyF]] | Def | rel: 0
// CHECK: [[@LINE-2]]:11 | protocol/Swift | AProtocol | s:14swift_ide_test9AProtocolP | Ref,RelExt | rel: 1 // CHECK: [[@LINE-2]]:11 | protocol/Swift | AProtocol | s:14swift_ide_test9AProtocolP | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | AProtocol | s:14swift_ide_test9AProtocolP // CHECK-NEXT: RelExt | AProtocol | [[EXT_AProtocol_USR]]
// TypeAlias // TypeAlias
typealias SomeAlias = AStruct typealias SomeAlias = AStruct

View File

@@ -134,6 +134,7 @@ class AClass {
} }
protocol AProtocol { protocol AProtocol {
// CHECK: [[@LINE-1]]:10 | protocol/Swift | AProtocol | [[AProtocol_USR:.*]] | Def | rel: 0
func foo() -> Int func foo() -> Int
// CHECK: [[@LINE-1]]:8 | instance-method/Swift | foo() | s:FP14swift_ide_test9AProtocol3fooFT_Si | Def,RelChild | rel: 1 // CHECK: [[@LINE-1]]:8 | instance-method/Swift | foo() | s:FP14swift_ide_test9AProtocol3fooFT_Si | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | AProtocol | s:P14swift_ide_test9AProtocol // CHECK-NEXT: RelChild | AProtocol | s:P14swift_ide_test9AProtocol
@@ -157,17 +158,32 @@ class ASubClass : AClass, AProtocol {
} }
// RelationExtendedBy // RelationExtendedBy
// FIXME give extensions their own USR like ObjC?
extension AClass { extension AClass {
// CHECK: [[@LINE-1]]:11 | extension/ext-class/Swift | AClass | s:e:s:FC14swift_ide_test6AClass3barFT_Si | Def | rel: 0 // CHECK: [[@LINE-1]]:11 | extension/ext-class/Swift | AClass | [[EXT_ACLASS_USR:.*]] | Def | rel: 0
// CHECK: [[@LINE-2]]:11 | class/Swift | AClass | s:C14swift_ide_test6AClass | Ref,RelExt | rel: 1 // CHECK: [[@LINE-2]]:11 | class/Swift | AClass | s:C14swift_ide_test6AClass | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | AClass | s:C14swift_ide_test6AClass // CHECK-NEXT: RelExt | AClass | [[EXT_ACLASS_USR]]
func bar() -> Int { return 2 } func bar() -> Int { return 2 }
// CHECK: [[@LINE-1]]:8 | instance-method/Swift | bar() | s:FC14swift_ide_test6AClass3barFT_Si | Def,RelChild | rel: 1 // CHECK: [[@LINE-1]]:8 | instance-method/Swift | bar() | s:FC14swift_ide_test6AClass3barFT_Si | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | AClass | s:C14swift_ide_test6AClass // CHECK-NEXT: RelChild | AClass | s:C14swift_ide_test6AClass
} }
struct OuterS {
// CHECK: [[@LINE-1]]:8 | struct/Swift | OuterS | [[OUTERS_USR:.*]] | Def | rel: 0
struct InnerS {}
// CHECK: [[@LINE-1]]:10 | struct/Swift | InnerS | [[INNERS_USR:.*]] | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | OuterS | [[OUTERS_USR]]
}
extension OuterS.InnerS : AProtocol {
// CHECK: [[@LINE-1]]:18 | extension/ext-struct/Swift | InnerS | [[EXT_INNERS_USR:.*]] | Def | rel: 0
// CHECK: [[@LINE-2]]:18 | struct/Swift | InnerS | [[INNERS_USR]] | Ref,RelExt | rel: 1
// CHECK-NEXT: RelExt | InnerS | [[EXT_INNERS_USR]]
// CHECK: [[@LINE-4]]:27 | protocol/Swift | AProtocol | [[AProtocol_USR]] | Ref,RelBase | rel: 1
// CHECK-NEXT: RelBase | InnerS | [[EXT_INNERS_USR]]
// CHECK: [[@LINE-6]]:11 | struct/Swift | OuterS | [[OUTERS_USR]] | Ref | rel: 0
func foo() {}
}
var anInstance = AClass(x: 1) var anInstance = AClass(x: 1)
// CHECK: [[@LINE-1]]:18 | class/Swift | AClass | s:C14swift_ide_test6AClass | Ref | rel: 0 // CHECK: [[@LINE-1]]:18 | class/Swift | AClass | s:C14swift_ide_test6AClass | Ref | rel: 0
// CHECK: [[@LINE-2]]:18 | constructor/Swift | init(x:) | s:FC14swift_ide_test6AClasscFT1xSi_S0_ | Ref,Call | rel: 0 // CHECK: [[@LINE-2]]:18 | constructor/Swift | init(x:) | s:FC14swift_ide_test6AClasscFT1xSi_S0_ | Ref,Call | rel: 0