Skip to content

Commit d2100b7

Browse files
committed
[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.
1 parent f8722df commit d2100b7

File tree

2 files changed

+36
-31
lines changed

2 files changed

+36
-31
lines changed

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -780,38 +780,43 @@ class ModuleWriter {
780780
std::mismatch(lhsProtos.begin(), lhsProtos.end(), rhsProtos.begin(),
781781
[] (const ProtocolDecl *nextLHSProto,
782782
const ProtocolDecl *nextRHSProto) {
783-
return nextLHSProto->getName() != nextRHSProto->getName();
783+
return nextLHSProto->getName() == nextRHSProto->getName();
784784
});
785785
if (mismatch.first != lhsProtos.end()) {
786786
StringRef lhsProtoName = (*mismatch.first)->getName().str();
787787
return lhsProtoName.compare((*mismatch.second)->getName().str());
788788
}
789789
}
790790

791-
// Still nothing? Fine, we'll pick the one with the alphabetically first
792-
// member instead.
791+
// Still nothing? Fine, we'll look for a difference between the members.
793792
{
794-
auto mismatch = std::mismatch(
795-
cast<ExtensionDecl>(*lhs)->getAllMembers().begin(),
796-
cast<ExtensionDecl>(*lhs)->getAllMembers().end(),
797-
cast<ExtensionDecl>(*rhs)->getAllMembers().begin(),
798-
[](const Decl *nextLHSDecl, const Decl *nextRHSDecl) {
799-
if (isa<ValueDecl>(nextLHSDecl) && isa<ValueDecl>(nextRHSDecl)) {
800-
return cast<ValueDecl>(nextLHSDecl)->getName() !=
801-
cast<ValueDecl>(nextRHSDecl)->getName();
802-
}
803-
return isa<ValueDecl>(nextLHSDecl) != isa<ValueDecl>(nextRHSDecl);
804-
});
805-
if (mismatch.first !=
806-
cast<ExtensionDecl>(*lhs)->getAllMembers().end()) {
807-
auto *lhsMember = dyn_cast<ValueDecl>(*mismatch.first),
808-
*rhsMember = dyn_cast<ValueDecl>(*mismatch.second);
793+
for (auto pair : llvm::zip_equal(lhsMembers, rhsMembers)) {
794+
auto *lhsMember = dyn_cast<ValueDecl>(std::get<0>(pair)),
795+
*rhsMember = dyn_cast<ValueDecl>(std::get<1>(pair));
809796
if (!rhsMember && lhsMember)
810797
return Descending;
811-
if (lhsMember && !rhsMember)
798+
if (!lhsMember && rhsMember)
812799
return Ascending;
813-
if (lhsMember && rhsMember)
814-
return rhsMember->getName().compare(lhsMember->getName());
800+
if (!lhsMember && !rhsMember)
801+
continue;
802+
803+
result = rhsMember->getName().compare(lhsMember->getName());
804+
if (result != 0)
805+
return result;
806+
807+
result = rhsMember->getInterfaceType().getString().compare(
808+
lhsMember->getInterfaceType().getString());
809+
if (result != 0)
810+
return result;
811+
812+
auto lhsGeneric = lhsMember->getAsGenericContext(),
813+
rhsGeneric = rhsMember->getAsGenericContext();
814+
if (lhsGeneric && rhsGeneric) {
815+
result = rhsGeneric->getGenericSignature().getAsString().compare(
816+
lhsGeneric->getGenericSignature().getAsString());
817+
if (result != 0)
818+
return result;
819+
}
815820
}
816821
}
817822

test/PrintAsObjC/extensions.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ extension A2 {
4444
@objc @objcMembers class A3 {}
4545

4646
// CHECK-NEXT: @interface A3 (SWIFT_EXTENSION(extensions))
47-
// CHECK-NEXT: @property (nonatomic, readonly) NSInteger some;
47+
// CHECK-NEXT: @property (nonatomic, readonly) NSInteger more;
4848
// CHECK-NEXT: @end
4949
// CHECK-EMPTY:
5050
// CHECK-NEXT: @interface A3 (SWIFT_EXTENSION(extensions))
51-
// CHECK-NEXT: @property (nonatomic, readonly) NSInteger more;
51+
// CHECK-NEXT: @property (nonatomic, readonly) NSInteger some;
5252
// CHECK-NEXT: @end
5353
// CHECK-EMPTY:
5454
extension A3 {
@@ -96,22 +96,22 @@ extension A5 {
9696
// CHECK-NEXT: @interface A6
9797
@objc class A6 {}
9898

99-
extension A6 {
100-
@objc(skippedBool:) func skipped(_: Bool) {}
101-
@objc func def() {}
102-
}
10399
extension A6 {
104100
@objc(skippedInt:) func skipped(_: Int) {}
105101
@objc func abc() {}
106102
}
103+
extension A6 {
104+
@objc(skippedBool:) func skipped(_: Bool) {}
105+
@objc func def() {}
106+
}
107107
// CHECK: @interface A6 (SWIFT_EXTENSION(extensions))
108-
// CHECK-NEXT: - (void)skippedInt:
109-
// CHECK-NEXT: - (void)abc
108+
// CHECK-NEXT: - (void)skippedBool:
109+
// CHECK-NEXT: - (void)def
110110
// CHECK-NEXT: @end
111111
// CHECK-EMPTY:
112112
// CHECK-NEXT: @interface A6 (SWIFT_EXTENSION(extensions))
113-
// CHECK-NEXT: - (void)skippedBool:
114-
// CHECK-NEXT: - (void)def
113+
// CHECK-NEXT: - (void)skippedInt:
114+
// CHECK-NEXT: - (void)abc
115115
// CHECK-NEXT: @end
116116
// CHECK-EMPTY:
117117

0 commit comments

Comments
 (0)