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

refactor(lang): reduce events generated code #2662

Merged
merged 11 commits into from
Nov 8, 2024
28 changes: 14 additions & 14 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ rpassword = "7.2.0"
rstest = "0.18.2"
rstest_reuse = "0.6.0"
salsa = "0.16.1"
scarb = { git = "https://github.com/dojoengine/scarb", rev = "a6d3b5b17b288502fe9cc63c96c0ae22fd175857" }
scarb-ui = { git = "https://github.com/dojoengine/scarb", rev = "a6d3b5b17b288502fe9cc63c96c0ae22fd175857" }
scarb = { git = "https://github.com/dojoengine/scarb", rev = "0f10b0b1d0e4afb7af278228a66196b5cb56b57b" }
scarb-ui = { git = "https://github.com/dojoengine/scarb", rev = "0f10b0b1d0e4afb7af278228a66196b5cb56b57b" }
semver = "1.0.5"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = { version = "1.0", features = [ "arbitrary_precision" ] }
Expand Down
4 changes: 2 additions & 2 deletions crates/dojo/core/src/event/component.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use dojo::event::{Event, IEvent, EventDefinition};
use dojo::event::{Event, IEvent, EventDef};
use dojo::meta::{Layout, introspect::Struct};

#[starknet::embeddable]
Expand All @@ -25,7 +25,7 @@ pub impl IStoredEventImpl<

#[starknet::embeddable]
pub impl IEventImpl<TContractState, E, +Event<E>> of IEvent<TContractState> {
fn definition(self: @TContractState) -> EventDefinition {
fn definition(self: @TContractState) -> EventDef {
Event::<E>::definition()
}
}
38 changes: 35 additions & 3 deletions crates/dojo/core/src/event/event.cairo
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
use dojo::meta::Layout;
use dojo::meta::introspect::Struct;
use dojo::meta::{Introspect, introspect::{Struct, Ty}};
use dojo::model::model::ModelParser;

#[derive(Drop, Serde, Debug, PartialEq)]
pub struct EventDefinition {
pub struct EventDef {
pub name: ByteArray,
pub layout: Layout,
pub schema: Struct
Comment on lines +6 to 9
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Ohayo, sensei! The renaming needs attention in several files.

The search results show that EventDefinition is still being used in multiple places while EventDef has been introduced, creating an inconsistent state:

  • crates/dojo/core/src/lib.cairo exports both EventDefinition and EventDef
  • crates/dojo/core/src/event/event.cairo uses both names:
    • Has the new EventDef struct
    • Still uses EventDefinition trait and implementations
  • crates/dojo/lang/src/plugin_test_data/event has multiple references to EventDefinition
  • crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo uses EventDefinition

The renaming appears to be incomplete and needs to be consistently applied across all these files.

🔗 Analysis chain

Ohayo, sensei! Ensure consistent renaming from EventDefinition to EventDef.

Please verify that all references to EventDefinition have been updated to EventDef throughout the codebase to prevent any compilation errors.

Run the following script to check for any remaining references:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for any remaining references to `EventDefinition`.

rg 'EventDefinition' --type cairo

Length of output: 63


Script:

#!/bin/bash
# Let's search for EventDefinition without file type restriction since cairo might not be recognized
rg "EventDefinition"

# Also search for EventDef to understand the context better
rg "EventDef"

# Let's also check all cairo files to see their presence
fd "\.cairo$"

Length of output: 9181

}
Comment on lines +2 to 10
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Ohayo, sensei! The EventDef renaming is inconsistent and needs attention.

The codebase shows mixed usage of both EventDef and EventDefinition:

