Skip to content

Conversation

@mgrebenets
Copy link

@mgrebenets mgrebenets commented Oct 30, 2025

Bug/issue #, if applicable: #1257

Summary

The basic setup is this:

// ImportedModule
struct ExtendedType {}

struct BaseType {}
// MainModule
import ImportedModule

extension ExtendedType {
    func extensionMethod()
}

With the above we have the following issues:

  • /ImportedModule/ExtendedType always resolves to the type extension link
  • /ImportModule/BaseType links are broken
  • Actually links to any module other than the main one are broken and resolve to plain text like /This/Does/Not/Work

Fix

Prioritize absolute links resolution to point to the module referenced in the link, so that /ImportedModule/BaseType finds the base type because the path starts with /.

To refer to the extended type or method, the non-absolute paths work in Xcode and with docc: ImportedModule/ExtendedType resolves to the type extension page, ImportedModule/ExtendedType/extensionMethod() resolves to the extension method page.

Dependencies

N/A

Testing

‼️🤖 Disclaimer: this is an AI-assisted change.

While AI was utilized to identify and apply the initial fix and create initial version of the tests, the code has been reviewed and modified where needed.

More importantly, I have tested the changes both with the sample project attached to the original issue and with a real work project where I'm using xcodebuild docbuild.

In the real world project I'm dealing with similar setup. ParentFramework imports ChildFramework and extends ChildType and then uses paths like /ChildFramework/ChildType in the documentation.

By passing DOCC_EXEC build setting to xcodebuild docbuild invocation along with --enable-experimental-combined-documentation and other required flags I was able to produce doc archives for the 2 modules, then docc merge them into one and in the resulting doc archive all cross-linking works as expected. I can also ue ChildFramework/ChildType/extensionMethod() links to create reference to the extension method doc page.

Steps for testing with the sample project:

  1. Build the DocC with swift build
  2. Clone the sample attached to original issue: https://github.com/keeshux/docc-combined-link-bug
  3. Go into the cloned sample project and run ./gen-docs.sh
  4. Open .build/plugins/Swift-DocC/outputs/intermediates/SubOne.doccarchive
  5. Check that documentation for ClassOne does not resolve the link and looks like this:

Class one from /Core/Module.

image
  1. Modify ./gen-docs.sh by adding the following at the start:

export DOCC_EXEC=/path/to/swift-docc/.build/debug/docc

  1. Run ./gen-docs.sh again
  2. Open .build/plugins/Swift-DocC/outputs/intermediates/SubOne.doccarchive again
  3. Confirm that documentation for ClassOne has the /Core/Module link rendered properly

Class one from Module

image

Checklist

Make sure you check off the following items. If they cannot be completed, provide a reason.

  • Added tests
  • Ran the ./bin/test script and it succeeded
  • Updated documentation if necessary

@d-ronnqvist d-ronnqvist self-requested a review October 31, 2025 15:45
Copy link
Contributor

@d-ronnqvist d-ronnqvist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this PR and thanks for being upfront about the use of AI assistance.

The new test passes without the changes in PathHierarchy+Find which makes me think that either the test isn't reproducing the issue or possibly that the change isn't doing anything. Can you update the test so that if fails like in #1257 (without the fix and passes with the fix).

}


func testAbsoluteLinksToOtherModuleWithExtensions() async throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test passes even without the changes in PathHierarchy+Find

@mgrebenets
Copy link
Author

Thanks for opening this PR and thanks for being upfront about the use of AI assistance.

The new test passes without the changes in PathHierarchy+Find which makes me think that either the test isn't reproducing the issue or possibly that the change isn't doing anything. Can you update the test so that if fails like in #1257 (without the fix and passes with the fix).

Thank you for the feedback and for catching the test behavior!

I dug deeper for better understanding.
The original tests had 2-module setup, while the fix is for 1-module use case.
Basically, the find call for the path from another module is expected to throw an error.
It will be replaced with placeholder like doc://ImportedModule/ExtendedType.
The link points to "nowhere" when single module is built.
Apparently when individual doc archives are merged together (docc merge) the references start pointing at real symbols and become functional. This is what I observed in real world project where I tested the fix.

So the test now makes sure that in-module paths are found and that paths leading to "outside" module can't be found and throw an error, which is expected (to be resolved later when modules are merged).
I also updated the test to enable the experimental linking feature flag at the start.

…endent module causes resolution failure

The basic setup is this:

```swift
// ImportedModule
struct ExtendedType {}

struct BaseType {}
```

```swift
// MainModule
import ImportedModule

extension ExtendedType {
    func extensionMethod()
}
```

With the above we have the following issues:

- `/ImportedModule/ExtendedType` **always** resolves to the type extension link
- `/ImportModule/BaseType` links are broken

Prioritize absolute links resolution to point to the module referenced in the link, so that `/ImportedModule/BaseType` finds the base type because the path starts with `/`.

To refer to the extended type or method, the non-absolute paths work in Xcode and with docc: `ImportedModule/ExtendedType` resolves to the type extension page, `ImportedModule/ExtendedType/extensionMethod()` resolves to the extension method page.

> ‼️🤖 Disclaimer: this is an AI-assisted change.

While AI was utilized to identify and apply the initial fix and create initial version of the tests, the code has been reviewed and modified where needed.

More importantly, I have tested the changes both with the sample project attached to the original issue and with a real work project where I'm using `xcodebuild docbuild`.

In the real world project I'm dealing with similar setup.
`ParentFramework` imports `ChildFramework` and extends `ChildType` and then uses paths like `/ChildFramework/ChildType` in the documentation.

By passing `DOCC_EXEC` build setting to `xcodebuild docbuild` invocation along with `--enable-experimental-combined-documentation` and other required flags I was able to produce doc archives for the 2 modules, then `docc merge` them into one and in the resulting doc archive all cross-linking works as expected.
I can also ue `ChildFramework/ChildType/extensionMethod()` links to create reference to the extension method doc page.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants