OpenZeppelin / solidity-docgen

Documentation generator for Solidity projects
MIT License
452 stars 118 forks source link

Documentation of Events work in interfaces but Structs and Enums are not working #413

Closed ngurmen closed 2 years ago

ngurmen commented 2 years ago

Hi, great work. We started using solidity-docgen in documenting our code. The Events are processed nicely in an interface file but for Structs and Enums docgen only generates the code block that shows the Struct or Enum but does not include @notice and @dev tags. Also, we couldn't access structs and enums separately. They are all lumped into types.

It would be great to have the following features, if at all possible.

  1. Could you please expose structs, enums and user defined value types separately like it is done for events? This would allow us to customize the rendered page better with better headers for each.
  2. Could you please include the ability to have @notice and @dev tags for structs, enums and user defined value types?
  3. Could you please add a config parameter to avoid ignoring of private functions or variables? If it is done this way, would it be possible to create an if statement in a theme template for the visibility of a function or variable? Again, this would allow us customize the rendered page much better with better section headings.

Many thanks for your consideration.

frangio commented 2 years ago

Hi @ngurmen, thanks for the kind words.

~What version of Solidity is the codebase using?~

Edit: I thought the lack of documentation for Structs and Enums was a limitation only present in older Soidity versions but it's actually not fixed yet, sadly. See https://github.com/ethereum/solidity/issues/12295.

frangio commented 2 years ago

Could you please expose structs, enums and user defined value types separately like it is done for events? This would allow us to customize the rendered page better with better headers for each.

Yes, but you can also do this with configuration.

If you've configured a templates directory docgen: { templates: 'docs-templates' } you can create a file docs-templates/properties.js with this content:

module.exports.structs = function ({ item }) {
  return item.types.filter(t => t.nodeType === 'StructDefinition');
};

module.exports.enums = function ({ item }) {
  return item.types.filter(t => t.nodeType === 'EnumDefinition');
};

These properties will then be available in contract.hbs as {{structs}} and {{enums}}.

Please try this and let me know if it works.

ngurmen commented 2 years ago

@frangio hello. Thanks you for your support.

For @notice and @dev tags of structs and enums, we will need to wait for them to be included by solc, I guess...

As for structs and enums' availability in theme templates, adding those functions to the properties.ts worked beautifully. Instead of JS version I used the TS one as follows:

export function structs({ item }: DocItemContext): StructDefinition[] | undefined {
  return item.types.filter(t => t.nodeType === "StructDefinition");
}

Lint complains that types is not available on DocItemContext but everything works.

However, to differentiate among different visibilities for variables and functions I used an ugly hack. I couldn't add a visibility parameter to the variables and functions. Or, maybe I added on the TS side but did not properly invoke them in the template file. They kept giving errors with fn...

Second, I tried to filter things by registration of an equality check helper called eq. But adding to helpers.ts or properties.ts file in my theme directory did not make it available to my templates.

In the end I duplicated variables and functions in properties,ts with different visibility levels calling them variablesPublic, variablesInternal, etc It is ugly but it is working.

If you can point me to a more elegant way of doing it I will implement it. Many thanks.

frangio commented 2 years ago

However, to differentiate among different visibilities for variables and functions I used an ugly hack. I couldn't add a visibility parameter to the variables and functions. Or, maybe I added on the TS side but did not properly invoke them in the template file. They kept giving errors with fn...

Can you share the template or code you're using for this? I'm sure there's a nicer way.

Second, I tried to filter things by registration of an equality check helper called eq. But adding to helpers.ts or properties.ts file in my theme directory did not make it available to my templates.

Hm, that sounds like it should work. If there's a repo you can share I can take a look.

ngurmen commented 2 years ago

Hi, the current set-up works pretty much the way we want but it is probably not the best implementation. It is part of our internal repo but I created a gist for you to take a look. I did not include all the files but these files illustrate the point I believe.

https://gist.github.com/ngurmen/df7366f2edfc1c5d174faf3485a50e81

frangio commented 2 years ago

I see what you mean now. In properties.ts you can't add parameters. Perhaps you could improve it by adding a helper in helpers.ts, since those do take parameters.

Odd that you weren't able to get eq working. I would expect that it would work by adding export const eq = (a, b) => a === b in helpers.ts.

Ah, perhaps you weren't parenthesizing the expression... This can be a quirk of Handlebars. Once you add it in the helpers file, you would use it like {{#if (eq x y)}}, note the parentheses.

ngurmen commented 1 year ago

@frangio, the way I implemented eliminated the need for eq for now. When the need arises I will try this again in helpers.ts with parentheses. thanks.

By the way, not finding a simple doc tags helper plugin for solidity in VS Code. I coded a very simple, no-frills extension for our internal usage. If solidity-docgen users may find it useful here it is:

https://github.com/Dexalot/vscode-solidity-comments