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: Improve bindgen types #2773

Merged
merged 5 commits into from
Dec 6, 2024

Conversation

MartianGreed
Copy link
Contributor

@MartianGreed MartianGreed commented Dec 5, 2024

Description

Long awaited PR is finally there. Mainly solves #2715

Checklist

  • I've formatted my code (scripts/prettier.sh, scripts/rust_fmt.sh, scripts/cairo_fmt.sh)
  • I've linted my code (scripts/clippy.sh, scripts/docs.sh)
  • I've commented my code
  • I've requested a review after addressing the comments

Summary by CodeRabbit

  • New Features

    • Added a method to insert strings at specific indices within the Buffer struct.
    • Introduced new constants for TypeScript imports related to Cairo and StarkNet.
    • Enhanced TypeScript enum generation with conditional imports and type definitions.
    • Improved handling of TypeScript schema types and namespaces.
  • Bug Fixes

    • Updated dependency versions for improved stability and compatibility.
  • Tests

    • Expanded test coverage for new functionalities in TypeScript generation and import handling.

Copy link

coderabbitai bot commented Dec 5, 2024

Walkthrough

Ohayo, sensei! This pull request introduces several updates primarily focused on dependency management in the Cargo.toml file, transitioning specific dependencies to stable tagged versions. Additionally, it enhances the TypeScript generation capabilities in the dojo-bindgen package by adding new methods and constants, improving type handling and import management across various files. The changes also include modifications to existing methods to accommodate new functionalities while maintaining the overall structure and logic.

Changes

File Change Summary
Cargo.toml Updated dependencies: cainome and cainome-cairo-serde to tagged version v0.4.10; serde_with updated from 3.9.0 to 3.11.0.
crates/dojo/bindgen/src/plugins/mod.rs Added method insert_at_index(&mut self, s: String, idx: usize) to Buffer struct.
crates/dojo/bindgen/src/plugins/typescript/generator/constants.rs Added new constants for TypeScript imports and type definitions related to Cairo and StarkNet.
crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs Added method check_import(&self, token: &Composite, buffer: &mut Buffer) and constant CAIRO_ENUM_TYPE_IMPL.
crates/dojo/bindgen/src/plugins/typescript/generator/function.rs Modified format_function_inputs method to alter logic for input type prefixes.
crates/dojo/bindgen/src/plugins/typescript/generator/interface.rs Added methods check_import(&self, token: &Composite, buffer: &mut Buffer) and add_input_type(&self, buffer: &mut Buffer); updated generate method.
crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs Added functions token_is_option(token: &Composite) -> bool and token_is_custom_enum(token: &Composite) -> bool.
crates/dojo/bindgen/src/plugins/typescript/generator/schema.rs Updated import statement for SchemaType and simplified schema type definition generation; added namespace_is_defined method.
crates/dojo/bindgen/src/plugins/typescript/writer.rs Commented out additional logging statements in write method of TsFileWriter; no changes to core functionality.

Possibly related PRs

Suggested reviewers

  • glihm

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 3

🧹 Outside diff range and nitpick comments (5)
crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs (1)

Line range hint 138-138: Typo in Test Function Name

Ohayo sensei! There is a minor typo in the test function name test_it_does_not_duplicates_enum. It should be test_it_does_not_duplicate_enum to reflect proper grammar.

Apply this diff to fix the typo:

