mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
swift-api-digester: de-duplicate protocol conformance entries in the Json output
For some unclear reasons, calling getAllConformances on Int.Words and UInt.Words returns duplicate entries for conforming to RandomAccessCollection. Since this isn't the case for swift-5.1-branch, we saw false positives shown in rdar://49568079. This patch fixes the ABI/API checker by de-duplicate results collected from getAllConformances.
This commit is contained in:
@@ -1024,27 +1024,34 @@ Requirement getCanonicalRequirement(Requirement &Req) {
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
StringRef printGenericSignature(SDKContext &Ctx, ArrayRef<Requirement> AllReqs) {
|
||||
llvm::SmallString<32> Result;
|
||||
llvm::raw_svector_ostream OS(Result);
|
||||
if (AllReqs.empty())
|
||||
return StringRef();
|
||||
OS << "<";
|
||||
bool First = true;
|
||||
for (auto Req: AllReqs) {
|
||||
if (!First) {
|
||||
OS << ", ";
|
||||
} else {
|
||||
First = false;
|
||||
}
|
||||
if (Ctx.checkingABI())
|
||||
getCanonicalRequirement(Req).print(OS, PrintOptions::printInterface());
|
||||
else
|
||||
Req.print(OS, PrintOptions::printInterface());
|
||||
}
|
||||
OS << ">";
|
||||
return Ctx.buffer(OS.str());
|
||||
}
|
||||
|
||||
static StringRef printGenericSignature(SDKContext &Ctx, Decl *D) {
|
||||
llvm::SmallString<32> Result;
|
||||
llvm::raw_svector_ostream OS(Result);
|
||||
if (auto *PD = dyn_cast<ProtocolDecl>(D)) {
|
||||
if (PD->getRequirementSignature().empty())
|
||||
return StringRef();
|
||||
OS << "<";
|
||||
bool First = true;
|
||||
for (auto Req: PD->getRequirementSignature()) {
|
||||
if (!First) {
|
||||
OS << ", ";
|
||||
} else {
|
||||
First = false;
|
||||
}
|
||||
if (Ctx.checkingABI())
|
||||
getCanonicalRequirement(Req).print(OS, PrintOptions::printInterface());
|
||||
else
|
||||
Req.print(OS, PrintOptions::printInterface());
|
||||
}
|
||||
OS << ">";
|
||||
return Ctx.buffer(OS.str());
|
||||
return printGenericSignature(Ctx, PD->getRequirementSignature());
|
||||
}
|
||||
|
||||
if (auto *GC = D->getAsGenericContext()) {
|
||||
@@ -1059,6 +1066,11 @@ static StringRef printGenericSignature(SDKContext &Ctx, Decl *D) {
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
static
|
||||
StringRef printGenericSignature(SDKContext &Ctx, ProtocolConformance *Conf) {
|
||||
return printGenericSignature(Ctx, Conf->getConditionalRequirements());
|
||||
}
|
||||
|
||||
static Optional<uint8_t> getSimilarMemberCount(NominalTypeDecl *NTD,
|
||||
ValueDecl *VD,
|
||||
llvm::function_ref<bool(Decl*)> Check) {
|
||||
@@ -1161,6 +1173,9 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *OD):
|
||||
|
||||
SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ProtocolConformance *Conform):
|
||||
SDKNodeInitInfo(Ctx, Conform->getProtocol()) {
|
||||
// The conformance can be conditional. The generic signature keeps track of
|
||||
// the requirements.
|
||||
GenericSig = printGenericSignature(Ctx, Conform);
|
||||
// Whether this conformance is ABI placeholder depends on the decl context
|
||||
// of this conformance.
|
||||
IsABIPlaceholder = isABIPlaceholderRecursive(Conform->getDeclContext()->
|
||||
@@ -1562,9 +1577,12 @@ SwiftDeclCollector::constructConformanceNode(ProtocolConformance *Conform) {
|
||||
void swift::ide::api::
|
||||
SwiftDeclCollector::addConformancesToTypeDecl(SDKNodeDeclType *Root,
|
||||
NominalTypeDecl *NTD) {
|
||||
// Avoid adding the same conformance twice.
|
||||
SmallPtrSet<ProtocolConformance*, 4> Seen;
|
||||
for (auto &Conf: NTD->getAllConformances()) {
|
||||
if (!Ctx.shouldIgnore(Conf->getProtocol()))
|
||||
if (!Ctx.shouldIgnore(Conf->getProtocol()) && !Seen.count(Conf))
|
||||
Root->addConformance(constructConformanceNode(Conf));
|
||||
Seen.insert(Conf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user