1 /*
2 * Copyright 2019 by its authors. See AUTHORS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef EOLIAN_MONO_MARSHALL_TYPE_HH
17 #define EOLIAN_MONO_MARSHALL_TYPE_HH
18
19 #include "grammar/generator.hpp"
20 #include "grammar/klass_def.hpp"
21 #include "grammar/case.hpp"
22
23 namespace eolian_mono {
24
25 namespace attributes = efl::eolian::grammar::attributes;
26 namespace detail {
27 template <typename OutputIterator, typename Context>
28 struct marshall_type_visitor_generate;
29 template <typename OutputIterator, typename Context>
30 struct marshall_annotation_visitor_generate;
31 }
32
33 /*
34 * Converts a given type/parameter to the type used in the DllImport signatures.
35 *
36 * For example, Eina.Value can be marshaled either as an eina.Value instance through
37 * CustomMarshallers if we have a ptr(Eina.Value) or through the intermediate
38 * eina.ValueNative blittable struct if it is passed by value.
39 *
40 * For details, check marshall_type_impl.h with the actual conversion rules.
41 */
42 struct marshall_type_generator
43 {
marshall_type_generatoreolian_mono::marshall_type_generator44 marshall_type_generator(bool is_return = false, bool is_special_subtype = false)
45 : is_return(is_return)
46 , is_special_subtype(is_special_subtype)
47 {}
48
49 template <typename OutputIterator, typename Context>
generateeolian_mono::marshall_type_generator50 bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
51 {
52 return type.original_type.visit(detail::marshall_type_visitor_generate<OutputIterator, Context>{
53 sink
54 , &context
55 , type.c_type
56 , false
57 , is_return
58 , type.is_ptr
59 , is_special_subtype
60 });
61 }
62 /* Some types may require a different conversion when they are in @out parameters. */
63 template <typename OutputIterator, typename Context>
generateeolian_mono::marshall_type_generator64 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
65 {
66 return param.type.original_type.visit(detail::marshall_type_visitor_generate<OutputIterator, Context>{
67 sink
68 , &context
69 , param.type.c_type
70 , param.direction != attributes::parameter_direction::in
71 , false
72 , param.type.is_ptr
73 , is_special_subtype
74 });
75 }
76
77 bool is_return;
78 bool is_special_subtype;
79 };
80
81 /*
82 * Generates the "[MarshalAs(...)]" rules for the given type.
83 *
84 * For example, the CustomMarshallers definitions for String and eina.Values and the
85 * boolean size defintion (Eina_Value is 1 byte, while C# bool has 4 bytes).
86 */
87 struct marshall_annotation_generator
88 {
marshall_annotation_generatoreolian_mono::marshall_annotation_generator89 marshall_annotation_generator(bool is_return = false)
90 : is_return(is_return) {}
91
92 template <typename OutputIterator, typename Context>
generateeolian_mono::marshall_annotation_generator93 bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
94 {
95 return type.original_type.visit(detail::marshall_annotation_visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
96 }
97 template <typename OutputIterator, typename Context>
generateeolian_mono::marshall_annotation_generator98 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
99 {
100 return param.type.original_type.visit(detail::marshall_annotation_visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
101 , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
102 }
103
104 bool is_return;
105 };
106
107 struct marshall_type_terminal
108 {
operator ()eolian_mono::marshall_type_terminal109 marshall_type_generator const operator()(bool is_return, bool is_special_subtype = false) const
110 {
111 return marshall_type_generator(is_return, is_special_subtype);
112 }
113 } const marshall_type = {};
114
as_generator(marshall_type_terminal)115 marshall_type_generator const as_generator(marshall_type_terminal)
116 {
117 return marshall_type_generator{};
118 }
119
120 struct marshall_annotation_terminal
121 {
operator ()eolian_mono::marshall_annotation_terminal122 marshall_annotation_generator const operator()(bool is_return) const
123 {
124 return marshall_annotation_generator(is_return);
125 }
126 } const marshall_annotation = {};
127
as_generator(marshall_annotation_terminal)128 marshall_annotation_generator const as_generator(marshall_annotation_terminal)
129 {
130 return marshall_annotation_generator{};
131 }
132
133
134 }
135
136 namespace efl { namespace eolian { namespace grammar {
137
138 template <>
139 struct is_eager_generator< ::eolian_mono::marshall_type_generator> : std::true_type {};
140 template <>
141 struct is_generator< ::eolian_mono::marshall_type_generator> : std::true_type {};
142 template <>
143 struct is_generator< ::eolian_mono::marshall_type_terminal> : std::true_type {};
144
145 namespace type_traits {
146 template <>
147 struct attributes_needed< ::eolian_mono::marshall_type_generator> : std::integral_constant<int, 1> {};
148 template <>
149 struct attributes_needed< ::eolian_mono::marshall_type_terminal> : std::integral_constant<int, 1> {};
150 }
151
152 template <>
153 struct is_eager_generator< ::eolian_mono::marshall_annotation_generator> : std::true_type {};
154 template <>
155 struct is_generator< ::eolian_mono::marshall_annotation_generator> : std::true_type {};
156 template <>
157 struct is_generator< ::eolian_mono::marshall_annotation_terminal> : std::true_type {};
158
159 namespace type_traits {
160 template <>
161 struct attributes_needed< ::eolian_mono::marshall_annotation_generator> : std::integral_constant<int, 1> {};
162 template <>
163 struct attributes_needed< ::eolian_mono::marshall_annotation_terminal> : std::integral_constant<int, 1> {};
164
165 }
166
167 } } }
168
169 #endif
170