Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TargetSwiftDebugSettings to PBXProj #2708

Merged
merged 3 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Foundation

public struct ReadTargetSwiftDebugSettingsFile {
private let callable: Callable

/// - Parameters:
/// - callable: The function that will be called in
/// `callAsFunction()`.
public init(callable: @escaping Callable = Self.defaultCallable) {
self.callable = callable
}

/// Reads the Swift debug settings for a specific target from a file.
public func callAsFunction(
from url: URL
) async throws -> TargetSwiftDebugSettings {
try await callable(/*url:*/ url)
}
}

// MARK: - ReadTargetSwiftDebugSettingsFile.Callable

extension ReadTargetSwiftDebugSettingsFile {
public typealias Callable =
(_ url: URL) async throws -> TargetSwiftDebugSettings

public static func defaultCallable(
url: URL
) async throws -> TargetSwiftDebugSettings {
return try await .decode(from: url)
}
}

56 changes: 56 additions & 0 deletions tools/generators/lib/PBXProj/src/TargetSwiftDebugSettings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Foundation
import ToolCommon

public struct TargetSwiftDebugSettings {
public let clangArgs: [String]
public let frameworkIncludes: [String]
public let swiftIncludes: [String]
}

extension TargetSwiftDebugSettings {
static func decode(from url: URL) async throws -> Self {
var iterator = url.lines.makeAsyncIterator()

let clangArgs = try await iterator.consumeArgs("clang args", in: url)
let frameworkIncludes =
try await iterator.consumeArgs("framework includes", in: url)
let swiftIncludes =
try await iterator.consumeArgs("swift includes", in: url)

return Self(
clangArgs: clangArgs,
frameworkIncludes: frameworkIncludes,
swiftIncludes: swiftIncludes
)
}
}

private extension AsyncLineSequence.AsyncIterator where Base == URL.AsyncBytes {
mutating func consumeArgs(
_ name: String,
in url: URL
) async throws -> [String] {
guard let rawCount = try await next() else {
throw PreconditionError(
message: url.prefixMessage("Missing \(name) count")
)
}
guard let count = Int(rawCount) else {
throw PreconditionError(message: url.prefixMessage("""
\(name) count "\(rawCount)" was not an integer
"""))
}

var args: [String] = []
for index in (0..<count) {
guard let arg = try await next()?.nullsToNewlines else {
throw PreconditionError(message: url.prefixMessage("""
Too few \(name). Found \(index), expected \(count)
"""))
}
args.append(arg)
}

return args
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import Foundation
import OrderedCollections

public struct WriteTargetSwiftDebugSettings {
private let callable: Callable

/// - Parameters:
/// - callable: The function that will be called in
/// `callAsFunction()`.
public init(callable: @escaping Callable = Self.defaultCallable) {
self.callable = callable
}

/// Writes the Swift debug settings for a certain target to disk.
public func callAsFunction(
clangArgs: [String],
frameworkIncludes: OrderedSet<String>,
swiftIncludes: OrderedSet<String>,
to url: URL
) throws {
try callable(
/*clangArgs:*/ clangArgs,
/*frameworkIncludes:*/ frameworkIncludes,
/*swiftIncludes:*/ swiftIncludes,
/*url:*/ url
)
}
}

// MARK: - WriteTargetSwiftDebugSettings.Callable

extension WriteTargetSwiftDebugSettings {
public typealias Callable = (
_ clangArgs: [String],
_ frameworkIncludes: OrderedSet<String>,
_ swiftIncludes: OrderedSet<String>,
_ url: URL
) throws -> Void

public static func defaultCallable(
clangArgs: [String],
frameworkIncludes: OrderedSet<String>,
swiftIncludes: OrderedSet<String>,
to url: URL
) throws {

var data = Data()

data.append(Data(String(clangArgs.count).utf8))
data.append(separator)
for arg in clangArgs {
data.append(Data(arg.utf8))
data.append(separator)
}

data.append(Data(String(frameworkIncludes.count).utf8))
data.append(separator)
for include in frameworkIncludes {
data.append(Data(include.utf8))
data.append(separator)
}

data.append(Data(String(swiftIncludes.count).utf8))
data.append(separator)
for include in swiftIncludes {
data.append(Data(include.utf8))
data.append(separator)
}

try data.write(to: url)
}
}

private let separator = Data([0x0a]) // Newline
Loading