mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[PrintAsClang] Beef up extension sorting rule
A couple of the rules that `ModuleContentsWriter::write()` uses to sort declarations didn’t actually work because of an incorrect predicate. In addition, there were a number of situations that could come up in C++ interop (where overloading is permitted) where extensions could not be sorted. Rework extension sorting to look for more kinds of differences between extension members.
This commit is contained in:
@@ -780,7 +780,7 @@ public:
|
||||
std::mismatch(lhsProtos.begin(), lhsProtos.end(), rhsProtos.begin(),
|
||||
[] (const ProtocolDecl *nextLHSProto,
|
||||
const ProtocolDecl *nextRHSProto) {
|
||||
return nextLHSProto->getName() != nextRHSProto->getName();
|
||||
return nextLHSProto->getName() == nextRHSProto->getName();
|
||||
});
|
||||
if (mismatch.first != lhsProtos.end()) {
|
||||
StringRef lhsProtoName = (*mismatch.first)->getName().str();
|
||||
@@ -788,30 +788,35 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Still nothing? Fine, we'll pick the one with the alphabetically first
|
||||
// member instead.
|
||||
// Still nothing? Fine, we'll look for a difference between the members.
|
||||
{
|
||||
auto mismatch = std::mismatch(
|
||||
cast<ExtensionDecl>(*lhs)->getAllMembers().begin(),
|
||||
cast<ExtensionDecl>(*lhs)->getAllMembers().end(),
|
||||
cast<ExtensionDecl>(*rhs)->getAllMembers().begin(),
|
||||
[](const Decl *nextLHSDecl, const Decl *nextRHSDecl) {
|
||||
if (isa<ValueDecl>(nextLHSDecl) && isa<ValueDecl>(nextRHSDecl)) {
|
||||
return cast<ValueDecl>(nextLHSDecl)->getName() !=
|
||||
cast<ValueDecl>(nextRHSDecl)->getName();
|
||||
}
|
||||
return isa<ValueDecl>(nextLHSDecl) != isa<ValueDecl>(nextRHSDecl);
|
||||
});
|
||||
if (mismatch.first !=
|
||||
cast<ExtensionDecl>(*lhs)->getAllMembers().end()) {
|
||||
auto *lhsMember = dyn_cast<ValueDecl>(*mismatch.first),
|
||||
*rhsMember = dyn_cast<ValueDecl>(*mismatch.second);
|
||||
for (auto pair : llvm::zip_equal(lhsMembers, rhsMembers)) {
|
||||
auto *lhsMember = dyn_cast<ValueDecl>(std::get<0>(pair)),
|
||||
*rhsMember = dyn_cast<ValueDecl>(std::get<1>(pair));
|
||||
if (!rhsMember && lhsMember)
|
||||
return Descending;
|
||||
if (lhsMember && !rhsMember)
|
||||
if (!lhsMember && rhsMember)
|
||||
return Ascending;
|
||||
if (lhsMember && rhsMember)
|
||||
return rhsMember->getName().compare(lhsMember->getName());
|
||||
if (!lhsMember && !rhsMember)
|
||||
continue;
|
||||
|
||||
result = rhsMember->getName().compare(lhsMember->getName());
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = rhsMember->getInterfaceType().getString().compare(
|
||||
lhsMember->getInterfaceType().getString());
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
auto lhsGeneric = lhsMember->getAsGenericContext(),
|
||||
rhsGeneric = rhsMember->getAsGenericContext();
|
||||
if (lhsGeneric && rhsGeneric) {
|
||||
result = rhsGeneric->getGenericSignature().getAsString().compare(
|
||||
lhsGeneric->getGenericSignature().getAsString());
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user