Skip to content

Conversation

@stevedylandev
Copy link

@stevedylandev stevedylandev commented Oct 31, 2025

This PR adds the templates-md and config-md.js to the docs directory, allowing us to generate API docs remotely in OpenZeppelin/docs. Please see the guide here.

Summary by CodeRabbit

  • New Features
    • Added Markdown-based Solidity contract documentation generation with comprehensive support for functions, events, errors, and modifiers.
    • Implemented cross-reference linking and anchor-based navigation for enhanced documentation navigation.
    • Added support for README files and content conversion in documentation output.

@stevedylandev stevedylandev requested a review from a team as a code owner October 31, 2025 04:34
@netlify
Copy link

netlify bot commented Oct 31, 2025

Deploy Preview for confidential-tokens ready!

Name Link
🔨 Latest commit 2a5a256
🔍 Latest deploy log https://app.netlify.com/projects/confidential-tokens/deploys/6925cfe1c5c8e50008fa5f6d
😎 Deploy Preview https://deploy-preview-237--confidential-tokens.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

A new Markdown documentation generation system is introduced for Solidity contracts. It includes a configuration module, Handlebars templates for rendering contract pages, and helper modules for content processing and AST analysis. The hardhat configuration is updated to reference the new documentation system.

Changes

Cohort / File(s) Summary
Configuration Module
docs/config-md.js
Exports docgen configuration with output directory, template path, exclusions, page extension, and a pages function to resolve README files in the source hierarchy
Handlebars Templates
docs/templates-md/contract.hbs, docs/templates-md/page.hbs
contract.hbs renders individual contract documentation with modifiers, functions, events, and errors sections; page.hbs defines the document structure with YAML front matter and contract iteration
Template Helpers
docs/templates-md/helpers.js, docs/templates-md/properties.js
helpers.js provides 20+ utility functions for template rendering, content processing (AsciiDoc to Markdown conversion), reference resolution, callout normalization, and link caching; properties.js exports 11 AST analysis utilities for anchor generation, inheritance resolution, and function/event/error detection
Build Configuration
hardhat.config.ts
Updated docgen path from ./docs/config to ./docs/config-md

Sequence Diagram

sequenceDiagram
    participant Hardhat
    participant Config as config-md.js
    participant Templates as Templates (contract.hbs)
    participant Helpers as helpers.js
    participant AST as properties.js

    Hardhat->>Config: Load documentation config
    Config-->>Hardhat: Return output dir, templates dir, pages resolver
    Hardhat->>Templates: Render contracts with template
    Templates->>Helpers: Process NATSPEC content
    Helpers->>Helpers: Cache cross-references (getAllLinks)
    Helpers->>Helpers: Replace reference patterns (processReferences)
    Helpers->>Helpers: Convert callouts and admonitions (processCallouts)
    Helpers-->>Templates: Return processed content
    Templates->>AST: Extract item properties
    AST->>AST: Analyze inheritance chain
    AST->>AST: Generate anchors from signatures
    AST-->>Templates: Return properties for rendering
    Templates-->>Hardhat: Generate markdown pages with YAML front matter
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • docs/templates-md/helpers.js: Requires careful review of sophisticated content processing pipelines including AsciiDoc-to-Markdown conversion via temporary file workflows, reference resolution with fuzzy matching and caching mechanisms, callout normalization patterns, and link generation logic with multiple cross-reference key strategies
  • docs/templates-md/properties.js: AST analysis and inheritance chain resolution logic needs validation for correctness across contract linearization and special handling of constructors
  • Template integration: Verify correct helper invocation patterns in contract.hbs and page.hbs, including optional rendering conditions and iterator correctness

Poem

🐰 A fuzzy system blooms today,

With templates and helpers at play,

From AsciiDoc we dance and sway,

To markdown links that find their way,

Contracts documented, hooray!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "chore: added markdown templates to docs" accurately describes a significant portion of the changeset, specifically the addition of the docs/templates-md/ directory containing template files and helpers (contract.hbs, page.hbs, helpers.js, and properties.js). The title is clear, specific, and directly related to the primary additions in the PR. However, the changeset also includes docs/config-md.js and a modification to hardhat.config.ts that are not reflected in the title. While the title captures the most substantive changes, it is partially rather than fully comprehensive of all deliverables mentioned in the PR objectives.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (6)
docs/templates-md/properties.js (2)

30-32: Clarify the trailing dash removal logic.

The code removes a trailing dash if present, but it's unclear when this edge case would occur. The slug function (from helpers.js) replaces non-word characters with dashes, so an empty signature () would become ---, which could explain this check.

Consider adding a comment to clarify when this edge case occurs:

  if (res.charAt(res.length - 1) === '-') {
+   // Remove trailing dash that can occur with empty signatures
    return res.slice(0, -1);
  }

36-45: Consider adding a comment for Context filtering logic.

The inheritance function has specific logic to filter out 'Context' except when it's the first item (i === 0). This business logic would benefit from a comment explaining why Context requires special handling.

module.exports.inheritance = function ({ item, build }) {
  if (!isNodeType('ContractDefinition', item)) {
    // Return empty array for non-contracts (interfaces, libraries)
    return [];
  }

  return item.linearizedBaseContracts
    .map(id => build.deref('ContractDefinition', id))
+   // Context is a base contract that should be hidden from docs unless it's the main contract
    .filter((c, i) => c.name !== 'Context' || i === 0);
};
docs/templates-md/helpers.js (4)

