From 2e584cae31e1080dcd98f2ee81f4c4cff275c12a Mon Sep 17 00:00:00 2001 From: yonihemi Date: Sun, 25 Feb 2024 15:22:40 +0800 Subject: [PATCH 1/2] Add visionOS support --- Package.resolved | 4 ++-- Package.swift | 2 +- Sources/SwiftDocC/Benchmark/Benchmark.swift | 2 ++ Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift | 2 +- .../Infrastructure/Symbol Graph/SymbolGraphLoader.swift | 2 +- Sources/SwiftDocC/Model/Rendering/RenderContext.swift | 2 +- .../SwiftDocC/Utility/Collection+ConcurrentPerform.swift | 2 +- Sources/SwiftDocC/Utility/LMDB/LMDB.swift | 2 +- Sources/SwiftDocC/Utility/Synchronization.swift | 8 ++++---- .../SymbolGraph/SymbolGraphLoaderTests.swift | 4 ++-- .../Utility/Collection+ConcurrentPerformTests.swift | 4 ++-- Tests/SwiftDocCTests/Utility/SynchronizationTests.swift | 4 ++-- 12 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Package.resolved b/Package.resolved index 9eeb30ab10..4be7c6efff 100644 --- a/Package.resolved +++ b/Package.resolved @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-crypto.git", "state" : { - "revision" : "33a20e650c33f6d72d822d558333f2085effa3dc", - "version" : "2.5.0" + "revision" : "60f13f60c4d093691934dc6cfdf5f508ada1f894", + "version" : "2.6.0" } }, { diff --git a/Package.swift b/Package.swift index 4ebb7f94ba..4f167b289a 100644 --- a/Package.swift +++ b/Package.swift @@ -138,7 +138,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { .package(url: "https://github.com/apple/swift-lmdb.git", branch: "main"), .package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.2"), .package(url: "https://github.com/apple/swift-docc-symbolkit", branch: "main"), - .package(url: "https://github.com/apple/swift-crypto.git", from: "2.5.0"), + .package(url: "https://github.com/apple/swift-crypto.git", from: "2.6.0"), .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.2.0"), ] } else { diff --git a/Sources/SwiftDocC/Benchmark/Benchmark.swift b/Sources/SwiftDocC/Benchmark/Benchmark.swift index 665733ddd4..beb166d9c0 100644 --- a/Sources/SwiftDocC/Benchmark/Benchmark.swift +++ b/Sources/SwiftDocC/Benchmark/Benchmark.swift @@ -42,6 +42,8 @@ public class Benchmark: Encodable { public let platform = "macOS" #elseif os(iOS) public let platform = "iOS" + #elseif os(visionOS) + public let platform = "visionOS" #elseif os(Linux) public let platform = "Linux" #elseif os(Android) diff --git a/Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift b/Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift index b434196fe4..0ddc0b9513 100644 --- a/Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift +++ b/Sources/SwiftDocC/Benchmark/Metrics/PeakMemory.swift @@ -26,7 +26,7 @@ extension Benchmark { memoryPeak = Self.peakMemory() } - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) private static func peakMemory() -> Int64? { // On macOS we use the Kernel framework to read a pretty accurate // memory footprint for the current task. The value reported here diff --git a/Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphLoader.swift b/Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphLoader.swift index 29ce84319f..d423d72ac9 100644 --- a/Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphLoader.swift +++ b/Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphLoader.swift @@ -109,7 +109,7 @@ struct SymbolGraphLoader { // load and decode each one on a separate thread. // This strategy benchmarks better when we have multiple // "larger" symbol graphs. - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) if bundle.symbolGraphURLs.filter({ !$0.lastPathComponent.contains("@") }).count > 1 { // There are multiple main symbol graphs, better parallelize all files decoding. decodingStrategy = .concurrentlyAllFiles diff --git a/Sources/SwiftDocC/Model/Rendering/RenderContext.swift b/Sources/SwiftDocC/Model/Rendering/RenderContext.swift index d7d957339f..1e5a4ff607 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderContext.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderContext.swift @@ -61,7 +61,7 @@ public struct RenderContext { ) } - #if os(macOS) || os(iOS) || os(Android) || os(Windows) + #if os(macOS) || os(iOS) || os(visionOS) || os(Android) || os(Windows) // Concurrently render content on macOS/iOS, Windows & Android let results: [(reference: ResolvedTopicReference, content: RenderReferenceStore.TopicContent)] = references.concurrentPerform { reference, results in results.append((reference, renderContentFor(reference))) diff --git a/Sources/SwiftDocC/Utility/Collection+ConcurrentPerform.swift b/Sources/SwiftDocC/Utility/Collection+ConcurrentPerform.swift index 7b952315e6..e14556ff3a 100644 --- a/Sources/SwiftDocC/Utility/Collection+ConcurrentPerform.swift +++ b/Sources/SwiftDocC/Utility/Collection+ConcurrentPerform.swift @@ -14,7 +14,7 @@ import Foundation // concurrency in the Collection extensions in this file and have tests expect // them to work serially on Linux. rdar://75794062 -#if os(macOS) || os(iOS) +#if os(macOS) || os(iOS) || os(visionOS) private let useConcurrentCollectionExtensions = true #else private let useConcurrentCollectionExtensions = false diff --git a/Sources/SwiftDocC/Utility/LMDB/LMDB.swift b/Sources/SwiftDocC/Utility/LMDB/LMDB.swift index ee7f6a4473..1200db9151 100644 --- a/Sources/SwiftDocC/Utility/LMDB/LMDB.swift +++ b/Sources/SwiftDocC/Utility/LMDB/LMDB.swift @@ -101,7 +101,7 @@ extension String: LMDBData { // This is required for macOS, for Linux the default implementation works as expected. extension Array: LMDBData where Element: FixedWidthInteger { -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) +#if os(macOS) || os(iOS) || os(visionOS) || os(tvOS) || os(watchOS) public init?(data: UnsafeRawBufferPointer) { var array = Array(repeating: 0, count: data.count / MemoryLayout.stride) _ = array.withUnsafeMutableBytes { data.copyBytes(to: $0) } diff --git a/Sources/SwiftDocC/Utility/Synchronization.swift b/Sources/SwiftDocC/Utility/Synchronization.swift index d4e4e2ad01..169696117a 100644 --- a/Sources/SwiftDocC/Utility/Synchronization.swift +++ b/Sources/SwiftDocC/Utility/Synchronization.swift @@ -28,7 +28,7 @@ public class Synchronized { /// A value that requires synchronized access. private var value: Value - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) /// A lock type appropriate for the current platform. /// > Note: To avoid access race reports we manage the memory manually. var lock: UnsafeMutablePointer @@ -46,7 +46,7 @@ public class Synchronized { public init(_ value: Value) { self.value = value - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) lock = UnsafeMutablePointer.allocate(capacity: 1) lock.initialize(to: os_unfair_lock()) #elseif os(Linux) || os(Android) @@ -71,7 +71,7 @@ public class Synchronized { /// - Returns: Returns the returned value of `block`, if any. @discardableResult public func sync(_ block: (inout Value) throws -> Result) rethrows -> Result { - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) os_unfair_lock_lock(lock) defer { os_unfair_lock_unlock(lock) } #elseif os(Linux) || os(Android) @@ -107,7 +107,7 @@ public extension Lock { @discardableResult func sync(_ block: () throws -> Result) rethrows -> Result { - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) os_unfair_lock_lock(lock) defer { os_unfair_lock_unlock(lock) } #elseif os(Linux) || os(Android) diff --git a/Tests/SwiftDocCTests/Infrastructure/SymbolGraph/SymbolGraphLoaderTests.swift b/Tests/SwiftDocCTests/Infrastructure/SymbolGraph/SymbolGraphLoaderTests.swift index d8f5b171bb..84f7b26bbc 100644 --- a/Tests/SwiftDocCTests/Infrastructure/SymbolGraph/SymbolGraphLoaderTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/SymbolGraph/SymbolGraphLoaderTests.swift @@ -281,7 +281,7 @@ class SymbolGraphLoaderTests: XCTestCase { var loader = try makeSymbolGraphLoader(symbolGraphURLs: [symbolGraphURL, extraSymbolGraphFile]) try loader.loadAll() - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) XCTAssertEqual(loader.decodingStrategy, .concurrentlyAllFiles) #else XCTAssertEqual(loader.decodingStrategy, .concurrentlyEachFileInBatches) @@ -323,7 +323,7 @@ class SymbolGraphLoaderTests: XCTestCase { var loader = try makeSymbolGraphLoader(symbolGraphURLs: symbolGraphURLs) try loader.loadAll() - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) XCTAssertEqual(loader.decodingStrategy, .concurrentlyAllFiles) #else XCTAssertEqual(loader.decodingStrategy, .concurrentlyEachFileInBatches) diff --git a/Tests/SwiftDocCTests/Utility/Collection+ConcurrentPerformTests.swift b/Tests/SwiftDocCTests/Utility/Collection+ConcurrentPerformTests.swift index 7d47d3b788..2a0bafaa06 100644 --- a/Tests/SwiftDocCTests/Utility/Collection+ConcurrentPerformTests.swift +++ b/Tests/SwiftDocCTests/Utility/Collection+ConcurrentPerformTests.swift @@ -76,7 +76,7 @@ class CollectionConcurrentPerformTests: XCTestCase { return next.start < result.end }) - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) // Expect all blocks ran concurrently on supported platforms. XCTAssertTrue(didBlocksExecuteConcurrently, "Blocks didn't run concurrently") #else @@ -122,7 +122,7 @@ class CollectionConcurrentPerformTests: XCTestCase { return next.start < result.end }) - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) // Expect all blocks ran concurrently on supported platforms. XCTAssertTrue(didBlocksExecuteConcurrently, "Blocks didn't run concurrently") #else diff --git a/Tests/SwiftDocCTests/Utility/SynchronizationTests.swift b/Tests/SwiftDocCTests/Utility/SynchronizationTests.swift index eff24f6533..8871bbb1e3 100644 --- a/Tests/SwiftDocCTests/Utility/SynchronizationTests.swift +++ b/Tests/SwiftDocCTests/Utility/SynchronizationTests.swift @@ -15,7 +15,7 @@ import func WinSDK.TryAcquireSRWLockExclusive #endif private func XCTAssertLockIsUnlocked(_ synced: Synchronized) { - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) XCTAssertTrue(os_unfair_lock_trylock(synced.lock)) #elseif os(Windows) XCTAssertNotEqual(TryAcquireSRWLockExclusive(synced.lock), 0) @@ -25,7 +25,7 @@ private func XCTAssertLockIsUnlocked(_ synced: Synchronized) { } private func XCTAssertLockIsLocked(_ synced: Synchronized) { - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) XCTAssertFalse(os_unfair_lock_trylock(synced.lock)) #elseif os(Windows) XCTAssertEqual(TryAcquireSRWLockExclusive(synced.lock), 0) From b1060653804abb917064f8dad7ebf02132aeabf5 Mon Sep 17 00:00:00 2001 From: yonihemi Date: Sun, 25 Feb 2024 15:39:58 +0800 Subject: [PATCH 2/2] Use MeasurementFormatter in visionOS benchmarks --- bin/benchmark/Sources/benchmark/Diff/DiffAnalysis.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/benchmark/Sources/benchmark/Diff/DiffAnalysis.swift b/bin/benchmark/Sources/benchmark/Diff/DiffAnalysis.swift index 1d3d665c4d..6b1dbcce9d 100644 --- a/bin/benchmark/Sources/benchmark/Diff/DiffAnalysis.swift +++ b/bin/benchmark/Sources/benchmark/Diff/DiffAnalysis.swift @@ -169,7 +169,7 @@ extension BenchmarkResultSeries.MetricSeries.ValueSeries { case .duration(let value): let average = value.mean() - #if os(macOS) || os(iOS) + #if os(macOS) || os(iOS) || os(visionOS) return durationFormatter.string(from: Measurement(value: average, unit: UnitDuration.seconds)) #else return durationFormatter.string(from: NSNumber(value: average))! + " sec" @@ -189,7 +189,7 @@ extension BenchmarkResultSeries.MetricSeries.ValueSeries { } } -#if os(macOS) || os(iOS) +#if os(macOS) || os(iOS) || os(visionOS) private let durationFormatter: MeasurementFormatter = { let fmt = MeasurementFormatter() fmt.unitStyle = .medium