Skip to content

Commit

Permalink
[move] Fixes for enums in Move model + add support in docgen (#18907)
Browse files Browse the repository at this point in the history
## Description 

Fixes some issues with enums in Move model creation, and adds support
for enums in docgen, and adding doc comments to enum variants.

## Test plan 

Added a test for docgen with enums -- this tests both the bugfixes and
also the generation of doc comments for enums.

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
  • Loading branch information
tzakian authored Aug 7, 2024
1 parent 98603ad commit 1ce3dda
Show file tree
Hide file tree
Showing 11 changed files with 573 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3428,6 +3428,7 @@ fn parse_enum_variant_decls(
// Parse an enum variant definition:
// VariantDecl = <Identifier> ("{" Comma<FieldAnnot> "}" | "(" Comma<PosField> ")")
fn parse_enum_variant_decl(context: &mut Context) -> Result<VariantDefinition, Box<Diagnostic>> {
context.tokens.match_doc_comments();
let start_loc = context.tokens.start_loc();
let name = parse_identifier(context)?;
let fields = parse_enum_variant_fields(context)?;
Expand Down
88 changes: 86 additions & 2 deletions external-crates/move/crates/move-docgen/src/docgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use move_model::{
code_writer::{CodeWriter, CodeWriterLabel},
emit, emitln,
model::{
AbilitySet, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, NamedConstantEnv,
Parameter, QualifiedId, StructEnv, TypeParameter,
AbilitySet, EnumEnv, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId,
NamedConstantEnv, Parameter, QualifiedId, StructEnv, TypeParameter,
},
symbol::Symbol,
ty::TypeDisplayContext,
Expand Down Expand Up @@ -584,6 +584,15 @@ impl<'env> Docgen<'env> {
}
}

if !module_env.get_enums().count() > 0 {
for s in module_env
.get_enums()
.sorted_by(|a, b| Ord::cmp(&a.get_loc(), &b.get_loc()))
{
self.gen_enum(&s);
}
}

if module_env.get_named_constant_count() > 0 {
// Introduce a Constant section
self.gen_named_constants();
Expand Down Expand Up @@ -896,6 +905,28 @@ impl<'env> Docgen<'env> {
self.decrement_section_nest();
}

/// Generates documentation for an enum.
fn gen_enum(&self, enum_env: &EnumEnv<'_>) {
let name = enum_env.get_name();
self.section_header(
&format!("Enum `{}`", self.name_string(enum_env.get_name())),
&self.label_for_module_item(&enum_env.module_env, name),
);
self.increment_section_nest();
self.doc_text(enum_env.get_doc());
self.code_block(&self.enum_header_display(enum_env));

if self.options.include_impl || (self.options.include_specs && self.options.specs_inlined) {
// Include field documentation if either impls or specs are present and inlined,
// because they are used by both.
self.begin_collapsed("Variants");
self.gen_enum_variants(enum_env);
self.end_collapsed();
}

self.decrement_section_nest();
}

/// Returns "Struct `N`" or "Resource `N`".
fn struct_title(&self, struct_env: &StructEnv<'_>) -> String {
// NOTE(mengxu): although we no longer declare structs with the `resource` keyword, it
Expand Down Expand Up @@ -960,6 +991,59 @@ impl<'env> Docgen<'env> {
self.end_definitions();
}

/// Generates code signature for an enum.
fn enum_header_display(&self, enum_env: &EnumEnv<'_>) -> String {
let name = self.name_string(enum_env.get_name());
let type_params = self.type_parameter_list_display(&enum_env.get_named_type_parameters());
let ability_tokens = self.ability_tokens(enum_env.get_abilities());
if ability_tokens.is_empty() {
format!("public enum {}{}", name, type_params)
} else {
format!(
"public enum {}{} has {}",
name,
type_params,
ability_tokens.join(", ")
)
}
}

fn gen_enum_variants(&self, enum_env: &EnumEnv<'_>) {
let tctx = {
let type_param_names = Some(
enum_env
.get_named_type_parameters()
.iter()
.map(|TypeParameter(name, _)| *name)
.collect_vec(),
);
TypeDisplayContext::WithEnv {
env: self.env,
type_param_names,
}
};
self.begin_definitions();
for variant_env in enum_env.get_variants() {
self.definition_text(
&format!("Variant `{}`", self.name_string(variant_env.get_name()),),
variant_env.get_doc(),
);
for field in variant_env.get_fields() {
self.begin_definitions();
self.definition_text(
&format!(
"`{}: {}`",
self.name_string(field.get_name()),
field.get_type().display(&tctx)
),
field.get_doc(),
);
self.end_definitions();
}
}
self.end_definitions();
}

/// Generates documentation for a function.
fn gen_function(&self, func_env: &FunctionEnv<'_>) {
let is_script = func_env.module_env.is_script_module();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// This is a doc comment above an annotation.
#[allow(unused_const)]
module 0x42::m {
/// This is a doc comment above an enum
public enum Enum {
/// This is a doc comment above a variant
A,
B(),
C(u64),
/// Another doc comment
D {
/// Doc text on variant field
x: u64
},
E { x: u64, y: u64 },
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

<a name="0x42_m"></a>

# Module `0x42::m`

This is a doc comment above an annotation.


- [Enum `Enum`](#0x42_m_Enum)


<pre><code></code></pre>



<a name="0x42_m_Enum"></a>

## Enum `Enum`

This is a doc comment above an enum


<pre><code><b>public</b> enum Enum
</code></pre>



<details>
<summary>Variants</summary>


<dl>
<dt>
Variant <code>A</code>
</dt>
<dd>
This is a doc comment above a variant
</dd>
<dt>
Variant <code>B</code>
</dt>
<dd>

</dd>
<dt>
Variant <code>C</code>
</dt>
<dd>

</dd>

<dl>
<dt>
<code>pos0: u64</code>
</dt>
<dd>

</dd>
</dl>

<dt>
Variant <code>D</code>
</dt>
<dd>
Another doc comment
</dd>

<dl>
<dt>
<code>x: u64</code>
</dt>
<dd>
Doc text on variant field
</dd>
</dl>

<dt>
Variant <code>E</code>
</dt>
<dd>

</dd>

<dl>
<dt>
<code>x: u64</code>
</dt>
<dd>

</dd>
</dl>


<dl>
<dt>
<code>y: u64</code>
</dt>
<dd>

</dd>
</dl>

</dl>


</details>
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@

<a name="0x42_m"></a>

# Module `0x42::m`

This is a doc comment above an annotation.


- [Enum `Enum`](#0x42_m_Enum)


<pre><code></code></pre>



<a name="0x42_m_Enum"></a>

## Enum `Enum`

This is a doc comment above an enum


<pre><code><b>public</b> enum Enum
</code></pre>



##### Variants


<dl>
<dt>
Variant <code>A</code>
</dt>
<dd>
This is a doc comment above a variant
</dd>
<dt>
Variant <code>B</code>
</dt>
<dd>

</dd>
<dt>
Variant <code>C</code>
</dt>
<dd>

</dd>

<dl>
<dt>
<code>pos0: u64</code>
</dt>
<dd>

</dd>
</dl>

<dt>
Variant <code>D</code>
</dt>
<dd>
Another doc comment
</dd>

<dl>
<dt>
<code>x: u64</code>
</dt>
<dd>
Doc text on variant field
</dd>
</dl>

<dt>
Variant <code>E</code>
</dt>
<dd>

</dd>

<dl>
<dt>
<code>x: u64</code>
</dt>
<dd>

</dd>
</dl>


<dl>
<dt>
<code>y: u64</code>
</dt>
<dd>

</dd>
</dl>

</dl>
Loading

0 comments on commit 1ce3dda

Please sign in to comment.