From eba20e759d599d1c5cd1674add5db4a3adbfce97 Mon Sep 17 00:00:00 2001 From: Andrea Fernandez Buitrago <15234535+anferbui@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:08:00 +0100 Subject: [PATCH 1/2] Adds a shared utility for determining beta status Adds an extension to `Array` which defines a property `isBeta` with the same logic currently defined in 3 separate locations: - `NavigatorIndexableRenderMetadataRepresentation` [1] - `OutOfProcessReferenceResolver.ResolvedInformation` [2] - `LinkDestinationSummary` [3] This will eliminate the possibility that these 3 implementations will inadvertently become out of sync with each other. The logic remains that an item is in beta if all platforms are marked as beta. There is still at least one more place in the code-base which determines beta status [4], but that remains hard to merge at the moment. [1]: https://github.com/swiftlang/swift-docc/blob/1c54e106f5c9a92a69225492b1a89c934677ae58/Sources/SwiftDocC/Indexing/Navigator/RenderNode%2BNavigatorIndex.swift#L126-L134 [2]: https://github.com/swiftlang/swift-docc/blob/1c54e106f5c9a92a69225492b1a89c934677ae58/Sources/SwiftDocC/Infrastructure/External%20Data/OutOfProcessReferenceResolver.swift#L592-L598 [3]: https://github.com/swiftlang/swift-docc/blob/1c54e106f5c9a92a69225492b1a89c934677ae58/Sources/SwiftDocC/Infrastructure/Link%20Resolution/ExternalPathHierarchyResolver.swift#L186-L192 [4]: https://github.com/swiftlang/swift-docc/blob/1c54e106f5c9a92a69225492b1a89c934677ae58/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift#L210 --- .../AvailabilityRenderMetadataItem.swift | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift b/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift index 8d8a137fa..a185ff8a3 100644 --- a/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift +++ b/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021-2023 Apple Inc. and the Swift project authors + Copyright (c) 2021-2025 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -163,3 +163,27 @@ public struct AvailabilityRenderItem: Codable, Hashable, Equatable { self.isBeta = isBeta } } + +extension Array where Array.Element == AvailabilityRenderItem { + /// Determines whether all platforms in the array are in beta. + /// + /// This property returns `true` if every availability item in the array has its `isBeta` property set to `true`, + /// indicating that the symbol is introduced in a beta version across all platforms. If the array is empty, + /// this property returns `false`, as an item with no platform availability information is not considered + /// to be in beta. + /// + /// This computed property centralizes the beta determination logic to avoid code duplication across multiple + /// components that need to check whether a symbol is in beta based on its platform availability. + /// `NavigatorIndexableRenderMetadataRepresentation`, `OutOfProcessReferenceResolver.ResolvedInformation` and `LinkDestinationSummary` all store an array of ``AvailabilityRenderItem`` and need to determine beta status based on platform availability, + /// so it is convenient to de-duplicate the shared logic here. + /// + /// - Returns: `true` if all platforms in the array are in beta; `false` if the array is empty or if any + /// platform is not in beta. + var isBeta: Bool { + guard !self.isEmpty else { + return false + } + + return self.allSatisfy { $0.isBeta == true } + } +} From da305b3e3064413573c1d01b695cf217f2b8523e Mon Sep 17 00:00:00 2001 From: Andrea Fernandez Buitrago <15234535+anferbui@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:08:55 +0100 Subject: [PATCH 2/2] Remove duplicate isBeta implementations Removes the duplicate implementations and delegates to the `Array` extension instead. --- .../Indexing/Navigator/RenderNode+NavigatorIndex.swift | 6 +----- .../External Data/OutOfProcessReferenceResolver.swift | 6 +----- .../Link Resolution/ExternalPathHierarchyResolver.swift | 8 ++------ 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Sources/SwiftDocC/Indexing/Navigator/RenderNode+NavigatorIndex.swift b/Sources/SwiftDocC/Indexing/Navigator/RenderNode+NavigatorIndex.swift index 21fc7aa5f..a7d918453 100644 --- a/Sources/SwiftDocC/Indexing/Navigator/RenderNode+NavigatorIndex.swift +++ b/Sources/SwiftDocC/Indexing/Navigator/RenderNode+NavigatorIndex.swift @@ -125,11 +125,7 @@ struct RenderNodeVariantView: NavigatorIndexableRenderNodeRepresentation { extension NavigatorIndexableRenderMetadataRepresentation { var isBeta: Bool { - guard let platforms, !platforms.isEmpty else { - return false - } - - return platforms.allSatisfy { $0.isBeta == true } + return platforms?.isBeta ?? false } } diff --git a/Sources/SwiftDocC/Infrastructure/External Data/OutOfProcessReferenceResolver.swift b/Sources/SwiftDocC/Infrastructure/External Data/OutOfProcessReferenceResolver.swift index e4a737fa7..88c381615 100644 --- a/Sources/SwiftDocC/Infrastructure/External Data/OutOfProcessReferenceResolver.swift +++ b/Sources/SwiftDocC/Infrastructure/External Data/OutOfProcessReferenceResolver.swift @@ -590,11 +590,7 @@ extension OutOfProcessReferenceResolver { /// A value that indicates whether this symbol is under development and likely to change. var isBeta: Bool { - guard let platforms, !platforms.isEmpty else { - return false - } - - return platforms.allSatisfy { $0.isBeta == true } + return platforms?.isBeta ?? false } /// Creates a new resolved information value with all its values. diff --git a/Sources/SwiftDocC/Infrastructure/Link Resolution/ExternalPathHierarchyResolver.swift b/Sources/SwiftDocC/Infrastructure/Link Resolution/ExternalPathHierarchyResolver.swift index 0d145a597..f4db774fb 100644 --- a/Sources/SwiftDocC/Infrastructure/Link Resolution/ExternalPathHierarchyResolver.swift +++ b/Sources/SwiftDocC/Infrastructure/Link Resolution/ExternalPathHierarchyResolver.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2023-2024 Apple Inc. and the Swift project authors + Copyright (c) 2023-2025 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -184,11 +184,7 @@ private extension Sequence { private extension LinkDestinationSummary { /// A value that indicates whether this symbol is under development and likely to change. var isBeta: Bool { - guard let platforms, !platforms.isEmpty else { - return false - } - - return platforms.allSatisfy { $0.isBeta == true } + return platforms?.isBeta ?? false } /// Create a topic render render reference for this link summary and its content variants.