[SourceKit] Add whether a property is dynamic

Properties can also be specified in a protocol/overridden by subclasses,
so they should also be classed as "dynamic" in these cases.

Removed receiver USRs when *not* dynamic, since it's not used for
anything in that case and should be equivalent to the container anyway.

Resolves rdar://92882348.
This commit is contained in:
Ben Barham
2022-05-09 11:18:22 -07:00
parent 78f937f405
commit 8889daedce
17 changed files with 438 additions and 232 deletions

View File

@@ -922,6 +922,7 @@ private:
}
bool reportPseudoAccessor(AbstractStorageDecl *D, AccessorKind AccKind,
bool IsRef, SourceLoc Loc);
bool reportIsDynamicRef(ValueDecl *D, IndexSymbol &Info);
bool finishCurrentEntity() {
Entity CurrEnt = EntitiesStack.pop_back_val();
@@ -1336,24 +1337,6 @@ bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet
return true;
}
static bool isDynamicVarAccessorOrFunc(ValueDecl *D, SymbolInfo symInfo) {
if (auto NTD = D->getDeclContext()->getSelfNominalTypeDecl()) {
bool isClassOrProtocol = isa<ClassDecl>(NTD) || isa<ProtocolDecl>(NTD);
bool isInternalAccessor =
symInfo.SubKind == SymbolSubKind::SwiftAccessorWillSet ||
symInfo.SubKind == SymbolSubKind::SwiftAccessorDidSet ||
symInfo.SubKind == SymbolSubKind::SwiftAccessorAddressor ||
symInfo.SubKind == SymbolSubKind::SwiftAccessorMutableAddressor;
if (isClassOrProtocol &&
symInfo.Kind != SymbolKind::StaticMethod &&
!isInternalAccessor &&
!D->isFinal()) {
return true;
}
}
return false;
}
bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
AccessorKind AccKind, bool IsRef,
SourceLoc Loc) {
@@ -1377,7 +1360,7 @@ bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
Info.symInfo.SubKind = getSubKindForAccessor(AccKind);
Info.roles |= (SymbolRoleSet)SymbolRole::Implicit;
Info.group = "";
if (isDynamicVarAccessorOrFunc(D, Info.symInfo)) {
if (ide::isDeclOverridable(D)) {
Info.roles |= (SymbolRoleSet)SymbolRole::Dynamic;
}
return false;
@@ -1569,6 +1552,27 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
return finishCurrentEntity();
}
bool IndexSwiftASTWalker::reportIsDynamicRef(ValueDecl *D, IndexSymbol &Info) {
Expr *BaseE = ide::getBase(ExprStack);
if (!BaseE)
return false;
if (!ide::isDynamicRef(BaseE, D))
return false;
Info.roles |= (unsigned)SymbolRole::Dynamic;
SmallVector<NominalTypeDecl *, 1> Types;
ide::getReceiverType(BaseE, Types);
for (auto *ReceiverTy : Types) {
if (addRelation(Info, (SymbolRoleSet) SymbolRole::RelationReceivedBy,
ReceiverTy))
return true;
}
return false;
}
bool IndexSwiftASTWalker::reportImplicitConformance(ValueDecl *witness, ValueDecl *requirement,
Decl *container) {
if (!shouldIndex(witness, /*IsRef=*/true))
@@ -1658,7 +1662,7 @@ bool IndexSwiftASTWalker::initFuncDeclIndexSymbol(FuncDecl *D,
if (initIndexSymbol(D, D->getLoc(/*SerializedOK*/false), /*IsRef=*/false, Info))
return true;
if (isDynamicVarAccessorOrFunc(D, Info.symInfo)) {
if (ide::isDeclOverridable(D)) {
Info.roles |= (SymbolRoleSet)SymbolRole::Dynamic;
}
@@ -1702,20 +1706,9 @@ bool IndexSwiftASTWalker::initFuncRefIndexSymbol(ValueDecl *D, SourceLoc Loc,
return true;
}
Expr *BaseE = ide::getBase(ExprStack);
if (!BaseE)
return false;
if (reportIsDynamicRef(D, Info))
return true;
if (ide::isDynamicCall(BaseE, D))
Info.roles |= (unsigned)SymbolRole::Dynamic;
SmallVector<NominalTypeDecl *, 1> Types;
ide::getReceiverType(BaseE, Types);
for (auto *ReceiverTy : Types) {
if (addRelation(Info, (SymbolRoleSet) SymbolRole::RelationReceivedBy,
ReceiverTy))
return true;
}
return false;
}
@@ -1740,6 +1733,9 @@ bool IndexSwiftASTWalker::initVarRefIndexSymbols(Expr *CurrentE, ValueDecl *D,
Info.roles |= (unsigned)SymbolRole::Write;
}
if (reportIsDynamicRef(D, Info))
return true;
return false;
}