Skip to content

Commit

Permalink
add conformance availability data to overloaded declarations (#1009)
Browse files Browse the repository at this point in the history
rdar://122589806
  • Loading branch information
QuietMisdreavus authored Oct 25, 2024
1 parent 065a609 commit 784ba58
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import SymbolKit

typealias OverloadDeclaration = (
declaration: [SymbolGraph.Symbol.DeclarationFragments.Fragment],
reference: ResolvedTopicReference
reference: ResolvedTopicReference,
conformance: ConformanceSection?
)

/// Translates a symbol's declaration into a render node's Declarations section.
Expand Down Expand Up @@ -141,7 +142,9 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
commonFragments: commonFragments)
otherDeclarations.append(.init(
tokens: translatedDeclaration,
identifier: overloadDeclaration.reference.absoluteString))
identifier: overloadDeclaration.reference.absoluteString,
conformance: overloadDeclaration.conformance
))

// Add a topic reference to the overload
renderNodeTranslator.collectedTopicReferences.append(
Expand All @@ -160,6 +163,8 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
return nil
}

let conformance = renderNodeTranslator.contentRenderer.conformanceSectionFor(overloadReference, collectedConstraints: [:])

let declarationFragments = overload.declarationVariants[trait]?.values
.first?
.declarationFragments
Expand All @@ -168,7 +173,7 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
"Overloaded symbols must have declaration fragments."
)
return declarationFragments.map({
(declaration: $0, reference: overloadReference)
(declaration: $0, reference: overloadReference, conformance: conformance)
})
}

Expand Down Expand Up @@ -204,13 +209,13 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
// Pre-process the declarations by splitting text fragments apart to increase legibility
let mainDeclaration = declaration.declarationFragments.flatMap(preProcessFragment(_:))
let processedOverloadDeclarations = overloadDeclarations.map({
OverloadDeclaration($0.declaration.flatMap(preProcessFragment(_:)), $0.reference)
OverloadDeclaration($0.declaration.flatMap(preProcessFragment(_:)), $0.reference, $0.conformance)
})

// Collect the "common fragments" so we can highlight the ones that are different
// in each declaration
let commonFragments = commonFragments(
for: (mainDeclaration, renderNode.identifier),
for: (mainDeclaration, renderNode.identifier, nil),
overloadDeclarations: processedOverloadDeclarations)

renderedTokens = translateDeclaration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,14 @@ public struct DeclarationRenderSection: Codable, Equatable {

/// The symbol's identifier.
public let identifier: String


public let conformance: ConformanceSection?

/// Creates a new other declaration for a symbol that is connected to this one, e.g. an overload.
public init(tokens: [Token], identifier: String) {
public init(tokens: [Token], identifier: String, conformance: ConformanceSection? = nil) {
self.tokens = tokens
self.identifier = identifier
self.conformance = conformance
}
}
/// The displayable declarations for this symbol's overloads.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2591,6 +2591,9 @@
},
"identifier": {
"type": "string"
},
"conformance": {
"$ref" : "#/components/schemas/ConformanceSection"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,50 @@ class DeclarationsRenderSectionTests: XCTestCase {
XCTAssert(declarations.tokens.allSatisfy({ $0.highlight == nil }))
}
}

func testOverloadConformanceDataIsSavedWithDeclarations() throws {
enableFeatureFlag(\.isExperimentalOverloadedSymbolPresentationEnabled)

let symbolGraphFile = Bundle.module.url(
forResource: "ConformanceOverloads",
withExtension: "symbols.json",
subdirectory: "Test Resources"
)!

let tempURL = try createTempFolder(content: [
Folder(name: "unit-test.docc", content: [
InfoPlist(displayName: "ConformanceOverloads", identifier: "com.test.example"),
CopyOfFile(original: symbolGraphFile),
])
])

let (_, bundle, context) = try loadBundle(from: tempURL)

// MyClass<T>
// - myFunc() where T: Equatable
// - myFunc() where T: Hashable // <- overload group
let reference = ResolvedTopicReference(
bundleIdentifier: bundle.identifier,
path: "/documentation/ConformanceOverloads/MyClass/myFunc()",
sourceLanguage: .swift
)
let symbol = try XCTUnwrap(context.entity(with: reference).semantic as? Symbol)
var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: reference)
let renderNode = try XCTUnwrap(translator.visitSymbol(symbol) as? RenderNode)
let declarationsSection = try XCTUnwrap(renderNode.primaryContentSections.compactMap({ $0 as? DeclarationsRenderSection }).first)
XCTAssertEqual(declarationsSection.declarations.count, 1)
let declarations = try XCTUnwrap(declarationsSection.declarations.first)

let otherDeclarations = try XCTUnwrap(declarations.otherDeclarations)
XCTAssertEqual(otherDeclarations.declarations.count, 1)

XCTAssertEqual(otherDeclarations.declarations.first?.conformance?.constraints, [
.codeVoice(code: "T"),
.text(" conforms to "),
.codeVoice(code: "Equatable"),
.text("."),
])
}
}

/// Render a list of declaration tokens as a plain-text decoration and as a plain-text rendering of which characters are highlighted.
Expand Down
Loading

0 comments on commit 784ba58

Please sign in to comment.