Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using variants storage for HTTP/REST/PropertyList sections #1104

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
32 changes: 16 additions & 16 deletions Sources/SwiftDocC/Infrastructure/DocumentationContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1600,11 +1600,11 @@ public class DocumentationContext {
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 {
d-ronnqvist marked this conversation as resolved.
Show resolved Hide resolved
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)
}
}
}
Expand All @@ -1613,11 +1613,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)
}
}
}
Expand All @@ -1629,12 +1629,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)
}
}
}
Expand All @@ -1643,11 +1643,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)
}
}
}
Expand Down
54 changes: 23 additions & 31 deletions Sources/SwiftDocC/Model/DocumentationNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -392,9 +386,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(
Expand All @@ -408,22 +400,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.
Expand Down Expand Up @@ -460,10 +452,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: [])
})
}
Expand Down Expand Up @@ -716,13 +708,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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,18 +17,18 @@ struct DictionaryKeysSectionTranslator: RenderSectionTranslator {
renderNode: inout RenderNode,
renderNodeTranslator: inout RenderNodeTranslator
) -> VariantCollection<CodableContentSection?>? {
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) }
)
}
))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,44 @@ struct HTTPBodySectionTranslator: RenderSectionTranslator {
renderNode: inout RenderNode,
renderNodeTranslator: inout RenderNodeTranslator
) -> VariantCollection<CodableContentSection?>? {
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) }
)
}
))
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -20,30 +20,27 @@ struct HTTPEndpointSectionTranslator: RenderSectionTranslator {
renderNodeTranslator: inout RenderNodeTranslator
) -> VariantCollection<CodableContentSection?>? {
// 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

Expand Down
Loading