ink_analyzer_ir/
constructor.rs

1//! ink! constructor IR.
2
3use ra_ap_syntax::ast;
4
5use crate::traits::IsInkCallable;
6
7/// An ink! constructor.
8#[ink_analyzer_macro::entity(arg_kind = Constructor)]
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Constructor {
11    // ASTNode type.
12    ast: ast::Fn,
13}
14
15impl_ast_type_trait!(Constructor, IsInkFn);
16
17impl IsInkCallable for Constructor {}
18
19#[cfg(test)]
20mod tests {
21    use super::*;
22    use crate::test_utils::*;
23    use crate::traits::{InkEntity, IsInkFn};
24    use test_utils::quote_as_str;
25
26    #[test]
27    fn cast_works() {
28        for (code, is_payable, has_selector, is_default, has_name) in [
29            (
30                quote_as_str! {
31                    #[ink(constructor)]
32                    pub fn my_constructor() -> Self {}
33                },
34                false,
35                false,
36                false,
37                false,
38            ),
39            (
40                quote_as_str! {
41                    #[ink(constructor, payable, default, selector=1, name="myConstructor")]
42                    pub fn my_constructor() -> Self {}
43                },
44                true,
45                true,
46                true,
47                true,
48            ),
49            (
50                quote_as_str! {
51                    #[ink(constructor)]
52                    #[ink(payable, default, selector=1, name="myConstructor")]
53                    pub fn my_constructor() -> Self {}
54                },
55                true,
56                true,
57                true,
58                true,
59            ),
60            (
61                quote_as_str! {
62                    #[ink(constructor)]
63                    #[ink(payable)]
64                    #[ink(default)]
65                    #[ink(selector=1)]
66                    #[ink(name="myConstructor")]
67                    pub fn my_constructor() -> Self {}
68                },
69                true,
70                true,
71                true,
72                true,
73            ),
74            (
75                quote_as_str! {
76                    #[ink(constructor, selector=0xA)]
77                    pub fn my_constructor() -> Self {}
78                },
79                false,
80                true,
81                false,
82                false,
83            ),
84            (
85                quote_as_str! {
86                    #[ink(constructor, selector=_)]
87                    pub fn my_constructor() -> Self {}
88                },
89                false,
90                true,
91                false,
92                false,
93            ),
94        ] {
95            let node = parse_first_syntax_node(code);
96
97            let constructor = Constructor::cast(node).unwrap();
98
99            // `payable` argument exists.
100            assert_eq!(constructor.payable_arg().is_some(), is_payable);
101
102            // `selector` argument exists.
103            assert_eq!(constructor.selector_arg().is_some(), has_selector);
104
105            // `default` argument exists.
106            assert_eq!(constructor.default_arg().is_some(), is_default);
107
108            // `name` argument exists.
109            assert_eq!(constructor.name_arg().is_some(), has_name);
110
111            // composed selector exists.
112            assert!(constructor.composed_selector().is_some());
113
114            // `fn` item exists.
115            assert!(constructor.fn_item().is_some());
116        }
117    }
118}