Skip to content

Commit 74b5e11

Browse files
committed
Introduce UnorderedComparingArray
1 parent decff3a commit 74b5e11

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

Sources/SafeDICore/Models/TypeDescription.swift

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable {
2727
/// A nested type with possible generics. e.g. Array.Element or Swift.Array<Element>
2828
indirect case nested(name: String, parentType: TypeDescription, generics: [TypeDescription])
2929
/// A composed type. e.g. Identifiable & Equatable
30-
indirect case composition(Set<TypeDescription>)
30+
indirect case composition(UnorderedComparingArray<TypeDescription>)
3131
/// An optional type. e.g. Int?
3232
indirect case optional(TypeDescription)
3333
/// An implicitly unwrapped optional type. e.g. Int!
@@ -201,6 +201,8 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable {
201201
}
202202
}
203203

204+
// MARK: - TypeSyntax
205+
204206
extension TypeSyntax {
205207

206208
/// - Returns: the type description for the receiver.
@@ -225,7 +227,7 @@ extension TypeSyntax {
225227
generics: genericTypeVisitor.genericArguments)
226228

227229
} else if let typeIdentifiers = CompositionTypeSyntax(self) {
228-
return .composition(Set(typeIdentifiers.elements.map { $0.type.typeDescription }))
230+
return .composition(UnorderedComparingArray(typeIdentifiers.elements.map { $0.type.typeDescription }))
229231

230232
} else if let typeIdentifier = OptionalTypeSyntax(self) {
231233
return .optional(typeIdentifier.wrappedType.typeDescription)
@@ -290,6 +292,8 @@ extension TypeSyntax {
290292
}
291293
}
292294

295+
// MARK: - ExprSyntax
296+
293297
extension ExprSyntax {
294298
public var typeDescription: TypeDescription {
295299
if let typeExpr = TypeExprSyntax(self) {
@@ -359,7 +363,7 @@ extension ExprSyntax {
359363
}
360364
} else if let sequenceExpr = SequenceExprSyntax(self) {
361365
if sequenceExpr.elements.contains(where: { BinaryOperatorExprSyntax($0) != nil }) {
362-
return .composition(Set(
366+
return .composition(UnorderedComparingArray(
363367
sequenceExpr
364368
.elements
365369
.filter { BinaryOperatorExprSyntax($0) == nil }
@@ -406,6 +410,38 @@ extension ExprSyntax {
406410
}
407411
}
408412

413+
// MARK: - UnorderedComparingArray
414+
415+
public struct UnorderedComparingArray<Element: Codable & Hashable & Sendable>: Codable, Hashable, Sendable, Collection {
416+
417+
init(_ array: [Element]) {
418+
self.array = array
419+
set = Set(array)
420+
}
421+
422+
let array: [Element]
423+
private let set: Set<Element>
424+
425+
public static func == (lhs: UnorderedComparingArray, rhs: UnorderedComparingArray) -> Bool {
426+
lhs.set == rhs.set
427+
}
428+
429+
public func makeIterator() -> IndexingIterator<Array<Element>> {
430+
array.makeIterator()
431+
}
432+
public var startIndex: Int { array.startIndex }
433+
public var endIndex: Int { array.endIndex }
434+
public func index(after i: Int) -> Int {
435+
array.index(after: i)
436+
}
437+
438+
public subscript(position: Int) -> Element {
439+
array[position]
440+
}
441+
}
442+
443+
// MARK: - GenericArgumentVisitor
444+
409445
private final class GenericArgumentVisitor: SyntaxVisitor {
410446

411447
private(set) var genericArguments = [TypeDescription]()

Tests/SafeDICoreTests/TypeDescriptionTests.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,27 +532,27 @@ final class TypeDescriptionTests: XCTestCase {
532532

533533
func test_equality_isTrueWhenComparingLexigraphicallyEquivalentCompositions() {
534534
XCTAssertEqual(
535-
TypeDescription.composition([
535+
TypeDescription.composition(.init([
536536
.simple(name: "Foo"),
537537
.simple(name: "Bar"),
538-
]),
539-
TypeDescription.composition([
538+
])),
539+
TypeDescription.composition(.init([
540540
.simple(name: "Foo"),
541541
.simple(name: "Bar"),
542-
])
542+
]))
543543
)
544544
}
545545

546546
func test_equality_isTrueWhenComparingReversedCompositions() {
547547
XCTAssertEqual(
548-
TypeDescription.composition([
548+
TypeDescription.composition(.init([
549549
.simple(name: "Foo"),
550550
.simple(name: "Bar"),
551-
]),
552-
TypeDescription.composition([
551+
])),
552+
TypeDescription.composition(.init([
553553
.simple(name: "Bar"),
554554
.simple(name: "Foo"),
555-
])
555+
]))
556556
)
557557
}
558558

0 commit comments

Comments
 (0)