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

Clarify the difference between empty map, none, and hidden in EEP 48 #33

Closed
wants to merge 1 commit into from
Closed

Conversation

josevalim
Copy link
Contributor

This aligns the EEP with the usage of those values in Erlang/OTP XML,
EDoc, and Elixir.

This aligns the EEP with the usage of those values in Erlang/OTP XML,
EDoc, and Elixir.
Copy link
Contributor

@garazdawi garazdawi left a comment

Choose a reason for hiding this comment

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

I'm trying to recall how all this works for Erlang/OTP.

As far as I can tell the way that I have implemented it is that none and #{} are for all intents and purposes equivalent. none is used when the docs are created automatically from the AST, while #{} is created when the docs are generated by erl_docgen. I found the previous discussions about this and I can't really make sense of why past me thought that there was a significant difference between the two.

How does elixir and ex_doc generate/consume these values?

Below follows a description of what Erlang/OTP does:

shell_docs

shell_docs renders this:

For modules and doc entrues:

  • #{ <<"en">> -> ... } -> render docs
  • #{ <<"se">> -> .., <<"pr_BR">> -> ...} -> render "first" docs
  • #{} -> render docs with text "There is no documentation for ?MODULE/?ENTRY"
  • none -> render docs with text "There is no documentation for ?MODULE/?ENTRY" (created by code:get_doc)
  • hidden -> render docs with text "The documentation for ?MODULE is hidden. This probably means
    that it is internal and not to be used by other applications."

erl_docgen

erl_docgen generates this:

For ModuleDocs

  • #{ <<"en">> -> ... } -> normal docs
  • hidden -> For modules that are internal

For doc entries:

  • #{ <<"en">> -> ... } -> normal docs
  • #{} -> for entries that are documented, but without any text. Only entries of the type type can create an empty map.

A hidden doc entry is just left out of the doc entry list. hidden or none are never used.

code:get_doc/1

code:get_doc/1 generates this for any module that does not have a code chunk:

For ModuleDocs

  • none -> There is no documentation

For doc entries:

  • none -> There is no documentation
  • If there is a -spec in the AST, we create a signature from that.

entry
An empty map may be given when the entry has no documentation but the
entry must still be listed. Alternatively, the atom `none` must be
used when the entry has no documentation and it must not be listed.
Copy link
Contributor

Choose a reason for hiding this comment

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

When describing the same mechanism for Doc we use the words public and reference index instead of listed. Can we rephrase this to use the same terminology?

@josevalim
Copy link
Contributor Author

@garazdawi I am totally fine with treating :none the same as %{}. The goal of this PR was exactly to align with your linked comment (and we changed ExDoc to align with your linked comment but we can revert it). /cc @erszcz

@erszcz
Copy link

erszcz commented Sep 20, 2021

As I understand it, the problem case was when:

  • we used ExDoc to generate HTML from EDoc chunks
  • a module in question had no ModuleDoc (none), but did have docs for functions

Ultimately, this lead to the module as a whole not getting an HTML page generated. erlang/otp#5205 changes EDoc to return #{} as the default if no ModuleDoc is present, so that the ExDoc HTML still gets generated and functions docs are accessible there.

In comparison to shell_docs, as far as I understand:

  • shell_docs prints There is no documentation for ?MODULE/?ENTRY if ModuleDoc is none
  • but it prints docs for the functions of the module in question when invoked with h(M, F) - by defaulting ModuleDoc to none in EDoc we would not get the ExDoc HTML page generated at all, effectively hiding function documentation that might've been present

@josevalim
Copy link
Contributor Author

@erszcz correct. The point though is that we made it so ExDoc treats none and %{} as distinct things, but we could make it so they are the same, so there is no need to merge the OTP PR.

@erszcz
Copy link

erszcz commented Sep 20, 2021

Indeed, one of the values seems redundant.

@garazdawi
Copy link
Contributor

So to recap, that would mean that both none and #{} mean that the module/entry are public but contain no documentation. So it should show up in listings and show potential signature+metadata.

While ModuleDoc = hidden means that it is not public, and entry missor or Doc = hidden means that it is not public.

Erlang treats doc chunk missing as if ModuleDoc = none and all the exported functions have Doc = none. I suppose that this is not a problem that you have in Elixir, except for Erlang code that is.

@erszcz
Copy link

erszcz commented Sep 20, 2021

@garazdawi

entry missing or Doc = hidden means that it is not public.

I think the shell_docs logic you described above is spot on:

  • entry missing -> There is no documentation for ?MODULE/?ENTRY
  • Doc = hidden -> The documentation for <entry> is hidden. This probably means that it is internal and not to be used by other applications. (in case of EDoc it's a hint you might actually get the docs visible by providing the private option to EDoc)

@josevalim
Copy link
Contributor Author

We are all on the same page. I will close this PR and update ExDoc. We can probably close the OTP PR for Edoc too. Thanks!

@josevalim josevalim closed this Sep 20, 2021
@garazdawi
Copy link
Contributor

@garazdawi

entry missing or Doc = hidden means that it is not public.

I think the shell_docs logic you described above is spot on:

  • entry missing -> There is no documentation for ?MODULE/?ENTRY
  • Doc = hidden -> The documentation for <entry> is hidden. This probably means that it is internal and not to be used by other applications. (in case of EDoc it's a hint you might actually get the docs visible by providing the private option to EDoc)

This not how shell_docs behaves today. For entry missing it prints nothing, only returns {error,function_missing}. Example:

1> h(user, start).
{error,function_missing}

This is the same return you get if you put a function that actually does not exist:

1> h(user, start_me_up).
{error,function_missing}

I wonder if we should start generating hidden entries for functions that are exported but not documented in erl_docgen... just as we generate ModuleDoc hidden for modules that are not public.

@josevalim josevalim reopened this Sep 21, 2021
@josevalim
Copy link
Contributor Author

Oops, misclick. Sorry.

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.

3 participants