-
Notifications
You must be signed in to change notification settings - Fork 57
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
include ModuleAlias target id in doc extraction #886
Comments
This sounds reasonable. @aspeddro something you could look into? |
I was thinking about adding a field for the file path. e.g: {
filepath: "file://src/Pkg__A.res"
} This could be an id? |
I guess it's good enough? Edit: // Root.res
module X = Helper.Render.Calc2 // Helper.res
module Calc = {
// ...
}
module Render = {
module Calc2 = Calc
// ...
}
edit2: |
The path where the module definition was made. Like go-to definition, LSP feature. You example: module X = Helper.Render.Calc2
// ^ go to definition here {
[2] = {
result = {
range = {
["end"] = {
character = 11,
line = 0
},
start = {
character = 7,
line = 0
}
},
uri = "file:///tmp/test/src/Helper.res"
}
}
} // Helper.res
module Calc = {
let a = 1
}
module Render = {
module Calc2 = Calc
// ...
} |
@aspeddro after thinking a bit about it, here's why I'm hesitant towards the idea of using the filename as an id:
On the other hand, it may be interesting to add the "metadata" of the path and location(like your goto definition example) to every doc item for downstream tooling consuming the docs. But I think of this as additional information, besides a |
The typed parsetree has a id by module Example: module Calc = {
let a = 1
}
module Render = {
module Calc2 = Calc
// ...
}
module A = Render.Calc2
module B = Render.Calc2 ./node_modules/.bin/bsc -dtypedtree src/Helper.res
Here module_binding record https://github.com/ocaml/ocaml/blob/5348fa9e7c040174f895ee10b5b57d4d22bf7490/typing/typedtree.ml#L312-L320 So now we know that, module |
module A = Render.Calc2
module B = Render.Calc2
module C = Calc In this case, A, B, and C should have the same |
Yes, I think so. |
@zth Some time ago, @aspeddro implemented #900, which includes
docgen json result: {
"name": "ModuleAlias",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 1,
"col": 1
},
"items": [
{
"id": "ModuleAlias.ArrayAlias1",
"kind": "moduleAlias",
"name": "ArrayAlias1",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 1,
"col": 8
},
"items": []
},
... complete json{
"name": "ModuleAlias",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 1,
"col": 1
},
"items": [
{
"id": "ModuleAlias.ArrayAlias1",
"kind": "moduleAlias",
"name": "ArrayAlias1",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 1,
"col": 8
},
"items": []
},
{
"id": "ModuleAlias.ArrayAlias2",
"kind": "moduleAlias",
"name": "ArrayAlias2",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 2,
"col": 8
},
"items": []
},
{
"id": "ModuleAlias.ExampleModuleAlias",
"kind": "moduleAlias",
"name": "ExampleModuleAlias",
"docstrings": ["This is an example module."],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 3,
"col": 8
},
"items": [
{
"id": "ModuleAlias.ExampleModuleAlias.Variants",
"name": "Variants",
"kind": "module",
"docstrings": ["module of variants"],
"source": {
"filepath": "test/ExampleModule.res",
"line": 5,
"col": 8
},
"items": [
{
"id": "ModuleAlias.ExampleModuleAlias.Variants.t",
"kind": "type",
"name": "t",
"signature": "type t =\n | First\n | Second(int)\n | Third({hello: string, goodbye: bool})\n | Fourth(bool, string, int)",
"docstrings": ["represents the variant"],
"source": {
"filepath": "test/ExampleModule.res",
"line": 13,
"col": 3
},
"detail":
{
"kind": "variant",
"items": [
{
"name": "First",
"docstrings": ["first variant constructor without payload"],
"signature": "First"
},
{
"name": "Second",
"docstrings": ["second variant with int payload"],
"signature": "Second(int)"
},
{
"name": "Third",
"docstrings": ["third constructor with inline record"],
"signature": "Third({hello: string, goodbye: bool})",
"payload": {
"kind": "inlineRecord",
"fields": [{
"name": "hello",
"optional": false,
"docstrings": ["hello prop"],
"signature": "string"
}, {
"name": "goodbye",
"optional": false,
"docstrings": ["goddbye prop"],
"signature": "bool"
}]
}
},
{
"name": "Fourth",
"docstrings": ["with several payload arguments"],
"signature": "Fourth(bool, string, int)"
}]
}
}]
},
{
"id": "ModuleAlias.ExampleModuleAlias.Record",
"name": "Record",
"kind": "module",
"docstrings": ["module to test record docs"],
"source": {
"filepath": "test/ExampleModule.res",
"line": 26,
"col": 8
},
"items": [
{
"id": "ModuleAlias.ExampleModuleAlias.Record.sub",
"kind": "type",
"name": "sub",
"signature": "type sub = {x: bool}",
"docstrings": ["this is a record"],
"source": {
"filepath": "test/ExampleModule.res",
"line": 34,
"col": 3
},
"detail":
{
"kind": "record",
"items": [{
"name": "x",
"optional": false,
"docstrings": ["representing a bool value"],
"signature": "bool"
}]
}
},
{
"id": "ModuleAlias.ExampleModuleAlias.Record.t",
"kind": "type",
"name": "t",
"signature": "type t = {\n a: string,\n b: int,\n optRecord?: sub,\n optStr?: string,\n}",
"docstrings": ["this is another record"],
"source": {
"filepath": "test/ExampleModule.res",
"line": 44,
"col": 3
},
"detail":
{
"kind": "record",
"items": [{
"name": "a",
"optional": false,
"docstrings": ["prop a"],
"signature": "string"
}, {
"name": "b",
"deprecated": "use sub instead",
"optional": false,
"docstrings": ["deprecated prop"],
"signature": "int"
}, {
"name": "optRecord",
"optional": true,
"docstrings": ["this is an optional field of another record"],
"signature": "option<sub>"
}, {
"name": "optStr",
"optional": true,
"docstrings": ["this is an optional string"],
"signature": "option<string>"
}]
}
}]
},
{
"id": "ModuleAlias.ExampleModuleAlias.Minimal_OptionalRecord",
"name": "Minimal_OptionalRecord",
"kind": "module",
"docstrings": [],
"source": {
"filepath": "test/ExampleModule.res",
"line": 57,
"col": 8
},
"items": [
{
"id": "ModuleAlias.ExampleModuleAlias.Minimal_OptionalRecord.t",
"kind": "type",
"name": "t",
"signature": "type t = {optStr?: string}",
"docstrings": [],
"source": {
"filepath": "test/ExampleModule.res",
"line": 58,
"col": 3
},
"detail":
{
"kind": "record",
"items": [{
"name": "optStr",
"optional": true,
"docstrings": [],
"signature": "option<string>"
}]
}
}]
}]
},
{
"id": "ModuleAlias.ExampleModuleAlias2",
"kind": "moduleAlias",
"name": "ExampleModuleAlias2",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 4,
"col": 8
},
"items": []
},
{
"id": "ModuleAlias.InlineModule",
"name": "InlineModule",
"kind": "module",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 5,
"col": 8
},
"items": [
{
"id": "ModuleAlias.InlineModule.x",
"kind": "value",
"name": "x",
"signature": "let x: int",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 6,
"col": 7
}
}]
},
{
"id": "ModuleAlias.InlineModuleAlias",
"kind": "moduleAlias",
"name": "InlineModuleAlias",
"docstrings": [],
"source": {
"filepath": "test/ModuleAlias.res",
"line": 8,
"col": 8
},
"items": []
}]
} Observations:
I think it's important to have the source record, because it will help to e.g. generate links to the source file. Another question also came to my mind: Should codegen only generate docs for the current package (defined in P.S: I tried several times to find my way around in the codebase thinking about trying to implement such thing on my own, but I feel pretty lost in general. |
Currently
ModuleAlias
is defined inDocExtraction.docItem
as:While this differentiates between a module implementation and an alias, there is no way of knowing if 2 aliases reference the same target.
E.g:
While the above is obviously bad interface design, it becomes more important if we were to extract docs from several different modules, which alias the same module.
When generating documentation for a complete project we most likely want to be able to avoid duplication.
If we were to run doc extraction on every module (file) in the example below, it would be nice to have an id stating the aliased module is the same as the one from another extracted json.
Therefore we need a way to uniquely identify a target module.
P.S: I guess we could compare identities by content of the json structures, but a simple id string is easier to handle.
The text was updated successfully, but these errors were encountered: