-
Notifications
You must be signed in to change notification settings - Fork 121
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
When documenting members of extensions to external protocols, display the external protocol's name #732
When documenting members of extensions to external protocols, display the external protocol's name #732
Conversation
the external protocol's name. This is helpful because these pages don’t have the context of being curated inside their “owning” type or protocol. Expand the section that we use for conditional constraints to display the external protocol name, for example: "Self is ExternalProtocol". The new "Self is ExternalProtocol" message will be combined with any other existing generic constraints. Do not do this for extended structs, classes or other extended types, since this generic constraint syntax wouldn't be accurate for them. Also as a related bug fix remove the extendedModule property of the Semanic Symbol class, and instead calculate this based on swiftExtensionVariants. Same for constraintsVariants. Fix the initializer of Semantic Symbol, which previously allowed a nil default value for the extendedModule property, allowing callers to accidentally leave it nil.
|
@swift-ci please test |
|
@swift-ci please test |
| // Double check the existing extension uses the same module and type. If it does not, | ||
| // we must have a tooling or data consistency problem. | ||
| assert( | ||
| existing.extendedModule == extendedModule, //&& existing.typeKind == typeKind, |
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.
Should the commented existing.typeKind == typeKind assertion be included or should it be removed?
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.
Oops I had disabled the second condition while debugging something. I added it back.
| - typeKind: The ``SymbolGraph/Symbol/KindIdentifier`` of the symbol this extension extends. | ||
| - constraint: The new generic constraints to add | ||
| - trait: Which generic constraints variant to append to | ||
| - Returns: True if the constraint was appended to an existing or new swift extension variant. False if there was an existing swift extension variant for a different module. |
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.
This function doesn't have a return value.
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.
Removed
| // MARK: - Private helpers | ||
|
|
||
| /// Return all of this symbol's Swift extension variants. | ||
| func swiftExtensionVariants() -> [DocumentationDataVariantsTrait : SymbolGraph.Symbol.Swift.Extension] { |
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 nothing other then Symbol needs to call this we could make it private
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.
Yes thank you. Marked private.
- Remove incorrect doc comment about a return value - Fix assertion in Symbol#addConstraint - Symbol#swiftExtensionVariants is private
|
@swift-ci please test |
| public func addConstraint( | ||
| extendedModule: String, | ||
| typeKind: SymbolGraph.Symbol.KindIdentifier? = nil, | ||
| constraint newConstraint: SymbolGraph.Symbol.Swift.GenericConstraint, | ||
| trait: DocumentationDataVariantsTrait = DocumentationDataVariantsTrait.swift |
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.
It's good that you are supporting multiple traits here but I'm wondering if we really need to.
Considering that the added constraint is Swift specific, I think maybe we could remove the trait argument and rename the method to indicate that this is only applicable to Swift. That would allow for the implementation to ignore the other traits which realistically should never have this mixin.
Maybe something like this?
/// Append a new generic constraint for the given extended module
/// - Parameters:
/// - extendedModule: The name of the extended module.
/// - extendedSymbolKind: The kind of the extended symbol.
/// - constraint: The new generic constraints to add.
public func addSwiftExtensionConstraint(
extendedModule: String,
extendedSymbolKind: SymbolGraph.Symbol.KindIdentifier? = nil,
constraint newConstraint: SymbolGraph.Symbol.Swift.GenericConstraint
) {- Rename Symbol#addConstraint to addSwiftExtensionConstraint and assume the only relevant trait is DocumentationDataVariantsTrait.swift. - Also rename the typeKind parameter to extendedSymbolKind.
|
@swift-ci please test |
| /// - engine: A diagnostic collecting engine. | ||
|
|
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.
| /// - engine: A diagnostic collecting engine. | |
| /// - documentationCache: A documentation node lookup by the node's resolved reference. | |
| // This symbol starts with 3 generic constraints. See: | ||
|
|
||
| // jq < "Tests/SwiftDocCTests/Test Bundles/TestBundle.docc/mykit-iOS.symbols.json" '.symbols[] | select(.identifier.precise == "s:5MyKit0A5ClassC10myFunctionyyF") | .swiftExtension' |
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.
I would maybe just remove the "jq" part of the comment.
| // This symbol starts with 3 generic constraints. See: | |
| // jq < "Tests/SwiftDocCTests/Test Bundles/TestBundle.docc/mykit-iOS.symbols.json" '.symbols[] | select(.identifier.precise == "s:5MyKit0A5ClassC10myFunctionyyF") | .swiftExtension' | |
| // The original symbol has 3 Swift extension constraints: |
| let constraints = try XCTUnwrap(withoutArticle.constraints) | ||
| XCTAssertEqual(3, constraints.count) | ||
| var constraint = constraints[0] | ||
| XCTAssertEqual(SymbolGraph.Symbol.Swift.GenericConstraint.Kind.sameType, constraint.kind) |
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.
FYI: The compiler should be able to infer the types here allowing these assertions to be shorter and more readable
| XCTAssertEqual(SymbolGraph.Symbol.Swift.GenericConstraint.Kind.sameType, constraint.kind) | |
| XCTAssertEqual(.sameType, constraint.kind) |
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.
That's great - it must be that since I wrote the expected value first, the compiler/Xcode showed me an error until I finished typing the line. I wonder if it makes more sense to write the actual value first inside of XCTAssertEqual for this reason...
| XCTAssertEqual(SymbolGraph.Symbol.Swift.GenericConstraint.Kind.superclass, constraint.kind) | ||
| XCTAssertEqual("Observer", constraint.leftTypeName) | ||
| XCTAssertEqual("NSObject", constraint.rightTypeName) |
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.
FYI: The constrain is equatable so you can compare the entire value on one XCTAsserEqual(...) if you want to:
| XCTAssertEqual(SymbolGraph.Symbol.Swift.GenericConstraint.Kind.superclass, constraint.kind) | |
| XCTAssertEqual("Observer", constraint.leftTypeName) | |
| XCTAssertEqual("NSObject", constraint.rightTypeName) | |
| XCTAssertEqual(.init(kind: .superclass, leftTypeName: "Observer", rightTypeName: "NSObject"), constraint) |
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.
This looks good to me.
I will just point out that this is a small source breaking change because the setters for
SwiftDocC/Symbol/constraintsVariants and SwiftDocC/Symbol/constraints are removed.
However, because assigning new values to those properties didn't really work before I think it's acceptable to remove them.
If we wanted we could add them back, mark them as deprecated, and assert in debug builds.
- Correct doc comment - Clean up/refactor unit test
|
@swift-ci please test |
|
@swift-ci please test |
…ded-protocol-names
|
@swift-ci please test |
Explanation: When documenting members of extensions to external protocols, display the
external protocol's name.
Scope: A small amount of new text appears on documentation pages for one type of Swift symbol.
GitHub Issue: none.
Risk: Low. Minor code changes that only impact how protocol extensions of external protocols are documented.
Testing: Ran the ./bin/test script and it succeeded
Reviewer: @d-ronnqvist
rdar://112219546
Summary
When documenting members of extensions to external protocols, display the
external protocol's name. This is helpful because these pages don’t have the
context of being curated inside their “owning” type or protocol.
Expand the section that we use for conditional constraints to display the
external protocol name. For example, this screenshot shows the documentation for
the
stablePartition(by:)symbol in the Swift Algorithms package. Since thispage is curated under "Partitioning and Rotating" it's not obvious that the
function is a member of a protocol extension, or that the protocol extension is
extending the MutableCollection protocol from the Swift Standard Library.
This code change will now show the external protocol's name,
MutableCollection, just below the declaration:Note the new text "Available when Self is MutableCollection."
The new "Self is ExternalProtocol" message will be combined with any other
existing generic constraints. For example,
uniquePermutations(ofCount:)already requires that the associated type
Elementconform to theHashableprotocol.
In this screenshot note the combined text "Available when Element conforms to
Hashable and Self is Collection."
Dependencies
This depends on a new initializer added to SymbolKit in swiftlang/swift-docc-symbolkit#63. We need to merge that PR first, before running the CI tests for this, or merging this.
Testing
The Swift DocC benchmark command
did not show any significant performance regressions or differences.
Rebuilding the documentation for the Swift Algorithms package causes the names of external protocols to appear as expected.
Rebuilding the documentation for other large Swift projects did not introduce any unexpected changes or regressions.
Unit tests were added, including a new test bundle ModuleWithProtocolExtensions.docc that includes symbol graph files showing the use of an external protocol.
Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.
./bin/testscript and it succeeded[ ] Updated documentation if necessary