Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Sources/SwiftDocC/Semantics/ReferenceResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ struct ReferenceResolver: SemanticVisitor {
deprecatedSummaryVariants: newDeprecatedSummaryVariants,
mixinsVariants: symbol.mixinsVariants,
declarationVariants: symbol.declarationVariants,
alternateDeclarationVariants: symbol.alternateDeclarationVariants,
defaultImplementationsVariants: symbol.defaultImplementationsVariants,
relationshipsVariants: symbol.relationshipsVariants,
abstractSectionVariants: newAbstractVariants,
Expand Down
42 changes: 38 additions & 4 deletions Sources/SwiftDocC/Semantics/Symbol/Symbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups
deprecatedSummaryVariants: DocumentationDataVariants<DeprecatedSection>,
mixinsVariants: DocumentationDataVariants<[String: Mixin]>,
declarationVariants: DocumentationDataVariants<[[PlatformName?]: SymbolGraph.Symbol.DeclarationFragments]> = .init(defaultVariantValue: [:]),
alternateDeclarationVariants: DocumentationDataVariants<[[PlatformName?]: [SymbolGraph.Symbol.DeclarationFragments]]> = .init(defaultVariantValue: [:]),
defaultImplementationsVariants: DocumentationDataVariants<DefaultImplementationsSection> = .init(defaultVariantValue: .init()),
relationshipsVariants: DocumentationDataVariants<RelationshipsSection> = .init(),
abstractSectionVariants: DocumentationDataVariants<AbstractSection>,
Expand Down Expand Up @@ -303,6 +304,7 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups

self.deprecatedSummaryVariants = deprecatedSummaryVariants
self.declarationVariants = declarationVariants
self.alternateDeclarationVariants = alternateDeclarationVariants

self.mixinsVariants = mixinsVariants

Expand All @@ -320,8 +322,10 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups
case let spi as SymbolGraph.Symbol.SPI:
self.isSPIVariants[trait] = spi.isSPI
case let alternateDeclarations as SymbolGraph.Symbol.AlternateDeclarations:
self.alternateDeclarationVariants[trait] = [[platformNameVariants[trait]]: alternateDeclarations.declarations]

// If alternate declarations weren't set explicitly use the ones from the mixins.
if !self.alternateDeclarationVariants.hasVariant(for: trait) {
self.alternateDeclarationVariants[trait] = [[platformNameVariants[trait]]: alternateDeclarations.declarations]
}
case let attribute as SymbolGraph.Symbol.Minimum:
attributes[.minimum] = attribute.value
case let attribute as SymbolGraph.Symbol.Maximum:
Expand Down Expand Up @@ -443,7 +447,7 @@ extension Symbol {
/// When building multi-platform documentation symbols might have more than one declaration
/// depending on variances in their implementation across platforms (e.g. use `NSPoint` vs `CGPoint` parameter in a method).
/// This method finds matching symbols between graphs and merges their declarations in case there are differences.
func mergeDeclaration(mergingDeclaration: SymbolGraph.Symbol.DeclarationFragments, identifier: String, symbolAvailability: SymbolGraph.Symbol.Availability?, selector: UnifiedSymbolGraph.Selector) throws {
func mergeDeclaration(mergingDeclaration: SymbolGraph.Symbol.DeclarationFragments, identifier: String, symbolAvailability: SymbolGraph.Symbol.Availability?, alternateDeclarations: SymbolGraph.Symbol.AlternateDeclarations?, selector: UnifiedSymbolGraph.Selector) throws {
let trait = DocumentationDataVariantsTrait(for: selector)
let platformName = selector.platform

Expand Down Expand Up @@ -472,6 +476,35 @@ extension Symbol {
declarationVariants[trait]?[[nil]] = mergingDeclaration
}
}

if let alternateDeclarations {
let mergingAlternateDeclarations = alternateDeclarations.declarations
if let platformName,
let existingKey = alternateDeclarationVariants[trait]?.first(
where: { pair in
return pair.value.map { $0.declarationFragments } == mergingAlternateDeclarations.map { $0.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 = alternateDeclarationVariants[trait]?.removeValue(forKey: existingKey)!
alternateDeclarationVariants[trait]?[existingKey + [platform]] = currentDeclaration
}
} else {
// Add new declaration
if let name = platformName {
alternateDeclarationVariants[trait]?[[PlatformName.init(operatingSystemName: name)]] = mergingAlternateDeclarations
} else {
alternateDeclarationVariants[trait]?[[nil]] = mergingAlternateDeclarations
}
}
}

// Merge the new symbol with the existing availability. If a value already exist, only override if it's for this platform.
if let symbolAvailability,
Expand Down Expand Up @@ -503,8 +536,9 @@ extension Symbol {
for (selector, mixins) in unifiedSymbol.mixins {
if let mergingDeclaration = mixins[SymbolGraph.Symbol.DeclarationFragments.mixinKey] as? SymbolGraph.Symbol.DeclarationFragments {
let availability = mixins[SymbolGraph.Symbol.Availability.mixinKey] as? SymbolGraph.Symbol.Availability
let alternateDeclarations = mixins[SymbolGraph.Symbol.AlternateDeclarations.mixinKey] as? SymbolGraph.Symbol.AlternateDeclarations

try mergeDeclaration(mergingDeclaration: mergingDeclaration, identifier: unifiedSymbol.uniqueIdentifier, symbolAvailability: availability, selector: selector)
try mergeDeclaration(mergingDeclaration: mergingDeclaration, identifier: unifiedSymbol.uniqueIdentifier, symbolAvailability: availability, alternateDeclarations: alternateDeclarations, selector: selector)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,6 @@ class DeclarationsRenderSectionTests: XCTestCase {
let declarationsSection = try XCTUnwrap(renderNode.primaryContentSections.compactMap({ $0 as? DeclarationsRenderSection }).first)

XCTAssertEqual(declarationsSection.declarations.count, 2)
XCTAssert(declarationsSection.declarations.allSatisfy({ $0.platforms == [.macOS] }))
XCTAssert(declarationsSection.declarations.allSatisfy({ $0.platforms == [.iOS, .macOS] }))
}
}
Loading