ink_codegen/
lib.rs

1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! The ink! code generation.
16//!
17//! This module defines everything the ink! procedural macro needs in order to
18//! generate Rust code for ink! smart contracts.
19//!
20//! We avoid structuring things via hidden or private modules, this
21//! was the ink! v1 way of doing code generation and it was bug prone
22//! and hard to maintain.
23//!
24//! What we do instead to generate code that is hidden from users is to
25//! pack it into anonymous `const` (so `const _: () = { … };`) and connect
26//! those to the outside world with private trait implementations.
27//!
28//! You can see how the generated code looks by installing
29//! [`cargo-expand`](https://github.com/dtolnay/cargo-expand)
30//! and executing `cargo expand --manifest-path ./integration-tests/flipper/Cargo.toml` in
31//! this repository.
32
33#![doc(
34    html_logo_url = "https://use.ink/img/crate-docs/logo.png",
35    html_favicon_url = "https://use.ink/crate-docs/favicon.png"
36)]
37
38pub use ink_primitives::{
39    abi::Abi,
40    reflect,
41};
42mod enforced_error;
43mod generator;
44mod traits;
45
46pub use generator::generate_type_spec;
47
48use self::{
49    enforced_error::EnforcedErrors,
50    traits::{
51        GenerateCode,
52        GenerateCodeUsing,
53    },
54};
55use proc_macro2::TokenStream as TokenStream2;
56
57/// Types for which code can be generated by this crate.
58pub trait CodeGenerator: Sized {
59    /// The underlying generator generating the code.
60    type Generator: From<Self> + GenerateCode;
61}
62
63impl<'a> CodeGenerator for &'a ir::Contract {
64    type Generator = generator::Contract<'a>;
65}
66
67impl<'a> CodeGenerator for &'a ir::Event {
68    type Generator = generator::Event<'a>;
69}
70
71impl<'a> CodeGenerator for &'a ir::StorageItem {
72    type Generator = generator::StorageItem<'a>;
73}
74
75impl<'a> CodeGenerator for &'a ir::InkTraitDefinition {
76    type Generator = generator::TraitDefinition<'a>;
77}
78
79impl<'a> CodeGenerator for (&'a ir::InkTraitDefinition, Option<Abi>) {
80    type Generator = generator::TraitDefinition<'a>;
81}
82
83impl<'a> CodeGenerator for &'a ir::InkTest {
84    type Generator = generator::InkTest<'a>;
85}
86
87impl<'a> CodeGenerator for &'a ir::SelectorMacro<ir::marker::SelectorId> {
88    type Generator = generator::SelectorId<'a>;
89}
90
91impl<'a> CodeGenerator for &'a ir::SelectorMacro<ir::marker::SelectorBytes> {
92    type Generator = generator::SelectorBytes<'a>;
93}
94
95impl<'a> CodeGenerator for &'a ir::Blake2x256Macro {
96    type Generator = generator::Blake2x256<'a>;
97}
98
99/// Generates the entire code for the given ink! contract.
100pub fn generate_code<T>(entity: T) -> TokenStream2
101where
102    T: CodeGenerator,
103{
104    <T as CodeGenerator>::Generator::from(entity).generate_code()
105}