@@ -43,6 +43,7 @@ extension Xcode.Project {
43
43
}
44
44
45
45
extension Xcode . Project : PropertyListSerializable {
46
+ fileprivate var xcodeClassName : String { " PBXProject " }
46
47
47
48
/// Generates and returns the contents of a `project.pbxproj` plist. Does
48
49
/// not generate any ancillary files, such as a set of schemes.
@@ -77,7 +78,7 @@ extension Xcode.Project: PropertyListSerializable {
77
78
// by Xcode when it opens the project and notices that they are missing.
78
79
// Note: we also skip schemes, since they are not in the project plist.
79
80
var dict = [ String: PropertyList] ( )
80
- dict [ " isa " ] = . string( " PBXProject " )
81
+ dict [ " isa " ] = . string( xcodeClassName )
81
82
// Since the project file is generated, we opt out of upgrade-checking.
82
83
// FIXME: Should we really? Why would we not want to get upgraded?
83
84
dict [ " attributes " ] = . dictionary( [ " LastUpgradeCheck " : . string( " 9999 " ) ,
@@ -108,26 +109,35 @@ extension Xcode.Project: PropertyListSerializable {
108
109
}
109
110
110
111
extension Xcode . Reference : PropertyListSerializable {
111
- fileprivate dynamic func serialize(
112
+ fileprivate var xcodeClassName : String {
113
+ switch self {
114
+ case is Xcode . Group :
115
+ " PBXGroup "
116
+ case let fileRef as Xcode . FileReference :
117
+ fileRef. isBuildableFolder ? " PBXFileSystemSynchronizedRootGroup "
118
+ : " PBXFileReference "
119
+ default :
120
+ fatalError ( " Unhandled subclass " )
121
+ }
122
+ }
123
+
124
+ fileprivate func serialize(
112
125
to serializer: PropertyListSerializer
113
126
) throws -> [ String : PropertyList ] {
114
127
var dict = [ String: PropertyList] ( )
128
+ dict [ " isa " ] = . string( xcodeClassName)
115
129
dict [ " path " ] = . string( path)
116
130
if let name = name {
117
131
dict [ " name " ] = . string( name)
118
132
}
119
133
dict [ " sourceTree " ] = . string( pathBase. rawValue)
120
134
121
- let xcodeClassName : String
122
135
switch self {
123
136
case let group as Xcode . Group :
124
- xcodeClassName = " PBXGroup "
125
137
dict [ " children " ] = try . array( group. subitems. map ( { reference in
126
138
try . identifier( serializer. serialize ( object: reference) )
127
139
} ) )
128
140
case let fileRef as Xcode . FileReference :
129
- xcodeClassName = fileRef. isBuildableFolder
130
- ? " PBXFileSystemSynchronizedRootGroup " : " PBXFileReference "
131
141
if let fileType = fileRef. fileType {
132
142
dict [ " explicitFileType " ] = . string( fileType)
133
143
}
@@ -138,19 +148,21 @@ extension Xcode.Reference: PropertyListSerializable {
138
148
default :
139
149
fatalError ( " Unhandled subclass " )
140
150
}
141
- dict [ " isa " ] = . string( xcodeClassName)
142
151
return dict
143
152
}
144
153
}
145
154
146
155
extension Xcode . Target : PropertyListSerializable {
156
+ fileprivate var xcodeClassName : String {
157
+ productType == nil ? " PBXAggregateTarget " : " PBXNativeTarget "
158
+ }
147
159
148
160
/// Called by the Serializer to serialize the Target.
149
161
fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
150
162
// Create either a `PBXNativeTarget` or an `PBXAggregateTarget` plist
151
163
// dictionary (depending on whether or not we have a product type).
152
164
var dict = [ String: PropertyList] ( )
153
- dict [ " isa " ] = . string( productType == nil ? " PBXAggregateTarget " : " PBXNativeTarget " )
165
+ dict [ " isa " ] = . string( xcodeClassName )
154
166
dict [ " name " ] = . string( name)
155
167
// Build settings are a bit tricky; in Xcode, each is stored in a named
156
168
// XCBuildConfiguration object, and the list of build configurations is
@@ -169,14 +181,16 @@ extension Xcode.Target: PropertyListSerializable {
169
181
/// glue between our value-based settings structures and the Xcode
170
182
/// project model's identity-based TargetDependency objects.
171
183
class TargetDependency : PropertyListSerializable {
184
+ var xcodeClassName : String { " PBXTargetDependency " }
185
+
172
186
var target : Xcode . Target
173
187
init ( target: Xcode . Target ) {
174
188
self . target = target
175
189
}
176
190
func serialize( to serializer: PropertyListSerializer ) -> [ String : PropertyList ] {
177
191
// Create a `PBXTargetDependency` plist dictionary.
178
192
var dict = [ String: PropertyList] ( )
179
- dict [ " isa " ] = . string( " PBXTargetDependency " )
193
+ dict [ " isa " ] = . string( xcodeClassName )
180
194
dict [ " target " ] = . identifier( serializer. id ( of: target) )
181
195
return dict
182
196
}
@@ -202,91 +216,60 @@ extension Xcode.Target: PropertyListSerializable {
202
216
}
203
217
}
204
218
205
- /// Private helper function that constructs and returns a partial property list
206
- /// dictionary for build phases. The caller can add to the returned dictionary.
207
- /// FIXME: It would be nicer to be able to use inheritance to serialize the
208
- /// attributes inherited from BuildPhase, but but in Swift 3.0 we get an error
209
- /// that "declarations in extensions cannot override yet".
210
- fileprivate func makeBuildPhaseDict(
211
- buildPhase: Xcode . BuildPhase ,
212
- serializer: PropertyListSerializer ,
213
- xcodeClassName: String
214
- ) throws -> [ String : PropertyList ] {
215
- var dict = [ String: PropertyList] ( )
216
- dict [ " isa " ] = . string( xcodeClassName)
217
- dict [ " files " ] = try . array( buildPhase. files. map ( { file in
218
- try . identifier( serializer. serialize ( object: file) )
219
- } ) )
220
- return dict
219
+ extension PropertyListSerializable where Self: Xcode . BuildPhase {
220
+ /// Helper function that constructs and returns the base property list
221
+ /// dictionary for build phases.
222
+ fileprivate func makeBuildPhaseDict(
223
+ serializer: PropertyListSerializer
224
+ ) throws -> [ String : PropertyList ] {
225
+ var dict = [ String: PropertyList] ( )
226
+ dict [ " isa " ] = . string( xcodeClassName)
227
+ dict [ " files " ] = try . array( files. map ( { file in
228
+ try . identifier( serializer. serialize ( object: file) )
229
+ } ) )
230
+ return dict
231
+ }
232
+
233
+ /// Default serialization implementation.
234
+ fileprivate func serialize(
235
+ to serializer: PropertyListSerializer
236
+ ) throws -> [ String : PropertyList ] {
237
+ try makeBuildPhaseDict ( serializer: serializer)
238
+ }
221
239
}
222
240
223
241
extension Xcode . HeadersBuildPhase : PropertyListSerializable {
224
-
225
- /// Called by the Serializer to serialize the HeadersBuildPhase.
226
- fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
227
- // Create a `PBXHeadersBuildPhase` plist dictionary.
228
- // FIXME: It would be nicer to be able to use inheritance for the code
229
- // inherited from BuildPhase, but but in Swift 3.0 we get an error that
230
- // "declarations in extensions cannot override yet".
231
- return try makeBuildPhaseDict ( buildPhase: self , serializer: serializer, xcodeClassName: " PBXHeadersBuildPhase " )
232
- }
242
+ fileprivate var xcodeClassName : String { " PBXHeadersBuildPhase " }
233
243
}
234
244
235
245
extension Xcode . SourcesBuildPhase : PropertyListSerializable {
236
-
237
- /// Called by the Serializer to serialize the SourcesBuildPhase.
238
- fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
239
- // Create a `PBXSourcesBuildPhase` plist dictionary.
240
- // FIXME: It would be nicer to be able to use inheritance for the code
241
- // inherited from BuildPhase, but but in Swift 3.0 we get an error that
242
- // "declarations in extensions cannot override yet".
243
- return try makeBuildPhaseDict ( buildPhase: self , serializer: serializer, xcodeClassName: " PBXSourcesBuildPhase " )
244
- }
246
+ fileprivate var xcodeClassName : String { " PBXSourcesBuildPhase " }
245
247
}
246
248
247
249
extension Xcode . FrameworksBuildPhase : PropertyListSerializable {
248
-
249
- /// Called by the Serializer to serialize the FrameworksBuildPhase.
250
- fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
251
- // Create a `PBXFrameworksBuildPhase` plist dictionary.
252
- // FIXME: It would be nicer to be able to use inheritance for the code
253
- // inherited from BuildPhase, but but in Swift 3.0 we get an error that
254
- // "declarations in extensions cannot override yet".
255
- return try makeBuildPhaseDict ( buildPhase: self , serializer: serializer, xcodeClassName: " PBXFrameworksBuildPhase " )
256
- }
250
+ fileprivate var xcodeClassName : String { " PBXFrameworksBuildPhase " }
257
251
}
258
252
259
253
extension Xcode . CopyFilesBuildPhase : PropertyListSerializable {
254
+ fileprivate var xcodeClassName : String { " PBXCopyFilesBuildPhase " }
260
255
261
- /// Called by the Serializer to serialize the FrameworksBuildPhase.
262
- fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
263
- // Create a `PBXCopyFilesBuildPhase` plist dictionary.
264
- // FIXME: It would be nicer to be able to use inheritance for the code
265
- // inherited from BuildPhase, but but in Swift 3.0 we get an error that
266
- // "declarations in extensions cannot override yet".
267
- var dict = try makeBuildPhaseDict (
268
- buildPhase: self ,
269
- serializer: serializer,
270
- xcodeClassName: " PBXCopyFilesBuildPhase "
271
- )
256
+ fileprivate func serialize(
257
+ to serializer: PropertyListSerializer
258
+ ) throws -> [ String : PropertyList ] {
259
+ var dict = try makeBuildPhaseDict ( serializer: serializer)
272
260
dict [ " dstPath " ] = . string( " " ) // FIXME: needs to be real
273
261
dict [ " dstSubfolderSpec " ] = . string( " " ) // FIXME: needs to be real
274
262
return dict
275
263
}
276
264
}
277
265
278
266
extension Xcode . ShellScriptBuildPhase : PropertyListSerializable {
267
+ fileprivate var xcodeClassName : String { " PBXShellScriptBuildPhase " }
279
268
280
- /// Called by the Serializer to serialize the ShellScriptBuildPhase.
281
- fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
282
- // Create a `PBXShellScriptBuildPhase` plist dictionary.
283
- // FIXME: It would be nicer to be able to use inheritance for the code
284
- // inherited from BuildPhase, but but in Swift 3.0 we get an error that
285
- // "declarations in extensions cannot override yet".
286
- var dict = try makeBuildPhaseDict (
287
- buildPhase: self ,
288
- serializer: serializer,
289
- xcodeClassName: " PBXShellScriptBuildPhase " )
269
+ fileprivate func serialize(
270
+ to serializer: PropertyListSerializer
271
+ ) throws -> [ String : PropertyList ] {
272
+ var dict = try makeBuildPhaseDict ( serializer: serializer)
290
273
dict [ " shellPath " ] = . string( " /bin/sh " ) // FIXME: should be settable
291
274
dict [ " shellScript " ] = . string( script)
292
275
dict [ " inputPaths " ] = . array( inputs. map { . string( $0) } )
@@ -297,12 +280,13 @@ extension Xcode.ShellScriptBuildPhase: PropertyListSerializable {
297
280
}
298
281
299
282
extension Xcode . BuildFile : PropertyListSerializable {
283
+ fileprivate var xcodeClassName : String { " PBXBuildFile " }
300
284
301
285
/// Called by the Serializer to serialize the BuildFile.
302
286
fileprivate func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
303
287
// Create a `PBXBuildFile` plist dictionary.
304
288
var dict = [ String: PropertyList] ( )
305
- dict [ " isa " ] = . string( " PBXBuildFile " )
289
+ dict [ " isa " ] = . string( xcodeClassName )
306
290
if let fileRef = fileRef {
307
291
dict [ " fileRef " ] = . identifier( serializer. id ( of: fileRef) )
308
292
}
@@ -317,6 +301,7 @@ extension Xcode.BuildFile: PropertyListSerializable {
317
301
}
318
302
319
303
extension Xcode . BuildSettingsTable : PropertyListSerializable {
304
+ fileprivate var xcodeClassName : String { " XCConfigurationList " }
320
305
321
306
/// Called by the Serializer to serialize the BuildFile. It is serialized
322
307
/// as an XCBuildConfigurationList and two additional XCBuildConfiguration
@@ -331,6 +316,8 @@ extension Xcode.BuildSettingsTable: PropertyListSerializable {
331
316
var overlaySettings : BuildSettings
332
317
let xcconfigFileRef : Xcode . FileReference ?
333
318
319
+ var xcodeClassName : String { " XCBuildConfiguration " }
320
+
334
321
init (
335
322
name: String ,
336
323
baseSettings: BuildSettings ,
@@ -346,7 +333,7 @@ extension Xcode.BuildSettingsTable: PropertyListSerializable {
346
333
func serialize( to serializer: PropertyListSerializer ) throws -> [ String : PropertyList ] {
347
334
// Create a `XCBuildConfiguration` plist dictionary.
348
335
var dict = [ String: PropertyList] ( )
349
- dict [ " isa " ] = . string( " XCBuildConfiguration " )
336
+ dict [ " isa " ] = . string( xcodeClassName )
350
337
dict [ " name " ] = . string( name)
351
338
// Combine the base settings and the overlay settings.
352
339
dict [ " buildSettings " ] = try combineBuildSettingsPropertyLists (
@@ -363,7 +350,7 @@ extension Xcode.BuildSettingsTable: PropertyListSerializable {
363
350
364
351
// Create a `XCConfigurationList` plist dictionary.
365
352
var dict = [ String: PropertyList] ( )
366
- dict [ " isa " ] = . string( " XCConfigurationList " )
353
+ dict [ " isa " ] = . string( xcodeClassName )
367
354
dict [ " buildConfigurations " ] = . array( [
368
355
// We use a private wrapper to "objectify" our two build settings
369
356
// structures (which, being structs, are value types).
@@ -535,6 +522,9 @@ fileprivate protocol PropertyListSerializable: AnyObject {
535
522
/// matters. So this is acceptable for now in the interest of getting it
536
523
/// done.
537
524
525
+ /// The ID for the `isa` field of the object.
526
+ var xcodeClassName : String { get }
527
+
538
528
/// A custom ID to use for the instance, if enabled.
539
529
///
540
530
/// This ID must be unique across the entire serialized graph.
0 commit comments