-
Notifications
You must be signed in to change notification settings - Fork 184
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/bindgen improve types #2816
Changes from 1 commit
354d7ec
f059637
85504a8
6917660
a541768
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,76 @@ | ||
use cainome::parser::tokens::{Composite, CompositeType}; | ||
|
||
use crate::error::BindgenResult; | ||
use crate::plugins::typescript::generator::JsType; | ||
use crate::plugins::{BindgenModelGenerator, Buffer}; | ||
|
||
use super::constants::{CAIRO_ENUM_IMPORT, CAIRO_ENUM_TOKEN, SN_IMPORT_SEARCH}; | ||
use super::token_is_custom_enum; | ||
|
||
const CAIRO_ENUM_TYPE_IMPL: &str = "export type TypedCairoEnum<T> = CairoCustomEnum & {\n\tvariant: { [K in keyof T]: T[K] | undefined };\n\tunwrap(): T[keyof T];\n}\n"; | ||
|
||
pub(crate) struct TsEnumGenerator; | ||
|
||
impl TsEnumGenerator { | ||
fn check_import(&self, token: &Composite, buffer: &mut Buffer) { | ||
// type is Enum with type variants, need to import CairoEnum | ||
// if enum has at least one inner that is a composite type | ||
if token_is_custom_enum(token) { | ||
if !buffer.has(SN_IMPORT_SEARCH) { | ||
buffer.push(CAIRO_ENUM_IMPORT.to_owned()); | ||
} else if !buffer.has(CAIRO_ENUM_TOKEN) { | ||
// If 'starknet' import is present, we add CairoEnum to the imported types | ||
buffer.insert_after(format!(" {CAIRO_ENUM_TOKEN}"), SN_IMPORT_SEARCH, "{", 1); | ||
} | ||
} | ||
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); | ||
} | ||
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible Panic when Calling Ohayo, sensei! There's a potential issue with the use of Apply this diff to handle the - 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
+ // For example, insert CAIRO_ENUM_TYPE_IMPL at a default position or log an error
+ }
|
||
} | ||
} | ||
|
||
impl BindgenModelGenerator for TsEnumGenerator { | ||
fn generate(&self, token: &Composite, buffer: &mut Buffer) -> BindgenResult<String> { | ||
if token.r#type != CompositeType::Enum || token.inners.is_empty() { | ||
return Ok(String::new()); | ||
} | ||
|
||
let gen = format!( | ||
"// Type definition for `{path}` enum | ||
let gen = if token_is_custom_enum(token) { | ||
self.check_import(token, buffer); | ||
format!( | ||
"// Type definition for `{path}` enum | ||
export type {name} = {{ | ||
{variants} | ||
}} | ||
export type {name}Enum = TypedCairoEnum<{name}>; | ||
", | ||
path = token.type_path, | ||
name = token.type_name(), | ||
variants = token | ||
.inners | ||
.iter() | ||
.map(|inner| { format!("\t{}: {};", inner.name, JsType::from(&inner.token)) }) | ||
.collect::<Vec<String>>() | ||
.join("\n") | ||
) | ||
} else { | ||
format!( | ||
"// Type definition for `{path}` enum | ||
export enum {name} {{ | ||
{variants} | ||
}} | ||
", | ||
path = token.type_path, | ||
name = token.type_name(), | ||
variants = token | ||
.inners | ||
.iter() | ||
.map(|inner| format!("\t{},", inner.name)) | ||
.collect::<Vec<String>>() | ||
.join("\n") | ||
); | ||
path = token.type_path, | ||
name = token.type_name(), | ||
variants = token | ||
.inners | ||
.iter() | ||
.map(|inner| format!("\t{},", inner.name)) | ||
.collect::<Vec<String>>() | ||
.join("\n") | ||
) | ||
}; | ||
|
||
if buffer.has(&gen) { | ||
return Ok(String::new()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,39 @@ | ||
use cainome::parser::tokens::{Composite, CompositeType}; | ||
use cainome::parser::tokens::{Composite, CompositeType, Token}; | ||
|
||
use super::JsType; | ||
use super::constants::{BIGNUMNERISH_IMPORT, CAIRO_OPTION_IMPORT, SN_IMPORT_SEARCH}; | ||
use super::{token_is_option, JsType}; | ||
use crate::error::BindgenResult; | ||
use crate::plugins::typescript::generator::constants::CAIRO_OPTION_TOKEN; | ||
use crate::plugins::{BindgenModelGenerator, Buffer}; | ||
|
||
const BIGNUMNERISH_IMPORT: &str = "import type { BigNumberish } from 'starknet';"; | ||
|
||
pub(crate) struct TsInterfaceGenerator; | ||
impl TsInterfaceGenerator { | ||
fn check_import(&self, token: &Composite, buffer: &mut Buffer) { | ||
// only search for end part of the import, as we append the other imports afterward | ||
if !buffer.has("BigNumberish } from 'starknet';") { | ||
buffer.push(BIGNUMNERISH_IMPORT.to_owned()); | ||
} | ||
|
||
// type is Option, need to import CairoOption | ||
if token_is_option(token) { | ||
// we directly add import if 'starknet' import is not present | ||
if !buffer.has(SN_IMPORT_SEARCH) { | ||
buffer.push(CAIRO_OPTION_IMPORT.to_owned()); | ||
} else if !buffer.has(CAIRO_OPTION_TOKEN) { | ||
// If 'starknet' import is present, we add CairoOption to the imported types | ||
buffer.insert_after(format!(" {CAIRO_OPTION_TOKEN}"), SN_IMPORT_SEARCH, "{", 1); | ||
Comment on lines
+22
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential Panic when Using Ohayo, sensei! In the Apply this diff to handle the - buffer.insert_after(format!(" {CAIRO_OPTION_TOKEN}"), SN_IMPORT_SEARCH, "{", 1);
+ if let Some(_) = buffer.pos(SN_IMPORT_SEARCH) {
+ buffer.insert_after(format!(" {CAIRO_OPTION_TOKEN}"), SN_IMPORT_SEARCH, "{", 1);
+ } else {
+ // Handle the case where SN_IMPORT_SEARCH is not found
+ // For example, insert CAIRO_OPTION_IMPORT at a default position or log an error
+ }
|
||
} | ||
} | ||
} | ||
} | ||
|
||
impl BindgenModelGenerator for TsInterfaceGenerator { | ||
fn generate(&self, token: &Composite, buffer: &mut Buffer) -> BindgenResult<String> { | ||
if token.r#type != CompositeType::Struct || token.inners.is_empty() { | ||
return Ok(String::new()); | ||
} | ||
|
||
if !buffer.has(BIGNUMNERISH_IMPORT) { | ||
buffer.push(BIGNUMNERISH_IMPORT.to_owned()); | ||
} | ||
self.check_import(token, buffer); | ||
|
||
Ok(format!( | ||
"// Type definition for `{path}` struct | ||
|
@@ -30,7 +47,15 @@ export interface {name} {{ | |
fields = token | ||
.inners | ||
.iter() | ||
.map(|inner| { format!("\t{}: {};", inner.name, JsType::from(&inner.token)) }) | ||
.map(|inner| { | ||
if let Token::Composite(composite) = &inner.token { | ||
if token_is_option(composite) { | ||
self.check_import(composite, buffer); | ||
} | ||
} | ||
|
||
format!("\t{}: {};", inner.name, JsType::from(&inner.token)) | ||
}) | ||
.collect::<Vec<String>>() | ||
.join("\n") | ||
)) | ||
|
@@ -93,6 +118,21 @@ mod tests { | |
); | ||
} | ||
|
||
#[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()); | ||
let option = create_option_token(); | ||
writer.check_import(&option, &mut buff); | ||
assert_eq!(1, buff.len()); | ||
let custom_enum = create_custom_enum_token(); | ||
writer.check_import(&custom_enum, &mut buff); | ||
assert_eq!(1, buff.len()); | ||
} | ||
|
||
fn create_test_struct_token() -> Composite { | ||
Composite { | ||
type_path: "core::test::TestStruct".to_owned(), | ||
|
@@ -122,4 +162,57 @@ mod tests { | |
alias: None, | ||
} | ||
} | ||
|
||
fn create_option_token() -> Composite { | ||
Composite { | ||
type_path: "core::option::Option<core::felt252>".to_owned(), | ||
inners: vec![CompositeInner { | ||
index: 0, | ||
name: "value".to_owned(), | ||
kind: CompositeInnerKind::Key, | ||
token: Token::CoreBasic(CoreBasic { type_path: "core::felt252".to_owned() }), | ||
}], | ||
generic_args: vec![], | ||
r#type: CompositeType::Struct, | ||
is_event: false, | ||
alias: None, | ||
} | ||
} | ||
fn create_custom_enum_token() -> Composite { | ||
Composite { | ||
type_path: "core::test::CustomEnum".to_owned(), | ||
inners: vec![ | ||
CompositeInner { | ||
index: 0, | ||
name: "Variant1".to_owned(), | ||
kind: CompositeInnerKind::NotUsed, | ||
token: Token::CoreBasic(CoreBasic { type_path: "core::felt252".to_owned() }), | ||
}, | ||
CompositeInner { | ||
index: 1, | ||
name: "Variant2".to_owned(), | ||
kind: CompositeInnerKind::NotUsed, | ||
token: Token::Composite(Composite { | ||
type_path: "core::test::NestedStruct".to_owned(), | ||
inners: vec![CompositeInner { | ||
index: 0, | ||
name: "nested_field".to_owned(), | ||
kind: CompositeInnerKind::Key, | ||
token: Token::CoreBasic(CoreBasic { | ||
type_path: "core::felt252".to_owned(), | ||
}), | ||
}], | ||
generic_args: vec![], | ||
r#type: CompositeType::Struct, | ||
is_event: false, | ||
alias: None, | ||
}), | ||
}, | ||
], | ||
generic_args: vec![], | ||
r#type: CompositeType::Enum, | ||
is_event: false, | ||
alias: None, | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -51,6 +51,9 @@ impl BindgenWriter for TsFileWriter { | |||||||||||
.iter() | ||||||||||||
.fold(Buffer::new(), |mut acc, g| { | ||||||||||||
composites.iter().for_each(|c| { | ||||||||||||
// println!("Generating code for model {}", c.type_path); | ||||||||||||
// println!("{:#?}", c); | ||||||||||||
// println!("====================="); | ||||||||||||
Comment on lines
+54
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Ohayo sensei! Consider using proper logging instead of commented-out print statements. Replace the commented debug prints with proper logging using the - // println!("Generating code for model {}", c.type_path);
- // println!("{:#?}", c);
- // println!("=====================");
+ log::debug!("Generating code for model {}", c.type_path);
+ log::trace!("Model details: {:#?}", c); 📝 Committable suggestion
Suggested change
|
||||||||||||
match g.generate(c, &mut acc) { | ||||||||||||
Ok(code) => { | ||||||||||||
if !code.is_empty() { | ||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in Constant Name
BIGNUMNERISH_IMPORT
Ohayo, sensei! There's a typo in the constant name
BIGNUMNERISH_IMPORT
. It should beBIGNUMBERISH_IMPORT
to match the correct spelling of 'BigNumberish'.Apply this diff to fix the typo:
Be sure to update all references to
BIGNUMNERISH_IMPORT
throughout the codebase to prevent any compilation errors.