diff --git a/crates/cairo-lang-defs/src/patcher.rs b/crates/cairo-lang-defs/src/patcher.rs index 7f0b01c424c..6aaf2d39cdc 100644 --- a/crates/cairo-lang-defs/src/patcher.rs +++ b/crates/cairo-lang-defs/src/patcher.rs @@ -23,6 +23,7 @@ pub enum RewriteNode { node: Box, }, Text(String), + TextAndMapping(String, Vec), } impl RewriteNode { pub fn new_trimmed(syntax_node: SyntaxNode) -> Self { @@ -123,7 +124,9 @@ impl RewriteNode { extract_matches!(self, RewriteNode::Modified) } RewriteNode::Modified(modified) => modified, - RewriteNode::Text(_) => panic!("A text node can't be modified"), + RewriteNode::Text(_) | RewriteNode::TextAndMapping(_, _) => { + panic!("A text node can't be modified") + } RewriteNode::Mapped { .. } => panic!("A mapped node can't be modified"), } } @@ -261,6 +264,12 @@ impl<'a> PatchBuilder<'a> { (self.code, self.code_mappings) } + /// Builds the patcher into a rewrite node enabling adding it to other patchers. + pub fn into_rewrite_node(self) -> RewriteNode { + let (code, mappings) = self.build(); + RewriteNode::TextAndMapping(code, mappings) + } + pub fn add_char(&mut self, c: char) { self.code.push(c); } @@ -284,6 +293,15 @@ impl<'a> PatchBuilder<'a> { } } RewriteNode::Text(s) => self.add_str(s.as_str()), + RewriteNode::TextAndMapping(s, mappings) => { + let mapping_fix = TextWidth::from_str(&self.code); + self.add_str(&s); + self.code_mappings.extend(mappings.into_iter().map(|mut mapping| { + mapping.span.start = mapping.span.start.add_width(mapping_fix); + mapping.span.end = mapping.span.end.add_width(mapping_fix); + mapping + })); + } } } diff --git a/crates/cairo-lang-starknet/src/plugin/derive/store.rs b/crates/cairo-lang-starknet/src/plugin/derive/store.rs index 17ab8ea9b63..287dc838cda 100644 --- a/crates/cairo-lang-starknet/src/plugin/derive/store.rs +++ b/crates/cairo-lang-starknet/src/plugin/derive/store.rs @@ -22,9 +22,7 @@ pub fn handle_store_derive( // a sub-pointers implementation. let store_trait_code = handle_struct_store(db, struct_ast)?; let sub_pointers_code = if !struct_ast.members(db).elements(db).is_empty() { - let (sub_pointers_code, _) = - handle_storage_interface_struct(db, struct_ast, metadata); - RewriteNode::Text(sub_pointers_code) + handle_storage_interface_struct(db, struct_ast, metadata).into_rewrite_node() } else { RewriteNode::Text("".to_string()) }; diff --git a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/components/component b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/components/component index 4ec94c8cf70..ad62f0bcaae 100644 --- a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/components/component +++ b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/components/component @@ -362,9 +362,9 @@ impl MyTypeSubPointersDrop of core::traits::Drop::; impl MyTypeSubPointersCopy of core::traits::Copy::; -lib.cairo:1:16 +lib.cairo:1:1 #[derive(Drop, starknet::Store)] - ^*************^ +^******************************^ impls: impl MyTypeSubPointersMutDrop of core::traits::Drop::; @@ -1101,8 +1101,3 @@ warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[featur --> lib.cairo:14:14 map: LegacyMap, ^*******^ - -warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead." - --> lib.cairo:11:5 - #[storage] - ^********^ diff --git a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/events b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/events index e81fe22d46a..3b885f6a0fc 100644 --- a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/events +++ b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/events @@ -453,9 +453,9 @@ impl ASubPointersDrop of core::traits::Drop::; impl ASubPointersCopy of core::traits::Copy::; -lib.cairo:1:27 +lib.cairo:1:1 #[derive(starknet::Event, starknet::Store, PartialEq, Drop, Serde)] - ^*************^ +^*****************************************************************^ impls: impl ASubPointersMutDrop of core::traits::Drop::; diff --git a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/new_storage_interface b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/new_storage_interface index aa04db04dba..c50a927b66d 100644 --- a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/new_storage_interface +++ b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/new_storage_interface @@ -2294,9 +2294,9 @@ impl SlicedBalanceTrioSubPointersDrop of core::traits::Drop::; -lib.cairo:34:16 +lib.cairo:34:1 #[derive(Drop, starknet::Store)] - ^*************^ +^******************************^ impls: impl SlicedBalanceTrioSubPointersMutDrop of core::traits::Drop::; @@ -2312,9 +2312,9 @@ impl SlicedBalancePairSubPointersDrop of core::traits::Drop::; -lib.cairo:40:16 +lib.cairo:40:1 #[derive(Drop, starknet::Store)] - ^*************^ +^******************************^ impls: impl SlicedBalancePairSubPointersMutDrop of core::traits::Drop::; @@ -3018,8 +3018,3 @@ warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[featur --> lib.cairo:75:28 legacy_map_balace: LegacyMap, ^*******^ - -warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead." - --> lib.cairo:70:5 - #[storage] - ^********^ diff --git a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/storage b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/storage index b4787b1bc0e..10e09acfc85 100644 --- a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/storage +++ b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/storage @@ -178,9 +178,9 @@ impl OuterTypeSubPointersDrop of core::traits::Drop::; impl OuterTypeSubPointersCopy of core::traits::Copy::; -lib.cairo:1:16 +lib.cairo:1:1 #[derive(Drop, starknet::Store, Hash)] - ^*************^ +^************************************^ impls: impl OuterTypeSubPointersMutDrop of core::traits::Drop::; @@ -457,8 +457,3 @@ warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[featur --> lib.cairo:24:35 inner_type_to_inner_type: LegacyMap::, ^*******^ - -warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead." - --> lib.cairo:9:5 - #[storage] - ^********^ diff --git a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/user_defined_types b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/user_defined_types index 54815c23f19..1bc223453c9 100644 --- a/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/user_defined_types +++ b/crates/cairo-lang-starknet/src/plugin/plugin_test_data/contracts/user_defined_types @@ -712,9 +712,9 @@ impl WrappedFelt252SubPointersDrop of core::traits::Drop::; -lib.cairo:13:26 +lib.cairo:13:5 #[derive(Drop, Hash, starknet::Store)] - ^*************^ + ^************************************^ impls: impl WrappedFelt252SubPointersMutDrop of core::traits::Drop::; @@ -735,8 +735,3 @@ warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[featur --> lib.cairo:11:28 zero_size_mapping: LegacyMap::, ^*******^ - -warning: Usage of deprecated feature `"deprecated_legacy_map"` with no `#[feature("deprecated_legacy_map")]` attribute. Note: "Use `starknet::storage::Map` instead." - --> lib.cairo:6:5 - #[storage] - ^********^ diff --git a/crates/cairo-lang-starknet/src/plugin/storage.rs b/crates/cairo-lang-starknet/src/plugin/storage.rs index 3626724088c..562c3d2262c 100644 --- a/crates/cairo-lang-starknet/src/plugin/storage.rs +++ b/crates/cairo-lang-starknet/src/plugin/storage.rs @@ -69,12 +69,13 @@ pub fn handle_storage_struct( } else { "".to_string() }; - let (storage_base_code, _) = handle_storage_interface_struct(db, &struct_ast, metadata); + let storage_base_code = + handle_storage_interface_struct(db, &struct_ast, metadata).into_rewrite_node(); data.state_struct_code = RewriteNode::interpolate_patched( &formatdoc!( " {storage_struct_code} - {storage_base_code} + $storage_base_code$ pub struct {full_state_struct_name} {{$substorage_members_struct_code$ }} @@ -110,6 +111,7 @@ pub fn handle_storage_struct( ", ), &[ + ("storage_base_code".to_string(), storage_base_code), ( "storage_struct_members".to_string(), RewriteNode::new_modified(storage_struct_members), diff --git a/crates/cairo-lang-starknet/src/plugin/storage_interfaces.rs b/crates/cairo-lang-starknet/src/plugin/storage_interfaces.rs index 9fea6a28280..36ac7d77f52 100644 --- a/crates/cairo-lang-starknet/src/plugin/storage_interfaces.rs +++ b/crates/cairo-lang-starknet/src/plugin/storage_interfaces.rs @@ -86,7 +86,7 @@ impl MacroPlugin for StorageInterfacesPlugin { return PluginResult { code: None, diagnostics, remove_original_item: false }; } let (content, code_mappings) = - handle_storage_interface_struct(db, &struct_ast, metadata); + handle_storage_interface_struct(db, &struct_ast, metadata).build(); PluginResult { code: Some(PluginGeneratedFile { name: "storage_node".into(), @@ -447,11 +447,11 @@ fn handle_storage_interface_for_interface_type( /// - From this plugin for adding storage nodes, and storage base trait. /// - From the derive plugin of the `Store` trait which also generates a sub-pointers interface. /// - From the contract storage plugin, which generates storage base trait. -pub fn handle_storage_interface_struct( - db: &dyn SyntaxGroup, +pub fn handle_storage_interface_struct<'a>( + db: &'a dyn SyntaxGroup, struct_ast: &ast::ItemStruct, metadata: &MacroPluginMetadata<'_>, -) -> (String, Vec) { +) -> PatchBuilder<'a> { let mut builder = PatchBuilder::new(db, struct_ast); // Run for both StorageNode and StorageTrait let storage_interface_types = if struct_ast.has_attr(db, STORAGE_NODE_ATTR) { @@ -472,7 +472,7 @@ pub fn handle_storage_interface_struct( &mut builder, ); } - builder.build() + builder } /// Adds the storage interface enum and its constructor impl, for enums with sub-pointers. @@ -633,9 +633,9 @@ fn add_node_enum_definition( let concrete_node_members_type = storage_node_info.concrete_node_members_type(&variant); let field_name = variant.name(db).as_syntax_node(); let field_type = match variant.type_clause(db) { - ast::OptionTypeClause::Empty(_) => "()".to_string(), + ast::OptionTypeClause::Empty(_) => RewriteNode::text("()"), ast::OptionTypeClause::TypeClause(tc) => { - tc.ty(db).as_syntax_node().get_text_without_trivia(db) + RewriteNode::new_trimmed(tc.ty(db).as_syntax_node()) } }; @@ -643,7 +643,7 @@ fn add_node_enum_definition( &format!(" $field_name$: {concrete_node_members_type},\n",), &[ ("field_name".to_string(), RewriteNode::new_trimmed(field_name)), - ("field_type".to_string(), RewriteNode::text(&field_type)), + ("field_type".to_string(), field_type), ] .into(), ));