rescript-lang / rescript-vscode

Official VSCode plugin for ReScript
MIT License
327 stars 55 forks source link

docgen does not distinguish between module and functor #1012

Open woeps opened 3 months ago

woeps commented 3 months ago

Currently a functor is treated exactly like a module (but ignores existent docstrings).

Example Functor to test docgen ```rescript /*** this module provides "convenient" utilities for logging NOTE: this is not a good example of a functor, but just to test docgen for functors */ module type Input = { /*** input module type of the functor */ /** type of the input */ type t /** converts the input to a string */ let toString: t => string } module type Logger = { /*** returned type of the functor */ /** type of the input */ type t /** logs the input */ let log: t => unit } module String = { /*** input module of the functor to hanle strings */ /** type of the input */ type t = string /** converts the input to a string */ let toString = (x: t) => x } module Int = { /*** input module of the functor to handle integers */ /** type of the input */ type t = int /** converts the input to a string */ let toString = (x: t) => x->Int.toString } /** functor that logs the input */ module MakeLogger = (I: Input): (Logger with type t := I.t) => { /*** functor that logs the input */ /** logs the Input */ let log = (x: I.t) => I.toString(x)->Console.log } /** the module that contains the functions to log strings */ module StringLogger = MakeLogger(String) /** the module that contains the functions to log integers */ module IntLogger = MakeLogger(Int) module Var = { /*** another input module for the Logger functor to handle a Variant of type type */ /** type of the input */ type t = Yes | No /** converts the input to a string */ let toString = x => switch x { | Yes => "Yes" | No => "No" } } module Included = { /*** module which includes the Var Logger! */ include MakeLogger(Var) } ```
generated json ```json { "name": "Functor", "docstrings": ["this module provides \"convenient\" utilities for logging \nNOTE: this is not a good example of a functor,\n but just to test docgen for functors"], "source": { "filepath": "test/Functor.res", "line": 1, "col": 1 }, "items": [ { "id": "Functor.Input", "name": "Input", "kind": "moduleType", "docstrings": [], "source": { "filepath": "test/Functor.res", "line": 7, "col": 13 }, "items": [ { "id": "Functor.Input.t", "kind": "type", "name": "t", "signature": "type t", "docstrings": ["type of the input"], "source": { "filepath": "test/Functor.res", "line": 15, "col": 3 } }, { "id": "Functor.Input.toString", "kind": "value", "name": "toString", "signature": "let toString: t => string", "docstrings": ["converts the input to a string"], "source": { "filepath": "test/Functor.res", "line": 16, "col": 3 } }] }, { "id": "Functor.Logger", "name": "Logger", "kind": "moduleType", "docstrings": [], "source": { "filepath": "test/Functor.res", "line": 22, "col": 13 }, "items": [ { "id": "Functor.Logger.t", "kind": "type", "name": "t", "signature": "type t", "docstrings": ["type of the input"], "source": { "filepath": "test/Functor.res", "line": 30, "col": 3 } }, { "id": "Functor.Logger.log", "kind": "value", "name": "log", "signature": "let log: t => unit", "docstrings": ["logs the input"], "source": { "filepath": "test/Functor.res", "line": 31, "col": 3 } }] }, { "id": "Functor.String", "name": "String", "kind": "module", "docstrings": ["input module of the functor to hanle strings"], "source": { "filepath": "test/Functor.res", "line": 37, "col": 8 }, "items": [ { "id": "Functor.String.t", "kind": "type", "name": "t", "signature": "type t = string", "docstrings": ["type of the input"], "source": { "filepath": "test/Functor.res", "line": 45, "col": 3 } }, { "id": "Functor.String.toString", "kind": "value", "name": "toString", "signature": "let toString: t => t", "docstrings": ["converts the input to a string"], "source": { "filepath": "test/Functor.res", "line": 50, "col": 7 } }] }, { "id": "Functor.Int", "name": "Int", "kind": "module", "docstrings": ["input module of the functor to handle integers"], "source": { "filepath": "test/Functor.res", "line": 53, "col": 8 }, "items": [ { "id": "Functor.Int.t", "kind": "type", "name": "t", "signature": "type t = int", "docstrings": ["type of the input"], "source": { "filepath": "test/Functor.res", "line": 61, "col": 3 } }, { "id": "Functor.Int.toString", "kind": "value", "name": "toString", "signature": "let toString: t => string", "docstrings": ["converts the input to a string"], "source": { "filepath": "test/Functor.res", "line": 66, "col": 7 } }] }, { "id": "Functor.MakeLogger", <-- this is the functor "name": "MakeLogger", "kind": "module", "docstrings": [], <-- empty docstrings "source": { "filepath": "test/Functor.res", "line": 1, "col": 1 }, "items": [ { "id": "Functor.MakeLogger.log", "kind": "value", "name": "log", "signature": "let log: I.t => unit", "docstrings": ["logs the input"], "source": { "filepath": "test/Functor.res", "line": 31, "col": 3 } }] }, { "id": "Functor.StringLogger", "kind": "moduleAlias", "name": "StringLogger", "docstrings": ["the module that contains the functions to log strings"], "source": { "filepath": "test/Functor.res", "line": 86, "col": 8 }, "items": [] }, { "id": "Functor.IntLogger", "kind": "moduleAlias", "name": "IntLogger", "docstrings": ["the module that contains the functions to log integers"], "source": { "filepath": "test/Functor.res", "line": 90, "col": 8 }, "items": [] }, { "id": "Functor.Var", "name": "Var", "kind": "module", "docstrings": ["another input module for the Logger functor to handle a Variant of type type"], "source": { "filepath": "test/Functor.res", "line": 92, "col": 8 }, "items": [ { "id": "Functor.Var.t", "kind": "type", "name": "t", "signature": "type t = Yes | No", "docstrings": ["type of the input"], "source": { "filepath": "test/Functor.res", "line": 100, "col": 3 }, "detail": { "kind": "variant", "items": [ { "name": "Yes", "docstrings": [], "signature": "Yes" }, { "name": "No", "docstrings": [], "signature": "No" }] } }, { "id": "Functor.Var.toString", "kind": "value", "name": "toString", "signature": "let toString: t => string", "docstrings": ["converts the input to a string"], "source": { "filepath": "test/Functor.res", "line": 105, "col": 7 } }] }, { "id": "Functor.Included", "name": "Included", "kind": "module", "docstrings": ["module which includes the Var Logger!"], "source": { "filepath": "test/Functor.res", "line": 112, "col": 8 }, "items": [ { "id": "Functor.Included.log", "kind": "value", "name": "log", "signature": "let log: Var.t => unit", "docstrings": ["logs the input"], "source": { "filepath": "test/Functor.res", "line": 31, "col": 3 } }] }] } ```

I guess we need to introduce a new kind called functor? At least a "signature" field should be present (similar to items of kind value): "signature": "module MakeLogger = (I: Input) => (Logger with type t := I.t)". And docstrings should be taken into account.

Questions