Skip to content

Commit 9928558

Browse files
bengineer42glihm
andauthored
fix(dojo-lang): raise an error on value before key in model (#2891)
* fix: Raise an error on value before key in model * fix: Raise an error on value before key in model * fix: Improve key member validation logic in parse_members function and clarity * fix: reorder fields in Message struct * fix: run linters * chore: bump scarb to add key before member diagnostic * tests: regenerate test db --------- Co-authored-by: glihm <[email protected]>
1 parent 4fb18a6 commit 9928558

File tree

8 files changed

+75
-158
lines changed

8 files changed

+75
-158
lines changed

Cargo.lock

Lines changed: 29 additions & 146 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ rpassword = "7.2.0"
212212
rstest = "0.18.2"
213213
rstest_reuse = "0.6.0"
214214
salsa = "0.16.1"
215-
scarb = { git = "https://github.com/dojoengine/scarb", rev = "7eac49b3e61236ce466e712225d9c989f9db1ef3" }
216-
scarb-ui = { git = "https://github.com/dojoengine/scarb", rev = "7eac49b3e61236ce466e712225d9c989f9db1ef3" }
215+
scarb = { git = "https://github.com/dojoengine/scarb", rev = "c811c5bcb073afa21cb9b1307adafe733c203eb9" }
216+
scarb-ui = { git = "https://github.com/dojoengine/scarb", rev = "c811c5bcb073afa21cb9b1307adafe733c203eb9" }
217217
semver = "1.0.5"
218218
serde = { version = "1.0", features = [ "derive" ] }
219219
serde_json = { version = "1.0", features = [ "arbitrary_precision" ] }

crates/dojo/lang/src/attribute_macros/element.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use cairo_lang_defs::patcher::RewriteNode;
2+
use cairo_lang_defs::plugin::PluginDiagnostic;
3+
use cairo_lang_diagnostics::Severity;
24
use cairo_lang_syntax::node::ast::Member as MemberAst;
35
use cairo_lang_syntax::node::db::SyntaxGroup;
46
use cairo_lang_syntax::node::helpers::QueryAttrs;
5-
use cairo_lang_syntax::node::{Terminal, TypedSyntaxNode};
7+
use cairo_lang_syntax::node::{Terminal, TypedStablePtr, TypedSyntaxNode};
68
use dojo_types::naming::compute_bytearray_hash;
79
use starknet_crypto::{poseidon_hash_many, Felt};
810

@@ -34,13 +36,45 @@ pub fn compute_unique_hash(
3436
poseidon_hash_many(&hashes)
3537
}
3638

37-
pub fn parse_members(db: &dyn SyntaxGroup, members: &[MemberAst]) -> Vec<Member> {
39+
pub fn parse_members(
40+
db: &dyn SyntaxGroup,
41+
members: &[MemberAst],
42+
diagnostics: &mut Vec<PluginDiagnostic>,
43+
) -> Vec<Member> {
44+
let mut parsing_keys = true;
45+
3846
members
3947
.iter()
40-
.map(|member_ast| Member {
41-
name: member_ast.name(db).text(db).to_string(),
42-
ty: member_ast.type_clause(db).ty(db).as_syntax_node().get_text(db).trim().to_string(),
43-
key: member_ast.has_attr(db, "key"),
48+
.map(|member_ast| {
49+
let is_key = member_ast.has_attr(db, "key");
50+
51+
let member = Member {
52+
name: member_ast.name(db).text(db).to_string(),
53+
ty: member_ast
54+
.type_clause(db)
55+
.ty(db)
56+
.as_syntax_node()
57+
.get_text(db)
58+
.trim()
59+
.to_string(),
60+
key: is_key,
61+
};
62+
63+
// Make sure all keys are before values in the model.
64+
if is_key && !parsing_keys {
65+
diagnostics.push(PluginDiagnostic {
66+
message: "Key members must be defined before non-key members.".into(),
67+
stable_ptr: member_ast.name(db).stable_ptr().untyped(),
68+
severity: Severity::Error,
69+
});
70+
// Don't return here, since we don't want to stop processing the members after the
71+
// first error to avoid diagnostics just because the field is
72+
// missing.
73+
}
74+
75+
parsing_keys &= is_key;
76+
77+
member
4478
})
4579
.collect::<Vec<_>>()
4680
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl DojoEvent {
5858
}
5959
}
6060

61-
let members = parse_members(db, &struct_ast.members(db).elements(db));
61+
let members = parse_members(db, &struct_ast.members(db).elements(db), &mut diagnostics);
6262

6363
let mut serialized_keys: Vec<RewriteNode> = vec![];
6464
let mut serialized_values: Vec<RewriteNode> = vec![];

crates/dojo/lang/src/attribute_macros/model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl DojoModel {
7272
let mut model_member_store_impls_processed: HashSet<String> = HashSet::new();
7373
let mut model_member_store_impls: Vec<String> = vec![];
7474

75-
let members = parse_members(db, &struct_ast.members(db).elements(db));
75+
let members = parse_members(db, &struct_ast.members(db).elements(db), &mut diagnostics);
7676

7777
members.iter().for_each(|member| {
7878
if member.key {

examples/spawn-and-move/src/models.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ pub struct Message {
2828
pub identity: ContractAddress,
2929
#[key]
3030
pub channel: felt252,
31-
pub message: ByteArray,
3231
#[key]
33-
pub salt: felt252
32+
pub salt: felt252,
33+
pub message: ByteArray,
3434
}
3535

3636
#[derive(Copy, Drop, Serde, Debug)]

spawn-and-move-db.tar.gz

9.76 KB
Binary file not shown.

types-test-db.tar.gz

-1.53 KB
Binary file not shown.

0 commit comments

Comments
 (0)