@@ -60,7 +60,25 @@ public enum PIF {
60
60
}
61
61
}
62
62
63
- public class TypedObject : Codable {
63
+ /// Represents a high-level PIF object.
64
+ ///
65
+ /// For instance, a JSON serialized *workspace* might look like this:
66
+ /// ```json
67
+ /// {
68
+ /// "type" : "workspace",
69
+ /// "signature" : "22e9436958aec481799",
70
+ /// "contents" : {
71
+ /// "guid" : "Workspace:/Users/foo/BarPackage",
72
+ /// "name" : "BarPackage",
73
+ /// "path" : "/Users/foo/BarPackage",
74
+ /// "projects" : [
75
+ /// "70a588f37dcfcddbc1f",
76
+ /// "c1d9cb257bd42cafbb8"
77
+ /// ]
78
+ /// }
79
+ /// }
80
+ /// ```
81
+ public class HighLevelObject : Codable {
64
82
class var type : String {
65
83
fatalError ( " \( self ) missing implementation " )
66
84
}
@@ -71,8 +89,9 @@ public enum PIF {
71
89
type = Swift . type ( of: self ) . type
72
90
}
73
91
74
- private enum CodingKeys : CodingKey {
92
+ fileprivate enum CodingKeys : CodingKey {
75
93
case type
94
+ case signature, contents // Used by subclasses.
76
95
}
77
96
78
97
public func encode( to encoder: Encoder ) throws {
@@ -86,7 +105,7 @@ public enum PIF {
86
105
}
87
106
}
88
107
89
- public final class Workspace : TypedObject {
108
+ public final class Workspace : HighLevelObject {
90
109
override class var type : String { " workspace " }
91
110
92
111
public let guid : GUID
@@ -113,8 +132,8 @@ public enum PIF {
113
132
114
133
public override func encode( to encoder: Encoder ) throws {
115
134
try super. encode ( to: encoder)
116
- var container = encoder. container ( keyedBy: StringKey . self)
117
- var contents = container . nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
135
+ var superContainer = encoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
136
+ var contents = superContainer . nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
118
137
try contents. encode ( " \( guid) @ \( schemaVersion) " , forKey: . guid)
119
138
try contents. encode ( name, forKey: . name)
120
139
try contents. encode ( path, forKey: . path)
@@ -123,29 +142,29 @@ public enum PIF {
123
142
guard let signature else {
124
143
throw InternalError ( " Expected to have workspace signature when encoding for SwiftBuild " )
125
144
}
126
- try container . encode ( signature, forKey: " signature " )
145
+ try superContainer . encode ( signature, forKey: . signature)
127
146
try contents. encode ( projects. map ( { $0. signature } ) , forKey: . projects)
128
147
} else {
129
148
try contents. encode ( projects, forKey: . projects)
130
149
}
131
150
}
132
151
133
152
public required init ( from decoder: Decoder ) throws {
134
- let superContainer = try decoder. container ( keyedBy: StringKey . self)
135
- let container = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
153
+ let superContainer = try decoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
154
+ let contents = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
136
155
137
- let guidString = try container . decode ( GUID . self, forKey: . guid)
156
+ let guidString = try contents . decode ( GUID . self, forKey: . guid)
138
157
self . guid = String ( guidString. dropLast ( " \( schemaVersion) " . count + 1 ) )
139
- self . name = try container . decode ( String . self, forKey: . name)
140
- self . path = try container . decode ( AbsolutePath . self, forKey: . path)
141
- self . projects = try container . decode ( [ Project ] . self, forKey: . projects)
158
+ self . name = try contents . decode ( String . self, forKey: . name)
159
+ self . path = try contents . decode ( AbsolutePath . self, forKey: . path)
160
+ self . projects = try contents . decode ( [ Project ] . self, forKey: . projects)
142
161
try super. init ( from: decoder)
143
162
}
144
163
}
145
164
146
165
/// A PIF project, consisting of a tree of groups and file references, a list of targets, and some additional
147
166
/// information.
148
- public final class Project : TypedObject {
167
+ public final class Project : HighLevelObject {
149
168
override class var type : String { " project " }
150
169
151
170
public let guid : GUID
@@ -191,8 +210,8 @@ public enum PIF {
191
210
192
211
public override func encode( to encoder: Encoder ) throws {
193
212
try super. encode ( to: encoder)
194
- var container = encoder. container ( keyedBy: StringKey . self)
195
- var contents = container . nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
213
+ var superContainer = encoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
214
+ var contents = superContainer . nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
196
215
try contents. encode ( " \( guid) @ \( schemaVersion) " , forKey: . guid)
197
216
try contents. encode ( name, forKey: . projectName)
198
217
try contents. encode ( " true " , forKey: . projectIsPackage)
@@ -206,7 +225,7 @@ public enum PIF {
206
225
guard let signature else {
207
226
throw InternalError ( " Expected to have project signature when encoding for SwiftBuild " )
208
227
}
209
- try container . encode ( signature, forKey: " signature " )
228
+ try superContainer . encode ( signature, forKey: . signature)
210
229
try contents. encode ( targets. map { $0. signature } , forKey: . targets)
211
230
} else {
212
231
try contents. encode ( targets, forKey: . targets)
@@ -216,19 +235,19 @@ public enum PIF {
216
235
}
217
236
218
237
public required init ( from decoder: Decoder ) throws {
219
- let superContainer = try decoder. container ( keyedBy: StringKey . self)
220
- let container = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
238
+ let superContainer = try decoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
239
+ let contents = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
221
240
222
- let guidString = try container . decode ( GUID . self, forKey: . guid)
241
+ let guidString = try contents . decode ( GUID . self, forKey: . guid)
223
242
self . guid = String ( guidString. dropLast ( " \( schemaVersion) " . count + 1 ) )
224
- self . name = try container . decode ( String . self, forKey: . projectName)
225
- self . path = try container . decode ( AbsolutePath . self, forKey: . path)
226
- self . projectDirectory = try container . decode ( AbsolutePath . self, forKey: . projectDirectory)
227
- self . developmentRegion = try container . decode ( String . self, forKey: . developmentRegion)
228
- self . buildConfigurations = try container . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
229
-
230
- let untypedTargets = try container . decode ( [ UntypedTarget ] . self, forKey: . targets)
231
- var targetContainer = try container . nestedUnkeyedContainer ( forKey: . targets)
243
+ self . name = try contents . decode ( String . self, forKey: . projectName)
244
+ self . path = try contents . decode ( AbsolutePath . self, forKey: . path)
245
+ self . projectDirectory = try contents . decode ( AbsolutePath . self, forKey: . projectDirectory)
246
+ self . developmentRegion = try contents . decode ( String . self, forKey: . developmentRegion)
247
+ self . buildConfigurations = try contents . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
248
+
249
+ let untypedTargets = try contents . decode ( [ UntypedTarget ] . self, forKey: . targets)
250
+ var targetContainer = try contents . nestedUnkeyedContainer ( forKey: . targets)
232
251
self . targets = try untypedTargets. map { target in
233
252
let type = target. contents. type
234
253
switch type {
@@ -241,13 +260,13 @@ public enum PIF {
241
260
}
242
261
}
243
262
244
- self . groupTree = try container . decode ( Group . self, forKey: . groupTree)
263
+ self . groupTree = try contents . decode ( Group . self, forKey: . groupTree)
245
264
try super. init ( from: decoder)
246
265
}
247
266
}
248
267
249
268
/// Abstract base class for all items in the group hierarchy.
250
- public class Reference : TypedObject {
269
+ public class Reference : HighLevelObject {
251
270
/// Determines the base path for a reference's relative path.
252
271
public enum SourceTree : String , Codable {
253
272
@@ -387,7 +406,7 @@ public enum PIF {
387
406
public required init ( from decoder: Decoder ) throws {
388
407
let container = try decoder. container ( keyedBy: CodingKeys . self)
389
408
390
- let untypedChildren = try container. decode ( [ TypedObject ] . self, forKey: . children)
409
+ let untypedChildren = try container. decode ( [ HighLevelObject ] . self, forKey: . children)
391
410
var childrenContainer = try container. nestedUnkeyedContainer ( forKey: . children)
392
411
393
412
self . children = try untypedChildren. map { child in
@@ -440,7 +459,7 @@ public enum PIF {
440
459
}
441
460
}
442
461
443
- public class BaseTarget : TypedObject {
462
+ public class BaseTarget : HighLevelObject {
444
463
class override var type : String { " target " }
445
464
public let guid : GUID
446
465
public var name : String
@@ -500,8 +519,8 @@ public enum PIF {
500
519
501
520
public override func encode( to encoder: Encoder ) throws {
502
521
try super. encode ( to: encoder)
503
- var container = encoder. container ( keyedBy: StringKey . self)
504
- var contents = container . nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
522
+ var superContainer = encoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
523
+ var contents = superContainer . nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
505
524
try contents. encode ( " aggregate " , forKey: . type)
506
525
try contents. encode ( " \( guid) @ \( schemaVersion) " , forKey: . guid)
507
526
try contents. encode ( name, forKey: . name)
@@ -514,22 +533,22 @@ public enum PIF {
514
533
guard let signature else {
515
534
throw InternalError ( " Expected to have \( Swift . type ( of: self ) ) signature when encoding for SwiftBuild " )
516
535
}
517
- try container . encode ( signature, forKey: " signature " )
536
+ try superContainer . encode ( signature, forKey: . signature)
518
537
}
519
538
}
520
539
521
540
public required init ( from decoder: Decoder ) throws {
522
- let superContainer = try decoder. container ( keyedBy: StringKey . self)
523
- let container = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
541
+ let superContainer = try decoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
542
+ let contents = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
524
543
525
- let guidString = try container . decode ( GUID . self, forKey: . guid)
544
+ let guidString = try contents . decode ( GUID . self, forKey: . guid)
526
545
let guid = String ( guidString. dropLast ( " \( schemaVersion) " . count + 1 ) )
527
546
528
- let name = try container . decode ( String . self, forKey: . name)
529
- let buildConfigurations = try container . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
547
+ let name = try contents . decode ( String . self, forKey: . name)
548
+ let buildConfigurations = try contents . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
530
549
531
- let untypedBuildPhases = try container . decode ( [ TypedObject ] . self, forKey: . buildPhases)
532
- var buildPhasesContainer = try container . nestedUnkeyedContainer ( forKey: . buildPhases)
550
+ let untypedBuildPhases = try contents . decode ( [ HighLevelObject ] . self, forKey: . buildPhases)
551
+ var buildPhasesContainer = try contents . nestedUnkeyedContainer ( forKey: . buildPhases)
533
552
534
553
let buildPhases : [ BuildPhase ] = try untypedBuildPhases. map {
535
554
guard let type = $0. type else {
@@ -538,8 +557,8 @@ public enum PIF {
538
557
return try BuildPhase . decode ( container: & buildPhasesContainer, type: type)
539
558
}
540
559
541
- let dependencies = try container . decode ( [ TargetDependency ] . self, forKey: . dependencies)
542
- let impartedBuildProperties = try container . decode ( BuildSettings . self, forKey: . impartedBuildProperties)
560
+ let dependencies = try contents . decode ( [ TargetDependency ] . self, forKey: . dependencies)
561
+ let impartedBuildProperties = try contents . decode ( BuildSettings . self, forKey: . impartedBuildProperties)
543
562
544
563
super. init (
545
564
guid: guid,
@@ -600,8 +619,8 @@ public enum PIF {
600
619
601
620
override public func encode( to encoder: Encoder ) throws {
602
621
try super. encode ( to: encoder)
603
- var container = encoder. container ( keyedBy: StringKey . self)
604
- var contents = container . nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
622
+ var superContainer = encoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
623
+ var contents = superContainer . nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
605
624
try contents. encode ( " \( guid) @ \( schemaVersion) " , forKey: . guid)
606
625
try contents. encode ( name, forKey: . name)
607
626
try contents. encode ( dependencies, forKey: . dependencies)
@@ -611,7 +630,7 @@ public enum PIF {
611
630
guard let signature else {
612
631
throw InternalError ( " Expected to have \( Swift . type ( of: self ) ) signature when encoding for SwiftBuild " )
613
632
}
614
- try container . encode ( signature, forKey: " signature " )
633
+ try superContainer . encode ( signature, forKey: . signature)
615
634
}
616
635
617
636
if productType == . packageProduct {
@@ -639,34 +658,34 @@ public enum PIF {
639
658
}
640
659
641
660
public required init ( from decoder: Decoder ) throws {
642
- let superContainer = try decoder. container ( keyedBy: StringKey . self)
643
- let container = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: " contents " )
661
+ let superContainer = try decoder. container ( keyedBy: HighLevelObject . CodingKeys . self)
662
+ let contents = try superContainer. nestedContainer ( keyedBy: CodingKeys . self, forKey: . contents)
644
663
645
- let guidString = try container . decode ( GUID . self, forKey: . guid)
664
+ let guidString = try contents . decode ( GUID . self, forKey: . guid)
646
665
let guid = String ( guidString. dropLast ( " \( schemaVersion) " . count + 1 ) )
647
- let name = try container . decode ( String . self, forKey: . name)
648
- let buildConfigurations = try container . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
649
- let dependencies = try container . decode ( [ TargetDependency ] . self, forKey: . dependencies)
666
+ let name = try contents . decode ( String . self, forKey: . name)
667
+ let buildConfigurations = try contents . decode ( [ BuildConfiguration ] . self, forKey: . buildConfigurations)
668
+ let dependencies = try contents . decode ( [ TargetDependency ] . self, forKey: . dependencies)
650
669
651
- let type = try container . decode ( String . self, forKey: . type)
670
+ let type = try contents . decode ( String . self, forKey: . type)
652
671
653
672
let buildPhases : [ BuildPhase ]
654
673
let impartedBuildProperties : ImpartedBuildProperties
655
674
656
675
if type == " packageProduct " {
657
676
self . productType = . packageProduct
658
677
self . productName = " "
659
- let fwkBuildPhase = try container . decodeIfPresent ( FrameworksBuildPhase . self, forKey: . frameworksBuildPhase)
678
+ let fwkBuildPhase = try contents . decodeIfPresent ( FrameworksBuildPhase . self, forKey: . frameworksBuildPhase)
660
679
buildPhases = fwkBuildPhase. map { [ $0] } ?? [ ]
661
680
impartedBuildProperties = ImpartedBuildProperties ( settings: BuildSettings ( ) )
662
681
} else if type == " standard " {
663
- self . productType = try container . decode ( ProductType . self, forKey: . productTypeIdentifier)
682
+ self . productType = try contents . decode ( ProductType . self, forKey: . productTypeIdentifier)
664
683
665
- let productReference = try container . decode ( [ String : String ] . self, forKey: . productReference)
684
+ let productReference = try contents . decode ( [ String : String ] . self, forKey: . productReference)
666
685
self . productName = productReference [ " name " ] !
667
686
668
- let untypedBuildPhases = try container . decodeIfPresent ( [ TypedObject ] . self, forKey: . buildPhases) ?? [ ]
669
- var buildPhasesContainer = try container . nestedUnkeyedContainer ( forKey: . buildPhases)
687
+ let untypedBuildPhases = try contents . decodeIfPresent ( [ HighLevelObject ] . self, forKey: . buildPhases) ?? [ ]
688
+ var buildPhasesContainer = try contents . nestedUnkeyedContainer ( forKey: . buildPhases)
670
689
671
690
buildPhases = try untypedBuildPhases. map {
672
691
guard let type = $0. type else {
@@ -675,7 +694,7 @@ public enum PIF {
675
694
return try BuildPhase . decode ( container: & buildPhasesContainer, type: type)
676
695
}
677
696
678
- impartedBuildProperties = try container . decode ( ImpartedBuildProperties . self, forKey: . impartedBuildProperties)
697
+ impartedBuildProperties = try contents . decode ( ImpartedBuildProperties . self, forKey: . impartedBuildProperties)
679
698
} else {
680
699
throw InternalError ( " Unhandled target type \( type) " )
681
700
}
@@ -693,7 +712,7 @@ public enum PIF {
693
712
}
694
713
695
714
/// Abstract base class for all build phases in a target.
696
- public class BuildPhase : TypedObject {
715
+ public class BuildPhase : HighLevelObject {
697
716
static func decode( container: inout UnkeyedDecodingContainer , type: String ) throws -> BuildPhase {
698
717
switch type {
699
718
case HeadersBuildPhase . type:
@@ -1158,7 +1177,7 @@ public struct SwiftBuildFileType: CaseIterable {
1158
1177
}
1159
1178
}
1160
1179
1161
- struct StringKey : CodingKey , ExpressibleByStringInterpolation {
1180
+ fileprivate struct StringKey : CodingKey , ExpressibleByStringInterpolation {
1162
1181
var stringValue : String
1163
1182
var intValue : Int ?
1164
1183
@@ -1253,6 +1272,8 @@ private struct UntypedTarget: Decodable {
1253
1272
let contents : TargetContents
1254
1273
}
1255
1274
1275
+ // MARK: - PIF Signature Support
1276
+
1256
1277
protocol PIFSignableObject : AnyObject {
1257
1278
var signature : String ? { get set }
1258
1279
}
0 commit comments