Skip to content

Commit b02d443

Browse files
committed
AST: Introduce StableAvailabilityDomainComparator.
1 parent dc61784 commit b02d443

File tree

3 files changed

+41
-41
lines changed

3 files changed

+41
-41
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,14 @@ inline void simple_display(llvm::raw_ostream &os,
265265
domain.print(os);
266266
}
267267

268+
/// A comparator that implements a stable, total ordering on
269+
/// `AvailabilityDomain` that can be used for sorting in contexts where the
270+
/// result must be stable and deterministic across compilations.
271+
struct StableAvailabilityDomainComparator {
272+
bool operator()(const AvailabilityDomain &lhs,
273+
const AvailabilityDomain &rhs) const;
274+
};
275+
268276
/// Represents an availability domain that has been defined in a module.
269277
class CustomAvailabilityDomain : public ASTAllocated<CustomAvailabilityDomain> {
270278
public:

lib/AST/Availability.cpp

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -168,46 +168,11 @@ void AvailabilityInference::applyInferredAvailableAttrs(
168168
Decl *ToDecl, ArrayRef<const Decl *> InferredFromDecls) {
169169
auto &Context = ToDecl->getASTContext();
170170

171-
/// A wrapper for AvailabilityDomain that implements a stable, total ordering for
172-
/// domains. This is needed to ensure that the inferred attributes are added to
173-
/// the declaration in a consistent order, preserving interface printing output
174-
/// stability across compilations.
175-
class OrderedAvailabilityDomain {
176-
public:
177-
AvailabilityDomain domain;
178-
179-
OrderedAvailabilityDomain(AvailabilityDomain domain) : domain(domain) {}
180-
181-
bool operator<(const OrderedAvailabilityDomain &other) const {
182-
auto kind = domain.getKind();
183-
auto otherKind = other.domain.getKind();
184-
if (kind != otherKind)
185-
return kind < otherKind;
186-
187-
switch (kind) {
188-
case AvailabilityDomain::Kind::Universal:
189-
case AvailabilityDomain::Kind::SwiftLanguage:
190-
case AvailabilityDomain::Kind::PackageDescription:
191-
case AvailabilityDomain::Kind::Embedded:
192-
return false;
193-
case AvailabilityDomain::Kind::Platform:
194-
return domain.getPlatformKind() < other.domain.getPlatformKind();
195-
case AvailabilityDomain::Kind::Custom: {
196-
auto mod = domain.getModule();
197-
auto otherMod = other.domain.getModule();
198-
if (mod != otherMod)
199-
return mod->getName() < otherMod->getName();
200-
201-
return domain.getNameForAttributePrinting() <
202-
other.domain.getNameForAttributePrinting();
203-
}
204-
}
205-
}
206-
};
207-
208171
// Iterate over the declarations and infer required availability on
209-
// a per-platform basis.
210-
std::map<OrderedAvailabilityDomain, InferredAvailability> Inferred;
172+
// a per-domain basis.
173+
std::map<AvailabilityDomain, InferredAvailability,
174+
StableAvailabilityDomainComparator>
175+
Inferred;
211176
for (const Decl *D : InferredFromDecls) {
212177
llvm::SmallVector<SemanticAvailableAttr, 8> MergedAttrs;
213178

@@ -242,8 +207,7 @@ void AvailabilityInference::applyInferredAvailableAttrs(
242207
// Create an availability attribute for each observed platform and add
243208
// to ToDecl.
244209
for (auto &Pair : Inferred) {
245-
if (auto Attr =
246-
createAvailableAttr(Pair.first.domain, Pair.second, Context))
210+
if (auto Attr = createAvailableAttr(Pair.first, Pair.second, Context))
247211
Attrs.add(Attr);
248212
}
249213
}

lib/AST/AvailabilityDomain.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "swift/AST/ASTContext.h"
1515
#include "swift/AST/Decl.h"
1616
#include "swift/AST/DiagnosticsSema.h"
17+
#include "swift/AST/Module.h"
1718
#include "swift/AST/TypeCheckRequests.h"
1819
#include "swift/Basic/Assertions.h"
1920
#include "llvm/ADT/StringSwitch.h"
@@ -203,6 +204,33 @@ AvailabilityDomain AvailabilityDomain::copy(ASTContext &ctx) const {
203204
}
204205
}
205206

207+
bool StableAvailabilityDomainComparator::operator()(
208+
const AvailabilityDomain &lhs, const AvailabilityDomain &rhs) const {
209+
auto lhsKind = lhs.getKind();
210+
auto rhsKind = rhs.getKind();
211+
if (lhsKind != rhsKind)
212+
return lhsKind < rhsKind;
213+
214+
switch (lhsKind) {
215+
case AvailabilityDomain::Kind::Universal:
216+
case AvailabilityDomain::Kind::SwiftLanguage:
217+
case AvailabilityDomain::Kind::PackageDescription:
218+
case AvailabilityDomain::Kind::Embedded:
219+
return false;
220+
case AvailabilityDomain::Kind::Platform:
221+
return lhs.getPlatformKind() < rhs.getPlatformKind();
222+
case AvailabilityDomain::Kind::Custom: {
223+
auto lhsMod = lhs.getModule();
224+
auto rhsMod = rhs.getModule();
225+
if (lhsMod != rhsMod)
226+
return lhsMod->getName() < rhsMod->getName();
227+
228+
return lhs.getNameForAttributePrinting() <
229+
rhs.getNameForAttributePrinting();
230+
}
231+
}
232+
}
233+
206234
CustomAvailabilityDomain::CustomAvailabilityDomain(Identifier name,
207235
ModuleDecl *mod, Kind kind)
208236
: name(name), kind(kind), mod(mod) {

0 commit comments

Comments
 (0)