rusty_bind_parser/cpp/
generator.rs

1//
2// Wildland Project
3//
4// Copyright © 2022 Golem Foundation,
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License version 3 as published by
8// the Free Software Foundation.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18/// The module consists of methods and structures for C++
19/// and SWIG code generation.
20///
21use super::{
22    create_enum_class,
23    enums_cpp_forward_declarations,
24    externs::create_extern_imports,
25    function_translator::*,
26    function_virtual_translator::*,
27    templates::*,
28    translate_enums,
29};
30use crate::binding_types::{ExternFunction, RustWrapperType, WrapperType};
31use crate::cpp::wasm_generator::create_wasm_module;
32use crate::extern_module_translator::{Exceptions, ExternModuleTranslator};
33
34fn create_classes_declarations(extern_module_translator: &ExternModuleTranslator) -> String {
35    extern_module_translator
36        .user_custom_types
37        .iter()
38        .map(|(wrapper_type, vec_of_functions)| {
39            let class_name = wrapper_type.wrapper_name.to_string();
40            let functions_declaration: String = vec_of_functions
41                .iter()
42                .map(|f| FunctionTranslator::from_class_method(f, &class_name))
43                .map(FunctionTranslator::generate_declaration)
44                .collect();
45            custom_class_definition(&class_name, functions_declaration)
46        })
47        .collect::<String>()
48}
49
50fn create_class_methods_definitions(extern_module_translator: &ExternModuleTranslator) -> String {
51    extern_module_translator
52        .user_custom_types
53        .iter()
54        .map(|(wrapper_type, vec_of_functions)| {
55            let class_name = wrapper_type.wrapper_name.to_string();
56            vec_of_functions
57                .iter()
58                .map(|f| FunctionTranslator::from_class_method(f, &class_name))
59                .map(FunctionTranslator::generate_definition)
60                .collect::<String>()
61        })
62        .collect::<String>()
63}
64
65fn create_abstract_classes_declarations(
66    extern_module_translator: &ExternModuleTranslator,
67) -> String {
68    extern_module_translator
69        .user_traits
70        .iter()
71        .map(|(wrapper_type, vec_of_functions)| {
72            let class_name = wrapper_type.wrapper_name.to_string();
73            let functions_declaration: String = vec_of_functions
74                .iter()
75                .map(|f| FunctionVirtualTranslator::from_virtual_function(f, &class_name))
76                .map(FunctionVirtualTranslator::generate_virtual_declaration)
77                .collect();
78            abstract_class_declaration(&class_name, &functions_declaration)
79        })
80        .collect::<String>()
81}
82
83fn create_virtual_method_calls(extern_module_translator: &ExternModuleTranslator) -> String {
84    extern_module_translator
85        .user_traits
86        .iter()
87        .map(|(wrapper_type, vec_of_functions)| {
88            let class_name = wrapper_type.wrapper_name.to_string();
89            vec_of_functions
90                .iter()
91                .map(|f| FunctionVirtualTranslator::from_virtual_function(f, &class_name))
92                .map(FunctionVirtualTranslator::generate_virtual_definition)
93                .collect::<String>()
94        })
95        .collect::<String>()
96}
97
98fn create_rust_types_wrappers(extern_module_translator: &ExternModuleTranslator) -> String {
99    extern_module_translator
100        .rust_types_wrappers
101        .ordered_iter()
102        .filter_map(|wrapper| match wrapper {
103            WrapperType {
104                rust_type: RustWrapperType::Vector(inner_type),
105                ..
106            } => {
107                let inner_type_name = inner_type.get_name();
108                let vec_base_impl = vector_impl(&inner_type_name, &inner_type.wrapper_name);
109                Some(vec_base_impl + &begin_end_impl(&inner_type_name, &inner_type.rust_type))
110            }
111            WrapperType {
112                rust_type: RustWrapperType::Option(inner_type),
113                ..
114            } => {
115                let inner_type_name = inner_type.get_name();
116                Some(option_class(&inner_type_name, &inner_type.wrapper_name))
117            }
118            WrapperType {
119                rust_type: RustWrapperType::Exceptions(Exceptions::NonPrimitive(idents)),
120                wrapper_name,
121                ..
122            } => Some(
123                idents
124                    .iter()
125                    .map(|exception| {
126                        create_non_primitive_exception_class(
127                            &exception.to_string(),
128                            wrapper_name,
129                            extern_module_translator.exception_trait_methods.iter(),
130                        )
131                    })
132                    .collect::<String>(),
133            ),
134            WrapperType {
135                rust_type: RustWrapperType::Exceptions(Exceptions::Primitive(idents)),
136                wrapper_name,
137                ..
138            } => Some(
139                idents
140                    .iter()
141                    .map(|exception| {
142                        create_primitive_exception_class(
143                            &exception.to_string(),
144                            wrapper_name,
145                            extern_module_translator.exception_trait_methods.iter(),
146                        )
147                    })
148                    .collect::<String>(),
149            ),
150            _ => None,
151        })
152        .collect()
153}
154
155fn create_result_wrappers(extern_module_translator: &ExternModuleTranslator) -> String {
156    extern_module_translator
157        .rust_types_wrappers
158        .ordered_iter()
159        .filter_map(|wrapper| match wrapper {
160            WrapperType {
161                rust_type: RustWrapperType::Result(ok_type, exceptions_type),
162                ..
163            } => {
164                let ok_type = ok_type.get_name();
165                let error_enum_name = &exceptions_type.wrapper_name;
166                Some(result_class(
167                    &wrapper.wrapper_name,
168                    &ok_type,
169                    error_enum_name,
170                ))
171            }
172            _ => None,
173        })
174        .collect()
175}
176
177fn create_global_functions_definitions(
178    extern_module_translator: &ExternModuleTranslator,
179) -> String {
180    extern_module_translator
181        .global_functions
182        .iter()
183        .map(FunctionTranslator::from_global_function)
184        .map(FunctionTranslator::generate_definition)
185        .collect()
186}
187
188pub fn create_classes_forward_declarations(
189    extern_module_translator: &ExternModuleTranslator,
190) -> String {
191    extern_module_translator
192        .rust_types_wrappers
193        .unordered_iter()
194        .map(|wrapper| match wrapper {
195            WrapperType {
196                wrapper_name,
197                rust_type:
198                    RustWrapperType::Custom
199                    | RustWrapperType::Trait
200                    | RustWrapperType::Result(_, _)
201                    | RustWrapperType::ArcMutex,
202                ..
203            } => {
204                format!("struct {wrapper_name};\n")
205            }
206            _ => "".to_owned(),
207        })
208        .collect()
209}
210
211fn create_exception_class_enum(extern_module_translator: &ExternModuleTranslator) -> String {
212    create_enum_class(
213        "ExceptionClass",
214        extern_module_translator
215            .exception_names
216            .iter()
217            .chain(std::iter::once(&RUST_EXCEPTION_BASE_CLASS_NAME.to_string())),
218    )
219}
220
221/// Results of this function can be written in the `*.hpp` and `*.i` files.
222/// The generated C++ header file can be used in C++ application. The header
223/// file and `*.i` file can be included to the SWIG interface file and used
224/// to generate glue code for Java, C# etc.
225///
226pub fn generate_cpp_file(
227    extern_module_translator: &ExternModuleTranslator,
228    extern_functions: &[ExternFunction],
229) -> String {
230    let externs = create_extern_imports(extern_functions);
231    let classes_forward_declarations =
232        create_classes_forward_declarations(extern_module_translator);
233    let enums_cpp_forward_declarations = enums_cpp_forward_declarations(extern_module_translator);
234    let enum_classes_definitions = translate_enums(extern_module_translator);
235    let classes_declaration = create_classes_declarations(extern_module_translator);
236    let classes_definition = create_class_methods_definitions(extern_module_translator);
237    let abstract_classes_declaration =
238        create_abstract_classes_declarations(extern_module_translator);
239    let virtual_methods_calls = create_virtual_method_calls(extern_module_translator);
240    let rust_types_wrappers = create_rust_types_wrappers(extern_module_translator);
241    let result_wrapper = create_result_wrappers(extern_module_translator);
242    let global_functions_definition: String =
243        create_global_functions_definitions(extern_module_translator);
244    let wasm_module = create_wasm_module(extern_module_translator);
245    let exception_class_enum = create_exception_class_enum(extern_module_translator);
246    let base_exception_class = base_exception_class(extern_module_translator);
247
248    format!(
249        "{IMPORTS}
250{exception_class_enum}
251{TYPEDEFS}
252{enums_cpp_forward_declarations}
253{classes_forward_declarations}
254extern \"C\" {{
255{externs}
256}}
257{PREDEFINED}
258{base_exception_class}
259{abstract_classes_declaration}
260{classes_declaration}
261{enum_classes_definitions}
262{rust_types_wrappers}
263{result_wrapper}
264{global_functions_definition}
265{classes_definition}
266{virtual_methods_calls}
267{wasm_module}"
268    )
269}