From aeb55a38967d5a159ec507fe13820e67cdef6d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20R=C3=B6nnqvist?= Date: Tue, 10 Dec 2024 15:06:34 +0100 Subject: [PATCH] Document how to disambiguate symbol links using type signature information (#1095) * Indent table markup for readability * Add more details about how relative symbol links works * Move examples about unambiguous links before "Ambiguous Symbol Links" section. * Reorder list of supported disambiguation symbol types * Add missing supported disambiguation symbol types * Move the symbol type disambiguation example above the hash disambiguation example * Update `Sloth/update(_:)` example to describe type disambiguation rdar://136207820 * Add another more complicated type disambiguation example rdar://136207820 * Minor refinements to the new documentation * Fix 3 incomplete sentences in the new documentation * Add a table of link disambiguation examples * Apply suggestions from code review Co-authored-by: Maya Epps <53411851+mayaepps@users.noreply.github.com> --------- Co-authored-by: Maya Epps <53411851+mayaepps@users.noreply.github.com> --- .../linking-to-symbols-and-other-content.md | 272 +++++++++++++----- 1 file changed, 200 insertions(+), 72 deletions(-) diff --git a/Sources/docc/DocCDocumentation.docc/linking-to-symbols-and-other-content.md b/Sources/docc/DocCDocumentation.docc/linking-to-symbols-and-other-content.md index e9665bb07..c30e36de9 100644 --- a/Sources/docc/DocCDocumentation.docc/linking-to-symbols-and-other-content.md +++ b/Sources/docc/DocCDocumentation.docc/linking-to-symbols-and-other-content.md @@ -6,74 +6,122 @@ Facilitate navigation between pages using links. DocC supports the following link types to enable navigation between pages: -| Type | Usage | -| --- | --- | -| Symbol | Links to a symbol's reference page in your documentation. | -| Article | Links to an article or API collection in your documentation catalog. | -| Tutorial | Links to a tutorial in your documentation catalog. | -| Web | Links to an external URL. | +| Type | Usage +| -------- | ----- +| Symbol | Links to a symbol's reference page in your documentation. +| Article | Links to an article or API collection in your documentation catalog. +| Tutorial | Links to a tutorial in your documentation catalog. +| Web | Links to an external URL. ### Navigate to a Symbol -To add a link to a symbol, wrap the symbol's name in a set of double backticks -(\`\`). +To add a link to a symbol in your module, wrap the symbol's name in a set of double backticks (\`\`): ```markdown -``SlothCreator`` +``Sloth`` ``` -For nested symbols, include the path to the symbol in the link. +For links to member symbols or nested types, include the path to the symbol in the link: ```markdown -``SlothCreator/Sloth/eat(_:quantity:)`` +``Sloth/eat(_:quantity:)`` +``Sloth/Food`` ``` -DocC resolves symbol links relative to the context they appear in. For example, -a symbol link that appears inline in the `Sloth` class, and targets a -symbol in that class, can omit the `SlothCreator/Sloth/` portion of the symbol -path. +DocC resolves symbol links relative to the context that the link appears in. +This allows links in a type's documentation comment to omit the type's name from the symbol path when referring to its members. +For example, in the `Sloth` structure below, the `init(name:color:power:)` symbol link omits the `Sloth/` portion of the symbol path: -In some cases, a symbol's path isn't unique, such as with overloaded methods in -Swift. For example, consider the `Sloth` structure, which has multiple -`update(_:)` methods: +```swift +/// ... +/// You can create a sloth using ``init(name:color:power:)``. +public struct Sloth { // ╰──────────┬──────────╯ + /// ... // ╰─────refers-to────╮ + public init(name: String, color: Color, power: Power) { // ◁─╯ + /* ... */ + } +} +``` + +If DocC can't resolve a link in the current context, it gradually expands the search to the containing scope. +This allows links from one member to another member of the same type to omit the containing type's name from the symbol path. +For example, in the `Sloth` structure below, +the `eat(_:quantity:)` symbol link in the `energyLevel` property's documentation comment omits the `Sloth/` portion of the symbol path: ```swift -/// Updates the sloth's power. -/// -/// - Parameter power: The sloth's new power. -mutating public func update(_ power: Power) { - self.power = power +/// ... +public struct Sloth { + /// ... + /// Restore the sloth's energy using ``eat(_:quantity:)``. + public var energyLevel = 10 // ╰───────┬──────╯ + // │ + /// ... // ╰──────refers-to─────╮ + public mutating func eat(_ food: Food, quantity: Int) -> Int { // ◁─╯ + /* ... */ + } } +``` -/// Updates the sloth's energy level. -/// -/// - Parameter energyLevel: The sloth's new energy level. -mutating public func update(_ energyLevel: Int) { - self.energyLevel = energyLevel +> Note: +If you prefer absolute symbol links you can prefix the symbol path with a leading slash followed by the name of the module to which that symbol belongs: +> +> ```markdown +> ``/SlothCreator/Sloth`` +> ``/SlothCreator/Sloth/eat(_:quantity:)`` +> ``/SlothCreator/Sloth/Food`` +> ``` +> +> DocC resolves absolute symbol links from the module's scope instead of the context that the link appears in. + +Symbol paths are case-sensitive, meaning that symbols with the same name in different text casing are unambiguous. +For example, consider a `Sloth` structure with both a `color` property and a `Color` enumeration type: + +```swift +public struct Sloth { + public var color: Color + + public enum Color { + /* ... */ + } } ``` -Both methods have an identical symbol path of `SlothCreator/Sloth/update(_:)`. -In this scenario, and to ensure uniqueness, DocC uses the symbol's unique -identifier instead of its name to disambiguate. DocC's warnings about ambiguous -symbol links suggests one disambiguation for each of the symbols that match the -ambiguous symbol path. +A ` ``Sloth/color`` ` symbol link unambiguously refers to the `color` property and a ` ``Sloth/Color`` ` symbol link unambiguously refers to the inner `Color` type. + +#### Symbols with Multiple Language Representations + +Symbol links to symbols that have representations in more than one programming language can use symbol paths in either source language. +For example, consider a `Sloth` class with `@objc` attributes: + +```swift +@objc(TLASloth) public class Sloth: NSObject { + @objc public init(name: String, color: Color, power: Power) { + self.name = name + self.color = color + self.power = power + } +} +``` + +You can write a symbol link to the Sloth initializer using the symbol path in either source language: + +**Swift name** ```markdown -### Updating Sloths -- ``Sloth/update(_:)-4ko57`` -- ``Sloth/update(_:)-jixx`` +``Sloth/init(name:color:power:)`` +``` + +**Objective-C name** + +```markdown +``TLASloth/initWithName:color:power:`` ``` -In the example above, both symbols are functions, so you need the unique -identifiers to disambiguate the `Sloth/update(_:)` link. +#### Ambiguous Symbol Links -Unique identifiers aren't the only way to disambiguate symbol links. If a symbol -has a different type from the other symbols with the same symbol path, you can -use that symbol's type suffix to disambiguate the link and make the link refer -to that symbol. For example, consider a `Color` structure with `red`, `green`, -and `blue` properties for color components and static properties for a handful -of predefined color values: +In some cases a symbol's path isn't unique. +This makes it ambiguous what specific symbol a symbol link refers to. +For example, consider a `Color` structure with `red`, `green`, and `blue` properties for color components and static properties for a handful of predefined color values: ```swift public struct Color { @@ -87,9 +135,8 @@ extension Color { } ``` -Both the `red` property and the `red` static property have a symbol path of -`Color/red`. Because these are different types of symbols you can disambiguate -`Color/red` with symbol type suffixes instead of the symbols' unique identifiers. +Both the `red` property and the `red` static property have a symbol path of `Color/red`. +Because these are different types of symbols you can disambiguate ` ``Color/red`` ` with a suffix indicating the symbol's type. The following example shows a symbol link to the `red` property: @@ -103,65 +150,146 @@ The following example shows a symbol link to the `red` static property: ``Color/red-type.property`` ``` -DocC supports the following symbol types for use in symbol links: +DocC supports the following symbol types as disambiguation in symbol links: | Symbol type | Suffix | |-------------------|-------------------| | Enumeration | `-enum` | | Enumeration case | `-enum.case` | | Protocol | `-protocol` | -| Operator | `-func.op` | | Typealias | `-typealias` | -| Function | `-func` | +| Associated Type | `-associatedtype` | | Structure | `-struct` | | Class | `-class` | +| Function | `-func` | +| Operator | `-func.op` | +| Property | `-property` | | Type property | `-type.property` | +| Method | `-method` | | Type method | `-type.method` | +| Subscript | `-subscript` | | Type subscript | `-type.subscript` | -| Property | `-property` | | Initializer | `-init` | | Deinitializer | `-deinit` | -| Method | `-method` | -| Subscript | `-subscript` | +| Global variable | `-var` | | Instance variable | `-ivar` | | Macro | `-macro` | | Module | `-module` | +| Namespace | `-namespace` | +| HTTP Request | `-httpRequest` | +| HTTP Parameter | `-httpParameter` | +| HTTP Response | `-httpResponse` | +| HTTPBody | `-httpBody` | +| Dictionary | `-dictionary` | +| Dictionary Key | `-dictionaryKey` | -Symbol type suffixes can include a source language identifier prefix — for -example, `-swift.enum` instead of `-enum`. However, the language -identifier doesn't disambiguate the link. +You can discover these symbol type suffixes from DocC's warnings about ambiguous symbol links. +DocC suggests one disambiguation for each of the symbols that match the ambiguous symbol path. -Symbol paths are case-sensitive, meaning that symbols with the same name in -different text casing don't need disambiguation. +Symbol type suffixes can include a source language identifier prefix---for example, `-swift.enum` instead of `-enum`. +However, the language identifier doesn't disambiguate the link. -Symbols that have representations in both Swift and Objective-C can use -symbol paths in either source language. For example, consider a `Sloth` -class with `@objc` attributes: + +In the example above, both symbols that match the ambiguous symbol path were different types of symbol. +If the symbols that match the ambiguous symbol path have are the same type of symbol, +such as with overloaded methods in Swift, a symbol type suffix won't disambiguate the link. +In this scenario, DocC uses information from the symbols' type signatures to disambiguate. +For example, consider the `Sloth` structure---from the SlothCreator example---which has two different `update(_:)` methods: ```swift -@objc(TLASloth) public class Sloth: NSObject { - @objc public init(name: String, color: Color, power: Power) { - self.name = name - self.color = color - self.power = power - } +/// Updates the sloth's power. +/// +/// - Parameter power: The sloth's new power. +mutating public func update(_ power: Power) { + self.power = power +} + +/// Updates the sloth's energy level. +/// +/// - Parameter energyLevel: The sloth's new energy level. +mutating public func update(_ energyLevel: Int) { + self.energyLevel = energyLevel } ``` -You can write a symbol link to the Sloth initializer using the symbol path in either source language. +Both methods have an identical symbol path of `SlothCreator/Sloth/update(_:)`. +In this example there's only one parameter and its type is `Power` for the first overload and `Int` for the second overload. +DocC uses this parameter type information to suggest adding `(Power)` and `(Int)` to disambiguate each respective overload. -**Swift name** +The following example shows a topic group with disambiguated symbol links to both `Sloth/update(_:)` methods: ```markdown -``Sloth/init(name:color:power:)`` +### Updating Sloths + +- ``Sloth/update(_:)-(Power)`` +- ``Sloth/update(_:)-(Int)`` ``` -**Objective-C name** +If there are more overloads with more parameters and return values, +DocC may suggest a combination of parameter types and return value types to uniquely disambiguate each overload. +For example consider a hypothetical weather service with these three overloads---with different parameter types and different return types---for a `forecast(for:at:)` method: + +```swift +public func forecast(for days: DateInterval, at location: Location) -> HourByHourForecast { /* ... */ } +public func forecast(for day: Date, at location: Location) -> MinuteByMinuteForecast { /* ... */ } +public func forecast(for day: Date, at location: Location) -> HourByHourForecast { /* ... */ } +``` + +The first overload is the only one with where the first parameter has a `DateInterval` type. +The second parameter type isn't necessary to disambiguate the overload, and is the same in all three overloads, +so DocC suggests to add `(DateInterval,_)` to disambiguate the first overload. + +The second overload is the only one with where the return value has a `MinuteByMinuteForecast` type, +so DocC suggests to add `‑>MinuteByMinuteForecast` to disambiguate the second overload. + +The third overload has the same parameter types as the second overload and the same return value as the first overload, +so neither parameter types nor return types alone can uniquely disambiguate this overload. +In this scenario, DocC considers a combination of parameter types and return types to disambiguate the overload. +The first parameter type is different from the first overload and the return type is different from the second overload. +Together this information uniquely disambiguates the third overload, +so DocC suggests to add `(Date,_)‑>HourByHourForecast` to disambiguate the third overload. + +You can discover the minimal combination of parameter types and return types for each overload from DocC's warnings about ambiguous symbol links. + +The following example shows a topic group with disambiguated symbol links to the three `forecast(for:at:)` methods from before: ```markdown -``TLASloth/initWithName:color:power:`` +### Requesting weather forecasts + +- ``forecast(for:at:)-(DateInterval,_)`` +- ``forecast(for:at:)->MinuteByMinuteForecast`` +- ``forecast(for:at:)->(Date,_)->HourByHourForecast`` +``` + +> Earlier Versions: +> Before Swift-DocC 6.1, disambiguation using parameter types or return types isn't supported. + +If DocC can't disambiguate the symbol link using either a symbol type suffix or a combination parameter type names and return type names, +it will fall back to using a short hash of each symbol's unique identifier to disambiguate the symbol link. +You can discover these hashes from DocC's warnings about ambiguous symbol links. +The following example shows the same topic group with symbol links to the three `forecast(for:at:)` methods as before, +but using each symbol's unique identifier hash for disambiguation: + +```markdown +### Requesting weather forecasts + +- ``forecast(for:at:)-3brnk`` +- ``forecast(for:at:)-4gcpg`` +- ``forecast(for:at:)-7f3u`` ``` +The table below shows some examples of the types of link disambiguation suffixes that DocC supports: + +| Disambiguation type | Example | Meaning +| ------------------------------- | --------------- | ------------ +| Type of symbol | `-enum` | This symbol is an enumeration. +| Parameter type names | `-(Int,_,_)` | This symbol has three parameters and the first parameter is an `Int` value. +| ^ | `-()` | This symbol has no parameters. +| Return type names | `->String` | This symbol returns a `String` value. +| ^ | `->(_,_)` | This symbol returns a tuple with two elements. +| Parameter and return type names | `-(Bool)->()` | This symbol has one `Bool` parameter and no return value. +| Symbol identifier hash | `-4gcpg` | The hash of this symbol's unique identifier is "`4gcpg`". + ### Navigate to an Article To add a link to an article, use the less-than symbol (`<`), the `doc` keyword,