Skip to content

Commit

Permalink
Added warnings for bad embeddable impls.
Browse files Browse the repository at this point in the history
commit-id:48280088
  • Loading branch information
orizi committed Jan 15, 2024
1 parent 1f29ddb commit 5d29b8b
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 20 deletions.
77 changes: 58 additions & 19 deletions crates/cairo-lang-starknet/src/analyzer.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,76 @@
use cairo_lang_defs::ids::ModuleId;
use cairo_lang_defs::plugin::PluginDiagnostic;
use cairo_lang_semantic::db::SemanticGroup;
use cairo_lang_semantic::items::attribute::SemanticQueryAttrs;
use cairo_lang_semantic::plugin::AnalyzerPlugin;
use cairo_lang_syntax::attribute::consts::STARKNET_INTERFACE_ATTR;
use cairo_lang_syntax::node::helpers::QueryAttrs;
use cairo_lang_syntax::node::TypedSyntaxNode;

use crate::abi::{ABIError, AbiBuilder, BuilderConfig};
use crate::contract::module_contract;
use crate::plugin::consts::EMBEDDABLE_ATTR;

/// Plugin to add diagnostics for contracts for bad ABI generation.
#[derive(Default, Debug)]
pub struct ABIAnalyzer;

impl AnalyzerPlugin for ABIAnalyzer {
fn diagnostics(&self, db: &dyn SemanticGroup, module_id: ModuleId) -> Vec<PluginDiagnostic> {
let Some(contract) = module_contract(db, module_id) else {
return vec![];
};
let Ok(abi_builder) = AbiBuilder::from_submodule(
db,
contract.submodule_id,
BuilderConfig { account_contract_validations: true },
) else {
return vec![];
};
let mut diagnostics = vec![];
for err in abi_builder.errors() {
if !matches!(err, ABIError::SemanticError) {
diagnostics.push(PluginDiagnostic::warning(
err.location(db)
.unwrap_or_else(|| contract.submodule_id.stable_ptr(db.upcast()).untyped()),
format!("Failed to generate ABI: {err}"),
));
}
}
add_non_starknet_interface_embeddable_diagnostics(db, module_id, &mut diagnostics);
add_abi_diagnostics(db, module_id, &mut diagnostics);
diagnostics
}
}

/// Add diagnostics for embeddable impls that do not implement a starknet interface.
fn add_non_starknet_interface_embeddable_diagnostics(
db: &dyn SemanticGroup,
module_id: ModuleId,
diagnostics: &mut Vec<PluginDiagnostic>,
) {
let Ok(impls) = db.module_impls(module_id) else {
return;
};
for (id, item) in impls.iter() {
if !item.has_attr(db.upcast(), EMBEDDABLE_ATTR) {
continue;
}
let Ok(impl_trait) = db.impl_def_trait(*id) else { continue };
if !impl_trait.has_attr(db.upcast(), STARKNET_INTERFACE_ATTR).unwrap_or(true) {
diagnostics.push(PluginDiagnostic::warning(
item.stable_ptr().untyped(),
"Impls with the embeddable attribute must implement a starknet interface trait."
.to_string(),
));
}
}
}

/// Add diagnostics for ABI generation.
fn add_abi_diagnostics(
db: &dyn SemanticGroup,
module_id: ModuleId,
diagnostics: &mut Vec<PluginDiagnostic>,
) {
let Some(contract) = module_contract(db, module_id) else {
return;
};
let Ok(abi_builder) = AbiBuilder::from_submodule(
db,
contract.submodule_id,
BuilderConfig { account_contract_validations: true },
) else {
return;
};
for err in abi_builder.errors() {
if !matches!(err, ABIError::SemanticError) {
diagnostics.push(PluginDiagnostic::warning(
err.location(db)
.unwrap_or_else(|| contract.submodule_id.stable_ptr(db.upcast()).untyped()),
format!("Failed to generate ABI: {err}"),
));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,11 @@ error: Plugin diagnostic: The first parameter of a function in an #[embeddable_a
fn self_of_wrong_type(self: ComponentState<TContractState>) {}
^**********************************^

warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo[component]:33:1
#[starknet::embeddable]
^*********************^

error: Not all trait items are implemented. Missing: 'no_self', 'self_of_wrong_type'.
--> lib.cairo:8:21
#[embeddable_as(MyImpl)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! > Test `embeddable_as` with Drop<TContractState>.

//! > test_runner_name
ExpandContractTestRunner(expect_diagnostics: false)
ExpandContractTestRunner(expect_diagnostics: true)

//! > cairo_code
#[starknet::component]
Expand Down Expand Up @@ -149,3 +149,7 @@ pub mod __constructor_MyImpl {
}

//! > expected_diagnostics
warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo[component]:33:1
#[starknet::embeddable]
^*********************^
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ impl EventIsEvent of starknet::Event<Event> {
}

//! > expected_diagnostics
warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo:1:1
#[starknet::embeddable]
^*********************^

warning: Plugin diagnostic: Failed to generate ABI: An embedded impl must be an impl of a trait marked with #[starknet::interface].
--> lib.cairo:17:5
#[abi(embed_v0)]
Expand Down Expand Up @@ -533,6 +538,16 @@ error: Plugin diagnostic: `embeddable` impls can't have impl generic parameters
impl DisallowedPanicDestruct: PanicDestruct<TContractState>
^*********************************************************^

warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo:1:1
#[starknet::embeddable]
^*********************^

warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo:12:1
#[starknet::embeddable]
^*********************^

warning: Plugin diagnostic: Failed to generate ABI: An embedded impl must be an impl of a trait marked with #[starknet::interface].
--> lib.cairo:28:5
#[abi(embed_v0)]
Expand Down Expand Up @@ -730,6 +745,11 @@ impl EventIsEvent of starknet::Event<Event> {
}

//! > expected_diagnostics
warning: Plugin diagnostic: Impls with the embeddable attribute must implement a starknet interface trait.
--> lib.cairo:1:1
#[starknet::embeddable]
^*********************^

warning: Plugin diagnostic: Failed to generate ABI: An embedded impl must be an impl of a trait marked with #[starknet::interface].
--> lib.cairo:17:5
#[abi(embed_v0)]
Expand Down

0 comments on commit 5d29b8b

Please sign in to comment.