Skip to content

Commit 2cf8c3d

Browse files
authored
Extract functionality to lang::ir::utils (#1392)
1 parent 17ec5fa commit 2cf8c3d

File tree

4 files changed

+114
-128
lines changed

4 files changed

+114
-128
lines changed

crates/lang/ir/src/ir/config.rs

Lines changed: 6 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
use crate::{
1616
ast,
17-
ast::MetaNameValue,
18-
error::ExtError as _,
17+
utils::{
18+
duplicate_config_err,
19+
WhitelistedAttributes,
20+
},
1921
};
20-
use std::collections::HashMap;
21-
use syn::spanned::Spanned;
2222

2323
/// The ink! configuration.
2424
#[derive(Debug, Default, PartialEq, Eq)]
@@ -33,83 +33,6 @@ pub struct Config {
3333
whitelisted_attributes: WhitelistedAttributes,
3434
}
3535

36-
/// The set of attributes that can be passed to call builder or call forwarder in the codegen.
37-
#[derive(Debug, PartialEq, Eq)]
38-
pub struct WhitelistedAttributes(pub HashMap<String, ()>);
39-
40-
impl Default for WhitelistedAttributes {
41-
fn default() -> Self {
42-
Self(HashMap::from([
43-
// Conditional compilation
44-
("cfg".to_string(), ()),
45-
("cfg_attr".to_string(), ()),
46-
// Diagnostics
47-
("allow".to_string(), ()),
48-
("warn".to_string(), ()),
49-
("deny".to_string(), ()),
50-
("forbid".to_string(), ()),
51-
("deprecated".to_string(), ()),
52-
("must_use".to_string(), ()),
53-
// Documentation
54-
("doc".to_string(), ()),
55-
// Formatting
56-
("rustfmt".to_string(), ()),
57-
]))
58-
}
59-
}
60-
61-
impl WhitelistedAttributes {
62-
/// Parses the `MetaNameValue` argument of `keep_attr` attribute. If the argument has
63-
/// a correct format `"foo, bar"` then `foo`, `bar` will be included in
64-
/// the whitelist of attributes. Else error about parsing will be returned.
65-
pub fn parse_arg_value(&mut self, arg: &MetaNameValue) -> Result<(), syn::Error> {
66-
return if let ast::PathOrLit::Lit(syn::Lit::Str(attributes)) = &arg.value {
67-
attributes.value().split(',').for_each(|attribute| {
68-
self.0.insert(attribute.trim().to_string(), ());
69-
});
70-
Ok(())
71-
} else {
72-
Err(format_err_spanned!(
73-
arg,
74-
"expected a string with attributes separated by `,`",
75-
))
76-
}
77-
}
78-
79-
/// Returns the filtered input vector of whitelisted attributes.
80-
/// All not whitelisted attributes are removed.
81-
pub fn filter_attr(&self, attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> {
82-
attrs
83-
.into_iter()
84-
.filter(|attr| {
85-
if let Some(ident) = attr.path.get_ident() {
86-
self.0.contains_key(&ident.to_string())
87-
} else {
88-
false
89-
}
90-
})
91-
.collect()
92-
}
93-
}
94-
95-
/// Return an error to notify about duplicate ink! configuration arguments.
96-
fn duplicate_config_err<F, S>(first: F, second: S, name: &str) -> syn::Error
97-
where
98-
F: Spanned,
99-
S: Spanned,
100-
{
101-
format_err!(
102-
second.span(),
103-
"encountered duplicate ink! `{}` configuration argument",
104-
name,
105-
)
106-
.into_combine(format_err!(
107-
first.span(),
108-
"first `{}` configuration argument here",
109-
name
110-
))
111-
}
112-
11336
impl TryFrom<ast::AttributeArgs> for Config {
11437
type Error = syn::Error;
11538

@@ -120,7 +43,7 @@ impl TryFrom<ast::AttributeArgs> for Config {
12043
for arg in args.into_iter() {
12144
if arg.name.is_ident("env") {
12245
if let Some((_, ast)) = env {
123-
return Err(duplicate_config_err(ast, arg, "env"))
46+
return Err(duplicate_config_err(ast, arg, "env", "contract"))
12447
}
12548
if let ast::PathOrLit::Path(path) = &arg.value {
12649
env = Some((Environment { path: path.clone() }, arg))
@@ -239,7 +162,7 @@ mod tests {
239162
env = ::my::env::Types,
240163
env = ::my::other::env::Types,
241164
},
242-
Err("encountered duplicate ink! `env` configuration argument"),
165+
Err("encountered duplicate ink! contract `env` configuration argument"),
243166
);
244167
}
245168

crates/lang/ir/src/ir/storage_item/config.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414

1515
use crate::{
1616
ast,
17-
error::ExtError as _,
17+
utils::duplicate_config_err,
1818
};
19-
use syn::spanned::Spanned;
2019

2120
/// The ink! configuration.
2221
#[derive(Debug, Default, PartialEq, Eq)]
@@ -28,24 +27,6 @@ pub struct StorageItemConfig {
2827
derive: bool,
2928
}
3029

31-
/// Return an error to notify about duplicate ink! ink storage configuration arguments.
32-
fn duplicate_config_err<F, S>(first: F, second: S, name: &str) -> syn::Error
33-
where
34-
F: Spanned,
35-
S: Spanned,
36-
{
37-
format_err!(
38-
second.span(),
39-
"encountered duplicate ink! storage item `{}` configuration argument",
40-
name,
41-
)
42-
.into_combine(format_err!(
43-
first.span(),
44-
"first `{}` configuration argument here",
45-
name
46-
))
47-
}
48-
4930
impl TryFrom<ast::AttributeArgs> for StorageItemConfig {
5031
type Error = syn::Error;
5132

@@ -54,7 +35,12 @@ impl TryFrom<ast::AttributeArgs> for StorageItemConfig {
5435
for arg in args.into_iter() {
5536
if arg.name.is_ident("derive") {
5637
if let Some(lit_bool) = derive {
57-
return Err(duplicate_config_err(lit_bool, arg, "derive"))
38+
return Err(duplicate_config_err(
39+
lit_bool,
40+
arg,
41+
"derive",
42+
"storage item",
43+
))
5844
}
5945
if let ast::PathOrLit::Lit(syn::Lit::Bool(lit_bool)) = &arg.value {
6046
derive = Some(lit_bool.clone())

crates/lang/ir/src/ir/trait_def/config.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
use crate::{
1616
ast,
17-
error::ExtError as _,
18-
ir::config::WhitelistedAttributes,
17+
utils::{
18+
duplicate_config_err,
19+
WhitelistedAttributes,
20+
},
1921
};
20-
use syn::spanned::Spanned;
2122

2223
/// The ink! configuration.
2324
#[derive(Debug, Default, PartialEq, Eq)]
@@ -48,24 +49,6 @@ impl TraitDefinitionConfig {
4849
}
4950
}
5051

51-
/// Return an error to notify about duplicate ink! trait definition configuration arguments.
52-
fn duplicate_config_err<F, S>(first: F, second: S, name: &str) -> syn::Error
53-
where
54-
F: Spanned,
55-
S: Spanned,
56-
{
57-
format_err!(
58-
second.span(),
59-
"encountered duplicate ink! trait definition `{}` configuration argument",
60-
name,
61-
)
62-
.into_combine(format_err!(
63-
first.span(),
64-
"first `{}` configuration argument here",
65-
name
66-
))
67-
}
68-
6952
impl TryFrom<ast::AttributeArgs> for TraitDefinitionConfig {
7053
type Error = syn::Error;
7154

@@ -75,7 +58,12 @@ impl TryFrom<ast::AttributeArgs> for TraitDefinitionConfig {
7558
for arg in args.into_iter() {
7659
if arg.name.is_ident("namespace") {
7760
if let Some((_, meta_name_value)) = namespace {
78-
return Err(duplicate_config_err(meta_name_value, arg, "namespace"))
61+
return Err(duplicate_config_err(
62+
meta_name_value,
63+
arg,
64+
"namespace",
65+
"trait definition",
66+
))
7967
}
8068
if let ast::PathOrLit::Lit(syn::Lit::Str(lit_str)) = &arg.value {
8169
if syn::parse_str::<syn::Ident>(&lit_str.value()).is_err() {

crates/lang/ir/src/ir/utils.rs

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@
1313
// limitations under the License.
1414

1515
use super::Selector;
16-
use crate::format_err;
16+
use crate::{
17+
ast,
18+
ast::MetaNameValue,
19+
error::ExtError as _,
20+
format_err,
21+
};
1722
use proc_macro2::Span;
18-
use syn::spanned::Spanned as _;
23+
use std::collections::HashMap;
24+
use syn::spanned::Spanned;
1925

2026
/// Ensures that the given visibility is `pub` and otherwise returns an appropriate error.
2127
///
@@ -55,3 +61,86 @@ pub fn local_message_id(ident: &syn::Ident) -> u32 {
5561
let selector = Selector::compute(&input);
5662
selector.into_be_u32()
5763
}
64+
65+
/// The set of attributes that can be passed to call builder or call forwarder in the codegen.
66+
#[derive(Debug, PartialEq, Eq)]
67+
pub struct WhitelistedAttributes(pub HashMap<String, ()>);
68+
69+
impl Default for WhitelistedAttributes {
70+
fn default() -> Self {
71+
Self(HashMap::from([
72+
// Conditional compilation
73+
("cfg".to_string(), ()),
74+
("cfg_attr".to_string(), ()),
75+
// Diagnostics
76+
("allow".to_string(), ()),
77+
("warn".to_string(), ()),
78+
("deny".to_string(), ()),
79+
("forbid".to_string(), ()),
80+
("deprecated".to_string(), ()),
81+
("must_use".to_string(), ()),
82+
// Documentation
83+
("doc".to_string(), ()),
84+
// Formatting
85+
("rustfmt".to_string(), ()),
86+
]))
87+
}
88+
}
89+
90+
impl WhitelistedAttributes {
91+
/// Parses the `MetaNameValue` argument of `keep_attr` attribute. If the argument has
92+
/// a correct format `"foo, bar"` then `foo`, `bar` will be included in
93+
/// the whitelist of attributes. Else error about parsing will be returned.
94+
pub fn parse_arg_value(&mut self, arg: &MetaNameValue) -> Result<(), syn::Error> {
95+
return if let ast::PathOrLit::Lit(syn::Lit::Str(attributes)) = &arg.value {
96+
attributes.value().split(',').for_each(|attribute| {
97+
self.0.insert(attribute.trim().to_string(), ());
98+
});
99+
Ok(())
100+
} else {
101+
Err(format_err_spanned!(
102+
arg,
103+
"expected a string with attributes separated by `,`",
104+
))
105+
}
106+
}
107+
108+
/// Returns the filtered input vector of whitelisted attributes.
109+
/// All not whitelisted attributes are removed.
110+
pub fn filter_attr(&self, attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> {
111+
attrs
112+
.into_iter()
113+
.filter(|attr| {
114+
if let Some(ident) = attr.path.get_ident() {
115+
self.0.contains_key(&ident.to_string())
116+
} else {
117+
false
118+
}
119+
})
120+
.collect()
121+
}
122+
}
123+
124+
/// Return an error to notify about duplicate ink! configuration arguments.
125+
pub(crate) fn duplicate_config_err<F, S>(
126+
first: F,
127+
second: S,
128+
name: &str,
129+
ink_attr: &str,
130+
) -> syn::Error
131+
where
132+
F: Spanned,
133+
S: Spanned,
134+
{
135+
format_err!(
136+
second.span(),
137+
"encountered duplicate ink! {} `{}` configuration argument",
138+
ink_attr,
139+
name,
140+
)
141+
.into_combine(format_err!(
142+
first.span(),
143+
"first `{}` configuration argument here",
144+
name
145+
))
146+
}

0 commit comments

Comments
 (0)