Skip to content

Commit 1ad9b6a

Browse files
Fix availability logic refactor (#1065)
Refactor symbol availability logic. This refactor was initiated by the need of stop using the module operating system name as an availability item. This change required a big refactoring of the logic, and now the symbol graph availability loading logic is like the following: 1. Every symbol graph is loaded and the symbols get only the availability information that's marked in the SDK. 2. Once all the SGFs are oaded, whe iterate over the symbols and we add the fallbkac and default availability if applies. * Refactor unit tests for testing symbol availability. * Refactor fallback platforms data structure. Instead of making a `[(FallbackPlatform, InheritedPlaform)]. The new struture to hold this information is in the way of `[InheritedPlatfor:[FallbackPlatforms]]`.
1 parent fe74f56 commit 1ad9b6a

File tree

9 files changed

+759
-639
lines changed

9 files changed

+759
-639
lines changed

Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphLoader.swift

Lines changed: 124 additions & 156 deletions
Large diffs are not rendered by default.

Sources/SwiftDocC/Infrastructure/Workspace/DefaultAvailability.swift

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2025 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -131,28 +131,30 @@ public struct DefaultAvailability: Codable, Equatable {
131131

132132
/// Fallback availability information for platforms we either don't emit SGFs for
133133
/// or have the same availability information as another platform.
134-
package static let fallbackPlatforms: [PlatformName: PlatformName] = [
135-
.catalyst: .iOS,
136-
.iPadOS: .iOS,
137-
]
134+
///
135+
/// The key corresponds to the fallback platform and the value to the platform it's
136+
/// fallbacking from.
137+
package static let fallbackPlatforms: [PlatformName: [PlatformName]] = [.iOS: [.catalyst, .iPadOS]]
138138

139139
/// Creates a default availability module.
140140
/// - Parameter modules: A map of modules and the default platform availability for symbols in that module.
141141
public init(with modules: [String: [ModuleAvailability]]) {
142142
self.modules = modules.mapValues { platformAvailabilities -> [DefaultAvailability.ModuleAvailability] in
143143
// If a module doesn't contain default availability information for any of the fallback platforms,
144144
// infer it from the corresponding mapped value.
145-
platformAvailabilities + DefaultAvailability.fallbackPlatforms.compactMap { (platform, fallbackPlatform) in
146-
if !platformAvailabilities.contains(where: { $0.platformName == platform }),
147-
let fallbackAvailability = platformAvailabilities.first(where: { $0.platformName == fallbackPlatform }),
148-
let fallbackIntroducedVersion = fallbackAvailability.introducedVersion
149-
{
150-
return DefaultAvailability.ModuleAvailability(
151-
platformName: platform,
152-
platformVersion: fallbackIntroducedVersion
153-
)
145+
platformAvailabilities + DefaultAvailability.fallbackPlatforms.flatMap { (fallbackPlatform, platform) in
146+
platform.compactMap { platformName in
147+
if !platformAvailabilities.contains(where: { $0.platformName == platformName }),
148+
let fallbackAvailability = platformAvailabilities.first(where: { $0.platformName == fallbackPlatform }),
149+
let fallbackIntroducedVersion = fallbackAvailability.introducedVersion
150+
{
151+
return DefaultAvailability.ModuleAvailability(
152+
platformName: platformName,
153+
platformVersion: fallbackIntroducedVersion
154+
)
155+
}
156+
return nil
154157
}
155-
return nil
156158
}
157159
}
158160
}

Sources/SwiftDocC/Semantics/Symbol/Symbol.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2025 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -591,10 +591,12 @@ extension Symbol {
591591
func mergeAvailabilities(unifiedSymbol: UnifiedSymbolGraph.Symbol) {
592592
for (selector, mixins) in unifiedSymbol.mixins {
593593
let trait = DocumentationDataVariantsTrait(for: selector)
594-
if let unifiedSymbolAvailability = mixins[SymbolGraph.Symbol.Availability.mixinKey] as? SymbolGraph.Symbol.Availability {
594+
guard let availabilityVariantTrait = availabilityVariants[trait] else {
595+
return
596+
}
597+
if let unifiedSymbolAvailability = mixins.getValueIfPresent(for: SymbolGraph.Symbol.Availability.self) {
595598
unifiedSymbolAvailability.availability.forEach { availabilityItem in
596-
guard let availabilityVariantTrait = availabilityVariants[trait] else { return }
597-
if (availabilityVariantTrait.availability.contains(where: { $0.domain?.rawValue == availabilityItem.domain?.rawValue })) {
599+
guard availabilityVariantTrait.availability.firstIndex(where: { $0.domain?.rawValue == availabilityItem.domain?.rawValue }) == nil else {
598600
return
599601
}
600602
availabilityVariants[trait]?.availability.append(availabilityItem)

Sources/SwiftDocCTestUtilities/FilesAndFolders.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public struct InfoPlist: File, DataRepresentable {
112112
self.identifier = identifier
113113
self.defaultAvailability = defaultAvailability
114114
}
115-
115+
116116
public init(from decoder: any Decoder) throws {
117117
let container = try decoder.container(keyedBy: DocumentationBundle.Info.CodingKeys.self)
118118
displayName = try container.decodeIfPresent(String.self, forKey: .displayName)

Sources/SwiftDocCUtilities/Action/Actions/Convert/ConvertAction.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2025 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -145,8 +145,10 @@ public struct ConvertAction: AsyncAction {
145145
// Inject current platform versions if provided
146146
if var currentPlatforms {
147147
// Add missing platforms if their fallback platform is present.
148-
for (platform, fallbackPlatform) in DefaultAvailability.fallbackPlatforms where currentPlatforms[platform.displayName] == nil {
149-
currentPlatforms[platform.displayName] = currentPlatforms[fallbackPlatform.displayName]
148+
for (fallbackPlatform, platforms) in DefaultAvailability.fallbackPlatforms {
149+
for platform in platforms where currentPlatforms[platform.displayName] == nil {
150+
currentPlatforms[platform.displayName] = currentPlatforms[fallbackPlatform.displayName]
151+
}
150152
}
151153
configuration.externalMetadata.currentPlatforms = currentPlatforms
152154
}

0 commit comments

Comments
 (0)