Skip to content

Commit

Permalink
Unify object access in PBXObjectReference
Browse files Browse the repository at this point in the history
  • Loading branch information
waltflanagan committed Jul 30, 2024
1 parent bec42a6 commit e2b09d3
Show file tree
Hide file tree
Showing 21 changed files with 107 additions and 115 deletions.
10 changes: 5 additions & 5 deletions Sources/XcodeProj/Objects/BuildPhase/PBXBuildFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public final class PBXBuildFile: PBXObject {
/// Returns the file the build file refers to.
public var file: PBXFileElement? {
get {
fileReference?.getObject()
fileReference?.object()
}
set {
fileReference = newValue?.reference
Expand All @@ -23,7 +23,7 @@ public final class PBXBuildFile: PBXObject {
/// Product.
public var product: XCSwiftPackageProductDependency? {
get {
productReference?.getObject()
productReference?.object()
}
set {
productReference = newValue?.reference
Expand Down Expand Up @@ -104,8 +104,8 @@ extension PBXBuildFile {
/// - Returns: file name.
/// - Throws: an error if the name cannot be obtained.
func fileName() throws -> String? {
if let fileElement: PBXFileElement = fileReference?.getObject(), let name = fileElement.fileName() { return name }
if let product: XCSwiftPackageProductDependency = productReference?.getObject() { return product.productName }
if let fileElement: PBXFileElement = fileReference?.object(), let name = fileElement.fileName() { return name }
if let product: XCSwiftPackageProductDependency = productReference?.object() { return product.productName }
return nil
}

Expand Down Expand Up @@ -171,7 +171,7 @@ final class PBXBuildPhaseFile: PlistSerializable, Equatable {
var dictionary: [CommentedString: PlistValue] = [:]
dictionary["isa"] = .string(CommentedString(PBXBuildFile.isa))
if let fileReference = buildFile.fileReference {
let fileElement: PBXFileElement? = fileReference.getObject()
let fileElement: PBXFileElement? = fileReference.object()
dictionary["fileRef"] = .string(CommentedString(fileReference.value, comment: fileElement?.fileName()))
}
if let product = buildFile.product {
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public class PBXBuildPhase: PBXContainerItem {
dictionary["buildActionMask"] = .string(CommentedString("\(buildActionMask)"))
if let fileReferences = fileReferences {
let files: PlistValue = .array(fileReferences.map { fileReference in
let buildFile: PBXBuildFile? = fileReference.getObject()
let buildFile: PBXBuildFile? = fileReference.object()
let name = buildFile.flatMap { try? $0.fileName() } ?? nil
let fileName: String = name ?? "(null)"
let type = self.name()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public final class XCBuildConfiguration: PBXObject {
/// Base xcconfig file reference.
public var baseConfiguration: PBXFileReference? {
get {
baseConfigurationReference?.getObject()
baseConfigurationReference?.object()
}
set {
if let newValue = newValue {
Expand Down Expand Up @@ -105,7 +105,7 @@ extension XCBuildConfiguration: PlistSerializable {
dictionary["name"] = .string(CommentedString(name))
dictionary["buildSettings"] = buildSettings.plist()
if let baseConfigurationReference = baseConfigurationReference {
let fileElement: PBXFileElement? = baseConfigurationReference.getObject()
let fileElement: PBXFileElement? = baseConfigurationReference.object()
dictionary["baseConfigurationReference"] = .string(CommentedString(baseConfigurationReference.value, comment: fileElement?.fileName()))
}
return (key: CommentedString(reference, comment: name), value: .dictionary(dictionary))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ extension XCConfigurationList: PlistSerializable {
dictionary["isa"] = .string(CommentedString(XCConfigurationList.isa))
dictionary["buildConfigurations"] = .array(buildConfigurationReferences
.map { configReference in
let config: XCBuildConfiguration? = configReference.getObject()
let config: XCBuildConfiguration? = configReference.object()
return .string(CommentedString(configReference.value, comment: config?.name))
})
dictionary["defaultConfigurationIsVisible"] = .string(CommentedString("\(defaultConfigurationIsVisible.int)"))
Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Objects/Files/PBXContainerItemProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public final class PBXContainerItemProxy: PBXObject {
var id: RemoteGlobalID {
switch self {
case let .reference(reference):
if let object = reference.getObject() {
if let object = reference.object() {
return .object(object)
} else {
return .string(reference.value)
Expand Down Expand Up @@ -65,7 +65,7 @@ public final class PBXContainerItemProxy: PBXObject {
/// Use isContainerPortalFileReference to check if you can use the getter
public var containerPortal: ContainerPortal {
get {
ContainerPortal(object: containerPortalReference.getObject())
ContainerPortal(object: containerPortalReference.object())
}
set {
guard let reference = newValue.reference else {
Expand Down
6 changes: 3 additions & 3 deletions Sources/XcodeProj/Objects/Files/PBXFileElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ public extension PBXFileElement {
/// - Returns: path to the variant group base file.
/// - Throws: an error if the path cannot be obtained.
private func baseVariantGroupPath() throws -> String? {
guard let variantGroup: PBXVariantGroup = reference.getObject() else { return nil }
guard let baseReference = try variantGroup
guard let variantGroup: PBXVariantGroup = reference.object() else { return nil }
guard let baseReference = variantGroup
.childrenReferences
.compactMap({ try $0.getThrowingObject() as PBXFileElement })
.compactMap({ $0.object(as: PBXFileElement.self) })
.first(where: { $0.name == "Base" }) else { return nil }
return baseReference.path
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeProj/Objects/Files/PBXGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public class PBXGroup: PBXFileElement {
var dictionary: [CommentedString: PlistValue] = try super.plistKeyAndValue(proj: proj, reference: reference).value.dictionary ?? [:]
dictionary["isa"] = .string(CommentedString(type(of: self).isa))
dictionary["children"] = .array(childrenReferences.map { (fileReference) -> PlistValue in
let fileElement: PBXFileElement? = fileReference.getObject()
let fileElement: PBXFileElement? = fileReference.object()
return .string(CommentedString(fileReference.value, comment: fileElement?.fileName()))
})

Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeProj/Objects/Files/XCVersionGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public final class XCVersionGroup: PBXGroup {
/// Returns the current version file reference.
public var currentVersion: PBXFileReference? {
get {
currentVersionReference?.getObject()
currentVersionReference?.object()
}
set {
currentVersionReference = newValue?.reference
Expand Down Expand Up @@ -91,7 +91,7 @@ public final class XCVersionGroup: PBXGroup {
dictionary["versionGroupType"] = .string(CommentedString(versionGroupType))
}
if let currentVersionReference = currentVersionReference {
let fileElement: PBXFileElement? = currentVersionReference.getObject()
let fileElement: PBXFileElement? = currentVersionReference.object()
dictionary["currentVersion"] = .string(CommentedString(currentVersionReference.value, comment: fileElement?.fileName()))
}
return (key: CommentedString(reference, comment: path?.split(separator: "/").last.map(String.init)),
Expand Down
58 changes: 25 additions & 33 deletions Sources/XcodeProj/Objects/Project/PBXObjectReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,32 @@ class PBXObjectReference: NSObject, Comparable, NSCopying, @unchecked Sendable {
}
private weak var _objects: PBXObjects?

// QUESTION: this is exposed to the project but so is `getThrowingObject` and `getObject`. What access patterns do we want to support?
/// A weak reference to the object
var object: PBXObject? {
get {
lock.withLock { _object }

/// The object referenced by this instance.
///
/// - Returns: object the reference is referring to. Returns nil if the objects property has been released or the reference doesn't exist
func object<T: PBXObject>() -> T? {
lock.withLock {
if let object = _object as? T {
return object
}

guard let object = objects?.get(reference: self) else { return nil }
_object = object

return object as? T

}
}


/// Typed object referenced by this instance.
/// - Parameter as: Type to cast to
/// - Returns: returns casted object if successful
func object<T: PBXObject>(as: T.Type) -> T? {
lock.withLock { _object } as? T
}

private weak var _object: PBXObject?

/// Initializes a non-temporary reference.
Expand Down Expand Up @@ -147,33 +166,6 @@ class PBXObjectReference: NSObject, Comparable, NSCopying, @unchecked Sendable {
}
}

/// Returns the object the reference is referfing to.
///
/// - Returns: object the reference is referring to. Returns nil if the objects property has been released or the reference doesn't exist
func getObject<T: PBXObject>() -> T? {
try? getThrowingObject()
}

/// Returns the object the reference is referfing to.
///
/// - Returns: object the reference is referring to.
/// - Throws: an errof it the objects property has been released or the reference doesn't exist.
func getThrowingObject<T: PBXObject>() throws -> T {
if let object = object as? T {
return object
}
return try lock.withLock {
guard let objects = objects else {
throw PBXObjectError.objectsReleased
}
guard let object = objects.get(reference: self) as? T else {
throw PBXObjectError.objectNotFound(value)
}
_object = object
return object
}

}
}

extension Array where Element: PBXObject {
Expand All @@ -184,6 +176,6 @@ extension Array where Element: PBXObject {

extension Array where Element: PBXObjectReference {
func objects<T: PBXObject>() -> [T] {
compactMap { $0.getObject() }
compactMap { $0.object() }
}
}
22 changes: 11 additions & 11 deletions Sources/XcodeProj/Objects/Project/PBXProj.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public final class PBXProj: Decodable {
rootObjectReference = newValue?.reference
}
get {
rootObjectReference?.getObject()
rootObjectReference?.object()
}
}

Expand All @@ -47,7 +47,7 @@ public final class PBXProj: Decodable {
self.classes = classes
rootObjectReference = rootObject?.reference
self.objects = PBXObjects(objects: objects)
if let rootGroup = try? rootGroup() {
if let rootGroup = rootGroup() {
rootGroup.assignParentToChildren()
}
}
Expand Down Expand Up @@ -154,7 +154,7 @@ public final class PBXProj: Decodable {
}
self.objects = objects

try rootGroup()?.assignParentToChildren()
rootGroup()?.assignParentToChildren()
}

// MARK: Static Methods
Expand All @@ -169,7 +169,7 @@ public final class PBXProj: Decodable {

let plistDecoder = XcodeprojPropertyListDecoder(context: context)
let pbxproj: PBXProj = try plistDecoder.decode(PBXProj.self, from: pbxProjData)
try pbxproj.updateProjectName(path: path)
pbxproj.updateProjectName(path: path)
return pbxproj
}

Expand Down Expand Up @@ -228,14 +228,14 @@ public extension PBXProj {
var buildPhases: [PBXBuildPhase] { Array(objects.buildPhases.values) }

/// Returns root project.
func rootProject() throws -> PBXProject? {
try rootObjectReference?.getThrowingObject()
func rootProject() -> PBXProject? {
rootObjectReference?.object()
}

/// Returns root project's root group.
func rootGroup() throws -> PBXGroup? {
let project = try rootProject()
return try project?.mainGroupReference.getThrowingObject()
func rootGroup() -> PBXGroup? {
let project = rootProject()
return project?.mainGroupReference.object()
}

/// Adds a new object to the project.
Expand Down Expand Up @@ -298,12 +298,12 @@ extension PBXProj {
///
/// - Parameters:
/// - path: path to .xcodeproj directory.
func updateProjectName(path: Path) throws {
func updateProjectName(path: Path) {
guard path.parent().extension == "xcodeproj" else {
return
}
let projectName = path.parent().lastComponent.split(separator: ".").first
try rootProject()?.name = projectName.map(String.init) ?? ""
rootProject()?.name = projectName.map(String.init) ?? ""
}
}

Expand Down
26 changes: 13 additions & 13 deletions Sources/XcodeProj/Objects/Project/PBXProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public final class PBXProject: PBXObject {
buildConfigurationListReference = newValue.reference
}
get {
buildConfigurationListReference.getObject()
buildConfigurationListReference.object()
}
}

Expand All @@ -41,7 +41,7 @@ public final class PBXProject: PBXObject {
mainGroupReference = newValue.reference
}
get {
mainGroupReference.getObject()
mainGroupReference.object()
}
}

Expand All @@ -54,7 +54,7 @@ public final class PBXProject: PBXObject {
productsGroupReference = newValue?.reference
}
get {
productsGroupReference?.getObject()
productsGroupReference?.object()
}
}

Expand All @@ -77,7 +77,7 @@ public final class PBXProject: PBXObject {
}
get {
projectReferences.map { project in
project.mapValues { $0.getObject()! }
project.mapValues { $0.object()! }
}
}
}
Expand Down Expand Up @@ -117,7 +117,7 @@ public final class PBXProject: PBXObject {
} get {
var attributes: [PBXTarget: [String: Any]] = [:]
targetAttributeReferences.forEach {
if let object: PBXTarget = $0.key.getObject() {
if let object: PBXTarget = $0.key.object() {
attributes[object] = $0.value
}
}
Expand Down Expand Up @@ -156,7 +156,7 @@ public final class PBXProject: PBXObject {

private func setPackageReferences<T: PBXContainerItem>(_ packages: [T]) {
let newReferences = packages.references()
var finalReferences: [PBXObjectReference] = packageReferences?.filter { !($0.getObject() is T) } ?? []
var finalReferences: [PBXObjectReference] = packageReferences?.filter { !($0.object() is T) } ?? []
for reference in newReferences {
if !finalReferences.contains(reference) {
finalReferences.append(reference)
Expand Down Expand Up @@ -224,7 +224,7 @@ public final class PBXProject: PBXObject {
objects.add(object: buildFile)

// Link the product
guard let frameworksBuildPhase = try target.frameworksBuildPhase() else { throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName) }
guard let frameworksBuildPhase = target.frameworksBuildPhase() else { throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName) }
frameworksBuildPhase.files?.append(buildFile)

return reference
Expand Down Expand Up @@ -257,7 +257,7 @@ public final class PBXProject: PBXObject {
objects.add(object: buildFile)

// Link the product
guard let frameworksBuildPhase = try target.frameworksBuildPhase() else {
guard let frameworksBuildPhase = target.frameworksBuildPhase() else {
throw PBXProjError.frameworksBuildPhaseNotFound(targetName: targetName)
}

Expand Down Expand Up @@ -492,10 +492,10 @@ extension PBXProject: PlistSerializable {
dictionary["knownRegions"] = PlistValue.array(knownRegions
.map { .string(CommentedString("\($0)")) })
}
let mainGroupObject: PBXGroup? = mainGroupReference.getObject()
let mainGroupObject: PBXGroup? = mainGroupReference.object()
dictionary["mainGroup"] = .string(CommentedString(mainGroupReference.value, comment: mainGroupObject?.fileName()))
if let productsGroupReference = productsGroupReference {
let productRefGroupObject: PBXGroup? = productsGroupReference.getObject()
let productRefGroupObject: PBXGroup? = productsGroupReference.object()
dictionary["productRefGroup"] = .string(CommentedString(productsGroupReference.value,
comment: productRefGroupObject?.fileName()))
}
Expand All @@ -510,7 +510,7 @@ extension PBXProject: PlistSerializable {
}
dictionary["targets"] = PlistValue.array(targetReferences
.map { targetReference in
let target: PBXTarget? = targetReference.getObject()
let target: PBXTarget? = targetReference.object()
return .string(CommentedString(targetReference.value, comment: target?.name))
})

Expand Down Expand Up @@ -553,9 +553,9 @@ extension PBXProject: PlistSerializable {
let projectRef = reference[Xcode.ProjectReference.projectReferenceKey] else {
return nil
}
let producGroup: PBXGroup? = productGroupReference.getObject()
let producGroup: PBXGroup? = productGroupReference.object()
let groupName = producGroup?.fileName()
let project: PBXFileElement? = projectRef.getObject()
let project: PBXFileElement? = projectRef.object()
let fileRefName = project?.fileName()

return [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class XCSwiftPackageProductDependency: PBXContainerItem, PlistSerializabl
/// Package the product dependency refers to.
public var package: XCRemoteSwiftPackageReference? {
get {
packageReference?.getObject()
packageReference?.object()
}
set {
packageReference = newValue?.reference
Expand Down
Loading

0 comments on commit e2b09d3

Please sign in to comment.