diff --git a/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift b/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift index 20cce55ce5..d616de1bb3 100644 --- a/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift +++ b/Sources/SwiftDocC/Infrastructure/DocumentationContext.swift @@ -1617,17 +1617,15 @@ public class DocumentationContext { } } - let trait = DocumentationDataVariantsTrait(for: selector) - // Merge in all the dictionary keys for each target into their section variants. keysByTarget.forEach { targetIdentifier, keys in let target = documentationCache[targetIdentifier] if let semantic = target?.semantic as? Symbol { - let keys = keys.sorted { $0.name < $1.name } - if semantic.dictionaryKeysSectionVariants[trait] == nil { - semantic.dictionaryKeysSectionVariants[trait] = DictionaryKeysSection(dictionaryKeys: keys) + let keys = keys.sorted(by: \.name) + if semantic.dictionaryKeysSection == nil { + semantic.dictionaryKeysSection = DictionaryKeysSection(dictionaryKeys: keys) } else { - semantic.dictionaryKeysSectionVariants[trait]?.mergeDictionaryKeys(keys) + semantic.dictionaryKeysSection?.mergeDictionaryKeys(keys) } } } @@ -1636,11 +1634,11 @@ public class DocumentationContext { parametersByTarget.forEach { targetIdentifier, parameters in let target = documentationCache[targetIdentifier] if let semantic = target?.semantic as? Symbol { - let parameters = parameters.sorted { $0.name < $1.name } - if semantic.httpParametersSectionVariants[trait] == nil { - semantic.httpParametersSectionVariants[trait] = HTTPParametersSection(parameters: parameters) + let parameters = parameters.sorted(by: \.name) + if semantic.httpParametersSection == nil { + semantic.httpParametersSection = HTTPParametersSection(parameters: parameters) } else { - semantic.httpParametersSectionVariants[trait]?.mergeParameters(parameters) + semantic.httpParametersSection?.mergeParameters(parameters) } } } @@ -1652,12 +1650,12 @@ public class DocumentationContext { // Add any body parameters to existing body record var localBody = body if let identifier = body.symbol?.preciseIdentifier, let bodyParameters = bodyParametersByTarget[identifier] { - localBody.parameters = bodyParameters.sorted { $0.name < $1.name } + localBody.parameters = bodyParameters.sorted(by: \.name) } - if semantic.httpBodySectionVariants[trait] == nil { - semantic.httpBodySectionVariants[trait] = HTTPBodySection(body: localBody) + if semantic.httpBodySection == nil { + semantic.httpBodySection = HTTPBodySection(body: localBody) } else { - semantic.httpBodySectionVariants[trait]?.mergeBody(localBody) + semantic.httpBodySection?.mergeBody(localBody) } } } @@ -1666,11 +1664,11 @@ public class DocumentationContext { responsesByTarget.forEach { targetIdentifier, responses in let target = documentationCache[targetIdentifier] if let semantic = target?.semantic as? Symbol { - let responses = responses.sorted { $0.statusCode < $1.statusCode } - if semantic.httpResponsesSectionVariants[trait] == nil { - semantic.httpResponsesSectionVariants[trait] = HTTPResponsesSection(responses: responses) + let responses = responses.sorted(by: \.statusCode) + if semantic.httpResponsesSection == nil { + semantic.httpResponsesSection = HTTPResponsesSection(responses: responses) } else { - semantic.httpResponsesSectionVariants[trait]?.mergeResponses(responses) + semantic.httpResponsesSection?.mergeResponses(responses) } } } diff --git a/Sources/SwiftDocC/Model/DocumentationNode.swift b/Sources/SwiftDocC/Model/DocumentationNode.swift index 5d865b9f9c..c0e5b14efa 100644 --- a/Sources/SwiftDocC/Model/DocumentationNode.swift +++ b/Sources/SwiftDocC/Model/DocumentationNode.swift @@ -229,14 +229,8 @@ public struct DocumentationNode { ?? .init(availability: []) } - let endpointVariants = DocumentationDataVariants( - symbolData: unifiedSymbol.mixins, - platformName: platformName - ) { mixins -> HTTPEndpointSection? in - if let endpoint = mixins[SymbolGraph.Symbol.HTTP.Endpoint.mixinKey] as? SymbolGraph.Symbol.HTTP.Endpoint { - return HTTPEndpointSection(endpoint: endpoint) - } - return nil + let endpointSection = unifiedSymbol.defaultSymbol?[mixin: SymbolGraph.Symbol.HTTP.Endpoint.self].map { endpoint in + HTTPEndpointSection(endpoint: endpoint) } let overloadVariants = DocumentationDataVariants( @@ -314,13 +308,13 @@ public struct DocumentationNode { seeAlsoVariants: .empty, returnsSectionVariants: .empty, parametersSectionVariants: .empty, - dictionaryKeysSectionVariants: .empty, - possibleValuesSectionVariants: .empty, - httpEndpointSectionVariants: endpointVariants, - httpBodySectionVariants: .empty, - httpParametersSectionVariants: .empty, - httpResponsesSectionVariants: .empty, - redirectsVariants: .empty, + dictionaryKeysSection: nil, + possibleValuesSection: nil, + httpEndpointSection: endpointSection, + httpBodySection: nil, + httpParametersSection: nil, + httpResponsesSection: nil, + redirects: nil, crossImportOverlayModule: moduleData.bystanders.map({ (moduleData.name, $0) }), overloadsVariants: overloadVariants ) @@ -399,9 +393,7 @@ public struct DocumentationNode { semantic.deprecatedSummaryVariants = DocumentationDataVariants( defaultVariantValue: deprecated ) - semantic.redirectsVariants = DocumentationDataVariants( - defaultVariantValue: documentationExtension?.redirects - ) + semantic.redirects = documentationExtension?.redirects let filter = ParametersAndReturnValidator(diagnosticEngine: engine, docChunkSources: docChunks.map(\.source)) let (parametersSectionVariants, returnsSectionVariants) = filter.makeParametersAndReturnsSections( @@ -415,22 +407,22 @@ public struct DocumentationNode { if let keys = markupModel.discussionTags?.dictionaryKeys, !keys.isEmpty { // Record the keys extracted from the markdown - semantic.dictionaryKeysSectionVariants[.fallback] = DictionaryKeysSection(dictionaryKeys:keys) + semantic.dictionaryKeysSection = DictionaryKeysSection(dictionaryKeys:keys) } if let parameters = markupModel.discussionTags?.httpParameters, !parameters.isEmpty { // Record the parameters extracted from the markdown - semantic.httpParametersSectionVariants[.fallback] = HTTPParametersSection(parameters: parameters) + semantic.httpParametersSection = HTTPParametersSection(parameters: parameters) } if let body = markupModel.discussionTags?.httpBody { // Record the body extracted from the markdown - semantic.httpBodySectionVariants[.fallback] = HTTPBodySection(body: body) + semantic.httpBodySection = HTTPBodySection(body: body) } if let responses = markupModel.discussionTags?.httpResponses, !responses.isEmpty { // Record the responses extracted from the markdown - semantic.httpResponsesSectionVariants[.fallback] = HTTPResponsesSection(responses: responses) + semantic.httpResponsesSection = HTTPResponsesSection(responses: responses) } // The property list symbol's allowed values. @@ -467,10 +459,10 @@ public struct DocumentationNode { } // Record the possible values extracted from the markdown. - semantic.possibleValuesSectionVariants[.fallback] = PropertyListPossibleValuesSection(possibleValues: knownPossibleValues) + semantic.possibleValuesSection = PropertyListPossibleValuesSection(possibleValues: knownPossibleValues) } else if let symbolAllowedValues { // Record the symbol possible values even if none are documented. - semantic.possibleValuesSectionVariants[.fallback] = PropertyListPossibleValuesSection(possibleValues: symbolAllowedValues.value.map { + semantic.possibleValuesSection = PropertyListPossibleValuesSection(possibleValues: symbolAllowedValues.value.map { PropertyListPossibleValuesSection.PossibleValue(value: String($0), contents: []) }) } @@ -778,13 +770,13 @@ public struct DocumentationNode { seeAlsoVariants: .init(swiftVariant: markupModel.seeAlsoSection), returnsSectionVariants: .init(swiftVariant: markupModel.discussionTags.flatMap({ $0.returns.isEmpty ? nil : ReturnsSection(content: $0.returns[0].contents) })), parametersSectionVariants: .init(swiftVariant: markupModel.discussionTags.flatMap({ $0.parameters.isEmpty ? nil : ParametersSection(parameters: $0.parameters) })), - dictionaryKeysSectionVariants: .init(swiftVariant: markupModel.discussionTags.flatMap({ $0.dictionaryKeys.isEmpty ? nil : DictionaryKeysSection(dictionaryKeys: $0.dictionaryKeys) })), - possibleValuesSectionVariants: .init(swiftVariant: markupModel.discussionTags.flatMap({ $0.possiblePropertyListValues.isEmpty ? nil : PropertyListPossibleValuesSection(possibleValues: $0.possiblePropertyListValues) })), - httpEndpointSectionVariants: .empty, - httpBodySectionVariants: .empty, - httpParametersSectionVariants: .empty, - httpResponsesSectionVariants: .empty, - redirectsVariants: .init(swiftVariant: article?.redirects) + dictionaryKeysSection: markupModel.discussionTags.flatMap({ $0.dictionaryKeys.isEmpty ? nil : DictionaryKeysSection(dictionaryKeys: $0.dictionaryKeys) }), + possibleValuesSection: markupModel.discussionTags.flatMap({ $0.possiblePropertyListValues.isEmpty ? nil : PropertyListPossibleValuesSection(possibleValues: $0.possiblePropertyListValues) }), + httpEndpointSection: nil, + httpBodySection: nil, + httpParametersSection: nil, + httpResponsesSection: nil, + redirects: article?.redirects ) self.isVirtual = symbol.isVirtual diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/DictionaryKeysSectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/DictionaryKeysSectionTranslator.swift index 8df7081a38..684c17f1d1 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/DictionaryKeysSectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/DictionaryKeysSectionTranslator.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2023 Apple Inc. and the Swift project authors + Copyright (c) 2023-2024 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 @@ -17,18 +17,18 @@ struct DictionaryKeysSectionTranslator: RenderSectionTranslator { renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator ) -> VariantCollection? { - translateSectionToVariantCollection( - documentationDataVariants: symbol.dictionaryKeysSectionVariants - ) { _, dictionaryKeysSection in - guard !dictionaryKeysSection.dictionaryKeys.isEmpty else { return nil } - - // Filter out keys that aren't backed by a symbol - let filteredKeys = dictionaryKeysSection.dictionaryKeys.filter { $0.symbol != nil } - - return PropertiesRenderSection( + guard let dictionaryKeysSection = symbol.dictionaryKeysSection, + !dictionaryKeysSection.dictionaryKeys.isEmpty + else { return nil } + + // Filter out keys that aren't backed by a symbol + let filteredKeys = dictionaryKeysSection.dictionaryKeys.filter { $0.symbol != nil } + + return VariantCollection(defaultValue: CodableContentSection( + PropertiesRenderSection( title: DictionaryKeysSection.title, items: filteredKeys.map { renderNodeTranslator.createRenderProperty(name: $0.name, contents: $0.contents, required: $0.required, symbol: $0.symbol) } ) - } + )) } } diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPBodySectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPBodySectionTranslator.swift index 05f318174c..4f9d389b35 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPBodySectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPBodySectionTranslator.swift @@ -17,43 +17,44 @@ struct HTTPBodySectionTranslator: RenderSectionTranslator { renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator ) -> VariantCollection? { - translateSectionToVariantCollection( - documentationDataVariants: symbol.httpBodySectionVariants - ) { _, httpBodySection -> RenderSection? in - guard let symbol = httpBodySection.body.symbol, let mediaType = httpBodySection.body.mediaType else { return nil } + guard let httpBodySection = symbol.httpBodySection, + let symbol = httpBodySection.body.symbol, + let mediaType = httpBodySection.body.mediaType + else { return nil } - // Filter out parameters that aren't backed by a symbol or don't have a "body" source. - let filteredParameters = httpBodySection.body.parameters.filter { $0.symbol != nil && $0.source == "body" } - - let bodyContent = renderNodeTranslator.visitMarkupContainer( - MarkupContainer(httpBodySection.body.contents) - ) as! [RenderBlockContent] - - let renderedTokens = symbol.declarationFragments?.map { token -> DeclarationRenderSection.Token in - // Create a reference if one found - let reference: ResolvedTopicReference? - if let preciseIdentifier = token.preciseIdentifier, - let resolved = renderNodeTranslator.context.localOrExternalReference(symbolID: preciseIdentifier) - { - reference = resolved - - // Add relationship to render references - renderNodeTranslator.collectedTopicReferences.append(resolved) - } else { - reference = nil - } + // Filter out parameters that aren't backed by a symbol or don't have a "body" source. + let filteredParameters = httpBodySection.body.parameters.filter { $0.symbol != nil && $0.source == "body" } + + let bodyContent = renderNodeTranslator.visitMarkupContainer( + MarkupContainer(httpBodySection.body.contents) + ) as! [RenderBlockContent] + + let renderedTokens = symbol.declarationFragments?.map { token -> DeclarationRenderSection.Token in + // Create a reference if one found + let reference: ResolvedTopicReference? + if let preciseIdentifier = token.preciseIdentifier, + let resolved = renderNodeTranslator.context.localOrExternalReference(symbolID: preciseIdentifier) + { + reference = resolved - // Add the declaration token - return DeclarationRenderSection.Token(fragment: token, identifier: reference?.absoluteString) + // Add relationship to render references + renderNodeTranslator.collectedTopicReferences.append(resolved) + } else { + reference = nil } - return RESTBodyRenderSection( + // Add the declaration token + return DeclarationRenderSection.Token(fragment: token, identifier: reference?.absoluteString) + } + + return VariantCollection(defaultValue: CodableContentSection( + RESTBodyRenderSection( title: "HTTP Body", mimeType: mediaType, bodyContentType: renderedTokens ?? [], content: bodyContent, parameters: filteredParameters.map { renderNodeTranslator.createRenderProperty(name: $0.name, contents: $0.contents, required: $0.required, symbol: $0.symbol) } ) - } + )) } } diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPEndpointSectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPEndpointSectionTranslator.swift index 177673e9dc..981a0f8c26 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPEndpointSectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPEndpointSectionTranslator.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2023 Apple Inc. and the Swift project authors + Copyright (c) 2023-2024 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 @@ -20,30 +20,27 @@ struct HTTPEndpointSectionTranslator: RenderSectionTranslator { renderNodeTranslator: inout RenderNodeTranslator ) -> VariantCollection? { // Check if there is any endpoint available - guard !symbol.httpEndpointSectionVariants.isEmpty else { return nil } + guard let section = symbol.httpEndpointSection else { return nil } - return translateSectionToVariantCollection( - documentationDataVariants: symbol.httpEndpointSectionVariants - ) { _, section in - let endpointURL: URL - - if endpointType == .production { - endpointURL = section.endpoint.baseURL - } else if let sandboxURL = section.endpoint.sandboxURL { - endpointURL = sandboxURL - } else { - return nil - } + let endpointURL: URL + if endpointType == .production { + endpointURL = section.endpoint.baseURL + } else if let sandboxURL = section.endpoint.sandboxURL { + endpointURL = sandboxURL + } else { + return nil + } - return RESTEndpointRenderSection( + return VariantCollection(defaultValue: CodableContentSection( + RESTEndpointRenderSection( title: (endpointType == .production ? "URL" : "Sandbox URL"), tokens: Self.tokensFor(method: section.endpoint.method, baseURL: endpointURL, path: section.endpoint.path) ) - } + )) } // Generate DeclarationFragments from endpoint data. - static func tokensFor(method: String, baseURL: URL?, path: String) -> [RESTEndpointRenderSection.Token] { + private static func tokensFor(method: String, baseURL: URL?, path: String) -> [RESTEndpointRenderSection.Token] { var fragments : [RESTEndpointRenderSection.Token] = [] // Operation type diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPParametersSectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPParametersSectionTranslator.swift index 8cc9b7dee3..d592c7a101 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPParametersSectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPParametersSectionTranslator.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2023 Apple Inc. and the Swift project authors + Copyright (c) 2023-2024 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 @@ -19,19 +19,18 @@ struct HTTPParametersSectionTranslator: RenderSectionTranslator { renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator ) -> VariantCollection? { - translateSectionToVariantCollection( - documentationDataVariants: symbol.httpParametersSectionVariants - ) { _, httpParametersSection in - // Filter out keys that aren't backed by a symbol or have a different source than requested - let filteredParameters = httpParametersSection.parameters.filter { $0.symbol != nil && $0.source != nil && $0.source == parameterSource.rawValue } - - if filteredParameters.isEmpty { return nil } - - return RESTParametersRenderSection( + guard let httpParametersSection = symbol.httpParametersSection else { return nil } + + // Filter out keys that aren't backed by a symbol or have a different source than requested + let filteredParameters = httpParametersSection.parameters.filter { $0.symbol != nil && $0.source != nil && $0.source == parameterSource.rawValue } + guard !filteredParameters.isEmpty else { return nil } + + return VariantCollection(defaultValue: CodableContentSection( + RESTParametersRenderSection( title: "\(parameterSource.rawValue.capitalized) Parameters", parameters: filteredParameters.map { renderNodeTranslator.createRenderProperty(name: $0.name, contents: $0.contents, required: $0.required, symbol: $0.symbol) }, source: parameterSource ) - } + )) } } diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPResponsesSectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPResponsesSectionTranslator.swift index 514c9cbca7..cc0575b2bb 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPResponsesSectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/HTTPResponsesSectionTranslator.swift @@ -17,22 +17,21 @@ struct HTTPResponsesSectionTranslator: RenderSectionTranslator { renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator ) -> VariantCollection? { - translateSectionToVariantCollection( - documentationDataVariants: symbol.httpResponsesSectionVariants - ) { _, httpResponsesSection in - // Filter out responses that aren't backed by a symbol - let filteredResponses = httpResponsesSection.responses.filter { $0.symbol != nil } - - if filteredResponses.isEmpty { return nil } - - return RESTResponseRenderSection( + guard let httpResponsesSection = symbol.httpResponsesSection else { return nil } + + // Filter out responses that aren't backed by a symbol + let filteredResponses = httpResponsesSection.responses.filter { $0.symbol != nil } + guard !filteredResponses.isEmpty else { return nil } + + return VariantCollection(defaultValue: CodableContentSection( + RESTResponseRenderSection( title: HTTPResponsesSection.title, responses: filteredResponses.map { translateResponse($0, &renderNodeTranslator) } ) - } + )) } - func translateResponse(_ response: HTTPResponse, _ renderNodeTranslator: inout RenderNodeTranslator) -> RESTResponse { + private func translateResponse(_ response: HTTPResponse, _ renderNodeTranslator: inout RenderNodeTranslator) -> RESTResponse { let responseContent = renderNodeTranslator.visitMarkupContainer( MarkupContainer(response.contents) ) as! [RenderBlockContent] @@ -71,7 +70,7 @@ struct HTTPResponsesSectionTranslator: RenderSectionTranslator { } // Default reason strings in case one not explicitly set. - static let reasonForStatusCode: [UInt: String] = [ + private static let reasonForStatusCode: [UInt: String] = [ 100: "Continue", 101: "Switching Protocols", 200: "OK", diff --git a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/PossibleValuesSectionTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/PossibleValuesSectionTranslator.swift index dd1b56d029..e9bd86e7b8 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/PossibleValuesSectionTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/PossibleValuesSectionTranslator.swift @@ -16,13 +16,12 @@ import Markdown struct PossibleValuesSectionTranslator: RenderSectionTranslator { func translateSection(for symbol: Symbol, renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator) -> VariantCollection? { + guard let possibleValuesSection = symbol.possibleValuesSection else { return nil } - return translateSectionToVariantCollection( - documentationDataVariants: symbol.possibleValuesSectionVariants - ) { _, possibleValuesSection in + return VariantCollection(defaultValue: CodableContentSection( // Render the possible values with the matching description from the // possible values listed in the markdown. - return PossibleValuesRenderSection( + PossibleValuesRenderSection( title: PropertyListPossibleValuesSection.title, values: possibleValuesSection.possibleValues.map { possibleValueTag in let valueContent = renderNodeTranslator.visitMarkupContainer( @@ -34,8 +33,6 @@ struct PossibleValuesSectionTranslator: RenderSectionTranslator { ) } ) - } + )) } - } - diff --git a/Sources/SwiftDocC/Semantics/ExternalLinks/ExternalReferenceWalker.swift b/Sources/SwiftDocC/Semantics/ExternalLinks/ExternalReferenceWalker.swift index 2b100183fb..26c578cdce 100644 --- a/Sources/SwiftDocC/Semantics/ExternalLinks/ExternalReferenceWalker.swift +++ b/Sources/SwiftDocC/Semantics/ExternalLinks/ExternalReferenceWalker.swift @@ -205,32 +205,32 @@ struct ExternalReferenceWalker: SemanticVisitor { } } - for dictionaryKeysSection in symbol.dictionaryKeysSectionVariants.allValues.map(\.variant) { + if let dictionaryKeysSection = symbol.dictionaryKeysSection { for dictionaryKeys in dictionaryKeysSection.dictionaryKeys { for markup in dictionaryKeys.contents { visitMarkup(markup) } } } - for httpParametersSection in symbol.httpParametersSectionVariants.allValues.map(\.variant) { + if let httpParametersSection = symbol.httpParametersSection { for param in httpParametersSection.parameters { for markup in param.contents { visitMarkup(markup) } } } - for httpResponsesSection in symbol.httpResponsesSectionVariants.allValues.map(\.variant) { + if let httpResponsesSection = symbol.httpResponsesSection { for param in httpResponsesSection.responses { for markup in param.contents { visitMarkup(markup) } } } - for httpBodySection in symbol.httpBodySectionVariants.allValues.map(\.variant) { + if let httpBodySection = symbol.httpBodySection { for markup in httpBodySection.body.contents { visitMarkup(markup) } for parameter in httpBodySection.body.parameters { for markup in parameter.contents { visitMarkup(markup) } } } - for possibleValuesSection in symbol.possibleValuesSectionVariants.allValues.map(\.variant) { + if let possibleValuesSection = symbol.possibleValuesSection { for possibleValue in possibleValuesSection.possibleValues { for markup in possibleValue.contents { visitMarkup(markup) } } diff --git a/Sources/SwiftDocC/Semantics/ReferenceResolver.swift b/Sources/SwiftDocC/Semantics/ReferenceResolver.swift index 8d0c3c243f..09a25cff25 100644 --- a/Sources/SwiftDocC/Semantics/ReferenceResolver.swift +++ b/Sources/SwiftDocC/Semantics/ReferenceResolver.swift @@ -447,16 +447,16 @@ struct ReferenceResolver: SemanticVisitor { let newDeprecatedSummaryVariants = symbol.deprecatedSummaryVariants.map { return DeprecatedSection(content: $0.content.map { visitMarkup($0) }) } - let newDictionaryKeysVariants = symbol.dictionaryKeysSectionVariants.map { dictionaryKeysSection -> DictionaryKeysSection in + let newDictionaryKeys = symbol.dictionaryKeysSection.map { dictionaryKeysSection -> DictionaryKeysSection in let keys = dictionaryKeysSection.dictionaryKeys.map { DictionaryKey(name: $0.name, contents: $0.contents.map { visitMarkup($0) }, symbol: $0.symbol, required: $0.required) } return DictionaryKeysSection(dictionaryKeys: keys) } - let newHTTPEndpointVariants = symbol.httpEndpointSectionVariants.map { httpEndpointSection -> HTTPEndpointSection in + let newHTTPEndpoint = symbol.httpEndpointSection.map { httpEndpointSection -> HTTPEndpointSection in return HTTPEndpointSection(endpoint: httpEndpointSection.endpoint) } - let newHTTPBodyVariants = symbol.httpBodySectionVariants.map { httpBodySection -> HTTPBodySection in + let newHTTPBody = symbol.httpBodySection.map { httpBodySection -> HTTPBodySection in let oldBody = httpBodySection.body let newBodyParameters = oldBody.parameters.map { HTTPParameter(name: $0.name, source: $0.source, contents: $0.contents.map { visitMarkup($0) }, symbol: $0.symbol, required: $0.required) @@ -464,20 +464,20 @@ struct ReferenceResolver: SemanticVisitor { let newBody = HTTPBody(mediaType: oldBody.mediaType, contents: oldBody.contents.map { visitMarkup($0) }, parameters: newBodyParameters, symbol: oldBody.symbol) return HTTPBodySection(body: newBody) } - let newHTTPParametersVariants = symbol.httpParametersSectionVariants.map { httpParametersSection -> HTTPParametersSection in + let newHTTPParameters = symbol.httpParametersSection.map { httpParametersSection -> HTTPParametersSection in let parameters = httpParametersSection.parameters.map { HTTPParameter(name: $0.name, source: $0.source, contents: $0.contents.map { visitMarkup($0) }, symbol: $0.symbol, required: $0.required) } return HTTPParametersSection(parameters: parameters) } - let newHTTPResponsesVariants = symbol.httpResponsesSectionVariants.map { httpResponsesSection -> HTTPResponsesSection in + let newHTTPResponses = symbol.httpResponsesSection.map { httpResponsesSection -> HTTPResponsesSection in let responses = httpResponsesSection.responses.map { HTTPResponse(statusCode: $0.statusCode, reason: $0.reason, mediaType: $0.mediaType, contents: $0.contents.map { visitMarkup($0) }, symbol: $0.symbol) } return HTTPResponsesSection(responses: responses) } - let possibleValuesVariants = symbol.possibleValuesSectionVariants.map { possibleValuesSection -> PropertyListPossibleValuesSection in + let newPossibleValuesSection = symbol.possibleValuesSection.map { possibleValuesSection -> PropertyListPossibleValuesSection in let possibleValues = possibleValuesSection.possibleValues.map { PropertyListPossibleValuesSection.PossibleValue(value: $0.value, contents: $0.contents.map { visitMarkup($0) }, nameRange: $0.nameRange, range: $0.range) } @@ -512,13 +512,13 @@ struct ReferenceResolver: SemanticVisitor { seeAlsoVariants: newSeeAlsoVariants, returnsSectionVariants: newReturnsVariants, parametersSectionVariants: newParametersVariants, - dictionaryKeysSectionVariants: newDictionaryKeysVariants, - possibleValuesSectionVariants: possibleValuesVariants, - httpEndpointSectionVariants: newHTTPEndpointVariants, - httpBodySectionVariants: newHTTPBodyVariants, - httpParametersSectionVariants: newHTTPParametersVariants, - httpResponsesSectionVariants: newHTTPResponsesVariants, - redirectsVariants: symbol.redirectsVariants, + dictionaryKeysSection: newDictionaryKeys, + possibleValuesSection: newPossibleValuesSection, + httpEndpointSection: newHTTPEndpoint, + httpBodySection: newHTTPBody, + httpParametersSection: newHTTPParameters, + httpResponsesSection: newHTTPResponses, + redirects: symbol.redirects, crossImportOverlayModule: symbol.crossImportOverlayModule, originVariants: symbol.originVariants, automaticTaskGroupsVariants: symbol.automaticTaskGroupsVariants, diff --git a/Sources/SwiftDocC/Semantics/Symbol/Symbol.swift b/Sources/SwiftDocC/Semantics/Symbol/Symbol.swift index 0fa858513b..c231eb67fd 100644 --- a/Sources/SwiftDocC/Semantics/Symbol/Symbol.swift +++ b/Sources/SwiftDocC/Semantics/Symbol/Symbol.swift @@ -206,26 +206,61 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups /// Any parameters of the symbol, if the symbol accepts parameters, in each language variant the symbol is available in. public var parametersSectionVariants: DocumentationDataVariants - /// Any dictionary keys of the symbol, if the symbol accepts keys, in each language variant the symbol is available in. - public var dictionaryKeysSectionVariants: DocumentationDataVariants + /// Any dictionary keys of the symbol, if the symbol accepts keys. + public var dictionaryKeysSection: DictionaryKeysSection? + @available(*, deprecated, renamed: "dictionaryKeysSection", message: "Use 'dictionaryKeysSection' instead. This deprecated API will be removed after 6.2 is released") + public var dictionaryKeysSectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: dictionaryKeysSection) } + set { dictionaryKeysSection = newValue.firstValue } + } - /// The symbol's possible values in each language variant the symbol is available in. - public var possibleValuesSectionVariants: DocumentationDataVariants + /// The symbol's possible values, if the symbol is a property list element with possible values. + public var possibleValuesSection: PropertyListPossibleValuesSection? + @available(*, deprecated, renamed: "possibleValuesSection", message: "Use 'possibleValuesSection' instead. This deprecated API will be removed after 6.2 is released") + public var possibleValuesSectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: possibleValuesSection) } + set { possibleValuesSection = newValue.firstValue } + } - /// The HTTP endpoint of an HTTP request, in each language variant the symbol is available in. - public var httpEndpointSectionVariants: DocumentationDataVariants + /// The HTTP endpoint of an HTTP request. + public var httpEndpointSection: HTTPEndpointSection? + @available(*, deprecated, renamed: "httpEndpointSection", message: "Use 'httpEndpointSection' instead. This deprecated API will be removed after 6.2 is released") + public var httpEndpointSectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: httpEndpointSection) } + set { httpEndpointSection = newValue.firstValue } + } - /// The upload body of an HTTP request, in each language variant the symbol is available in. - public var httpBodySectionVariants: DocumentationDataVariants + /// The upload body of an HTTP request. + public var httpBodySection: HTTPBodySection? + @available(*, deprecated, renamed: "httpBodySection", message: "Use 'httpBodySection' instead. This deprecated API will be removed after 6.2 is released") + public var httpBodySectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: httpBodySection) } + set { httpBodySection = newValue.firstValue } + } - /// The parameters of an HTTP request, in each language variant the symbol is available in. - public var httpParametersSectionVariants: DocumentationDataVariants + /// The parameters of an HTTP request. + public var httpParametersSection: HTTPParametersSection? + @available(*, deprecated, renamed: "httpParametersSection", message: "Use 'httpParametersSection' instead. This deprecated API will be removed after 6.2 is released") + public var httpParametersSectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: httpParametersSection) } + set { httpParametersSection = newValue.firstValue } + } - /// The responses of an HTTP request, in each language variant the symbol is available in. - public var httpResponsesSectionVariants: DocumentationDataVariants + /// The responses of an HTTP request. + public var httpResponsesSection: HTTPResponsesSection? + @available(*, deprecated, renamed: "httpResponsesSection", message: "Use 'httpResponsesSection' instead. This deprecated API will be removed after 6.2 is released") + public var httpResponsesSectionVariants: DocumentationDataVariants { + get { .init(defaultVariantValue: httpResponsesSection) } + set { httpResponsesSection = newValue.firstValue } + } - /// Any redirect information of the symbol, if the symbol has been moved from another location, in each language variant the symbol is available in. - public var redirectsVariants: DocumentationDataVariants<[Redirect]> + /// Any redirect information of the symbol, if the symbol has been moved from another location. + public var redirects: [Redirect]? + @available(*, deprecated, renamed: "redirects", message: "Use 'redirects' instead. This deprecated API will be removed after 6.2 is released") + public var redirectsVariants: DocumentationDataVariants<[Redirect]> { + get { .init(defaultVariantValue: redirects) } + set { redirects = newValue.firstValue } + } /// The symbol's abstract summary as a single paragraph, in each language variant the symbol is available in. public var abstractVariants: DocumentationDataVariants { @@ -282,13 +317,13 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups seeAlsoVariants: DocumentationDataVariants, returnsSectionVariants: DocumentationDataVariants, parametersSectionVariants: DocumentationDataVariants, - dictionaryKeysSectionVariants: DocumentationDataVariants, - possibleValuesSectionVariants: DocumentationDataVariants, - httpEndpointSectionVariants: DocumentationDataVariants, - httpBodySectionVariants: DocumentationDataVariants, - httpParametersSectionVariants: DocumentationDataVariants, - httpResponsesSectionVariants: DocumentationDataVariants, - redirectsVariants: DocumentationDataVariants<[Redirect]>, + dictionaryKeysSection: DictionaryKeysSection?, + possibleValuesSection: PropertyListPossibleValuesSection?, + httpEndpointSection: HTTPEndpointSection?, + httpBodySection: HTTPBodySection?, + httpParametersSection: HTTPParametersSection?, + httpResponsesSection: HTTPResponsesSection?, + redirects: [Redirect]?, crossImportOverlayModule: (declaringModule: String, bystanderModules: [String])? = nil, originVariants: DocumentationDataVariants = .init(), automaticTaskGroupsVariants: DocumentationDataVariants<[AutomaticTaskGroupSection]> = .init(defaultVariantValue: []), @@ -313,7 +348,7 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups self.deprecatedSummaryVariants = deprecatedSummaryVariants self.declarationVariants = declarationVariants - self.possibleValuesSectionVariants = possibleValuesSectionVariants + self.possibleValuesSection = possibleValuesSection self.alternateDeclarationVariants = alternateDeclarationVariants self.alternateSignatureVariants = alternateSignatureVariants @@ -380,12 +415,12 @@ public final class Symbol: Semantic, Abstracted, Redirected, AutomaticTaskGroups self.seeAlsoVariants = seeAlsoVariants self.returnsSectionVariants = returnsSectionVariants self.parametersSectionVariants = parametersSectionVariants - self.dictionaryKeysSectionVariants = dictionaryKeysSectionVariants - self.httpEndpointSectionVariants = httpEndpointSectionVariants - self.httpBodySectionVariants = httpBodySectionVariants - self.httpParametersSectionVariants = httpParametersSectionVariants - self.httpResponsesSectionVariants = httpResponsesSectionVariants - self.redirectsVariants = redirectsVariants + self.dictionaryKeysSection = dictionaryKeysSection + self.httpEndpointSection = httpEndpointSection + self.httpBodySection = httpBodySection + self.httpParametersSection = httpParametersSection + self.httpResponsesSection = httpResponsesSection + self.redirects = redirects self.originVariants = originVariants self.automaticTaskGroupsVariants = automaticTaskGroupsVariants self.overloadsVariants = overloadsVariants @@ -687,12 +722,6 @@ extension Symbol { set { seeAlsoVariants.firstValue = newValue } } - /// Any redirect information of the first variant of the symbol, if the symbol has been moved from another location. - public var redirects: [Redirect]? { - get { redirectsVariants.firstValue } - set { redirectsVariants.firstValue = newValue } - } - /// Any return value information of the first variant of the symbol, if the symbol returns. public var returnsSection: ReturnsSection? { get { returnsSectionVariants.firstValue } diff --git a/Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift b/Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift index 4c61ba3adc..a8234ec5d5 100644 --- a/Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift @@ -1256,10 +1256,7 @@ class ExternalReferenceResolverTests: XCTestCase { // Get the variant of the example symbol that has no interface language, meaning it was // generated by the markup above. - let variant = symbol.dictionaryKeysSectionVariants.allValues.first( - where: { $0.trait == .init(interfaceLanguage: nil) } - ) - let section = try XCTUnwrap(variant?.variant) + let section = try XCTUnwrap(symbol.dictionaryKeysSection) XCTAssertEqual(section.dictionaryKeys.count, 4) // Check that the two keys with external links in the markup above were found @@ -1325,10 +1322,7 @@ class ExternalReferenceResolverTests: XCTestCase { // Get the variant of the example symbol that has no interface language, meaning it was // generated by the markup above. let symbol = try exampleRESTDocumentation() - let variant = symbol.httpParametersSectionVariants.allValues.first( - where: { $0.trait == .init(interfaceLanguage: nil) } - ) - let section = try XCTUnwrap(variant?.variant) + let section = try XCTUnwrap(symbol.httpParametersSection) XCTAssertEqual(section.parameters.count, 3) // Check that the two keys with external links in the markup above were found @@ -1354,10 +1348,7 @@ class ExternalReferenceResolverTests: XCTestCase { // Get the variant of the example symbol that has no interface language, meaning it was // generated by the markup above. let symbol = try exampleRESTDocumentation() - let variant = symbol.httpBodySectionVariants.allValues.first( - where: { $0.trait == .init(interfaceLanguage: nil) } - ) - let section = try XCTUnwrap(variant?.variant) + let section = try XCTUnwrap(symbol.httpBodySection) // Check that the two keys with external links in the markup above were found // and processed by the test external reference resolver. @@ -1370,10 +1361,7 @@ class ExternalReferenceResolverTests: XCTestCase { // Get the variant of the example symbol that has no interface language, meaning it was // generated by the markup above. let symbol = try exampleRESTDocumentation() - let variant = symbol.httpBodySectionVariants.allValues.first( - where: { $0.trait == .init(interfaceLanguage: nil) } - ) - let section = try XCTUnwrap(variant?.variant) + let section = try XCTUnwrap(symbol.httpBodySection) XCTAssertEqual(section.body.parameters.count, 3) // Check that the two keys with external links in the markup above were found @@ -1400,10 +1388,7 @@ class ExternalReferenceResolverTests: XCTestCase { // Get the variant of the example symbol that has no interface language, meaning it was // generated by the markup above. let symbol = try exampleRESTDocumentation() - let variant = symbol.httpResponsesSectionVariants.allValues.first( - where: { $0.trait == .init(interfaceLanguage: nil) } - ) - let section = try XCTUnwrap(variant?.variant) + let section = try XCTUnwrap(symbol.httpResponsesSection) XCTAssertEqual(section.responses.count, 3) // Check that the two keys with external links in the markup above were found @@ -1448,7 +1433,7 @@ class ExternalReferenceResolverTests: XCTestCase { path: "/documentation/DictionaryData/Genre" ) - let section = try XCTUnwrap(symbol.possibleValuesSectionVariants.firstValue) + let section = try XCTUnwrap(symbol.possibleValuesSection) XCTAssertEqual(section.possibleValues.count, 3) // Check that the two keys with external links in the markup above were found diff --git a/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift b/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift index ddb663ec37..d5e7bba993 100644 --- a/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift @@ -695,7 +695,6 @@ class ReferenceResolverTests: XCTestCase { populateObjCVariantAndCreateAssertion(keyPath: \.isRequiredVariants), populateObjCVariantAndCreateAssertion(keyPath: \.externalIDVariants), populateObjCVariantAndCreateAssertion(keyPath: \.accessLevelVariants), - populateObjCVariantAndCreateAssertion(keyPath: \.redirectsVariants), populateObjCVariantAndCreateAssertion(keyPath: \.originVariants), // Otherwise, for variants properties that don't a value that is Equatable, populate the Objective-C variant diff --git a/Tests/SwiftDocCTests/Model/PropertyListPossibleValuesSectionTests.swift b/Tests/SwiftDocCTests/Model/PropertyListPossibleValuesSectionTests.swift index e804e371e8..f551be022d 100644 --- a/Tests/SwiftDocCTests/Model/PropertyListPossibleValuesSectionTests.swift +++ b/Tests/SwiftDocCTests/Model/PropertyListPossibleValuesSectionTests.swift @@ -118,7 +118,7 @@ class PropertyListPossibleValuesSectionTests: XCTestCase { let node = try context.entity(with: ResolvedTopicReference(bundleID: bundle.id, path: "/documentation/DictionaryData/Month", sourceLanguage: .swift)) let symbol = node.semantic as! Symbol - let possibleValues = try XCTUnwrap(symbol.possibleValuesSectionVariants.firstValue?.possibleValues) + let possibleValues = try XCTUnwrap(symbol.possibleValuesSection?.possibleValues) // Check that possible value defined in the markdown but not part of the SymbolGraph is dropped. XCTAssertEqual(possibleValues.count, 3) @@ -138,7 +138,7 @@ class PropertyListPossibleValuesSectionTests: XCTestCase { let node = try context.entity(with: ResolvedTopicReference(bundleID: bundle.id, path: "/documentation/DictionaryData/Month", sourceLanguage: .swift)) let symbol = node.semantic as! Symbol - let possibleValues = try XCTUnwrap(symbol.possibleValuesSectionVariants.firstValue?.possibleValues) + let possibleValues = try XCTUnwrap(symbol.possibleValuesSection?.possibleValues) // Check that possible value not defined in the markdown but part of the SymbolGraph are not dropped. XCTAssertEqual(possibleValues.map { $0.value }, ["January", "February", "March"]) diff --git a/Tests/SwiftDocCTests/Rendering/DocumentationContentRendererTests.swift b/Tests/SwiftDocCTests/Rendering/DocumentationContentRendererTests.swift index db9f15b22a..6204727875 100644 --- a/Tests/SwiftDocCTests/Rendering/DocumentationContentRendererTests.swift +++ b/Tests/SwiftDocCTests/Rendering/DocumentationContentRendererTests.swift @@ -210,13 +210,13 @@ private extension DocumentationContentRendererTests { seeAlsoVariants: .init(swiftVariant: nil), returnsSectionVariants: .init(swiftVariant: nil), parametersSectionVariants: .init(swiftVariant: nil), - dictionaryKeysSectionVariants: .init(swiftVariant: nil), - possibleValuesSectionVariants: .init(swiftVariant: nil), - httpEndpointSectionVariants: .init(swiftVariant: nil), - httpBodySectionVariants: .init(swiftVariant: nil), - httpParametersSectionVariants: .init(swiftVariant: nil), - httpResponsesSectionVariants: .init(swiftVariant: nil), - redirectsVariants: .init(swiftVariant: nil) + dictionaryKeysSection: nil, + possibleValuesSection: nil, + httpEndpointSection: nil, + httpBodySection: nil, + httpParametersSection: nil, + httpResponsesSection: nil, + redirects: nil ) return node diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift index 45b5cdcd3b..8d8d5dfaa7 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift @@ -13,6 +13,7 @@ import XCTest import SymbolKit import Markdown @testable import SwiftDocC +import SwiftDocCTestUtilities class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { @@ -500,72 +501,53 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { ) } - func testDictionaryKeysSectionVariants() throws { - func propertiesSection(in renderNode: RenderNode) throws -> PropertiesRenderSection { - let propertiesSectionIndex = 1 + func testDictionaryKeysSection() throws { + let keySymbol = makeSymbol(id: "some-key", language: .data, kind: .dictionaryKey, pathComponents: ["SomeDictionary", "SomeKey"]) + let catalog = Folder(name: "unit-test.docc", content: [ + JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(moduleName: "ModuleName", symbols: [ + makeSymbol(id: "some-dictionary", language: .data, kind: .dictionary, pathComponents: ["SomeDictionary"]), + keySymbol, + ])) + ]) + + let (bundle, context) = try loadBundle(catalog: catalog) + let moduleReference = try XCTUnwrap(context.soleRootModuleReference) + let dictionaryReference = moduleReference.appendingPath("SomeDictionary") + + let node = try context.entity(with: dictionaryReference) + let symbol = try XCTUnwrap(node.semantic as? Symbol) + + func propertiesSection(for dictionaryKeysSection: DictionaryKeysSection) throws -> PropertiesRenderSection { + symbol.dictionaryKeysSection = dictionaryKeysSection + context.documentationCache[dictionaryReference] = node - guard renderNode.primaryContentSections.indices.contains(propertiesSectionIndex) else { - XCTFail("Missing properties section") - return PropertiesRenderSection(title: "Properties", items: []) - } + let converter = DocumentationNodeConverter(bundle: bundle, context: context) + let renderNode = converter.convert(node) - return try XCTUnwrap(renderNode.primaryContentSections[propertiesSectionIndex] as? PropertiesRenderSection) + return try XCTUnwrap(renderNode.primaryContentSections.mapFirst(where: { $0 as? PropertiesRenderSection })) } // Dictionary Keys that are backed by a SymbolGraph symbol survive to the render section... - try assertMultiVariantSymbol( - configureSymbol: { symbol in - let keySymbol1 = SymbolGraph.Symbol(identifier: SymbolGraph.Symbol.Identifier(precise: "precise1", interfaceLanguage: "swift"), names: SymbolGraph.Symbol.Names(title: "Title1", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["path1"], docComment: nil, accessLevel: SymbolGraph.Symbol.AccessControl(rawValue: "public"), kind: SymbolGraph.Symbol.Kind(rawIdentifier: "dictKey", displayName: "Key"), mixins: [:]) - let keySymbol2 = SymbolGraph.Symbol(identifier: SymbolGraph.Symbol.Identifier(precise: "precise2", interfaceLanguage: "swift"), names: SymbolGraph.Symbol.Names(title: "Title2", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["path2"], docComment: nil, accessLevel: SymbolGraph.Symbol.AccessControl(rawValue: "public"), kind: SymbolGraph.Symbol.Kind(rawIdentifier: "dictKey", displayName: "Key"), mixins: [:]) - - symbol.dictionaryKeysSectionVariants[.swift] = DictionaryKeysSection( - dictionaryKeys: [DictionaryKey(name: "Swift property", contents: [], symbol: keySymbol1)] - ) - - symbol.dictionaryKeysSectionVariants[.objectiveC] = DictionaryKeysSection( - dictionaryKeys: [DictionaryKey(name: "Objective-C property", contents: [], symbol: keySymbol2)] - ) - }, - assertOriginalRenderNode: { renderNode in - let propertiesSection = try propertiesSection(in: renderNode) - - XCTAssertEqual(propertiesSection.items.count, 1) - - let property = try XCTUnwrap(propertiesSection.items.first) - XCTAssertEqual(property.name, "Swift property") - XCTAssertEqual(property.content, []) - }, - assertAfterApplyingVariant: { renderNode in - let propertiesSection = try propertiesSection(in: renderNode) - - XCTAssertEqual(propertiesSection.items.count, 1) - - let property = try XCTUnwrap(propertiesSection.items.first) - XCTAssertEqual(property.name, "Objective-C property") - XCTAssertEqual(property.content, []) - } - ) + do { + let propertiesSection = try propertiesSection(for: DictionaryKeysSection(dictionaryKeys: [ + DictionaryKey(name: "Some property", contents: [], symbol: keySymbol) + ])) + + XCTAssertEqual(propertiesSection.items.count, 1) + + let property = try XCTUnwrap(propertiesSection.items.first) + XCTAssertEqual(property.name, "Some property") + XCTAssertEqual(property.content, []) + } // ... but Dictionary Keys that are NOT backed by a SymbolGraph symbol get filtered out. - try assertMultiVariantSymbol( - configureSymbol: { symbol in - symbol.dictionaryKeysSectionVariants[.swift] = DictionaryKeysSection( - dictionaryKeys: [DictionaryKey(name: "Swift property", contents: [], symbol: nil)] - ) - - symbol.dictionaryKeysSectionVariants[.objectiveC] = DictionaryKeysSection( - dictionaryKeys: [DictionaryKey(name: "Objective-C property", contents: [], symbol: nil)] - ) - }, - assertOriginalRenderNode: { renderNode in - let propertiesSection = try propertiesSection(in: renderNode) - XCTAssertEqual(propertiesSection.items.count, 0) - }, - assertAfterApplyingVariant: { renderNode in - let propertiesSection = try propertiesSection(in: renderNode) - XCTAssertEqual(propertiesSection.items.count, 0) - } - ) + do { + let propertiesSection = try propertiesSection(for: DictionaryKeysSection(dictionaryKeys: [ + DictionaryKey(name: "Some property", contents: [], symbol: nil) // No symbol for this key + ])) + + XCTAssertEqual(propertiesSection.items.count, 0) + } } func testDiscussionSectionVariants() throws { diff --git a/Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift b/Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift index 3ce8375760..d653800be1 100644 --- a/Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift +++ b/Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift @@ -159,7 +159,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentFor( tagName: "DictionaryKey someKey", findModelContent: { semantic in - semantic.dictionaryKeysSectionVariants.allValues.first?.variant.dictionaryKeys.first?.contents + semantic.dictionaryKeysSection?.dictionaryKeys.first?.contents }, renderVerification: .skip ) @@ -167,7 +167,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentOutlineFor( tagName: "DictionaryKeys", findModelContent: { semantic in - semantic.dictionaryKeysSectionVariants.allValues.first?.variant.dictionaryKeys.first?.contents + semantic.dictionaryKeysSection?.dictionaryKeys.first?.contents }, renderVerification: .skip ) @@ -175,7 +175,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentFor( tagName: "HTTPResponse 200", findModelContent: { semantic in - semantic.httpResponsesSectionVariants.allValues.first?.variant.responses.first?.contents + semantic.httpResponsesSection?.responses.first?.contents }, renderVerification: .skip ) @@ -183,7 +183,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentOutlineFor( tagName: "HTTPResponses", findModelContent: { semantic in - semantic.httpResponsesSectionVariants.allValues.first?.variant.responses.first?.contents + semantic.httpResponsesSection?.responses.first?.contents }, renderVerification: .skip ) @@ -191,7 +191,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentFor( tagName: "httpBody", findModelContent: { semantic in - semantic.httpBodySectionVariants.allValues.first?.variant.body.contents + semantic.httpBodySection?.body.contents }, renderVerification: .skip ) @@ -199,7 +199,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentFor( tagName: "HTTPParameter someParameter", findModelContent: { semantic in - semantic.httpParametersSectionVariants.allValues.first?.variant.parameters.first?.contents + semantic.httpParametersSection?.parameters.first?.contents }, renderVerification: .skip ) @@ -207,7 +207,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentOutlineFor( tagName: "HTTPParameters", findModelContent: { semantic in - semantic.httpParametersSectionVariants.allValues.first?.variant.parameters.first?.contents + semantic.httpParametersSection?.parameters.first?.contents }, renderVerification: .skip ) @@ -215,7 +215,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentFor( tagName: "HTTPBodyParameter someParameter", findModelContent: { semantic in - semantic.httpBodySectionVariants.allValues.first?.variant.body.parameters.first?.contents + semantic.httpBodySection?.body.parameters.first?.contents }, renderVerification: .skip ) @@ -223,7 +223,7 @@ class ListItemExtractorTests: XCTestCase { try assertExtractsRichContentOutlineFor( tagName: "HTTPBodyParameters", findModelContent: { semantic in - semantic.httpBodySectionVariants.allValues.first?.variant.body.parameters.first?.contents + semantic.httpBodySection?.body.parameters.first?.contents }, renderVerification: .skip )