  • EventDef is the new struct name in event.cairo
  • EventDefinition is still used as a trait name and in test data
  • Both names are exported in lib.cairo: pub use event::{Event, EventDefinition, EventDef}

This dual naming creates confusion and violates consistent naming conventions. Either revert to EventDefinition throughout or complete the renaming to EventDef consistently.

🔗 Analysis chain

Ohayo, sensei! Verify the EventDef renaming across the codebase.

The renaming from EventDefinition to EventDef needs to be consistently applied across all files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to EventDefinition
# and verify EventDef usage

echo "Checking for remaining EventDefinition references:"
rg "EventDefinition" --type cairo

echo -e "\nVerifying EventDef usage:"
rg "EventDef" --type cairo

Length of output: 298


Script:

#!/bin/bash
# Let's try without file type filtering since cairo isn't recognized
echo "Checking for remaining EventDefinition references:"
rg "EventDefinition"

echo -e "\nVerifying EventDef usage:"
rg "EventDef"

Length of output: 4421


pub trait EventDefinition<E> {
fn name() -> ByteArray;
}

pub trait Event<T> {
fn name() -> ByteArray;
fn definition() -> EventDefinition;
fn definition() -> EventDef;
fn layout() -> Layout;
fn schema() -> Struct;
fn serialized_keys(self: @T) -> Span<felt252>;
fn serialized_values(self: @T) -> Span<felt252>;
/// Returns the selector of the event computed for the given namespace hash.
fn selector(namespace_hash: felt252) -> felt252;
}

pub impl EventImpl<E, +ModelParser<E>, +EventDefinition<E>, +Serde<E>, +Introspect<E>> of Event<E> {
fn name() -> ByteArray {
EventDefinition::<E>::name()
}
fn definition() -> EventDef {
EventDef { name: Self::name(), layout: Self::layout(), schema: Self::schema() }
}
fn layout() -> Layout {
Introspect::<E>::layout()
}
fn schema() -> Struct {
match Introspect::<E>::ty() {
Ty::Struct(s) => s,
_ => panic!("Event: invalid schema.")
}
Comment on lines +38 to +41
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ohayo, sensei! Consider graceful error handling in the schema method.

Using panic! may halt the program unexpectedly. Consider returning a Result type to handle errors more gracefully and provide better error propagation.

Apply this diff to modify the schema method:

 fn schema() -> Struct {
     match Introspect::<E>::ty() {
         Ty::Struct(s) => s,
-        _ => panic!("Event: invalid schema.")
+        _ => {
+            // Return an error for invalid schema type
+            let err_msg = "Event: invalid schema.";
+            Err(err_msg)
+        }
     }
 }

This change allows calling functions to handle the error appropriately.

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

}
fn serialized_keys(self: @E) -> Span<felt252> {
ModelParser::<E>::serialize_keys(self)
}
fn serialized_values(self: @E) -> Span<felt252> {
ModelParser::<E>::serialize_values(self)
}
fn selector(namespace_hash: felt252) -> felt252 {
dojo::utils::selector_from_namespace_and_name(namespace_hash, @Self::name())
}
}
2 changes: 1 addition & 1 deletion crates/dojo/core/src/event/interface.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[starknet::interface]
pub trait IEvent<T> {
fn definition(self: @T) -> super::EventDefinition;
fn definition(self: @T) -> super::EventDef;
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Ohayo sensei! The EventDef transition is incomplete!

The codebase still contains multiple references to EventDefinition that need to be updated to EventDef, particularly in:

  • crates/dojo/lang/src/plugin_test_data/event (multiple occurrences)
  • crates/dojo/core/src/event/event.cairo (trait and impl definitions)
  • crates/dojo/core/src/lib.cairo (exports)

This inconsistency could lead to confusion and potential issues. The change should be applied uniformly across all files.

🔗 Analysis chain

Ohayo sensei! The return type change looks good!

The change from EventDefinition to EventDef aligns well with the PR's objective of reducing generated code by simplifying type names.

Let's verify the consistency of this change across the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that EventDefinition has been completely replaced with EventDef

# Test 1: Check for any remaining references to EventDefinition
echo "Checking for remaining EventDefinition references..."
rg "EventDefinition"

# Test 2: Verify the new EventDef usage
echo "Verifying EventDef usage..."
rg "EventDef"

Length of output: 4423

}
2 changes: 1 addition & 1 deletion crates/dojo/core/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod event {
pub mod component;

pub mod event;
pub use event::{Event, EventDefinition};
pub use event::{Event, EventDefinition, EventDef};

pub mod interface;
pub use interface::{IEvent, IEventDispatcher, IEventDispatcherTrait};
Expand Down
16 changes: 13 additions & 3 deletions crates/dojo/lang/src/attribute_macros/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@
});
}

let members_values = members
.iter()
.filter_map(|m| {
if m.key {
None

Check warning on line 88 in crates/dojo/lang/src/attribute_macros/event.rs

View check run for this annotation

Codecov / codecov/patch

crates/dojo/lang/src/attribute_macros/event.rs#L84-L88

Added lines #L84 - L88 were not covered by tests
} else {
Some(RewriteNode::Text(format!("pub {}: {},\n", m.name, m.ty)))

Check warning on line 90 in crates/dojo/lang/src/attribute_macros/event.rs

View check run for this annotation

Codecov / codecov/patch

crates/dojo/lang/src/attribute_macros/event.rs#L90

Added line #L90 was not covered by tests
}
})
.collect::<Vec<_>>();

Check warning on line 94 in crates/dojo/lang/src/attribute_macros/event.rs

View check run for this annotation

Codecov / codecov/patch

crates/dojo/lang/src/attribute_macros/event.rs#L92-L94

Added lines #L92 - L94 were not covered by tests
let member_names = members
.iter()
.map(|member| RewriteNode::Text(format!("{},\n", member.name.clone())))
Expand All @@ -96,9 +107,7 @@
// and do not derive IntrospectPacked.
if derive_attr_names.contains(&DOJO_PACKED_DERIVE.to_string()) {
diagnostics.push(PluginDiagnostic {
message: format!(
"Event should derive {DOJO_INTROSPECT_DERIVE} instead of {DOJO_PACKED_DERIVE}."
),
message: format!("Deriving {DOJO_PACKED_DERIVE} on event is not allowed."),

Check warning on line 110 in crates/dojo/lang/src/attribute_macros/event.rs

View check run for this annotation

Codecov / codecov/patch

crates/dojo/lang/src/attribute_macros/event.rs#L110

Added line #L110 was not covered by tests
stable_ptr: struct_ast.name(db).stable_ptr().untyped(),
severity: Severity::Error,
});
Expand All @@ -125,6 +134,7 @@
("serialized_keys".to_string(), RewriteNode::new_modified(serialized_keys)),
("serialized_values".to_string(), RewriteNode::new_modified(serialized_values)),
("unique_hash".to_string(), RewriteNode::Text(unique_hash)),
("members_values".to_string(), RewriteNode::new_modified(members_values)),

Check warning on line 137 in crates/dojo/lang/src/attribute_macros/event.rs

View check run for this annotation

Codecov / codecov/patch

crates/dojo/lang/src/attribute_macros/event.rs#L137

Added line #L137 was not covered by tests
]),
);

Expand Down
59 changes: 24 additions & 35 deletions crates/dojo/lang/src/attribute_macros/patches/event.patch.cairo
Original file line number Diff line number Diff line change
@@ -1,56 +1,38 @@
pub impl $type_name$DojoEventImpl of dojo::event::Event<$type_name$> {
// EventValue on it's own does nothing since events are always emitted and
// never read from the storage. However, it's required by the ABI to
// ensure that the event definition contains both keys and values easily distinguishable.
// Only derives strictly required traits.
#[derive(Drop, Serde)]
pub struct $type_name$Value {
$members_values$
}

pub impl $type_name$Definition of dojo::event::EventDefinition<$type_name$>{
#[inline(always)]
fn name() -> ByteArray {
"$type_name$"
}
}

#[inline(always)]
fn definition() -> dojo::event::EventDefinition {
dojo::event::EventDefinition {
name: Self::name(),
layout: Self::layout(),
schema: Self::schema()
}
}

#[inline(always)]
fn layout() -> dojo::meta::Layout {
dojo::meta::introspect::Introspect::<$type_name$>::layout()
}

#[inline(always)]
fn schema() -> dojo::meta::introspect::Struct {
if let dojo::meta::introspect::Ty::Struct(s) = dojo::meta::introspect::Introspect::<$type_name$>::ty() {
s
}
else {
panic!("Event `$type_name$`: invalid schema.")
}
}

#[inline(always)]
fn serialized_keys(self: @$type_name$) -> Span<felt252> {
pub impl $type_name$ModelParser of dojo::model::model::ModelParser<$type_name$>{
fn serialize_keys(self: @$type_name$) -> Span<felt252> {
let mut serialized = core::array::ArrayTrait::new();
$serialized_keys$
core::array::ArrayTrait::span(@serialized)
}

#[inline(always)]
fn serialized_values(self: @$type_name$) -> Span<felt252> {
fn serialize_values(self: @$type_name$) -> Span<felt252> {
let mut serialized = core::array::ArrayTrait::new();
$serialized_values$
core::array::ArrayTrait::span(@serialized)
}

#[inline(always)]
fn selector(namespace_hash: felt252) -> felt252 {
dojo::utils::selector_from_namespace_and_name(namespace_hash, @Self::name())
}
}

pub impl $type_name$EventImpl = dojo::event::event::EventImpl<$type_name$>;

#[starknet::contract]
pub mod e_$type_name$ {
use super::$type_name$;
use super::$type_name$Value;

#[storage]
struct Storage {}
Expand All @@ -74,6 +56,13 @@ pub mod e_$type_name$ {
let _event = event;
}

// Outputs EventValue to allow a simple diff from the ABI compared to the
// event to retrieved the keys of an event.
#[external(v0)]
fn ensure_values(self: @ContractState, value: $type_name$Value) {
let _value = value;
}

// Ensures the generated contract has a unique classhash, using
// a hardcoded hash computed on event and member names.
#[external(v0)]
Expand Down
1 change: 1 addition & 0 deletions scripts/rebuild_test_artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ cargo +nightly-2024-08-28 fmt --all -- "$@"
# CAIRO_FIX_TESTS=1 cargo test --package dojo-lang semantics

# Re-run the minimal tests, this will re-build the projects + generate the build artifacts.
./target/release/sozo build --manifest-path examples/simple/Scarb.toml
./target/release/sozo build --manifest-path examples/spawn-and-move/Scarb.toml
./target/release/sozo build --manifest-path examples/spawn-and-move/Scarb.toml -P release
./target/release/sozo build --manifest-path crates/torii/types-test/Scarb.toml
Expand Down
Binary file modified spawn-and-move-db.tar.gz
Binary file not shown.
Binary file modified types-test-db.tar.gz
Binary file not shown.
Loading