in Sources/SwiftDocC/Semantics/Symbol/Symbol.swift [308:362]
func mergeDeclaration(mergingDeclaration: SymbolGraph.Symbol.DeclarationFragments, identifier: String, symbolAvailability: SymbolGraph.Symbol.Availability?, selector: UnifiedSymbolGraph.Selector) throws {
let trait = DocumentationDataVariantsTrait(interfaceLanguage: selector.interfaceLanguage)
let platformName = selector.platform
if let platformName = platformName,
let existingKey = declarationVariants[trait]?.first(
where: { pair in
return pair.value.declarationFragments == mergingDeclaration.declarationFragments
}
)?.key
{
guard !existingKey.contains(nil) else {
throw DocumentationContext.ContextError.unexpectedEmptyPlatformName(identifier)
}
let platform = PlatformName(operatingSystemName: platformName)
if !existingKey.contains(platform) {
// Matches one of the existing declarations, append to the existing key.
let currentDeclaration = declarationVariants[trait]?.removeValue(forKey: existingKey)!
declarationVariants[trait]?[existingKey + [platform]] = currentDeclaration
}
} else {
// Add new declaration
if let name = platformName {
declarationVariants[trait]?[[PlatformName.init(operatingSystemName: name)]] = mergingDeclaration
} else {
declarationVariants[trait]?[[nil]] = mergingDeclaration
}
}
// Merge the new symbol with the existing availability. If a value already exist, only override if it's for this platform.
if let symbolAvailability = symbolAvailability,
symbolAvailability.availability.isEmpty == false || availabilityVariants[trait]?.availability.isEmpty == false // Nothing to merge if both are empty
{
var items = availabilityVariants[trait]?.availability ?? []
// Add all the domains that don't already have availability information
for availability in symbolAvailability.availability {
guard !items.contains(where: { $0.domain?.rawValue == availability.domain?.rawValue }) else { continue }
items.append(availability)
}
// Override the availability for all domains that apply to this platform
if let modulePlatformName = platformName.map(PlatformName.init) {
let symbolAvailabilityForPlatform = symbolAvailability.filterItems(thatApplyTo: modulePlatformName)
for availability in symbolAvailabilityForPlatform.availability {
items.removeAll(where: { $0.domain?.rawValue == availability.domain?.rawValue })
items.append(availability)
}
}
availabilityVariants[trait] = SymbolGraph.Symbol.Availability(availability: items)
}
}