@@ -27,7 +27,7 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable {
27
27
/// A nested type with possible generics. e.g. Array.Element or Swift.Array<Element>
28
28
indirect case nested( name: String , parentType: TypeDescription , generics: [ TypeDescription ] )
29
29
/// A composed type. e.g. Identifiable & Equatable
30
- indirect case composition( Set < TypeDescription > )
30
+ indirect case composition( UnorderedComparingArray < TypeDescription > )
31
31
/// An optional type. e.g. Int?
32
32
indirect case optional( TypeDescription )
33
33
/// An implicitly unwrapped optional type. e.g. Int!
@@ -73,8 +73,6 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable {
73
73
case let . composition( types) :
74
74
return types
75
75
. map { $0. asSource }
76
- // Sort the result to ensure stable code generation.
77
- . sorted ( )
78
76
. joined ( separator: " & " )
79
77
case let . optional( type) :
80
78
return " \( type. asSource) ? "
@@ -201,6 +199,8 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable {
201
199
}
202
200
}
203
201
202
+ // MARK: - TypeSyntax
203
+
204
204
extension TypeSyntax {
205
205
206
206
/// - Returns: the type description for the receiver.
@@ -225,7 +225,7 @@ extension TypeSyntax {
225
225
generics: genericTypeVisitor. genericArguments)
226
226
227
227
} else if let typeIdentifiers = CompositionTypeSyntax ( self ) {
228
- return . composition( Set ( typeIdentifiers. elements. map { $0. type. typeDescription } ) )
228
+ return . composition( UnorderedComparingArray ( typeIdentifiers. elements. map { $0. type. typeDescription } ) )
229
229
230
230
} else if let typeIdentifier = OptionalTypeSyntax ( self ) {
231
231
return . optional( typeIdentifier. wrappedType. typeDescription)
@@ -290,6 +290,8 @@ extension TypeSyntax {
290
290
}
291
291
}
292
292
293
+ // MARK: - ExprSyntax
294
+
293
295
extension ExprSyntax {
294
296
public var typeDescription : TypeDescription {
295
297
if let typeExpr = TypeExprSyntax ( self ) {
@@ -359,7 +361,7 @@ extension ExprSyntax {
359
361
}
360
362
} else if let sequenceExpr = SequenceExprSyntax ( self ) {
361
363
if sequenceExpr. elements. contains ( where: { BinaryOperatorExprSyntax ( $0) != nil } ) {
362
- return . composition( Set (
364
+ return . composition( UnorderedComparingArray (
363
365
sequenceExpr
364
366
. elements
365
367
. filter { BinaryOperatorExprSyntax ( $0) == nil }
@@ -406,6 +408,38 @@ extension ExprSyntax {
406
408
}
407
409
}
408
410
411
+ // MARK: - UnorderedComparingArray
412
+
413
+ public struct UnorderedComparingArray < Element: Codable & Hashable & Sendable > : Codable , Hashable , Sendable , Collection {
414
+
415
+ init ( _ array: [ Element ] ) {
416
+ self . array = array
417
+ set = Set ( array)
418
+ }
419
+
420
+ let array : [ Element ]
421
+ private let set : Set < Element >
422
+
423
+ public static func == ( lhs: UnorderedComparingArray , rhs: UnorderedComparingArray ) -> Bool {
424
+ lhs. set == rhs. set
425
+ }
426
+
427
+ public func makeIterator( ) -> IndexingIterator < Array < Element > > {
428
+ array. makeIterator ( )
429
+ }
430
+ public var startIndex : Int { array. startIndex }
431
+ public var endIndex : Int { array. endIndex }
432
+ public func index( after i: Int ) -> Int {
433
+ array. index ( after: i)
434
+ }
435
+
436
+ public subscript( position: Int ) -> Element {
437
+ array [ position]
438
+ }
439
+ }
440
+
441
+ // MARK: - GenericArgumentVisitor
442
+
409
443
private final class GenericArgumentVisitor : SyntaxVisitor {
410
444
411
445
private( set) var genericArguments = [ TypeDescription] ( )
0 commit comments