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

feat(graindoc)!: Replace module attribute with docblock on module header #1647

Merged
merged 7 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions compiler/graindoc/docblock.re
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ let enumerate_exports = stmts => {
},
vbinds,
)
| _ => ()
| TTopModule(_)
| TTopInclude(_)
| TTopException(_)
| TTopExpr(_) => ()
};
};
});
Expand All @@ -95,12 +98,6 @@ let location_for_ident = (~exports, ident) => {
snd(Ident.find_name(Ident.name(ident), exports));
};

let module_name_of_location = (loc: Grain_parsing.Location.t) => {
Grain_utils.Filepath.String.filename_to_module_name(
loc.loc_start.pos_fname,
);
};

let title_for_api = (~module_name, ident: Ident.t) => {
Format.asprintf("%s.**%a**", module_name, Printtyp.ident, ident);
};
Expand Down Expand Up @@ -148,8 +145,8 @@ let lookup_type_expr = (~idx, type_exprs) => {
let for_value_description =
(
~comments,
~loc,
~module_name=module_name_of_location(loc),
~loc: Grain_parsing.Location.t,
~module_name,
~ident: Ident.t,
vd: Types.value_description,
) => {
Expand Down Expand Up @@ -188,8 +185,8 @@ let for_value_description =
let for_type_declaration =
(
~comments,
~loc,
~module_name=module_name_of_location(loc),
~loc: Grain_parsing.Location.t,
~module_name,
~ident: Ident.t,
td: Types.type_declaration,
) => {
Expand All @@ -211,19 +208,19 @@ let for_signature_item =
(
~comments,
~exports: Ident.tbl(Grain_parsing.Location.t),
~module_name=?,
~module_name,
sig_item: Types.signature_item,
) => {
switch (sig_item) {
| TSigValue(ident, vd) =>
let loc = location_for_ident(~exports, ident);
let docblock =
for_value_description(~comments, ~module_name?, ~ident, ~loc, vd);
for_value_description(~comments, ~module_name, ~ident, ~loc, vd);
Some(docblock);
| TSigType(ident, td, _rec) =>
let loc = location_for_ident(~exports, ident);
let docblock =
for_type_declaration(~comments, ~module_name?, ~ident, ~loc, td);
for_type_declaration(~comments, ~module_name, ~ident, ~loc, td);
Some(docblock);
| _ => None
};
Expand Down
52 changes: 23 additions & 29 deletions compiler/graindoc/graindoc.re
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,14 @@ let generate_docs =
let signature_items = program.signature.cmi_sign;

let buf = Buffer.create(0);
let module_comment = Comments.Doc.find_module(comments);
let module_name = ref(None);
let module_name = program.module_name.txt;
let module_comment =
Comments.Doc.ending_on(
~lnum=program.module_name.loc.loc_start.pos_lnum - 1,
comments,
);

Buffer.add_string(buf, Markdown.frontmatter([("title", module_name)]));
switch (module_comment) {
| Some((_, desc, attrs)) =>
let deprecations =
Expand All @@ -104,31 +110,20 @@ let generate_docs =
}
});

// TODO(#787): Should we fail if more than one `@module` attribute?
let module_attr = attrs |> List.find(Comments.Attribute.is_module);
switch (module_attr) {
| Module({attr_name, attr_desc}) =>
module_name := Some(attr_name);
Buffer.add_string(buf, Markdown.frontmatter([("title", attr_name)]));
if (List.length(deprecations) > 0) {
List.iter(
msg =>
Buffer.add_string(
buf,
Markdown.blockquote(
Markdown.bold("Deprecated:") ++ " " ++ msg,
),
),
deprecations,
);
};
Buffer.add_string(buf, Markdown.paragraph(attr_desc));
switch (desc) {
// Guard isn't be needed because we turn an empty string into None during extraction
| Some(desc) => Buffer.add_string(buf, Markdown.paragraph(desc))
| None => ()
};
| _ => failwith("Unreachable: Non-`module` attribute can't exist here.")
if (List.length(deprecations) > 0) {
List.iter(
msg =>
Buffer.add_string(
buf,
Markdown.blockquote(Markdown.bold("Deprecated:") ++ " " ++ msg),
),
deprecations,
);
};

switch (desc) {
| Some(desc) => Buffer.add_string(buf, Markdown.paragraph(desc))
| None => ()
};

// TODO(#787): Should we fail if more than one `@since` attribute?
Expand Down Expand Up @@ -187,13 +182,12 @@ let generate_docs =
| None => ()
};

let module_name = module_name^;
let add_docblock = sig_item => {
let docblock =
Docblock.for_signature_item(
~comments,
~exports,
~module_name?,
~module_name,
sig_item,
);
switch (docblock) {
Expand Down
41 changes: 0 additions & 41 deletions compiler/src/diagnostics/comments.re
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ module Attribute = {
attr_desc,
attr_type,
})
| Module({
attr_name,
attr_desc,
})
// Currently only accepts single-line examples
| Example({attr_desc})
| Section({
Expand Down Expand Up @@ -72,19 +68,6 @@ module Attribute = {
};
};

let parse_module = (~attr, content) => {
let re = Str.regexp({|^\([^:]+\):[ ]+\(.+\)$|});
if (Str.string_match(re, content, 0)) {
let attr_name = Str.matched_group(1, content);
let attr_desc = Str.matched_group(2, content);
Module({attr_name, attr_desc});
} else {
raise(
MalformedAttribute(attr, "@module ModuleName: Description of module"),
);
};
};

let parse_example = (~attr, content) => {
let re = Str.regexp({|^\(.+\)$|});
if (Str.string_match(re, content, 0)) {
Expand Down Expand Up @@ -181,9 +164,6 @@ module Attribute = {
| "returns" =>
let returns_attr = parse_returns(~attr, content);
attrs := [returns_attr, ...attrs^];
| "module" =>
let module_attr = parse_module(~attr, content);
attrs := [module_attr, ...attrs^];
| "example" =>
let example_attr = parse_example(~attr, content);
attrs := [example_attr, ...attrs^];
Expand Down Expand Up @@ -235,13 +215,6 @@ module Attribute = {
};
};

let is_module = (attr: t) => {
switch (attr) {
| Module(_) => true
| _ => false
};
};

let is_example = (attr: t) => {
switch (attr) {
| Example(_) => true
Expand Down Expand Up @@ -414,20 +387,6 @@ module Doc = {
ending_on_lnum_help(lnum, true);
};

let find_module = (module C: OrderedComments) => {
let module_comments = ref([]);
C.iter((_, (_comment, _desc, attrs) as comment) =>
if (List.exists(Attribute.is_module, attrs)) {
module_comments := [comment, ...module_comments^];
}
);
if (List.length(module_comments^) > 1) {
failwith("More than one @module block is not supported");
} else {
List.nth_opt(module_comments^, 0);
};
};

let find_sections = (module C: OrderedComments) => {
let section_comments = ref([]);
C.iter((_, (_comment, _desc, attrs) as comment) =>
Expand Down
1 change: 1 addition & 0 deletions compiler/src/typed/typedtree.re
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ type comment =

[@deriving sexp]
type typed_program = {
module_name: loc(string),
statements: list(toplevel_stmt),
env: [@sexp.opaque] Env.t,
signature: Cmi_format.cmi_infos,
Expand Down
1 change: 1 addition & 0 deletions compiler/src/typed/typedtree.rei
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ type comment =

[@deriving sexp]
type typed_program = {
module_name: loc(string),
statements: list(toplevel_stmt),
env: Env.t,
signature: Cmi_format.cmi_infos,
Expand Down
8 changes: 7 additions & 1 deletion compiler/src/typed/typemod.re
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,13 @@ let type_implementation = prog => {
check_nongen_schemes(finalenv, simple_sg);
let normalized_sig = normalize_signature(finalenv, simple_sg);
let signature = Env.build_signature(normalized_sig, module_name, filename);
{statements, env: finalenv, signature, comments: prog.comments};
{
module_name: prog.module_name,
statements,
env: finalenv,
signature,
comments: prog.comments,
};
};

/* Error report */
Expand Down
22 changes: 0 additions & 22 deletions compiler/src/utils/filepath.re
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,6 @@ module String = {
Printf.sprintf("%s.%s", remove_extension(baseName), newExt);
};

// TODO(#216): Turn this into a function that only operates on Fp
let filename_to_module_name = fname => {
let baseName =
Option.bind(from_string(fname), p =>
switch (p) {
| Absolute(path) => Fp.baseName(path)
| Relative(path) => Fp.baseName(path)
}
);
let name =
switch (baseName) {
| Some(baseName) => remove_extension(baseName)
| None =>
raise(
Invalid_argument(
Printf.sprintf("Invalid filepath (fname: '%s')", fname),
),
)
};
String.capitalize_ascii(name);
};

let normalize_separators = path =>
if (Sys.unix) {
path;
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/stdlib/bigint.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module BigintTest
include "list"
include "runtime/wasi"
include "bigint"
from Bigint use *
from BigInt use *

assert toString(15t) == "15"
assert toString(-15t) == "-15"
Expand Down
2 changes: 1 addition & 1 deletion stdlib/array.gr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module Array: Utilities for working with arrays.
* Utilities for working with arrays.
*
* @example include "array"
*
Expand Down
5 changes: 3 additions & 2 deletions stdlib/bigint.gr
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/**
* @module BigInt: Utilities for working with the BigInt type.
* Utilities for working with the BigInt type.
*
* @example include "bigint"
*
* @since v0.5.0
*/

module Bigint
module BigInt

include "runtime/unsafe/wasmi32"
include "runtime/unsafe/memory"
Expand Down
2 changes: 1 addition & 1 deletion stdlib/buffer.gr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module Buffer: Utilities for working with buffers.
* Utilities for working with buffers.
*
* Buffers are data structures that automatically expand as more data is appended. They are useful for storing and operating on an unknown number of bytes. All set or append operations mutate the buffer.
* @example include "buffer"
Expand Down
2 changes: 1 addition & 1 deletion stdlib/bytes.gr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module Bytes: Utilities for working with byte sequences.
* Utilities for working with byte sequences.
*
* @example include "bytes"
*
Expand Down
2 changes: 1 addition & 1 deletion stdlib/char.gr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module Char: Utilities for working with the Char type.
* Utilities for working with the Char type.
*
* The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
*
Expand Down
2 changes: 1 addition & 1 deletion stdlib/exception.gr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module Exception: Utilities for working with the Exception type.
* Utilities for working with the Exception type.
*
* The Exception type represents an error that has occured during computation.
*
Expand Down
Loading