Skip to content

Commit

Permalink
Added better mapping for contract type-aliases.
Browse files Browse the repository at this point in the history
commit-id:e1b0c9fb
  • Loading branch information
orizi committed Aug 18, 2024
1 parent 405e9dc commit 51d56e4
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 27 deletions.
7 changes: 6 additions & 1 deletion crates/cairo-lang-defs/src/patcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl RewriteNode {
}

pub fn mapped_text(text: &str, origin: TextSpan) -> Self {
Self::Mapped { origin, node: Box::new(RewriteNode::Text(text.to_string())) }
RewriteNode::Text(text.to_string()).mapped(origin)
}

pub fn empty() -> Self {
Expand Down Expand Up @@ -201,6 +201,11 @@ impl RewriteNode {
) -> RewriteNode {
RewriteNode::new_modified(itertools::intersperse(children, separator).collect_vec())
}

/// Creates a new rewrite node wrapped in a mapping to the original code.
pub fn mapped(self, origin: TextSpan) -> Self {
RewriteNode::Mapped { origin, node: Box::new(self) }
}
}
impl Default for RewriteNode {
fn default() -> Self {
Expand Down
12 changes: 3 additions & 9 deletions crates/cairo-lang-starknet/src/plugin/derive/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cairo_lang_defs::patcher::{PatchBuilder, RewriteNode};
use cairo_lang_defs::patcher::PatchBuilder;
use cairo_lang_defs::plugin::{
DynGeneratedFileAuxData, MacroPluginMetadata, PluginGeneratedFile, PluginResult,
};
Expand Down Expand Up @@ -31,19 +31,13 @@ pub fn handle_derive(
if let Some((node, starknet_aux_data)) =
event::handle_event_derive(db, &item_ast, &mut diagnostics)
{
builder.add_modified(RewriteNode::Mapped {
node: node.into(),
origin: derive_arg.as_syntax_node().span_without_trivia(db),
});
builder.add_modified(node.mapped(derive_arg.as_syntax_node().span_without_trivia(db)));
aux_data = Some(DynGeneratedFileAuxData::new(starknet_aux_data));
}
}
if let Some(derive_arg) = has_derive(&item_ast, db, STORE_TRAIT) {
if let Some(node) = store::handle_store_derive(db, &item_ast, &mut diagnostics, metadata) {
builder.add_modified(RewriteNode::Mapped {
node: node.into(),
origin: derive_arg.as_syntax_node().span_without_trivia(db),
});
builder.add_modified(node.mapped(derive_arg.as_syntax_node().span_without_trivia(db)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13488,3 +13488,196 @@ impls:

impl StorageStorageBaseMutDrop of core::traits::Drop::<StorageStorageBaseMut>;
impl StorageStorageBaseMutCopy of core::traits::Copy::<StorageStorageBaseMut>;

//! > ==========================================================================

//! > Test `#[abi(embed_v0)]` with bad trait.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::contract]
mod contract {
#[storage]
struct Storage {}

#[abi(embed_v0)]
impl MyEmbeddedImpl = super::NonExistent<ContractState>;
}

//! > expected_diagnostics
error: Impl not found.
--> lib.cairo:7:34
impl MyEmbeddedImpl = super::NonExistent<ContractState>;
^*********^

error: Trait not found.
--> lib.cairo:6:5
#[abi(embed_v0)]
^**************^

//! > generated_cairo_code
lib.cairo:

#[starknet::contract]
mod contract {
#[storage]
struct Storage {}

#[abi(embed_v0)]
impl MyEmbeddedImpl = super::NonExistent<ContractState>;
}

lib.cairo:1:1
#[starknet::contract]
^*******************^
contract:

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {}


#[phantom]
pub struct Storage {
}

#[derive(Drop, Copy)]
pub struct StorageStorageBase {
}
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
type BaseType = StorageStorageBase;
fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
StorageStorageBase {
}
}
}
#[derive(Drop, Copy)]
pub struct StorageStorageBaseMut {
}
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
type BaseType = StorageStorageBaseMut;
fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
StorageStorageBaseMut {
}
}
}

pub struct ContractState {
}

impl ContractStateDrop of Drop<ContractState> {}

impl ContractStateDeref of core::ops::SnapshotDeref<ContractState> {
type Target = starknet::storage::FlattenedStorage<Storage>;
fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage<Storage> {
starknet::storage::FlattenedStorage {}
}
}
impl ContractStateDerefMut of core::ops::DerefMut<ContractState> {
type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
starknet::storage::FlattenedStorage {}
}
}
pub fn unsafe_new_contract_state() -> ContractState {
ContractState {
}
}
#[cfg(target: 'test')]
#[inline(always)]
pub fn contract_state_for_testing() -> ContractState {
unsafe_new_contract_state()
}

// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
feature: "deprecated_legacy_map",
note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;
#[cfg(target: 'test')]
pub const TEST_CLASS_HASH: felt252 = 0x314a67237979226310a3a898d2577480ced0373867bd5ec746c163e74c47da9;

impl ContractStateNonExistent of
super::UnsafeNewContractStateTraitForNonExistent<ContractState> {
fn unsafe_new_contract_state() -> ContractState {
unsafe_new_contract_state()
}
}

pub mod __external {
}
pub mod __l1_handler {
}
pub mod __constructor {
}
impl ContractStateEventEmitter of starknet::event::EventEmitter<
ContractState, Event
> {
fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(
ref self: ContractState, event: S
) {
let event: Event = core::traits::Into::into(event);
let mut keys = Default::<core::array::Array>::default();
let mut data = Default::<core::array::Array>::default();
starknet::Event::append_keys_and_data(@event, ref keys, ref data);
starknet::SyscallResultTrait::unwrap_syscall(
starknet::syscalls::emit_event_syscall(
core::array::ArrayTrait::span(@keys),
core::array::ArrayTrait::span(@data),
)
)
}
}



lib.cairo:1:1
#[starknet::contract]
^*******************^
impls:

impl EventDrop of core::traits::Drop::<Event>;


lib.cairo:1:1
#[starknet::contract]
^*******************^
starknet_derive:

impl EventIsEvent of starknet::Event<Event> {
fn append_keys_and_data(
self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
) {
match self {
}
}
fn deserialize(
ref keys: Span<felt252>, ref data: Span<felt252>,
) -> Option<Event> {
let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
Option::None
}
}



lib.cairo:1:1
#[starknet::contract]
^*******************^
impls:

impl StorageStorageBaseDrop of core::traits::Drop::<StorageStorageBase>;
impl StorageStorageBaseCopy of core::traits::Copy::<StorageStorageBase>;


lib.cairo:1:1
#[starknet::contract]
^*******************^
impls:

impl StorageStorageBaseMutDrop of core::traits::Drop::<StorageStorageBaseMut>;
impl StorageStorageBaseMutCopy of core::traits::Copy::<StorageStorageBaseMut>;
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,7 @@ fn handle_component_impl(
.into(),
);

data.specific
.generated_impls
.push(RewriteNode::Mapped { origin, node: generated_impl_node.into() });
data.specific.generated_impls.push(generated_impl_node.mapped(origin));
}

