# Combined documentation of multiple targets

**URL:** <https://forums.swift.org/t/combined-documentation-of-multiple-targets/59579>\
**Category:** Swift-DocC\
**Tags:** docc\
**Created:** [August 10, 2022, 11:00pm UTC](https://forums.swift.org/t/combined-documentation-of-multiple-targets/59579 "2022-08-10T23:00:20Z")\
**Posts on this page:** 1\
**Showing post:** 16

<div class="post-metadata">

**Author:** ![ronnqvist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ronnqvist/32/20110_2.png) [@ronnqvist](https://forums.swift.org/u/ronnqvist)\
**Post date:** [August 12, 2022, 9:15pm UTC](https://forums.swift.org/t/combined-documentation-of-multiple-targets/59579/16 "2022-08-12T21:15:22Z")

</div>

## Symbol link priorities and links to extensions

There are a number of subtleties to how symbol links work in DocC.

> [@taylorswift](#):
>
> > [@ronnqvist](#):
> >
> > Collisions between symbols and targets shouldn't happen with this syntax. For example if "MyTarget" had a "Something" dependency and a "Something" symbol then `/Something` would refer to the dependency and ` Something` would refer to the symbol.
> 
> based on reading [How to properly reference a type and module with the same name?](https://forums.swift.org/t/how-to-properly-reference-a-type-and-module-with-the-same-name/55964) , i assumed `Something` would refer to the _module_, and `Something/Something` would refer to the the symbol. if this is true, then `/Something` would not provide any additional expressive power.
> 
> i always found this strange, but i implemented the lookup algorithm in Biome this way for consistency with DocC.

That's mostly true but the missing piece is that DocC resolves all references relative to the page where the link occurs. For example, in this hypothetical code:

```swift
// 1: the module is named "Something"
class TopLevelSymbol {
    class Something { // 2: the first nested symbol
        class NestedOne {
            class NestedTwo {
                class Something { // 3: the deeply nested symbol
                    ...
                }
            }
        }
    }
}
class DifferentSymbol {
    ...
}

```

The link ```Something``` from the documentation for `NestedOne` would resolve to the outer nested symbol (2) since that's the container scope but the same link from the `NestedTwo` documentation would resolve to the deeply nested symbol (3) since that's the descendant.

Similarly, the ```Something``` link from the documentation for `TopLevelSymbol` would resolve to its descendant symbol (2). Only from the documentation for `DifferentSymbol` would the ```Something``` link resolve to the module (1).

A leading slash would provide the ability to express an intentional reference to the module in cases where relative descendant or container symbols would otherwise be preferred.

If instead the hypothetical code had a top level "Something" symbol like this:

```swift
// 1: the module is named "Something"
class Something { // 2: now a top-level symbol
    class NestedOne {
        class NestedTwo {
            class Something { // 3: a deeply nested symbol
                ...
            }
        }
    }
}
class DifferentSymbol {
    ...
}

```

then a ```Something/Something``` link could either be interpreted as `"<module> / <top-level>"`, `"<top-level> / <member-of-top-level>"`, or `"<nested> / <member-of-nested>"` in all of the possible scopes. Only the first interpretation would resolve successfully. This means that link resolver implementations need to either back track, branch, or look ahead depending on what their overall link resolution strategy is.

This also becomes relevant for links to extensions.

> [@theMomax](#):
>
> However, I think it would be beneficial to also allow (sufficiently qualified, i.e. starting with a target name) relative links to be used for referring to pages from other targets. This results in relative links behaving just like Swift code, where a local extension to external types can shadow the original member.

This is a very good point and I see that my phrasing was a big the ambiguous when I said (emphasis added)

> I propose that the existing symbol link syntax be extended with a leading slash for links to symbols in **other targets**.

What I should have said is

> [...] a leading slash for links to symbols in **documentation archives passed as dependencies**.

Since extensions are content for the extending module and as passed as the main input to DocC they would be resolved as local symbol links and wouldn't need a leading slash. It would still be optional and DocC would try to resolve the link locally before checking external resolvers.

> [@Document Extensions to External Types Using DocC](https://forums.swift.org/t/document-extensions-to-external-types-using-docc/56060/26):
>
> This point already came up in my proposal-discussion on how to [Document Extensions to External Types Using DocC](https://forums.swift.org/t/document-extensions-to-external-types-using-docc/56060) :
> 
> > [@Document Extensions to External Types Using DocC](https://forums.swift.org/t/document-extensions-to-external-types-using-docc/56060/26):
> >
> > Once [[SR-15431] Support DocC references to symbols defined in another module - Swift ](https://bugs.swift.org/browse/SR-15431) is implemented, we always follow a local first strategy. I.e. if a module shadows a symbol, the simple `EXTENDED_MODULE_NAME/SYMBOL_PATH` identifier links to the local page of the extension (`hostpath/EXTENDING_MODULE_NAME/EXTENDED_MODULE_NAME/SYMBOL_PATH`), not to the original page in the extended module's documentation catalogue (`hostpath/EXTENDED_MODULE_NAME/SYMBOL_PATH`).
> > 
> > In order to reference shadowed symbols, one must use **absolute** identifiers. Absolute identifiers are basically the URL without the leading `hostpath`. That is, shadowed symbols can be referenced unambiguously using `/EXTENDED_MODULE_NAME/SYMBOL_PATH` (note the leading slash).
> > 
> > Firstly, note that absolute identifiers are always an option, i.e. one could also refer to `SlothCreator`'s `NameGenerator` in the Sloth Creator documentation catalogue using `/SlothCreator/NameGenerator`.

If I understand this correctly it means that local content is prioritized over external content. If so, that's how I imagine it would work as well. Even with an optional leading slash, DocC would try to resolve links locally before resolving them as external references. Because of the way that links are always resolved relative to other pages I feel that it's still useful to prefix a local link to with a slash to treat it as an "absolute1" symbol link instead of resolving it relative to the current page.

1. The term "absolute" symbol links can have many meanings. The resolved path to the symbol page in the documentation archive will have an added initial "documentation" path component. This isn't necessary to include when writing the link in content since symbols links can't resolve to tutorials but it is supported to write a symbol link like ```/documentation/SomeTarget/Something``` .

This would mean that if a local extension matched ```/OtherTarget/Something``` then DocC wouldn't attempt to resolve "Something" in the external "OtherTarget" documentation archive dependency.

> [@Document Extensions to External Types Using DocC](https://forums.swift.org/t/document-extensions-to-external-types-using-docc/56060/26):
>
> > [@Document Extensions to External Types Using DocC](https://forums.swift.org/t/document-extensions-to-external-types-using-docc/56060/26):
> >
> > Secondly, relative identifiers **can** be used for referencing external symbols, **if** they are not shadowed. That is, `Swift/Array/count` is a valid identifier in the `SlothCreator` module, even though there is no local extension that defines a `count` on `Swift.Array`.

This is what I propose that we change. I view it as a benefit to the developer or contributor of the documentation to be able to read or write a symbol link without a leading slash and know that it refers to some local symbol or some local extension.

---

_[View the full topic](https://forums.swift.org/t/combined-documentation-of-multiple-targets/59579)._
