Skip to content

Commit

Permalink
Stach
Browse files Browse the repository at this point in the history
  • Loading branch information
bengineer42 committed Dec 31, 2024
1 parent 54fbacd commit b39dc35
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 23 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/dojo/lang/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cairo-lang-syntax.workspace = true
cairo-lang-utils.workspace = true
dojo-types.workspace = true
itertools.workspace = true
regex.workspace = true
serde.workspace = true
smol_str.workspace = true
starknet.workspace = true
Expand Down
88 changes: 67 additions & 21 deletions crates/dojo/lang/src/derive_macros/introspect/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ use cairo_lang_syntax::node::{ids, Terminal, TypedSyntaxNode};
use starknet::core::utils::get_selector_from_name;

use super::utils::{
get_array_item_type, get_tuple_item_types, is_array, is_byte_array, is_tuple,
is_unsupported_option_type, primitive_type_introspection,
get_array_item_type, get_fixed_array_type_and_size, get_tuple_item_types, is_array,
is_byte_array, is_fixed_array, is_tuple, is_unsupported_option_type,
primitive_type_introspection,
};

pub enum Wrapper {
Introspect,
Array(String),
}

/// build the full layout for every field in the Struct.
pub fn build_field_layouts(
db: &dyn SyntaxGroup,
Expand Down Expand Up @@ -110,26 +116,62 @@ pub fn build_array_layout_from_type(
) -> String {
let array_item_type = get_array_item_type(item_type);

if is_tuple(&array_item_type) {
format!(
"dojo::meta::Layout::Array(
array![
{}
].span()
)",
build_item_layout_from_type(diagnostics, diagnostic_item, &array_item_type)
)
} else if is_array(&array_item_type) {
format!(
"dojo::meta::Layout::Array(
array![
{}
].span()
)",
build_array_layout_from_type(diagnostics, diagnostic_item, &array_item_type)
)
match build_member_layout_from_type(diagnostics, diagnostic_item, &array_item_type) {
Wrapper::Introspect => {
format!("dojo::meta::introspect::Introspect::<{}>::layout()", array_item_type)
}
Wrapper::Array(layout) => {
format!(
"dojo::meta::Layout::Array(
array![
{}
].span(),
)",
layout
)
}
}
}

pub fn build_member_layout_from_type(
diagnostics: &mut Vec<PluginDiagnostic>,
diagnostic_item: ids::SyntaxStablePtrId,
item_type: &str,
) -> Wrapper {
if is_array(item_type) {
Wrapper::Array(build_array_layout_from_type(diagnostics, diagnostic_item, item_type))
} else if is_fixed_array(item_type) {
Wrapper::Array(build_fixed_array_layout_from_type(diagnostics, diagnostic_item, item_type))
} else if is_tuple(item_type) {
Wrapper::Array(build_tuple_layout_from_type(diagnostics, diagnostic_item, item_type))
} else {
format!("dojo::meta::introspect::Introspect::<{}>::layout()", item_type)
Wrapper::Introspect
}
}

pub fn build_fixed_array_layout_from_type(
diagnostics: &mut Vec<PluginDiagnostic>,
diagnostic_item: ids::SyntaxStablePtrId,
item_type: &str,
) -> String {
let (array_item_type, array_size) = get_fixed_array_type_and_size(item_type);
match build_member_layout_from_type(diagnostics, diagnostic_item, &array_item_type) {
Wrapper::Introspect => {
format!(
"dojo::meta::introspect::Introspect::<({}, {})>::layout()",
array_item_type, array_size
)
}
Wrapper::Array(layout) => {
format!(
"dojo::meta::Layout::FixedArray(
array![
({}, {})
].span(),
)",
layout, array_size
)
}
}
}