/// Returns a RewriteNode of a path similar to the given path, but without generic params.
Expand Down
31 changes: 17 additions & 14 deletions crates/cairo-lang-starknet/src/plugin/starknet_module/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,21 +539,24 @@ fn handle_embed_impl_alias(
impl_module.iter().map(|segment| RewriteNode::new_trimmed(segment.as_syntax_node())),
RewriteNode::text("::"),
);
data.generated_wrapper_functions.push(RewriteNode::interpolate_patched(
&formatdoc! {"
impl ContractState$impl_name$ of
$impl_module$::UnsafeNewContractStateTraitFor$impl_name$<{CONTRACT_STATE_NAME}> {{
fn unsafe_new_contract_state() -> {CONTRACT_STATE_NAME} {{
unsafe_new_contract_state()
data.generated_wrapper_functions.push(
RewriteNode::interpolate_patched(
&formatdoc! {"
impl ContractState$impl_name$ of
$impl_module$::UnsafeNewContractStateTraitFor$impl_name$<{CONTRACT_STATE_NAME}> {{
fn unsafe_new_contract_state() -> {CONTRACT_STATE_NAME} {{
unsafe_new_contract_state()
}}
}}
}}
"},
&[
("impl_name".to_string(), RewriteNode::new_trimmed(impl_name.as_syntax_node())),
("impl_module".to_string(), impl_module),
]
.into(),
));
"},
&[
("impl_name".to_string(), RewriteNode::new_trimmed(impl_name.as_syntax_node())),
("impl_module".to_string(), impl_module),
]
.into(),
)
.mapped(alias_ast.as_syntax_node().span_without_trivia(db)),
);
}

/// Handles a `component!` inline macro. Assumes that the macro name is `COMPONENT_INLINE_MACRO`.
Expand Down

0 comments on commit 51d56e4

Please sign in to comment.