Skip to content
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

Add All Types page generation #3267

Merged
merged 24 commits into from
Nov 24, 2023
Merged

Add All Types page generation #3267

merged 24 commits into from
Nov 24, 2023

Conversation

whyoleg
Copy link
Collaborator

@whyoleg whyoleg commented Oct 27, 2023

Fixes #2887

Notes:

  • All Types page (and link to it) is not generated when there are no types (classes, type aliases, etc) to document in module
  • Link to page is located under all packages in navigation page (HTML format only) and under the Packages block on module page for all formats
  • If documentation or tag (f.e. SinceKotlin) on type differs depending on sourceSet - we don't show documentation or tag for this type
  • Path to all page relative to root of the module:
    • module: **/htmlMultiModule/kotlinx-coroutines-core/index.html
    • all types: **/htmlMultiModule/kotlinx-coroutines-core/all-types.html

Preview of how it will look like with kotlinx-coroutines codebase:

All Types page image
Link to All Types page on module page image
When there are no types in module image
Since Kotlin image

@whyoleg whyoleg self-assigned this Oct 27, 2023
@IgnatBeresnev
Copy link
Member

Superb work, thank you for the description and the screenshots!

If documentation on type (or SinceKotlin tag) differs depending on sourceSet - we don't show it

Huh, we indeed forgot about this corner case. I wonder if "no documentation" is better than "some documentation", even if "some documentation" is not complete.

What I mean is: right now, if common and jvm documentation differs, we don't show anything. But what if we show common's documentation in this case? I would expect it to still be correct and provide at least some basic information, without implementation details.

@ilya-g do you have any thoughts on that? Maybe some stdlib cases come to mind where it would be beneficial or undesirable?

Path to all page relative to root of the module

Is there a way to avoid the whitespace in the filename, and maybe have a different filename altogether? That is, have the page be "All Types", but the html file be all-types.html (without the upper-case prefixes)? Or is it super tightly coupled?

@IgnatBeresnev
Copy link
Member

Link to page is located under all packages in navigation page (HTML format only)

This is also a bit of a technical limitation, right?

If I remember correctly, the navigation tree resets (or even throws an error) if you visit an html page that has no line in the navigation sidemenu. If this is the case, then removing the All Types link from the sidemenu might require additional and somewhat unrelated technical debt work. We also forgot about it while discussing this issue

@whyoleg
Copy link
Collaborator Author

whyoleg commented Oct 30, 2023

Regarding documentation block selection:
Now it uses similar (a little improved) approach which was used for packages description, though different documentation for packages are much harder to achieve comparing to type documentations.
What I spotted in kx.coroutines is:

  • CancellationException has no documentation in common, but has a little different documentation in shared source sets - so no documentation is shown
  • Runnable has the same documentation for all declarations, but because it actualised by typealias on JVM something was lost somewhere

Is there a way to avoid the whitespace in the filename

Found how to fix this in rather simple way, will do, thanks for pointing on it!

@whyoleg
Copy link
Collaborator Author

whyoleg commented Oct 30, 2023

This is also a bit of a technical limitation, right?

Yes and no I believe. Because all-types page is child of module page, we add it to children of module page, and as so it appears on the same level with packages and automatically added to navigation page. I haven't tried to remove it during navigation page generation (may be it will be not so hard), as I thought that may be it's fine to show it there, as IMO it's better for UX to somehow show on which page user is located now in nav bar

@ilya-g
Copy link
Member

ilya-g commented Oct 31, 2023

What I mean is: right now, if common and jvm documentation differs, we don't show anything. But what if we show common's documentation in this case? I would expect it to still be correct and provide at least some basic information, without implementation details.
do you have any thoughts on that? Maybe some stdlib cases come to mind where it would be beneficial or undesirable?

In the old dokka it was hard coded to something like "if there's no common documentation, use the one from JVM". I think too that in this case it would be better to show some summary (e.g. common documentation).

@whyoleg
Copy link
Collaborator Author

whyoleg commented Nov 1, 2023