Expand Down Expand Up @@ -164,6 +206,8 @@ pub fn build_item_layout_from_type(
) -> String {
if is_array(item_type) {
build_array_layout_from_type(diagnostics, diagnostic_item, item_type)
} else if is_fixed_array(item_type) {
build_fixed_array_layout_from_type(diagnostics, diagnostic_item, item_type)
} else if is_tuple(item_type) {
build_tuple_layout_from_type(diagnostics, diagnostic_item, item_type)
} else {
Expand Down Expand Up @@ -343,6 +387,8 @@ pub fn get_packed_item_layout_from_type(
vec!["ERROR".to_string()]
} else if is_tuple(item_type) {
get_packed_tuple_layout_from_type(diagnostics, diagnostic_item, item_type)
} else if is_fixed_array(item_type) {
// TODO: Implement fixed array packed layout
} else {
let primitives = primitive_type_introspection();

Expand Down
18 changes: 16 additions & 2 deletions crates/dojo/lang/src/derive_macros/introspect/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use cairo_lang_syntax::node::db::SyntaxGroup;
use cairo_lang_syntax::node::helpers::QueryAttrs;
use cairo_lang_syntax::node::{Terminal, TypedSyntaxNode};

use super::utils::{get_array_item_type, get_tuple_item_types, is_array, is_byte_array, is_tuple};
use super::utils::{
get_array_item_type, get_fixed_array_type_and_size, get_tuple_item_types, is_array,
is_byte_array, is_fixed_array, is_tuple,
};

pub fn build_struct_ty(db: &dyn SyntaxGroup, name: &String, struct_ast: &ItemStruct) -> String {
let members_ty = struct_ast
Expand Down Expand Up @@ -56,7 +59,7 @@ pub fn build_member_ty(db: &dyn SyntaxGroup, member: &Member) -> String {
let attrs = if member.has_attr(db, "key") { vec!["'key'"] } else { vec![] };

format!(
"dojo::meta::introspect::Member {{
"dojo::meta::introspect::FixedArray {{
name: '{name}',
attrs: array![{}].span(),
ty: {}
Expand Down Expand Up @@ -107,6 +110,17 @@ pub fn build_item_ty_from_type(item_type: &String) -> String {
)",
build_item_ty_from_type(&array_item_type)
)
} else if is_fixed_array(item_type) {
let (array_item_type, size) = get_fixed_array_type_and_size(&item_type);
format!(
"dojo::meta::introspect::Ty::FixedArray(
array![
({}, {})
].span()
)",
build_item_ty_from_type(&array_item_type),
size
)
} else if is_byte_array(item_type) {
"dojo::meta::introspect::Ty::ByteArray".to_string()
} else if is_tuple(item_type) {
Expand Down
12 changes: 12 additions & 0 deletions crates/dojo/lang/src/derive_macros/introspect/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use regex::Regex;
use std::collections::HashMap;

const FIXED_ARRAY_REGEX: &str = r"\[[^;]+;\s*\d{1,10}\s*\]";

#[derive(Clone, Default, Debug)]
pub struct TypeIntrospection(pub usize, pub Vec<usize>);

Expand Down Expand Up @@ -27,6 +30,11 @@ pub fn is_unsupported_option_type(ty: &str) -> bool {
ty.starts_with("Option<(")
}

pub fn is_fixed_array(ty: &str) -> bool {
let re = Regex::new(FIXED_ARRAY_REGEX).unwrap();
re.is_match(ty)
}

pub fn is_byte_array(ty: &str) -> bool {
ty.eq("ByteArray")
}
Expand All @@ -47,6 +55,10 @@ pub fn get_array_item_type(ty: &str) -> String {
}
}

pub fn get_fixed_array_type_and_size(ty: &str) -> (String, usize) {
let mut parts = ty.trim().strip_prefix('[').unwrap().strip_suffix(']').unwrap().split(';');
(parts.next().unwrap().trim().to_string(), parts.last().unwrap().trim().parse().unwrap())
}
/// split a tuple in array of items (nested tuples are not splitted).
/// example (u8, (u16, u32), u128) -> ["u8", "(u16, u32)", "u128"]
pub fn get_tuple_item_types(ty: &str) -> Vec<String> {
Expand Down

0 comments on commit b39dc35

Please sign in to comment.