Skip to content

Docstring lowering #3

@c42f

Description

@c42f

I've been reading the existing system for dealing with docstrings in Base. It looks to have grown organically over time and first impressions are that it's a bit of a horrifying maze at this point. Though some parts are undoubtedly required complexity which I don't appreciate yet.

Some observations:

  • The parser emits GlobalRef(Core, Symbol("@doc")) rather than something symbolic. This seems like premature lowering.
  • @doc calls Core.atdoc() during macro expansion. This is so bootstrapping works even without Base.Docs being defined. Bootstrapping sets this function to either
    • A no-op (in boot.jl)
    • A simple docstring accumulator docm() defined in "docs/core.jl" (in various places, but basically to deal with docs before Base.Docs is defined)
    • The full implementation in Docs.docm()
  • Docs.docm() does various gymnastics to work around the fact that lowering's desugaring pass hasn't occurred by the time @doc runs:
    • It calls macroexpand to expand user macros to deal with "docstr"\n@some_user_macro xx (like what is supposed to be documented there without knowing what @some_user_macro expands to?)
    • It pattern matches various special syntax cases, particularly short form function syntax
  • Docs.__@doc__ exists for good reasons but "feels pretty weird" - it's used as a marker by macro authors that want a docstring to propagate to only a part of the syntax emitted by the macro.

All this is just to document what I've found so far.

Currently JuliaSyntax already emits a special K"doc" kind for docstrings:

julia> parsestmt(SyntaxNode, "\"docstring\"\nfoo")
line:col│ tree                                   │ file_name
   1:1  │[doc]                                   │
   1:1  │  [string]
   1:2  │    "docstring"
   2:1  │  foo

In JuliaLowering we should somehow use this to make the implementation of docstrings a lot cleaner. Largely this can be managed by not expanding to @doc and rather just lowering the K"doc" kind as part of lowering proper - this way user macros won't be an issue.

It's unclear what to do about @__doc__, if anything. It serves a useful purpose but does feel like an oddity. One option could be to still represent this as a macro, but have it expand to some expression metadata which can be recognized by the lowering of K"doc" nodes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions