-
Notifications
You must be signed in to change notification settings - Fork 146
Populate abbreviated declaration fragments in external render nodes #1255
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
base: main
Are you sure you want to change the base?
Populate abbreviated declaration fragments in external render nodes #1255
Conversation
8401492
to
ee465d6
Compare
Some tests are failing in The full declaration fragments are used to determine the full name of the symbol for diagnostic reporting: swift-docc/Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy+Error.swift Lines 115 to 117 in 1b4a185
I think we will need a new field in |
LinkDestinationSummary contains a summary of an element that you can link to from outside the documentation bundle. [1] This information is meant to be used by a server to provide information to an out-of-process resolver to resolve links to external entities, so that the partner implementation of `LinkDestinationSummary` is `OutOfProcessReferenceResolver.ResolvedInformation` [2]. As part of `LinkDestinationSummary`, we store the full declaration fragments of the symbol [3][4]. However, currently `OutOfProcessReferenceResolver` is using these full declaration fragments to populate `TopicRenderReference.fragmentsVariants` [5], which expects the abbreviated declaration fragments [6]. These abbreviated declaration fragments are meant to be used in the Topics section and the navigation index in order to reduce verbosity and improve readability by removing any declaration fragments non-essential to the core of the symbol declaration. These abbreviated declaration fragments are not captured as part of `LinkDestinationSummary` or `OutOfProcessReferenceResolver.ResolvedInformation`. To start capturing this information, this commit modifies `LinkDestinationSummary` to add a new optional field `subHeadingDeclarationFragments` which stores the abbreviated declaration fragments from `renderNode.metadata.fragmentsVariants` (abbreviated declaration fragments are derived from the `subHeading` of the symbol [7], further processed during the render node transformation phase, and finally stored as `renderNode.metadata.fragmentsVariants` [8]). This will enable us to use them in `OutOfProcessReferenceResolver.ResolvedInformation` to initialise `TopicRenderReference.fragmentsVariants` with the expected value. The final goal is for a symbol's representation in the Topics section and the navigation index to look the same regardless of whether the symbol is a local or external one. Fixes rdar://156488052. Alternatives considered: ------------------------ Considered modifying `LinkDestinationSummary.declarationFragments` instead of adding a new optional field, however the full declaration fragments are used to determine the full name [9] of the symbol for diagnostic reporting [10]. By introducing a new field we also ensure this is a non-breaking change. [1]: https://github.com/swiftlang/swift-docc/blob/65aaf926ec079ddbd40f29540d4180a70af99e5e/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift#L66 [2]: https://github.com/swiftlang/swift-docc/blob/65aaf926ec079ddbd40f29540d4180a70af99e5e/Sources/SwiftDocC/Infrastructure/External%20Data/OutOfProcessReferenceResolver.swift#L558-L562 [3]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift#L140-L141 [4]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift#L445 [5]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Infrastructure/External%20Data/OutOfProcessReferenceResolver.swift#L169 [6]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Model/Rendering/References/TopicRenderReference.swift#L50-L53 [7]: https://github.com/swiftlang/swift-docc-symbolkit/blob/ebe89c7da4cf03ded04cd708f3399087c6f2dad7/Sources/SymbolKit/SymbolGraph/Symbol/Names.swift#L28-L31 [8]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift#L1304 [9]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Infrastructure/Link%20Resolution/ExternalPathHierarchyResolver.swift#L61-L63 [10]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Infrastructure/Link%20Resolution/PathHierarchy%2BError.swift#L115-L117
`LinkDestinationSummary` now provides information for both the full and abbreviated declaration fragments. This commit adds the abbreviated declaration fragments to its counterpart type `OutOfProcessReferenceResolver.ResolvedInformation` [1], and uses them to initialise the external entity's `TopicRenderReference`. This is because the `TopicRenderReference` expects the abbreviated declaration fragments [2]. This results in the abbreviated declaration fragments correctly being used in the Topics and navigation index, rather than the full declaration fragments. Fixes rdar://156488052. [1]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Infrastructure/External%20Data/OutOfProcessReferenceResolver.swift#L559-L562 [2]: https://github.com/swiftlang/swift-docc/blob/1b4a1850dd2785a8ebabded139ae0af3551bb029/Sources/SwiftDocC/Model/Rendering/References/TopicRenderReference.swift#L50-L53
Now that the declaration fragments will be the abbreviated declaration fragments from `LinkDestinationSummary`, we can propagate those to the navigator metadata for them to be used to inform the title of the navigator item [1]. Fixes rdar://156488052. [1]: https://github.com/swiftlang/swift-docc/blob/65aaf926ec079ddbd40f29540d4180a70af99e5e/Sources/SwiftDocC/Indexing/Navigator/RenderNode%2BNavigatorIndex.swift#L140
ee465d6
to
79c9844
Compare
I've updated the implementation so that all unit tests should now pass. |
@swift-ci please test |
@swift-ci please test |
Thanks for the incredible work on documenting this PR, Andrea! The only question I have about the implementation is if TopicRenderReference only takes fragments, and not subheadingFragments [1], why do we need to add subHeadingDeclarationFragments into the ResolvedInformation [2]? Can't we simply keep the summarized version and default its value to the full declaration from the LinkDestinationSummary in case this is nil? [1] https://github.com/swiftlang/swift-docc/pull/1255/files#diff-c195a5776f681e560e52fc959b22479573bbc847217e4ba4b66c0a0f29f31424L169 |
XCTAssertEqual(summary.subHeadingDeclarationFragments, [ | ||
.init(text: "func", kind: .keyword, identifier: nil), | ||
.init(text: " ", kind: .text, identifier: nil), | ||
.init(text: "globalFunction", kind: .identifier, identifier: nil), | ||
.init(text: "(", kind: .text, identifier: nil), | ||
.init(text: "Data", kind: .typeIdentifier, identifier: nil, preciseIdentifier: "s:10Foundation4DataV"), | ||
.init(text: ", ", kind: .text, identifier: nil), | ||
.init(text: "considering", kind: .identifier, identifier: nil), | ||
.init(text: ": ", kind: .text, identifier: nil), | ||
.init(text: "Int", kind: .typeIdentifier, identifier: nil, preciseIdentifier: "s:Si"), | ||
.init(text: ")", kind: .text, identifier: nil) | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an example where the subheading declaration fragments and the full declaration fragments are not the same?
/// Information about the resolved abbreviated declaration fragments, if any. | ||
/// | ||
/// They are used for displaying in contexts where the full declaration fragments would be too verbose, like in the Topics section or the navigation index. | ||
public let subHeadingDeclarationFragments: DeclarationFragments? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the subheading declaration fragments it's used instead of the fragments in the TopicRenderReference why do we want to keep declarationFragments here instead of only keeping the subheading one?
Bug/issue #, if applicable: rdar://156488052
Summary
Improves the quality of the navigator titles for external render nodes. Navigator titles are derived from the item's declaration fragments when at least one of the following is met 1:
These declaration fragments are expected to be the abbreviated declaration fragments 3 of the symbol.
This PR helps capture the abbreviated declaration fragments of the symbol for external entities, so that they can be used in the navigator. The final goal is to have external entities in the navigator render no differently from local entities.
Implementation
There was no change needed to the
LinkResolver.ExternalEntity
type, as some declaration fragments were already being stored as part ofLinkResolver.ExternalEntity.TopicRenderReference.fragmentsVariants
4.The main issue was that while
OutOfProcessReferenceResolver.ResolvedInformation
relied on the fragments that it was receiving from theOutOfProcessReferenceResolver
to be the abbreviated declaration fragments,LinkDestinationSummary
was only encoding the full declaration fragments only as part of its summary:swift-docc/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift
Line 445 in 1b4a185
swift-docc/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift
Line 454 in 1b4a185
The abbreviated declaration fragments are different from the full declaration fragments and defined as a different field (
subHeading
5) in the symbol graph (and therefore cannot be derived by DocC), but they're ultimately processed and captured as part ofRenderMetadata.fragmentsVariants
6.The main changes needed were to update the documentation of
OutOfProcessReferenceResolver.ResolvedInformation
andLinkDestinationSummary
to have an extra property,subHeadingDeclarationFragments
, which stores the abbreviated declaration fragments. These declaration fragments can then be used when initialisingLinkResolver.ExternalEntity.TopicRenderReference.fragmentsVariants
.More detail on the implementation can be found in commit 832f1eb.
Alternatives considered
Considered modifying
LinkDestinationSummary.declarationFragments
instead of adding a new optional field, however the full declaration fragments are used to determine the full name 7 of the symbol for diagnostic reporting 8.By introducing a new field we also ensure this is a non-breaking change.
Navigator comparison (using swift-docc-render):
This compares what it looks like to refer to those symbols within its local DocC bundle versus what it would look like to curate them as external links:
And if we also bring in the symbol kind changes from #1251, it becomes even closer:
Dependencies
N/A
Testing
Verified by using 2 bundles -- one for generating linkable entities, another for referencing an external link from the other bundle -- and verifying that the declaration fragments in the linkable entities are the abbreviated, subheading declaration fragments.
Steps:
swift run docc preview ExampleA.docc --emit-digest
a. Look at http://localhost:8000/documentation/mykit
b. Look at the Topics section and the navigator titles for both the class and the function
DOCC_LINK_RESOLVER_EXECUTABLE=ExampleB.docc/bin/test-data-external-resolver swift run docc preview ExampleB.docc
Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.
AddedUpdated tests./bin/test
script and it succeeded