- fn test_it_does_not_duplicates_enum() {
+ fn test_it_does_not_duplicate_enum() {
crates/dojo/bindgen/src/plugins/typescript/generator/interface.rs (1)

137-150: Enhance Test Coverage in test_check_import

Ohayo sensei! The test_check_import function currently asserts only the length of the buffer. To ensure that the correct imports are being added or not added, consider enhancing the test to assert the actual contents of the buffer after each call to check_import. This will improve the test coverage and catch any potential issues with import management.

Apply this diff to enhance the test:

 fn test_check_import() {
     let mut buff = Buffer::new();
     let writer = TsInterfaceGenerator;
     let token = create_test_struct_token();
     writer.check_import(&token, &mut buff);
     assert_eq!(1, buff.len());
+    assert!(buff[0].contains("import type { BigNumberish } from 'starknet';"));

     let option = create_option_token();
     writer.check_import(&option, &mut buff);
     assert_eq!(1, buff.len()); // Shouldn't add duplicate imports
+    // Check that CairoOption import is added
+    assert!(buff[0].contains("CairoOption"));

     let custom_enum = create_custom_enum_token();
     writer.check_import(&custom_enum, &mut buff);
     assert_eq!(1, buff.len()); // Shouldn't add duplicate imports

+    // Additional assertions can be added here if necessary
 }
crates/dojo/bindgen/src/plugins/typescript/generator/schema.rs (1)

93-95: Consider Using a More Robust Method for Checking Namespace Definition

Ohayo sensei! In the namespace_is_defined method, the current implementation checks for the namespace definition in the buffer using a string match. This approach might be fragile and could fail if the formatting changes. Consider using a more robust method, such as parsing the buffer into an abstract syntax tree (AST) or maintaining a separate data structure to track the defined namespaces.

crates/dojo/bindgen/src/plugins/typescript/writer.rs (1)

54-56: Ohayo sensei! Remove commented debug print statements.

Instead of commenting out debug statements, it's better to remove them entirely. If debugging is needed in the future, we can rely on proper logging mechanisms or version control history.

-                    // println!("Generating code for model {}", c.type_path);
-                    // println!("{:#?}", c);
-                    // println!("=====================");
crates/dojo/bindgen/src/plugins/typescript/generator/function.rs (1)

91-96: Consider refactoring to improve maintainability

The type prefix logic could be enhanced for better maintainability:

  1. Extract magic strings as constants
  2. Simplify nested conditions using pattern matching
+ const CORE_PREFIX: &str = "core";
+ const MODELS_PREFIX: &str = "models.";
+ const MODELS_INPUT_PREFIX: &str = "models.Input";

  match &input.1 {
      Token::Composite(t) => match t.r#type {
          CompositeType::Enum => MODELS_PREFIX,
          CompositeType::Struct if !t.type_path.starts_with(CORE_PREFIX) => MODELS_INPUT_PREFIX,
          _ => "",
      },
      _ => "",
  }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b5d7ded and a541768.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Cargo.toml (2 hunks)
  • crates/dojo/bindgen/src/plugins/mod.rs (1 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/constants.rs (1 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/enum.rs (1 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/function.rs (1 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/interface.rs (3 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/mod.rs (6 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/generator/schema.rs (7 hunks)
  • crates/dojo/bindgen/src/plugins/typescript/writer.rs (1 hunks)
🔇 Additional comments (4)
crates/dojo/bindgen/src/plugins/mod.rs (1)

77-84: Ohayo sensei! The new Buffer method looks good!

The insert_at_index implementation is clean and well-documented, following the existing codebase style.

Cargo.toml (2)

74-75: Ohayo sensei! Good move using tagged versions!

Moving from commit hashes to tagged versions (v0.4.10) for cainome and cainome-cairo-serde improves dependency stability and version tracking.


213-213: Verify compatibility with serde_with 3.11.0

The update from serde_with 3.9.0 to 3.11.0 might include breaking changes.

✅ Verification successful

Let me check the actual usage patterns in the codebase to ensure the changes in the changelog won't affect the current implementation.


Ohayo! The update to serde_with 3.11.0 is safe to proceed, sensei!

The changelog shows only additions and fixes between 3.9.0 and 3.11.0:

  • Added support for hashbrown v0.15
  • Added new line separators (UnixLineSeparator, DosLineSeparator)
  • Fixed cfg_attr handling in serde_as macro

Our codebase only uses the basic #[serde_with::serde_as] attribute macro on structs in the genesis module, which is unaffected by these changes. The improvements to cfg_attr handling actually makes the macro more robust.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for breaking changes in serde_with changelog

# Get the changelog or release notes for serde_with
gh api repos/jonasbb/serde_with/releases | jq -r '.[] | select(.tag_name | contains("3.10.0","3.11.0")) | .body'

Length of output: 660


Script:

#!/bin/bash
# Search for serde_with usage patterns to check compatibility
ast-grep --pattern 'use serde_with::{$$$}'

# Also check for any direct attribute usage
rg '#\[serde_with' -A 2

Length of output: 1172

crates/dojo/bindgen/src/plugins/typescript/generator/function.rs (1)

91-96: Ohayo sensei! The type handling logic looks good! ✨

The separation of enum and struct type handling improves clarity and maintainability.

Comment on lines +27 to +31
if !buffer.has(CAIRO_ENUM_TYPE_IMPL) {
let pos = buffer.pos(SN_IMPORT_SEARCH).unwrap();
buffer.insert_at_index(CAIRO_ENUM_TYPE_IMPL.to_owned(), pos + 1);
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Panic due to Unwrap on None

Ohayo sensei! In the check_import method, using buffer.pos(SN_IMPORT_SEARCH).unwrap() may cause a panic if SN_IMPORT_SEARCH is not found in the buffer. To prevent this, consider handling the Option returned by buffer.pos gracefully, perhaps using if let Some(pos) = buffer.pos(SN_IMPORT_SEARCH) or providing a default value.

Apply this diff to fix the potential panic:

- let pos = buffer.pos(SN_IMPORT_SEARCH).unwrap();
+ if let Some(pos) = buffer.pos(SN_IMPORT_SEARCH) {
+     buffer.insert_at_index(CAIRO_ENUM_TYPE_IMPL.to_owned(), pos + 1);
+ } else {
+     // Handle the case where SN_IMPORT_SEARCH is not found
+     buffer.insert(CAIRO_ENUM_TYPE_IMPL.to_owned());
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if !buffer.has(CAIRO_ENUM_TYPE_IMPL) {
let pos = buffer.pos(SN_IMPORT_SEARCH).unwrap();
buffer.insert_at_index(CAIRO_ENUM_TYPE_IMPL.to_owned(), pos + 1);
}
}
if !buffer.has(CAIRO_ENUM_TYPE_IMPL) {
if let Some(pos) = buffer.pos(SN_IMPORT_SEARCH) {
buffer.insert_at_index(CAIRO_ENUM_TYPE_IMPL.to_owned(), pos + 1);
} else {
// Handle the case where SN_IMPORT_SEARCH is not found
buffer.insert(CAIRO_ENUM_TYPE_IMPL.to_owned());
}
}
}

Comment on lines +167 to +172
match value.inners[0].token.to_composite() {
Ok(c) => JsDefaultValue::from(c),
Err(_) => {
JsDefaultValue(format!("{}.{}", value.type_name(), value.inners[0].name))
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Index Out of Bounds Panic in JsDefaultValue::from

Ohayo sensei! In the JsDefaultValue::from implementation for enums, accessing value.inners[0] without checking if inners is non-empty may cause an index out of bounds panic if inners is empty. To prevent this, consider adding a check to ensure value.inners is not empty before accessing the first element.

Apply this diff to fix the potential panic:

 match value.r#type {
     CompositeType::Enum => {
-        match value.inners[0].token.to_composite() {
+        if let Some(first_inner) = value.inners.first() {
+            match first_inner.token.to_composite() {
                 Ok(c) => JsDefaultValue::from(c),
                 Err(_) => {
-                    JsDefaultValue(format!("{}.{}", value.type_name(), value.inners[0].name))
+                    JsDefaultValue(format!("{}.{}", value.type_name(), first_inner.name))
                 }
             }
+        } else {
+            // Handle the case where inners is empty
+            JsDefaultValue("undefined".to_string())
+        }
     }
     // other cases...
 }

Committable suggestion skipped: line range outside the PR's diff.

@@ -14,3 +14,20 @@ pub const CAIRO_BOOL: &str = "bool";
pub const JS_BOOLEAN: &str = "boolean";
pub const JS_STRING: &str = "string";
pub const JS_BIGNUMBERISH: &str = "BigNumberish";

pub(crate) const BIGNUMNERISH_IMPORT: &str = "import type { BigNumberish } from 'starknet';\n";
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Typo in Constant Name BIGNUMNERISH_IMPORT

Ohayo sensei! There is a typo in the constant name BIGNUMNERISH_IMPORT. It should be BIGNUMBERISH_IMPORT to match the correct spelling of BigNumberish.

Apply this diff to fix the typo:

- pub(crate) const BIGNUMNERISH_IMPORT: &str = "import type { BigNumberish } from 'starknet';\n";
+ pub(crate) const BIGNUMBERISH_IMPORT: &str = "import type { BigNumberish } from 'starknet';\n";

Also, update all references to BIGNUMNERISH_IMPORT throughout the codebase to match the corrected name.

Committable suggestion skipped: line range outside the PR's diff.

Copy link

codecov bot commented Dec 5, 2024

Codecov Report

Attention: Patch coverage is 91.31175% with 51 lines in your changes missing coverage. Please review.

Project coverage is 55.80%. Comparing base (ebcc23d) to head (a541768).
Report is 65 commits behind head on main.

Files with missing lines Patch % Lines
...o/bindgen/src/plugins/typescript/generator/enum.rs 26.66% 33 Missing ⚠️
...dgen/src/plugins/typescript/generator/interface.rs 95.04% 5 Missing ⚠️
...jo/bindgen/src/plugins/typescript/generator/mod.rs 98.43% 5 Missing ⚠️
crates/dojo/bindgen/src/plugins/mod.rs 0.00% 3 Missing ⚠️
...ates/dojo/bindgen/src/plugins/typescript/writer.rs 0.00% 3 Missing ⚠️
...ndgen/src/plugins/typescript/generator/function.rs 60.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2773      +/-   ##
==========================================
- Coverage   56.24%   55.80%   -0.45%     
==========================================
  Files         415      444      +29     
  Lines       53241    57319    +4078     
==========================================
+ Hits        29948    31989    +2041     
- Misses      23293    25330    +2037     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

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

I don't have much ts perspective to evaluate the generated code. Will iterate with the contributors currently working around that. Thanks for the unlock @MartianGreed!

We should think of a way to have functional test with the bindgen. That would be great to ensure we don't break and the generated code being actually functional in the way it is intended to be. 👍

@glihm glihm merged commit 575040c into dojoengine:main Dec 6, 2024
13 of 14 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 11, 2024
@coderabbitai coderabbitai bot mentioned this pull request Dec 17, 2024
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants