Skip to content

Conversation

@d-ronnqvist
Copy link
Contributor

@d-ronnqvist d-ronnqvist commented Jul 10, 2024

Bug/issue #, if applicable: rdar://130496794

Summary

This fixes a special case with the validation of parameter and return value documentation where different platforms have different signatures for the language representation of the same symbol.

Dependencies

None.

Testing

  • Define a C function with different parameters for different platforms, for example:

    #if TARGET_OS_OSX
    void doSomething(int first);
    #else
    int doSomething(int first, int second);
    #endif
  • Extract symbol graph files for both platforms

  • Document the function in a documentation extension file:

    # ``doSomething``
    
    Some documentation for this function
    
    - Parameters:
      - first: Some description for the parameter that's available on all platforms.
      - second: Some description for the parameter that's available on some platforms.
    - Returns: Some description for the return value that's only available on some platforms.
  • Build documentation using both platform's symbol graph files.

    • There shouldn't be a warning about the documentation for the second parameter or the return value.
    • The rendered page should display both parameter's documentation and the return value documentation.
Screenshot 2024-07-10 at 15 54 09

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 Not applicable

@d-ronnqvist d-ronnqvist requested a review from anferbui July 10, 2024 11:16
@anferbui
Copy link
Contributor

@d-ronnqvist Could you please share a screenshot of the rendered page for the example symbol from your PR description?

@d-ronnqvist
Copy link
Contributor Author

@d-ronnqvist Could you please share a screenshot of the rendered page for the example symbol from your PR description?

Absolutely. I added a screenshot. It's not particularly exciting; just both declarations and both parameter's documentation (and the return value documentation).

Without these changes it would non-deterministically (depending on which symbol graph file it loaded first) display either the return value documentation (which applies to one platform) or the second parameter's documentation (which only applies to the other platform).

Copy link
Contributor

@anferbui anferbui left a comment

Choose a reason for hiding this comment

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

LGTM with minor comments :)

Thanks for the screenshot, that helped me understand the changes!

Comment on lines +295 to +299
if !existing.parameters.elementsEqual(signature.parameters, by: hasSameNames) {
for case .insert(offset: let offset, element: let element, _) in signature.parameters.difference(from: existing.parameters, by: hasSameNames) {
existing.parameters.insert(element, at: offset)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this if statement is not needed because if there's no difference then the array will be empty and the loop will iterate over nothing (which is the desired behaviour)

Suggested change
if !existing.parameters.elementsEqual(signature.parameters, by: hasSameNames) {
for case .insert(offset: let offset, element: let element, _) in signature.parameters.difference(from: existing.parameters, by: hasSameNames) {
existing.parameters.insert(element, at: offset)
}
}
for case .insert(offset: let offset, element: let element, _) in signature.parameters.difference(from: existing.parameters, by: hasSameNames) {
existing.parameters.insert(element, at: offset)
}

Copy link
Contributor Author

@d-ronnqvist d-ronnqvist Jul 10, 2024

Choose a reason for hiding this comment

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

The extra if-statement isn't necessary but it's faster in the common case where the API has the same signature on all platforms.

Here's a chart (that I made just now) of a microbenchmark where I create 1000 fake symbols, that each exist on two platforms and have an increasing number of fake parameters named "AAAAAAA", "BBBBBBB", "CCCCCCC", etc. on both platforms.

chart

You can see that the equalElements(_:by:) check makes a fairly fast early exit compared to much more sophisticated differences(from:by) computation that finds no differences. As the symbols get more and more parameters this difference is lessened but at fewer than 10 parameters, it's a rather significant difference.

If I update the benchmark to have minor differences between the parameters of each platform for all 1000 fake symbols, the overhead of the redundant equalElements(_:by:) check is barely measurable:

chart

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll add a shorter version of this comment to the code so that someone else (including me when I inevitably forget about this) doesn't remove the if-statement in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the deep-dive, sounds great!

@d-ronnqvist
Copy link
Contributor Author

@swift-ci please test

@d-ronnqvist d-ronnqvist merged commit 563b958 into swiftlang:main Jul 11, 2024
@d-ronnqvist d-ronnqvist deleted the platform-specific-properties branch July 11, 2024 06:31
d-ronnqvist added a commit to d-ronnqvist/swift-docc that referenced this pull request Jul 11, 2024
…wiftlang#979)

* Support documenting platform specific properties and return values

rdar://130496794

* Add comment that the redundant `equalElements(_:by:)` check is faster in the common case.
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