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

EDoc & co. - known issues and next steps #25

Closed
erszcz opened this issue Mar 31, 2021 · 6 comments
Closed

EDoc & co. - known issues and next steps #25

erszcz opened this issue Mar 31, 2021 · 6 comments
Labels
Agenda Item Item to be discussed at WG meeting

Comments

@erszcz
Copy link

erszcz commented Mar 31, 2021

Background

When working on adding chunk generation support to EDoc (erlef/documentation-wg#4 and erlang/otp#2803) I ran into a number of things which were out of scope for the immediate goal, but are worth considering in general. Some of these are possible future goals which need some broader discussion, some are just known bugs or desirable, simple improvements.

Objective(s)

Could erl_docgen use chunks instead of custom EDoc doclets?

erl_docgen uses custom EDoc doclets to extract type and spec information from -spec/-type tags and inject it into OTP docs. These doclets are prone to breakage when changes in EDoc are introduced. Could erl_docgen use data from chunks instead?

One potential issue here is that EDoc does not store @spec and @type data in chunks at all, whereas the doclets can and do consume this information in case of code that's not yet ported to use -spec and -type attributes.

Callback/type docs are subpar

Callbacks as a language feature are newer than EDoc and proper support has never been added. Rudimentary callback doc support was added together with chunk generation support, but these docs can currently only be plain text. https://github.com/erlang/otp/blob/5d0668a47cd23b5a64996fa31f54c60fe8f7f80c/lib/edoc/test/eep48_SUITE.erl tests codify some features which are and are not supported.

Specifically, @since and @deprecated tags are not supported on -type and -callback attributes. Moreover, it might make sense to support XRef-style -deprecated attributes, instead of the @deprecated tag, similarly to how we prefer -spec/-type to @spec/@type.

Module with no functions crashes EDoc

It's reasonable to create a module which only defines some types, callbacks, and their respective documentation. Currently, EDoc will crash when generating documentation for such a module. Thanks to @DianaOlympos for spotting this.

EDoc escript ($ERL_TOP/lib/edoc/bin/edoc) does not pass on all OTP apps

No matter if chunks or HTML is generated. See https://gist.github.com/erszcz/69a63c8fe2162ab8f6569787639dcf0e for a summary (older revisions contain some specific errors). This happens due to edoc (the script) not accepting -D to define macros from the command line and, what follows, improper invocation - some OTP app specific macros are defined in Makefiles, so it's not trivial to run a batch script across all apps, which would be aware of these macros and define them properly per app.

shell_docs display glitch

11:16:04 erszcz @ x6 : ~/work/josefs/gradualizer (record-field-zip-fix *%)
$ r3 as docs shell
Erlang/OTP 24 [RELEASE CANDIDATE 1] [erts-12.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Eshell V12.0  (abort with ^G)
1> h(typechecker, return, 1).

\240\240return(X)

  There is no documentation for return/1
ok

Steps to reproduce. \240\240 is not expected. There's no newline after There is no documentation....

See erlang/otp#5206

Multiple constraints on the same variable are not supported when generating chunks

%% Helper module for binaries/bitstrings
-module(gradualizer_bin).
-export([compute_type/1]).
-include("gradualizer.hrl").
%% Computes the type of a bitstring expression or pattern based on the sizes
%% of the elements. The returned type is a normalized bitstring type.
-spec compute_type(ExprOrPat) -> gradualizer_type:abstract_type()
        when ExprOrPat :: {bin, _, _},
             ExprOrPat :: gradualizer_type:abstract_expr().
compute_type(Bin) ->
    View = bin_view(Bin),
    bitstr_view_to_type(View).

Repeated ExprOrPat causes EDoc to crash. Same steps to reproduce as in the previous item.

Line numbering in chunks

@wojtekmach reported an inconsistency / issue with line numbers for POIs stored in the chunks. IIRC the lines of @doc tags are stored in the chunk, whereas the corresponding function head lines would make more sense. I can't recover the details, since the original post is old and too deep in the Slack archive now :|

shell_docs - no newline before type name

Eshell V11.1.7  (abort with ^G)
1> ht(typechecker).
   typechecker

These types are documented in this module:

EDoc - top level text is not wrapped into paragraphs

This one is also lost in the Slack archive, but the issue is that EDoc does not reliably wrap all paragraphs into <p> elements. For example:

%% @doc Text.
%%
%% More text.
f() -> ok.

Text. will be returned as <p>Text.</p>, but the latter More text. won't. This is a nuisance for tools which later consume doc chunks.

EDoc - simple text lists are not picked up as lists

This was never a feature of EDoc and is not in the parser at all, but apparently, some projects assume it was, possibly due to how natural it feels to write in this style.

$ head src/gradualizer.erl
%%% @doc Main external API of the Gradualizer
%%%
%%% The functions `type_check(file|module|dir)' accept the following options:
%%% - `{i, Dir}': Include path for `-include' and `-include_lib' when checking
%%%   Erlang source files. Specify multiple times for multiple include paths.
%%% - `stop_on_first_error': if `true' stop type checking at the first error,
%%%   if `false' continue checking all functions in the given file and all files

Renders as:

1> h(gradualizer).

   gradualizer

  Main external API of the Gradualizer

  The functions type_check(file|module|dir) accept the following
  options: - {i, Dir}: Include path for -include and
  -include_lib when checking Erlang source files. Specify
  multiple times for multiple include paths. -
  stop_on_first_error: if true stop type checking at the first

EDoc / EEP-48 - @deprecated discrepancy

@deprecated tag in EDoc allows markup, in the EEP has to be a flat binary. ExDoc assumes it might contain markup, e.g. links to better deprecation rationale.

Formatting issues

1> h(erl_syntax, form_list).

  -spec form_list(Forms :: [syntaxTree()]) -> syntaxTree().

  Creates an abstract sequence of "source code forms". If Forms is [F1, ..., Fn], where each Fi is a form (see is_form/1, the result
  represents

    F1
         ...
         Fn

  where the Fi are separated by one or more line breaks. A node of type form_list is itself regarded as a source code form; see
  flatten_form_list/1.

  Note: this is simply a way of grouping source code forms as a single syntax tree, usually in order to form an Erlang module definition.
  See also: flatten_form_list/1, form_list_elements/1, is_form/1.
ok

Preformatted text (F1 ... Fn) is not formatted properly.
See also: is clumped together with the preceding text - this might be caused by top-level text not being always wrapped in a <p>.

@erszcz erszcz added the Agenda Item Item to be discussed at WG meeting label Mar 31, 2021
@erszcz
Copy link
Author

erszcz commented Mar 31, 2021

Another one - some apps/projects use HTML tables (or other tags) which are stripped before getting stored in chunks - erlang/otp#2803 (comment)

@paulo-ferraz-oliveira
Copy link

Here's another one (OTP 24)...

-ifdef(TEST).
%% @doc start in TEST
-spec start(Any :: any()) -> ok.
start(_Args) ->
    ok.
-else.
%% @doc start in TEST
-spec start(Any :: any()) -> ok.
start(_Args) ->
    ok.
-endif.

It crashes with {'EXIT', {{badmatch, false}, [{edoc_extract, insert_specs, 3, [{file, "edoc_extract.erl"}, ...

As per @erszcz, I also tried with @clear between -else. and %%.

In OTP 21.3, for example, it doesn't throw an exception, but generates duplicates like

Function Details

start/1
start(Any::any()) -> ok
start in TEST

start/1
start(Any::any()) -> ok
start in TEST

@erszcz
Copy link
Author

erszcz commented Apr 7, 2021

#25 (comment) is partially addressed by erlang/otp#4716. Partially, because @docs might still cause errors, but at least -specs are handled better.

@paulo-ferraz-oliveira
Copy link

😄 I got into the habit of always using {preprocess, true} in my rebar.config.

@josevalim
Copy link
Contributor

On today's meeting, we discussed opening up an Action Item to integrate Rebar3 and EDoc. In particular, we want to build the Docs chunk for dependencies directly from Edoc, so Erlang devs can access documentation from EDoc projects from the shell, editors, etc.

@ferd
Copy link
Member

ferd commented Jan 4, 2022

I believe this has been discussed and fixed. Rebar3_hex v7 does support and demoes this feature, and I believe this was the last straggler to tackle: https://github.com/erlef/rebar3_hex#documentation and https://hexdocs.pm/rebar3_hex/readme.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Agenda Item Item to be discussed at WG meeting
Projects
None yet
Development

No branches or pull requests

4 participants