31-42: Consider concurrency safety if templates are rendered in parallel.

The global functionNameCounts object works for single-threaded documentation generation but could cause race conditions if templates are ever rendered concurrently.


67-72: Enhance input validation.

The slug function only checks for undefined but doesn't handle null or other invalid types. Consider using a more robust check.

 const slug = (module.exports.slug = str => {
-  if (str === undefined) {
+  if (typeof str !== 'string' || !str) {
     throw new Error('Missing argument');
   }
   return str.replace(/\W/g, '-');
 });

320-323: Add timeout to prevent hanging builds.

The execSync call lacks a timeout, which could cause the documentation build to hang indefinitely if downdoc encounters issues.

     execSync(`npx downdoc "${tempAdocFile}"`, {
       stdio: 'pipe',
       cwd: process.cwd(),
+      timeout: 30000, // 30 second timeout
+      maxBuffer: 10 * 1024 * 1024, // 10MB buffer
     });

353-411: Consider refactoring for maintainability.

The processCallouts function performs 15+ sequential regex replacements, making it difficult to maintain and potentially impacting performance on large documents. Consider:

  1. Grouping related patterns into helper functions
  2. Using a single pass with a more sophisticated regex where possible
  3. Adding inline comments explaining each transformation's purpose
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89b9ba4 and deeb75a.

📒 Files selected for processing (6)
  • docs/config-md.js (1 hunks)
  • docs/templates-md/contract.hbs (1 hunks)
  • docs/templates-md/helpers.js (1 hunks)
  • docs/templates-md/page.hbs (1 hunks)
  • docs/templates-md/properties.js (1 hunks)
  • hardhat.config.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
hardhat.config.ts (2)
docs/templates-md/helpers.js (2)
  • require (1-1)
  • require (4-4)
docs/templates-md/properties.js (2)
  • require (1-1)
  • require (2-2)
docs/templates-md/properties.js (1)
docs/templates-md/helpers.js (2)
  • slug (67-72)
  • i (139-139)
docs/config-md.js (1)
docs/templates-md/helpers.js (4)
  • path (3-3)
  • require (1-1)
  • require (4-4)
  • fs (2-2)
docs/templates-md/helpers.js (1)
docs/templates-md/properties.js (2)
  • require (1-1)
  • require (2-2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: coverage
  • GitHub Check: slither
  • GitHub Check: tests
🔇 Additional comments (14)
hardhat.config.ts (1)

37-37: LGTM!

The configuration update correctly points to the new markdown documentation config file.

docs/templates-md/page.hbs (1)

1-13: LGTM!

The page template structure is clean and follows Handlebars conventions. The YAML front matter, conditional prelude, and items iteration logic are all properly implemented.

docs/templates-md/contract.hbs (2)

3-3: Verify the inline style syntax.

The inline style uses style=\{{...}} syntax with escaped braces. Please verify this renders correctly in the target MDX environment and that the backslash escaping is intentional for JSX compatibility.


14-14: Verify the import path prefix.

The import statement uses @openzeppelin/ prefix followed by the absolute path. Ensure this matches the actual package structure for openzeppelin-confidential-contracts. The standard OpenZeppelin contracts use @openzeppelin/contracts/, but this repository may require a different prefix.

docs/templates-md/properties.js (1)

82-91: LGTM!

The inherited-functions logic correctly filters out base functions and handles constructor visibility. The implementation properly groups functions by their declaring contract.

docs/templates-md/helpers.js (9)

1-9: LGTM!

The imports and version export follow standard Node.js patterns. The use of built-in modules is appropriate for a documentation generation helper.


17-27: LGTM - Appropriate error handling for optional content.

The pattern of logging warnings and returning empty strings is appropriate for optional README content in documentation generation. The existence check prevents unnecessary errors.


74-124: LGTM - Effective caching strategy.

The two-level caching approach using WeakMap and Map is appropriate for this use case, allowing garbage collection while maintaining per-page caches. The minor duplication in cache setup (lines 80-84 vs 115-119) is acceptable for code clarity.


126-158: LGTM!

The relative path calculation logic correctly handles same-page anchors, sibling pages, and pages at different directory levels. The approach of finding the common base and calculating up/down navigation is sound.


284-299: LGTM!

The HTML entity replacements are in the correct order (with & processed last to avoid double-decoding), and the URL markdown conversion pattern is appropriate.


225-249: LGTM!

The reference resolution logic appropriately tries exact matches before falling back to fuzzy matching. The two-level approach balances precision with flexibility for cross-references.


413-430: LGTM!

The title and description helpers provide reasonable default formatting for page metadata derived from the file path structure.


432-439: LGTM!

The with-prelude helper follows the same processing pattern as process-natspec, maintaining consistency in how content is transformed throughout the documentation generation pipeline.


52-61: LGTM!

The process-natspec function provides a clean orchestration layer, delegating to specialized functions for link generation, reference processing, and callout handling.

@stevedylandev
Copy link
Author

Please follow the example of the community contracts PR and make a new one internally

OpenZeppelin/openzeppelin-community-contracts#220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants