APIDigester: Stop calling getAllConformances() on protocols

This commit is contained in:
Slava Pestov
2022-08-22 19:29:57 -04:00
parent 064b713db0
commit f0907d3e10
3 changed files with 48 additions and 31 deletions

View File

@@ -50,7 +50,7 @@ struct swift::ide::api::SDKNodeInitInfo {
SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD); SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD);
SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *D); SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *D);
SDKNodeInitInfo(SDKContext &Ctx, ImportDecl *ID); SDKNodeInitInfo(SDKContext &Ctx, ImportDecl *ID);
SDKNodeInitInfo(SDKContext &Ctx, ProtocolConformance *Conform); SDKNodeInitInfo(SDKContext &Ctx, ProtocolConformanceRef Conform);
SDKNodeInitInfo(SDKContext &Ctx, Type Ty, TypeInitInfo Info = TypeInitInfo()); SDKNodeInitInfo(SDKContext &Ctx, Type Ty, TypeInitInfo Info = TypeInitInfo());
SDKNode* createSDKNode(SDKNodeKind Kind); SDKNode* createSDKNode(SDKNodeKind Kind);
}; };
@@ -1459,17 +1459,21 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ImportDecl *ID):
Name = PrintedName = Ctx.buffer(content); Name = PrintedName = Ctx.buffer(content);
} }
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ProtocolConformance *Conform): SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ProtocolConformanceRef Conform):
SDKNodeInitInfo(Ctx, Conform->getProtocol()) { SDKNodeInitInfo(Ctx, Conform.getRequirement()) {
// The conformance can be conditional. The generic signature keeps track of // The conformance can be conditional. The generic signature keeps track of
// the requirements. // the requirements.
GenericSig = printGenericSignature(Ctx, Conform, Ctx.checkingABI()); if (Conform.isConcrete()) {
SugaredGenericSig = Ctx.checkingABI() ? auto *Concrete = Conform.getConcrete();
printGenericSignature(Ctx, Conform, false): StringRef();
// Whether this conformance is ABI placeholder depends on the decl context GenericSig = printGenericSignature(Ctx, Concrete, Ctx.checkingABI());
// of this conformance. SugaredGenericSig = Ctx.checkingABI() ?
IsABIPlaceholder = isABIPlaceholderRecursive(Conform->getDeclContext()-> printGenericSignature(Ctx, Concrete, false): StringRef();
getAsDecl()); // Whether this conformance is ABI placeholder depends on the decl context
// of this conformance.
IsABIPlaceholder = isABIPlaceholderRecursive(Concrete->getDeclContext()->
getAsDecl());
}
} }
static bool isProtocolRequirement(ValueDecl *VD) { static bool isProtocolRequirement(ValueDecl *VD) {
@@ -1910,7 +1914,7 @@ SwiftDeclCollector::constructConformanceNode(ProtocolConformance *Conform) {
if (Ctx.checkingABI()) if (Ctx.checkingABI())
Conform = Conform->getCanonicalConformance(); Conform = Conform->getCanonicalConformance();
auto ConfNode = cast<SDKNodeConformance>(SDKNodeInitInfo(Ctx, auto ConfNode = cast<SDKNodeConformance>(SDKNodeInitInfo(Ctx,
Conform).createSDKNode(SDKNodeKind::Conformance)); ProtocolConformanceRef(Conform)).createSDKNode(SDKNodeKind::Conformance));
Conform->forEachTypeWitness( Conform->forEachTypeWitness(
[&](AssociatedTypeDecl *assoc, Type ty, TypeDecl *typeDecl) -> bool { [&](AssociatedTypeDecl *assoc, Type ty, TypeDecl *typeDecl) -> bool {
ConfNode->addChild(constructTypeWitnessNode(assoc, ty)); ConfNode->addChild(constructTypeWitnessNode(assoc, ty));
@@ -1922,12 +1926,25 @@ SwiftDeclCollector::constructConformanceNode(ProtocolConformance *Conform) {
void swift::ide::api:: void swift::ide::api::
SwiftDeclCollector::addConformancesToTypeDecl(SDKNodeDeclType *Root, SwiftDeclCollector::addConformancesToTypeDecl(SDKNodeDeclType *Root,
NominalTypeDecl *NTD) { NominalTypeDecl *NTD) {
// Avoid adding the same conformance twice. if (auto *PD = dyn_cast<ProtocolDecl>(NTD)) {
SmallPtrSet<ProtocolConformance*, 4> Seen; PD->walkInheritedProtocols([&](ProtocolDecl *inherited) {
for (auto &Conf: NTD->getAllConformances()) { if (PD != inherited && !Ctx.shouldIgnore(inherited)) {
if (!Ctx.shouldIgnore(Conf->getProtocol()) && !Seen.count(Conf)) ProtocolConformanceRef Conf(inherited);
Root->addConformance(constructConformanceNode(Conf)); auto ConfNode = SDKNodeInitInfo(Ctx, Conf)
Seen.insert(Conf); .createSDKNode(SDKNodeKind::Conformance);
Root->addConformance(ConfNode);
}
return TypeWalker::Action::Continue;
});
} else {
// Avoid adding the same conformance twice.
SmallPtrSet<ProtocolConformance*, 4> Seen;
for (auto &Conf: NTD->getAllConformances()) {
if (!Ctx.shouldIgnore(Conf->getProtocol()) && !Seen.count(Conf))
Root->addConformance(constructConformanceNode(Conf));
Seen.insert(Conf);
}
} }
} }

View File

@@ -100,19 +100,19 @@
"genericSig": "<τ_0_0 : cake.P1, τ_0_0 : cake.P2>", "genericSig": "<τ_0_0 : cake.P1, τ_0_0 : cake.P2>",
"sugared_genericSig": "<Self : cake.P1, Self : cake.P2>", "sugared_genericSig": "<Self : cake.P1, Self : cake.P2>",
"conformances": [ "conformances": [
{
"kind": "Conformance",
"name": "P2",
"printedName": "P2",
"usr": "s:4cake2P2P",
"mangledName": "$s4cake2P2P"
},
{ {
"kind": "Conformance", "kind": "Conformance",
"name": "P1", "name": "P1",
"printedName": "P1", "printedName": "P1",
"usr": "s:4cake2P1P", "usr": "s:4cake2P1P",
"mangledName": "$s4cake2P1P" "mangledName": "$s4cake2P1P"
},
{
"kind": "Conformance",
"name": "P2",
"printedName": "P2",
"usr": "s:4cake2P2P",
"mangledName": "$s4cake2P2P"
} }
] ]
}, },

View File

@@ -98,19 +98,19 @@
"moduleName": "cake", "moduleName": "cake",
"genericSig": "<Self : cake.P1, Self : cake.P2>", "genericSig": "<Self : cake.P1, Self : cake.P2>",
"conformances": [ "conformances": [
{
"kind": "Conformance",
"name": "P2",
"printedName": "P2",
"usr": "s:4cake2P2P",
"mangledName": "$s4cake2P2P"
},
{ {
"kind": "Conformance", "kind": "Conformance",
"name": "P1", "name": "P1",
"printedName": "P1", "printedName": "P1",
"usr": "s:4cake2P1P", "usr": "s:4cake2P1P",
"mangledName": "$s4cake2P1P" "mangledName": "$s4cake2P1P"
},
{
"kind": "Conformance",
"name": "P2",
"printedName": "P2",
"usr": "s:4cake2P2P",
"mangledName": "$s4cake2P2P"
} }
] ]
}, },