Update:

  • hide All Types page under a flag dokka.shouldDisplayAllTypesPage (can be enabled in the same way as sinceKotlin (could be revisited in scope of Introduce extra options for plugin configuration #2776)
  • documentation for type now shown in any case (if it's exists), with priority to common documentation
  • also I've reverted some accidental formatting changes from previous commits, so it should be easier to review PR

typelike.descriptions[sourceSet]?.let { sourceSet to it }
}.distinctBy { it.second }.singleOrNull()

val customTags = typelike.customTags.values.mapNotNull { sourceSetTag ->
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to show all custom tags, e.g. author, throws and so on?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As far as I see from code, author and throws are not custom tags.
In our codebase there are 2 custom tags provider: SinceKotlin and Mathjax
Still, may be we really need to show SinceKotlin only

Copy link
Contributor

@vmishenev vmishenev Nov 2, 2023

Choose a reason for hiding this comment

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

As far as I see from code, author and throws are not custom tags.

Oh, sorry, I forgot(

Still, may be we really need to show SinceKotlin only

I think it should be consistent with a list of types in a regular page (package, classlike ..) so showing all custom tags is ok.

Copy link
Member

Choose a reason for hiding this comment

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

Looks as if it can get SinceKotlin and the description from different source sets, which might be misleading, as there might be cases when a type's actual was added later (like ConcurrentModificationException)

I think the logic here needs to be predetermined and intentional. I can think of two solutions, but both have drawbacks

  • Get SinceKotlin from the same source set as the description. Drawback: if the description is taken from JVM, common's SinceKotlin might be lower/higher.
  • Get the earliest SinceKotlin. Drawback: it might be inconsistent with the text in the description.

Wouldn't hurt consulting Ilya about this

Still, may be we really need to show SinceKotlin only

I don't think it's a problem for now, and hardcoding it is less than ideal, so I'd leave it as is

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@ilya-g what are your thoughts regarding comment above about best (more correct) way of showing SinceKotlin/description when they are different per source set?

Copy link
Member

Choose a reason for hiding this comment

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

I'd propose to do the same as in the old dokka: showing the minimum version among those remained after filtering with platform selector.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks! Now we take minimum SinceKotlin version in All Types page. Implemented in d744e49

Though, it's not affected by platform selector and will only show minimum version based on all platforms, as it looks like it's not possible to show different content based on different set of platform selectors.

Also I've checked how current stdlib documentation behaves, and looks like it doesn't show SinceKotlin at all if they are different per sourceSet + no changes after filtering by platform.
Here is an example for kotlin.ConcurrentModificationException:

With all platforms selected image
With only Native selected image

So I would propose to go for now without additional filtering based on selected platforms. And implement it later if needed. @ilya-g WDYT?

Copy link
Member

@IgnatBeresnev IgnatBeresnev Nov 23, 2023

Choose a reason for hiding this comment

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

We discussed this question with Oleg, and it looks like we indeed don't have the technical ability to change the value dynamically based on platform selectors.

Implementing it would take considerable time, and it doesn't seem to be that critical for the initial release, so let's just merge the PR with the currently implemented and consistent logic: always show the earliest version

We can change it later on if it becomes apparent that it's misleading or is a problem

Copy link
Member

@IgnatBeresnev IgnatBeresnev left a comment

Choose a reason for hiding this comment

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

We discussed most of these in voice, so I didn't go into too much detail. Leaving the comments to not forget about something

core/src/main/kotlin/pages/PageNodes.kt Outdated Show resolved Hide resolved
core/src/main/kotlin/model/Documentable.kt Outdated Show resolved Hide resolved
typelike.descriptions[sourceSet]?.let { sourceSet to it }
}.distinctBy { it.second }.singleOrNull()

val customTags = typelike.customTags.values.mapNotNull { sourceSetTag ->
Copy link
Member

Choose a reason for hiding this comment

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

Looks as if it can get SinceKotlin and the description from different source sets, which might be misleading, as there might be cases when a type's actual was added later (like ConcurrentModificationException)

I think the logic here needs to be predetermined and intentional. I can think of two solutions, but both have drawbacks

  • Get SinceKotlin from the same source set as the description. Drawback: if the description is taken from JVM, common's SinceKotlin might be lower/higher.
  • Get the earliest SinceKotlin. Drawback: it might be inconsistent with the text in the description.

Wouldn't hurt consulting Ilya about this

Still, may be we really need to show SinceKotlin only

I don't think it's a problem for now, and hardcoding it is less than ideal, so I'd leave it as is

plugins/base/src/test/kotlin/content/AllTypesPageTest.kt Outdated Show resolved Hide resolved
Copy link
Member

@IgnatBeresnev IgnatBeresnev left a comment

Choose a reason for hiding this comment

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

Good job and thank you for addressing so many review comments!

Platform.wasm to SinceKotlinVersion("1.8"),
)

fun minSinceKotlinVersionOfPlatform(platform: Platform): SinceKotlinVersion {
Copy link
Member

Choose a reason for hiding this comment

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

nit: since this was moved into SinceKotlinVersion, I think it can be renamed to be just minVersionOfPlatform, so that the call looks like SinceKotlinVersion.minVersionOfPlatform() instead of duplicating SinceKotlinVersion.minSinceKotlinVersionOfPlatform()

Comment on lines 166 to 167
// the structure of custom tag content for SinceKotlin should be in sync
// with how DefaultPageCreator.contentForAllTypes reads it
Copy link
Member

Choose a reason for hiding this comment

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

Also not that critical, but if the two parts must be in sync, it makes sense to have them in a single place. For instance,

// inside one class or file and next to each other, maybe inside SinceKotlinVersion

fun createSinceKotlinCustomTag(): CustomTagWrapper { ... }

fun extractSinceKotlinFromCustomTag(customTagWrapper: CustomTagWrapper): SinceKotlinVersion? {}

The benefit of having these two things next to each other is that you see clearly the correlation between the two, and if one changes - it'll be easier to find and remember to change the other. And you'll be able to reference it in the KDoc

@whyoleg whyoleg merged commit 17ad866 into master Nov 24, 2023
9 checks passed
@whyoleg whyoleg deleted the all-types branch November 24, 2023 09:52
vmishenev pushed a commit that referenced this pull request Mar 20, 2024
* Hide All Types page under a system property
* Show documentation if it exists selecting most relevant
* Take the minimum SinceKotlin version if they differ
* Extract internal configuration properties to one place
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.

Provide an alternative to the alltypes page from old Dokka
4 participants