summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/eolian_mono/eolian/mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/alias_definition.hh103
-rw-r--r--src/bin/eolian_mono/eolian/mono/async_function_definition.hh49
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh48
-rw-r--r--src/bin/eolian_mono/eolian/mono/culture_info.hh61
-rw-r--r--src/bin/eolian_mono/eolian/mono/documentation.hh223
-rw-r--r--src/bin/eolian_mono/eolian/mono/enum_definition.hh37
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh240
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_declaration.hh19
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh635
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_helpers.hh22
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh48
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh17
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh24
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh116
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh293
-rw-r--r--src/bin/eolian_mono/eolian/mono/logging.hh15
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh158
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type.hh15
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh20
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh126
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh338
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh42
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh325
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_fields.hh60
-rw-r--r--src/bin/eolian_mono/eolian/mono/type.hh15
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh43
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_match.hh46
-rw-r--r--src/bin/eolian_mono/eolian/mono/using_decl.hh15
-rw-r--r--src/bin/eolian_mono/eolian/mono/utils.hh17
-rw-r--r--src/bin/eolian_mono/eolian/mono/variable_definition.hh21
30 files changed, 2375 insertions, 816 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/alias_definition.hh b/src/bin/eolian_mono/eolian/mono/alias_definition.hh
index 5d275a3..d7fda07 100644
--- a/src/bin/eolian_mono/eolian/mono/alias_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/alias_definition.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_ALIAS_DEFINITION_HH 16#ifndef EOLIAN_MONO_ALIAS_DEFINITION_HH
2#define EOLIAN_MONO_ALIAS_DEFINITION_HH 17#define EOLIAN_MONO_ALIAS_DEFINITION_HH
3 18
@@ -41,14 +56,20 @@ struct alias_definition_generator
41 alias_type_doc = utils::replace_all(alias_type, "<", "&lt;"); 56 alias_type_doc = utils::replace_all(alias_type, "<", "&lt;");
42 alias_type_doc = utils::replace_all(alias_type_doc, ">", "&gt;"); 57 alias_type_doc = utils::replace_all(alias_type_doc, ">", "&gt;");
43 58
59 std::string alias_since;
60 if (!documentation_helpers::generate_since_tag_line(std::back_inserter(alias_since), alias.documentation, scope_tab, context))
61 return false;
62
44 std::string const alias_name = utils::remove_all(alias.eolian_name, '_'); 63 std::string const alias_name = utils::remove_all(alias.eolian_name, '_');
45 if (!as_generator( 64 if (!as_generator(
46 documentation 65 documentation
47 << "public struct " << alias_name << "\n" 66 << "public struct " << alias_name << " : IEquatable<" << alias_name << ">\n"
48 << "{\n" 67 << "{\n"
49 << scope_tab << "private " << alias_type << " payload;\n\n" 68 << scope_tab << "private " << alias_type << " payload;\n\n"
50 69
51 << scope_tab << "/// <summary>Converts an instance of " << alias_type_doc << " to this struct.</summary>\n" 70 << scope_tab << "/// <summary>Converts an instance of " << alias_type_doc << " to this struct.\n"
71 << alias_since
72 << scope_tab << "/// </summary>\n"
52 << scope_tab << "/// <param name=\"value\">The value to be converted.</param>\n" 73 << scope_tab << "/// <param name=\"value\">The value to be converted.</param>\n"
53 << scope_tab << "/// <returns>A struct with the given value.</returns>\n" 74 << scope_tab << "/// <returns>A struct with the given value.</returns>\n"
54 << scope_tab << "public static implicit operator " << alias_name << "(" << alias_type << " value)\n" 75 << scope_tab << "public static implicit operator " << alias_name << "(" << alias_type << " value)\n"
@@ -56,14 +77,88 @@ struct alias_definition_generator
56 << scope_tab << scope_tab << "return new " << alias_name << "{payload=value};\n" 77 << scope_tab << scope_tab << "return new " << alias_name << "{payload=value};\n"
57 << scope_tab << "}\n\n" 78 << scope_tab << "}\n\n"
58 79
59 << scope_tab << "/// <summary>Converts an instance of this struct to " << alias_type_doc << ".</summary>\n" 80 << scope_tab << "/// <summary>Converts an instance of this struct to " << alias_type_doc << ".\n"
81 << alias_since
82 << scope_tab << "/// </summary>\n"
60 << scope_tab << "/// <param name=\"value\">The value to be converted packed in this struct.</param>\n" 83 << scope_tab << "/// <param name=\"value\">The value to be converted packed in this struct.</param>\n"
61 << scope_tab << "/// <returns>The actual value the alias is wrapping.</returns>\n" 84 << scope_tab << "/// <returns>The actual value the alias is wrapping.</returns>\n"
62 << scope_tab << "public static implicit operator " << alias_type << "(" << alias_name << " value)\n" 85 << scope_tab << "public static implicit operator " << alias_type << "(" << alias_name << " value)\n"
63 << scope_tab << "{\n" 86 << scope_tab << "{\n"
64 << scope_tab << scope_tab << "return value.payload;\n" 87 << scope_tab << scope_tab << "return value.payload;\n"
65 << scope_tab << "}\n" 88 << scope_tab << "}\n"
66 << "}\n" 89
90 << scope_tab << "/// <summary>Converts an instance of " << alias_type_doc << " to this struct.</summary>\n"
91 << scope_tab << "/// <param name=\"value\">The value to be converted.</param>\n"
92 << scope_tab << "/// <returns>A struct with the given value.</returns>\n"
93 << scope_tab << "public static " << alias_name << " From" << name_helpers::translate_value_type(alias_type) << "(" << alias_type << " value)\n"
94 << scope_tab << "{\n"
95 << scope_tab << scope_tab << "return value;\n"
96 << scope_tab << "}\n\n"
97
98 << scope_tab << "/// <summary>Converts an instance of this struct to " << alias_type_doc << ".</summary>\n"
99 << scope_tab << "/// <returns>The actual value the alias is wrapping.</returns>\n"
100 << scope_tab << "public " << alias_type << " To" << name_helpers::translate_value_type(alias_type) << "()\n"
101 << scope_tab << "{\n"
102 << scope_tab << scope_tab << "return this;\n"
103 << scope_tab << "}\n"
104 ).generate(sink, alias, context))
105 return false;
106
107 std::string since_line;
108 if (!alias.documentation.since.empty())
109 if (!as_generator(scope_tab << "/// <para>Since EFL " + alias.documentation.since + ".</para>\n"
110 ).generate(std::back_inserter(since_line), attributes::unused, context))
111 return false;
112
113 // GetHashCode (needed by the equality comparisons)
114 if (!as_generator(
115 scope_tab << "/// <summary>Get a hash code for this item.\n"
116 << since_line
117 << scope_tab << "/// </summary>\n"
118 << scope_tab << "public override int GetHashCode() => payload.GetHashCode();\n"
119 ).generate(sink, attributes::unused, context))
120 return false;
121
122 // IEquatble<T> Equals
123 if (!as_generator(
124 scope_tab << "/// <summary>Equality comparison.\n"
125 << since_line
126 << scope_tab << "/// </summary>\n"
127 << scope_tab << "public bool Equals(" << alias_name << " other) => payload == other.payload;\n"
128 ).generate(sink, attributes::unused, context))
129 return false;
130
131 // ValueType.Equals
132 if (!as_generator(
133 scope_tab << "/// <summary>Equality comparison.\n"
134 << since_line
135 << scope_tab << "/// </summary>\n"
136 << scope_tab << "public override bool Equals(object other)\n"
137 << scope_tab << scope_tab << "=> ((other is " << alias_name << ") ? Equals((" << alias_name << ")other) : false);\n"
138 ).generate(sink, attributes::unused, context))
139 return false;
140
141 // Equality operators
142 if (!as_generator(
143 scope_tab << "/// <summary>Equality comparison.\n"
144 << since_line
145 << scope_tab << "/// </summary>\n"
146 << scope_tab << "public static bool operator ==(" << alias_name << " lhs, " << alias_name << " rhs)\n"
147 << scope_tab << scope_tab << "=> lhs.payload == rhs.payload;\n"
148 ).generate(sink, attributes::unused, context))
149 return false;
150
151 if (!as_generator(
152 scope_tab << "/// <summary>Equality comparison.\n"
153 << since_line
154 << scope_tab << "/// </summary>\n"
155 << scope_tab << "public static bool operator !=(" << alias_name << " lhs, " << alias_name << " rhs)\n"
156 << scope_tab << scope_tab << "=> lhs.payload != rhs.payload;\n"
157 ).generate(sink, attributes::unused, context))
158 return false;
159
160 if (!as_generator(
161 "}\n"
67 ).generate(sink, alias, context)) 162 ).generate(sink, alias, context))
68 return false; 163 return false;
69 164
diff --git a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
index 8ca3c5c..bc0bb68 100644
--- a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH 16#ifndef EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH
2#define EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH 17#define EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH
3 18
@@ -57,30 +72,30 @@ struct async_function_declaration_generator
57 return true; 72 return true;
58 73
59 if (!as_generator( 74 if (!as_generator(
60 scope_tab << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n" 75 scope_tab(2) << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n"
61 ).generate(sink, attributes::unused, context)) 76 ).generate(sink, attributes::unused, context))
62 return false; 77 return false;
63 78
64 if (!f.documentation.since.empty()) 79 if (!f.documentation.since.empty())
65 if (!as_generator 80 if (!as_generator
66 (scope_tab << "/// <para>Since EFL " + f.documentation.since + ".</para>\n") 81 (scope_tab(2) << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
67 .generate (sink, attributes::unused, context)) 82 .generate (sink, attributes::unused, context))
68 return false; 83 return false;
69 84
70 if (!as_generator( 85 if (!as_generator(
71 scope_tab << "/// </summary>\n" 86 scope_tab(2) << "/// </summary>\n"
72 ).generate(sink, attributes::unused, context)) 87 ).generate(sink, attributes::unused, context))
73 return false; 88 return false;
74 89
75 // generate_parameter is not a proper as_generator-compatible generator, so we had to do an old fashioned loop 90 // generate_parameter is not a proper as_generator-compatible generator, so we had to do an old fashioned loop
76 for (auto&& param : f.parameters) 91 for (auto&& param : f.parameters)
77 if (!documentation(1).generate_parameter(sink, param, context)) 92 if (!documentation(2).generate_parameter(sink, param, context))
78 return false; 93 return false;
79 94
80 if (!as_generator( 95 if (!as_generator(
81 scope_tab << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n" 96 scope_tab(2) << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
82 << scope_tab << "/// <returns>An async task wrapping the result of the operation.</returns>\n" 97 << scope_tab(2) << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
83 << scope_tab << "System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") << 98 << scope_tab(2) << "System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") <<
84 " System.Threading.CancellationToken token = default(System.Threading.CancellationToken));\n\n" 99 " System.Threading.CancellationToken token = default(System.Threading.CancellationToken));\n\n"
85 ).generate(sink, f.parameters, context)) 100 ).generate(sink, f.parameters, context))
86 return false; 101 return false;
@@ -115,18 +130,18 @@ struct async_function_definition_generator
115 std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding); 130 std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding);
116 131
117 if (!as_generator( 132 if (!as_generator(
118 scope_tab << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n" 133 scope_tab(2) << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n"
119 ).generate(sink, attributes::unused, context)) 134 ).generate(sink, attributes::unused, context))
120 return false; 135 return false;
121 136
122 if (!f.documentation.since.empty()) 137 if (!f.documentation.since.empty())
123 if (!as_generator 138 if (!as_generator
124 (scope_tab << "/// <para>Since EFL " + f.documentation.since + ".</para>\n") 139 (scope_tab(2) << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
125 .generate (sink, attributes::unused, context)) 140 .generate (sink, attributes::unused, context))
126 return false; 141 return false;
127 142
128 if (!as_generator( 143 if (!as_generator(
129 scope_tab << "/// </summary>\n" 144 scope_tab(2) << "/// </summary>\n"
130 ).generate(sink, attributes::unused, context)) 145 ).generate(sink, attributes::unused, context))
131 return false; 146 return false;
132 147
@@ -136,13 +151,13 @@ struct async_function_definition_generator
136 return false; 151 return false;
137 152
138 if(!as_generator( 153 if(!as_generator(
139 scope_tab << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n" 154 scope_tab(2) << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
140 << scope_tab << "/// <returns>An async task wrapping the result of the operation.</returns>\n" 155 << scope_tab(2) << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
141 << scope_tab << "public System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") << " System.Threading.CancellationToken token = default(System.Threading.CancellationToken))\n" 156 << scope_tab(2) << "public System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") << " System.Threading.CancellationToken token = default(System.Threading.CancellationToken))\n"
142 << scope_tab << "{\n" 157 << scope_tab(2) << "{\n"
143 << scope_tab << scope_tab << "Eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ",") << ");\n" 158 << scope_tab(2) << scope_tab << "Eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ", ") << ");\n"
144 << scope_tab << scope_tab << "return Efl.Eo.Globals.WrapAsync(future, token);\n" 159 << scope_tab(2) << scope_tab << "return Efl.Eo.Globals.WrapAsync(future, token);\n"
145 << scope_tab << "}\n\n" 160 << scope_tab(2) << "}\n\n"
146 ).generate(sink, std::make_tuple(f.parameters, param_forwarding), context)) 161 ).generate(sink, std::make_tuple(f.parameters, param_forwarding), context))
147 return false; 162 return false;
148 return true; 163 return true;
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index 49cded5..70bc34a 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_BLACKLIST_HH 16#ifndef EOLIAN_MONO_BLACKLIST_HH
2#define EOLIAN_MONO_BLACKLIST_HH 17#define EOLIAN_MONO_BLACKLIST_HH
3 18
@@ -49,6 +64,12 @@ inline bool is_function_blacklisted(std::string const& c_name)
49 || c_name == "efl_ui_list_model_size_get" 64 || c_name == "efl_ui_list_model_size_get"
50 || c_name == "efl_ui_list_relayout_layout_do" 65 || c_name == "efl_ui_list_relayout_layout_do"
51 || c_name == "efl_event_callback_forwarder_priority_add" // Depends on constants support. 66 || c_name == "efl_event_callback_forwarder_priority_add" // Depends on constants support.
67 || c_name == "efl_event_callback_forwarder_del"
68 || c_name == "efl_ui_text_context_menu_item_add"
69 || c_name == "efl_ui_widget_input_event_handler"
70 || c_name == "efl_access_object_event_handler_add"
71 || c_name == "efl_access_object_event_handler_del"
72 || c_name == "efl_access_object_event_emit"
52 ; 73 ;
53} 74}
54 75
@@ -131,7 +152,32 @@ inline bool is_alias_blacklisted(attributes::alias_def const& alias, Context con
131 152
132inline bool is_property_blacklisted(std::string const& name) 153inline bool is_property_blacklisted(std::string const& name)
133{ 154{
134 return name == "Efl.IText.Text"; 155 auto properties = std::vector<std::string>{
156 // These properties encode (void* arr, int len) arrays
157 "Efl.Gfx.IGradient.Stop"
158 , "Efl.Gfx.GradientConcrete.Stop"
159 , "Efl.Gfx.IShape.StrokeDash"
160 , "Efl.Gfx.ShapeConcrete.StrokeDash"
161 , "Efl.Gfx.Vg.ValueProvider.Transform"
162 , "Efl.Canvas.Vg.Node.Transformation"
163 // Will be bound manually
164 , "Efl.Core.Env.Env"
165 // Setter returns a future
166 , "Efl.IModel.Property"
167 // Protected
168 , "Efl.Access.IAction.ActionName"
169 , "Efl.Access.IAction.ActionLocalizedName"
170 , "Efl.Access.IComponent.Extents"
171 , "Efl.Access.IText.AccessSelection"
172 , "Efl.Access.IText.AccessText"
173 , "Efl.Access.IText.BoundedRanges"
174 , "Efl.Access.IText.Character"
175 , "Efl.Access.IText.OffsetAtPoint"
176 , "Efl.Access.IText.String"
177 , "Efl.Access.IText.TextAttributes"
178 };
179
180 return std::find(std::begin(properties), std::end(properties), name) != std::end(properties);
135} 181}
136 182
137template<typename Context> 183template<typename Context>
diff --git a/src/bin/eolian_mono/eolian/mono/culture_info.hh b/src/bin/eolian_mono/eolian/mono/culture_info.hh
new file mode 100644
index 0000000..f1efb1c
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/culture_info.hh
@@ -0,0 +1,61 @@
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 CULTURE_INFO_GENERATOR_HH
17#define CULTURE_INFO_GENERATOR_HH
18
19#include "grammar/generator.hpp"
20#include "grammar/klass_def.hpp"
21
22namespace eolian_mono {
23
24namespace attributes = efl::eolian::grammar::attributes;
25
26// Some methods on string require a culture info parameter due to warning CA1307
27struct culture_info_generator
28{
29 template<typename OutputIterator, typename Context>
30 bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
31 {
32 std::string managed_name;
33
34 if (!as_generator(type).generate(std::back_inserter(managed_name), field.type, context))
35 return false;
36
37 if (managed_name == "System.String")
38 if (!as_generator(lit("StringComparison.Ordinal")).generate(sink, attributes::unused, context))
39 return false;
40
41 return true;
42 }
43} const culture_info {};
44
45}
46
47namespace efl { namespace eolian { namespace grammar {
48
49template <>
50struct is_eager_generator< ::eolian_mono::culture_info_generator> : std::true_type {};
51template <>
52struct is_generator< ::eolian_mono::culture_info_generator> : std::true_type {};
53
54namespace type_traits {
55template <>
56struct attributes_needed< ::eolian_mono::culture_info_generator> : std::integral_constant<int, 1> {};
57}
58
59} } }
60
61#endif // CULTURE_INFO_GENERATOR_HH
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh
index 7bcdfc5..db00ba8 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_DOCUMENTATION_HPP 16#ifndef EOLIAN_MONO_DOCUMENTATION_HPP
2#define EOLIAN_MONO_DOCUMENTATION_HPP 17#define EOLIAN_MONO_DOCUMENTATION_HPP
3 18
@@ -6,6 +21,7 @@
6#include "grammar/html_escaped_string.hpp" 21#include "grammar/html_escaped_string.hpp"
7#include "using_decl.hh" 22#include "using_decl.hh"
8#include "name_helpers.hh" 23#include "name_helpers.hh"
24#include "helpers.hh"
9#include "generation_contexts.hh" 25#include "generation_contexts.hh"
10#include "blacklist.hh" 26#include "blacklist.hh"
11 27
@@ -27,18 +43,15 @@ struct documentation_generator
27 : scope_size(scope_size) {} 43 : scope_size(scope_size) {}
28 44
29 45
30 // Returns the number of parameters (values + keys) that a property method requires 46 // Returns the number of keys that a property method requires
31 // Specify if you want the Setter or the Getter method. 47 // Specify if you want the Setter or the Getter method.
32 static int property_num_parameters(const ::Eolian_Function *function, ::Eolian_Function_Type ftype) 48 static int property_num_keys(const ::Eolian_Function *function, ::Eolian_Function_Type ftype)
33 { 49 {
34 Eina_Iterator *itr = ::eolian_property_keys_get(function, ftype); 50 Eina_Iterator *itr = ::eolian_property_keys_get(function, ftype);
35 Eolian_Function_Parameter *pr; 51 Eolian_Function_Parameter *pr;
36 int n = 0; 52 int n = 0;
37 EINA_ITERATOR_FOREACH(itr, pr) { n++; } 53 EINA_ITERATOR_FOREACH(itr, pr) { n++; }
38 eina_iterator_free(itr); 54 eina_iterator_free(itr);
39 itr = ::eolian_property_values_get(function, ftype);
40 EINA_ITERATOR_FOREACH(itr, pr) { n++; }
41 eina_iterator_free(itr);
42 return n; 55 return n;
43 } 56 }
44 57
@@ -64,13 +77,17 @@ struct documentation_generator
64 // The name_tail parameter is the last 4 chars of the original string, which 77 // The name_tail parameter is the last 4 chars of the original string, which
65 // could be ".set" or ".get" and in this case they are ignored by Eolian. 78 // could be ".set" or ".get" and in this case they are ignored by Eolian.
66 // We want them to know what the documentation intended to reference. 79 // We want them to know what the documentation intended to reference.
67 static std::string function_conversion(const ::Eolian_Object *klass, const ::Eolian_Function *function, std::string name_tail) 80 template<typename Context>
81 static std::string function_conversion(const ::Eolian_Object *klass
82 , const ::Eolian_Function *function
83 , std::string name_tail
84 , Context const& context)
68 { 85 {
69 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function); 86 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function);
70 const char* eo_name = ::eolian_function_name_get(function); 87 const char* eo_name = ::eolian_function_name_get(function);
71 std::string name = object_ref_conversion(klass); 88 std::string name = object_ref_conversion(klass);
72 89
73 // Klass is needed to check the property naming rulles 90 // Klass is needed to check the property naming rules
74 attributes::klass_def klass_d((const ::Eolian_Class *)klass, eolian_object_unit_get(klass)); 91 attributes::klass_def klass_d((const ::Eolian_Class *)klass, eolian_object_unit_get(klass));
75 92
76 // Comment the block below to enable @see reference conversion for non-public interface members. 93 // Comment the block below to enable @see reference conversion for non-public interface members.
@@ -110,14 +127,27 @@ struct documentation_generator
110 break; 127 break;
111 case ::EOLIAN_PROPERTY: 128 case ::EOLIAN_PROPERTY:
112 { 129 {
113 int getter_params = property_num_parameters(function, ::EOLIAN_PROP_GET);
114 int setter_params = property_num_parameters(function, ::EOLIAN_PROP_SET);
115 std::string short_name = name_helpers::property_managed_name(klass_d, eo_name); 130 std::string short_name = name_helpers::property_managed_name(klass_d, eo_name);
116 bool blacklisted = blacklist::is_property_blacklisted(name + "." + short_name); 131
117 // EO properties with keys, with more than one value, or blacklisted, are not 132 // We need to replace the current class context with the context
118 // converted into C# properties. 133 // from the class that originated this property.
119 // In these cases we refer to the getter method instead of the property. 134 class_context::wrapper_kind klass_kind;
120 if ((getter_params > 1) || (setter_params > 1) || (blacklisted)) name += ".Get" + short_name; 135 if (helpers::is_managed_interface(klass_d))
136 klass_kind = class_context::interface;
137 else
138 klass_kind = class_context::inherit;
139
140 auto my_context = grammar::context_replace_tag(class_context{klass_kind}, context);
141
142 auto unit = eolian_object_unit_get((const Eolian_Object*)function);
143 attributes::function_def getter_func{function, ::EOLIAN_PROP_GET, nullptr, unit};
144 attributes::function_def setter_func{function, ::EOLIAN_PROP_SET, nullptr, unit};
145 attributes::property_def prop{function, getter_func, setter_func, unit};
146
147 auto has_wrapper = helpers::has_property_wrapper(prop, &klass_d, my_context);
148
149 if (has_wrapper == helpers::has_property_wrapper_bit::has_none)
150 name += ".Get" + short_name;
121 else if (name_tail == ".get") name += ".Get" + short_name; 151 else if (name_tail == ".get") name += ".Get" + short_name;
122 else if (name_tail == ".set") name += ".Set" + short_name; 152 else if (name_tail == ".set") name += ".Set" + short_name;
123 else name += "." + short_name; 153 else name += "." + short_name;
@@ -154,9 +184,13 @@ struct documentation_generator
154 } 184 }
155 185
156 // Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag 186 // Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
157 static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail, 187 template<typename Context>
158 bool want_beta) 188 static std::string ref_conversion(const ::Eolian_Doc_Token *token
189 , const Eolian_State *state
190 , std::string name_tail
191 , Context const& context)
159 { 192 {
193 bool want_beta = context_want_beta(context);
160 const Eolian_Object *data, *data2; 194 const Eolian_Object *data, *data2;
161 ::Eolian_Object_Type type = 195 ::Eolian_Object_Type type =
162 ::eolian_doc_token_ref_resolve(token, state, &data, &data2); 196 ::eolian_doc_token_ref_resolve(token, state, &data, &data2);
@@ -184,7 +218,7 @@ struct documentation_generator
184 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2); 218 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
185 break; 219 break;
186 case ::EOLIAN_OBJECT_FUNCTION: 220 case ::EOLIAN_OBJECT_FUNCTION:
187 ref += function_conversion(data, (const ::Eolian_Function *)data2, name_tail); 221 ref += function_conversion(data, (const ::Eolian_Function *)data2, name_tail, context);
188 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2); 222 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
189 break; 223 break;
190 case ::EOLIAN_OBJECT_CONSTANT: 224 case ::EOLIAN_OBJECT_CONSTANT:
@@ -216,71 +250,88 @@ struct documentation_generator
216 } 250 }
217 251
218 // Turns EO documentation syntax into C# triple-slash XML comment syntax 252 // Turns EO documentation syntax into C# triple-slash XML comment syntax
219 static std::string syntax_conversion(std::string text, const Eolian_State *state, bool want_beta) 253 template<typename Context>
254 static std::string syntax_conversion(std::string text, const Eolian_State *state, Context const& context)
220 { 255 {
221 std::string new_text, ref; 256 std::string new_text, ref;
222 ::Eolian_Doc_Token token;
223 const char *text_ptr = text.c_str();
224 ::eolian_doc_token_init(&token);
225 ::Eolian_Doc_Token_Type previous_token_type = ::EOLIAN_DOC_TOKEN_UNKNOWN; 257 ::Eolian_Doc_Token_Type previous_token_type = ::EOLIAN_DOC_TOKEN_UNKNOWN;
226 while ((text_ptr = ::eolian_documentation_tokenize(text_ptr, &token)) != NULL) 258 ::Eina_List *paragraphs = ::eolian_documentation_string_split(text.c_str());
259 if (!paragraphs) return new_text;
260 ::Eina_List *data = paragraphs;
261 // For every paragraph
262 do
227 { 263 {
228 std::string token_text, name_tail; 264 char *par = (char *)::eina_list_data_get(data);
229 char *token_text_cstr = ::eolian_doc_token_text_get(&token); 265 const char *text_ptr = par;
230 if (token_text_cstr) 266 ::Eolian_Doc_Token token;
267 ::eolian_doc_token_init(&token);
268 // For every token inside the paragraph
269 while ((text_ptr = ::eolian_documentation_tokenize(text_ptr, &token)) != NULL)
231 { 270 {
232 token_text = token_text_cstr; 271 std::string token_text, name_tail;
233 free(token_text_cstr); 272 char *token_text_cstr = ::eolian_doc_token_text_get(&token);
234 if (token_text.length() > 4) 273 if (token_text_cstr)
235 name_tail = token_text.substr(token_text.length() - 4, 4);
236 }
237 ::Eolian_Doc_Token_Type token_type = ::eolian_doc_token_type_get(&token);
238 switch(token_type)
239 {
240 case ::EOLIAN_DOC_TOKEN_TEXT:
241 // If previous token was a reference and this text token starts with
242 // parentheses, remove them, since the reference will be rendered
243 // with the parentheses already.
244 if ((previous_token_type == ::EOLIAN_DOC_TOKEN_REF) &&
245 (token_text.substr(0, 2) == "()"))
246 token_text = token_text.substr(2, token_text.length() - 2);
247 new_text += token_text;
248 break;
249 case ::EOLIAN_DOC_TOKEN_REF:
250 ref = ref_conversion(&token, state, name_tail, want_beta);
251 if (ref != "")
252 { 274 {
253 if (utils::ends_with(ref, BETA_REF_SUFFIX)) 275 token_text = token_text_cstr;
254 new_text += "<span class=\"text-muted\">" + ref + "</span>"; 276 free(token_text_cstr);
255 else 277 if (token_text.length() > 4)
256 new_text += "<see cref=\"" + ref + "\"/>"; 278 name_tail = token_text.substr(token_text.length() - 4, 4);
257 } 279 }
258 else 280 ::Eolian_Doc_Token_Type token_type = ::eolian_doc_token_type_get(&token);
259 // Unresolved references are passed through. 281 switch(token_type)
260 // They will appear in the docs as plain text, without link, 282 {
261 // but at least they won't be removed by DocFX. 283 case ::EOLIAN_DOC_TOKEN_TEXT:
262 new_text += token_text; 284 // If previous token was a reference and this text token starts with
263 break; 285 // parentheses, remove them, since the reference will be rendered
264 case ::EOLIAN_DOC_TOKEN_MARK_NOTE: 286 // with the parentheses already.
265 new_text += "NOTE: " + token_text; 287 if ((previous_token_type == ::EOLIAN_DOC_TOKEN_REF) &&
266 break; 288 (token_text.substr(0, 2) == "()"))
267 case ::EOLIAN_DOC_TOKEN_MARK_WARNING: 289 token_text = token_text.substr(2, token_text.length() - 2);
268 new_text += "WARNING: " + token_text; 290 new_text += token_text;
269 break; 291 break;
270 case ::EOLIAN_DOC_TOKEN_MARK_REMARK: 292 case ::EOLIAN_DOC_TOKEN_REF:
271 new_text += "REMARK: " + token_text; 293 ref = ref_conversion(&token, state, name_tail, context);
272 break; 294 if (ref != "")
273 case ::EOLIAN_DOC_TOKEN_MARK_TODO: 295 {
274 new_text += "TODO: " + token_text; 296 if (utils::ends_with(ref, BETA_REF_SUFFIX))
275 break; 297 new_text += "<span class=\"text-muted\">" + ref + "</span>";
276 case ::EOLIAN_DOC_TOKEN_MARKUP_MONOSPACE: 298 else
277 new_text += "<c>" + token_text + "</c>"; 299 new_text += "<see cref=\"" + ref + "\"/>";
278 break; 300 }
279 default: 301 else
280 break; 302 // Unresolved references are passed through.
281 } 303 // They will appear in the docs as plain text, without link,
282 previous_token_type = token_type; 304 // but at least they won't be removed by DocFX.
283 } 305 new_text += token_text;
306 break;
307 case ::EOLIAN_DOC_TOKEN_MARK_NOTE:
308 new_text += "<b>NOTE: </b>";
309 break;
310 case ::EOLIAN_DOC_TOKEN_MARK_WARNING:
311 new_text += "<b>WARNING: </b>";
312 break;
313 case ::EOLIAN_DOC_TOKEN_MARK_REMARK:
314 new_text += "<b>REMARK: </b>";
315 break;
316 case ::EOLIAN_DOC_TOKEN_MARK_TODO:
317 new_text += "<b>TODO: </b>";
318 break;
319 case ::EOLIAN_DOC_TOKEN_MARKUP_MONOSPACE:
320 new_text += "<c>" + token_text + "</c>";
321 break;
322 default:
323 break;
324 }
325 previous_token_type = token_type;
326 }
327 // Free this paragraph
328 free(par);
329 // Fetch the next paragraph
330 data = ::eina_list_next(data);
331 // If there's another paragraph afterwards, separate them with a blank line
332 if (data) new_text += "\n\n";
333 } while (data);
334 ::eina_list_free(paragraphs);
284 return new_text; 335 return new_text;
285 } 336 }
286 337
@@ -304,7 +355,7 @@ struct documentation_generator
304 if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context)) 355 if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context))
305 return false; 356 return false;
306 auto options = context_find_tag<options_context>(context); 357 auto options = context_find_tag<options_context>(context);
307 new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, options.want_beta); 358 new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, context);
308 359
309 std::string tabs; 360 std::string tabs;
310 as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context); 361 as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context);
@@ -626,7 +677,7 @@ struct documentation_string_generator
626 677
627 auto options = context_find_tag<options_context>(context); 678 auto options = context_find_tag<options_context>(context);
628 auto state = context_find_tag<eolian_state_context>(context).state; 679 auto state = context_find_tag<eolian_state_context>(context).state;
629 if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, options.want_beta), context)) 680 if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, context), context))
630 return false; 681 return false;
631 682
632 return true; 683 return true;
@@ -634,8 +685,24 @@ struct documentation_string_generator
634 685
635} const documentation_string {}; 686} const documentation_string {};
636 687
637} // namespace eolian_mono 688namespace documentation_helpers
689{
690
691template<typename OutputIterator, typename Indent, typename Context>
692bool generate_since_tag_line(OutputIterator sink, attributes::documentation_def const& doc, Indent indentation, Context context)
693{
694 if (doc.since.empty())
695 return true;
696
697 return as_generator
698 (
699 indentation << ("/// <para>Since EFL " + doc.since + ".</para>\n")
700 ).generate(sink, attributes::unused, context);
701}
638 702
703} // documentation_helpers
704
705} // namespace eolian_mono
639 706
640namespace efl { namespace eolian { namespace grammar { 707namespace efl { namespace eolian { namespace grammar {
641 708
diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
index 96595d3..4b07652 100644
--- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_ENUM_DEFINITION_HH 16#ifndef EOLIAN_MONO_ENUM_DEFINITION_HH
2#define EOLIAN_MONO_ENUM_DEFINITION_HH 17#define EOLIAN_MONO_ENUM_DEFINITION_HH
3 18
@@ -25,15 +40,22 @@ struct enum_definition_generator
25 if(!name_helpers::open_namespaces(sink, enum_.namespaces, context)) 40 if(!name_helpers::open_namespaces(sink, enum_.namespaces, context))
26 return false; 41 return false;
27 42
28 if(!as_generator(documentation).generate(sink, enum_, context)) 43 std::string enum_name = name_helpers::typedecl_managed_name(enum_);
29 return false; 44 std::string flags_attribute;
45
46 // CA1717
47 if (utils::ends_with(enum_name, "Flags") || utils::ends_with(enum_name, "InputHints")) // Special provision while Text api is revamped
48 flags_attribute = "[Flags]";
30 49
31 if(!as_generator 50 if(!as_generator
32 ( 51 (
33 "[Efl.Eo.BindingEntity]\n" 52 documentation(1)
34 "public enum " << string << "\n{\n" 53 << scope_tab << flags_attribute << "\n"
54 << scope_tab << "[Efl.Eo.BindingEntity]\n"
55 << scope_tab << "public enum " << enum_name << "\n"
56 << scope_tab << "{\n"
35 ) 57 )
36 .generate(sink, name_helpers::typedecl_managed_name(enum_), context)) 58 .generate(sink, enum_, context))
37 return false; 59 return false;
38 60
39 // iterate enum fiels 61 // iterate enum fiels
@@ -44,13 +66,14 @@ struct enum_definition_generator
44 auto literal = (*first).value.literal; 66 auto literal = (*first).value.literal;
45 if (!as_generator 67 if (!as_generator
46 ( 68 (
47 documentation << string << " = " << string << ",\n" 69 documentation(2)
70 << scope_tab(2) << string << " = " << string << ",\n"
48 ) 71 )
49 .generate(sink, std::make_tuple(*first, name, literal), context)) 72 .generate(sink, std::make_tuple(*first, name, literal), context))
50 return false; 73 return false;
51 } 74 }
52 75
53 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; 76 if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, context)) return false;
54 77
55 if(!name_helpers::close_namespaces(sink, enum_.namespaces, context)) 78 if(!name_helpers::close_namespaces(sink, enum_.namespaces, context))
56 return false; 79 return false;
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index 5ca6b1b..7405f8c 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -1,16 +1,35 @@
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 */
1#ifndef EOLIAN_MONO_EVENTS_HH 16#ifndef EOLIAN_MONO_EVENTS_HH
2#define EOLIAN_MONO_EVENTS_HH 17#define EOLIAN_MONO_EVENTS_HH
3 18
4#include <iterator> 19#include <iterator>
5 20
21#include <Eina.hh>
22
6#include "grammar/generator.hpp" 23#include "grammar/generator.hpp"
7#include "grammar/klass_def.hpp" 24#include "grammar/klass_def.hpp"
8#include "type_impl.hh" // For call_match 25#include "type_match.hh"
9#include "name_helpers.hh" 26#include "name_helpers.hh"
10#include "using_decl.hh" 27#include "using_decl.hh"
11 28
12namespace eolian_mono { 29namespace eolian_mono {
13 30
31namespace eina = efl::eina;
32
14template<typename OutputIterator, typename Context> 33template<typename OutputIterator, typename Context>
15struct unpack_event_args_visitor 34struct unpack_event_args_visitor
16{ 35{
@@ -22,7 +41,7 @@ struct unpack_event_args_visitor
22 typedef bool result_type; 41 typedef bool result_type;
23 bool operator()(grammar::attributes::regular_type_def const& regular) const 42 bool operator()(grammar::attributes::regular_type_def const& regular) const
24 { 43 {
25 std::string const& arg = "evt.Info"; 44 std::string const& arg = "info";
26 std::string arg_type = name_helpers::type_full_managed_name(regular); 45 std::string arg_type = name_helpers::type_full_managed_name(regular);
27 46
28 if (regular.is_struct()) 47 if (regular.is_struct())
@@ -30,7 +49,7 @@ struct unpack_event_args_visitor
30 // Structs are usually passed by pointer to events, like having a ptr<> modifier 49 // Structs are usually passed by pointer to events, like having a ptr<> modifier
31 // Uses implicit conversion from IntPtr 50 // Uses implicit conversion from IntPtr
32 return as_generator( 51 return as_generator(
33 " evt.Info" 52 " info"
34 ).generate(sink, attributes::unused, *context); 53 ).generate(sink, attributes::unused, *context);
35 } 54 }
36 else if (type.is_ptr) 55 else if (type.is_ptr)
@@ -99,24 +118,33 @@ struct unpack_event_args_visitor
99 return as_generator(conversion).generate(sink, attributes::unused, *context); 118 return as_generator(conversion).generate(sink, attributes::unused, *context);
100 }; 119 };
101 120
102 if (eina::optional<bool> b = call_match(match_table, filter_func, accept_func)) 121 if (eina::optional<bool> b = type_match::get_match(match_table, filter_func, accept_func))
103 return *b; 122 return *b;
104 else 123 else
105 { 124 {
106 // Type defined in Eo is passed here. (e.g. enum type defined in Eo) 125 // Type defined in Eo is passed here. (e.g. enum type defined in Eo)
107 // Uses conversion from IntPtr with type casting to the given type. 126 // Uses conversion from IntPtr with type casting to the given type.
108 return as_generator( 127 return as_generator(
109 " (" << arg_type << ")evt.Info" 128 " (" << arg_type << ")info"
110 ).generate(sink, attributes::unused, *context); 129 ).generate(sink, attributes::unused, *context);
111 } 130 }
112 } 131 }
113 bool operator()(grammar::attributes::klass_name const& cls) const 132 bool operator()(grammar::attributes::klass_name const& cls) const
114 { 133 {
115 return as_generator("(Efl.Eo.Globals.CreateWrapperFor(evt.Info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context); 134 return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context);
116 } 135 }
117 bool operator()(attributes::complex_type_def const&) const 136 bool operator()(attributes::complex_type_def const& types) const
118 { 137 {
119 return as_generator("new " << eolian_mono::type << "(evt.Info, false, false)").generate(sink, type, *context); 138 if (types.outer.base_type == "iterator")
139 return as_generator("Efl.Eo.Globals.IteratorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
140 else if (types.outer.base_type == "accessor")
141 return as_generator("Efl.Eo.Globals.AccessorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
142 else if (types.outer.base_type == "array")
143 return as_generator("Efl.Eo.Globals.NativeArrayTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
144 else if (types.outer.base_type == "list")
145 return as_generator("Efl.Eo.Globals.NativeListTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
146 else
147 return as_generator("new " << eolian_mono::type << "(info, false, false)").generate(sink, type, *context);
120 } 148 }
121}; 149};
122 150
@@ -126,8 +154,8 @@ struct pack_event_info_and_call_visitor
126 mutable OutputIterator sink; 154 mutable OutputIterator sink;
127 Context const* context; 155 Context const* context;
128 attributes::type_def const& type; 156 attributes::type_def const& type;
129 157 std::string library_name;
130 static auto constexpr native_call = "Efl.Eo.Globals.CallEventCallback(this.NativeHandle, desc, info);\n"; 158 std::string evt_c_name;
131 159
132 typedef pack_event_info_and_call_visitor<OutputIterator, Context> visitor_type; 160 typedef pack_event_info_and_call_visitor<OutputIterator, Context> visitor_type;
133 typedef bool result_type; 161 typedef bool result_type;
@@ -141,16 +169,9 @@ struct pack_event_info_and_call_visitor
141 if (regular.is_struct()) 169 if (regular.is_struct())
142 { 170 {
143 return as_generator( 171 return as_generator(
144 indent << "IntPtr info = Marshal.AllocHGlobal(Marshal.SizeOf(e.arg));\n" 172 indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
145 << indent << "try\n" 173 << indent.inc() << "IntPtr info = Marshal.AllocHGlobal(Marshal.SizeOf(e.arg));\n"
146 << indent << "{\n" 174 << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
147 << indent << scope_tab << "Marshal.StructureToPtr(e.arg, info, false);\n"
148 << indent << scope_tab << this->native_call
149 << indent << "}\n"
150 << indent << "finally\n"
151 << indent << "{\n"
152 << indent << scope_tab << "Marshal.FreeHGlobal(info);\n"
153 << indent << "}\n"
154 ).generate(sink, attributes::unused, *context); 175 ).generate(sink, attributes::unused, *context);
155 } 176 }
156 177
@@ -176,18 +197,13 @@ struct pack_event_info_and_call_visitor
176 auto str_accept_func = [&](std::string const& conversion) 197 auto str_accept_func = [&](std::string const& conversion)
177 { 198 {
178 return as_generator( 199 return as_generator(
179 indent << "IntPtr info = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(" << conversion << ");\n" 200 indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
180 << indent << "try\n" 201 << indent.inc() << "IntPtr info = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(" << conversion << ");\n"
181 << indent << "{\n" 202 << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Eina.MemoryNative.Free(p));\n"
182 << indent << scope_tab << this->native_call 203 ).generate(sink, attributes::unused, *context);
183 << indent << "}\n"
184 << indent << "finally\n"
185 << indent << "{\n"
186 << indent << scope_tab << "Eina.MemoryNative.Free(info);\n"
187 << indent << "}\n").generate(sink, attributes::unused, *context);
188 }; 204 };
189 205
190 if (eina::optional<bool> b = call_match(str_table, filter_func, str_accept_func)) 206 if (eina::optional<bool> b = type_match::get_match(str_table, filter_func, str_accept_func))
191 return *b; 207 return *b;
192 208
193 match const value_table [] = 209 match const value_table [] =
@@ -200,18 +216,13 @@ struct pack_event_info_and_call_visitor
200 auto value_accept_func = [&](std::string const& conversion) 216 auto value_accept_func = [&](std::string const& conversion)
201 { 217 {
202 return as_generator( 218 return as_generator(
203 indent << "IntPtr info = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << conversion << ");\n" 219 indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
204 << indent << "try\n" 220 << indent.inc() << "IntPtr info = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << conversion << ");\n"
205 << indent << "{\n" 221 << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
206 << indent << scope_tab << this->native_call 222 ).generate(sink, attributes::unused, *context);
207 << indent << "}\n"
208 << indent << "finally\n"
209 << indent << "{\n"
210 << indent << scope_tab << "Marshal.FreeHGlobal(info);\n"
211 << indent << "}\n").generate(sink, attributes::unused, *context);
212 }; 223 };
213 224
214 if (eina::optional<bool> b = call_match(value_table, filter_func, value_accept_func)) 225 if (eina::optional<bool> b = type_match::get_match(value_table, filter_func, value_accept_func))
215 return *b; 226 return *b;
216 227
217 return value_accept_func("e.args"); 228 return value_accept_func("e.args");
@@ -219,14 +230,32 @@ struct pack_event_info_and_call_visitor
219 bool operator()(grammar::attributes::klass_name const&) const 230 bool operator()(grammar::attributes::klass_name const&) const
220 { 231 {
221 auto const& indent = current_indentation(*context); 232 auto const& indent = current_indentation(*context);
222 return as_generator(indent << "IntPtr info = e.arg.NativeHandle;\n" 233 return as_generator(
223 << indent << this->native_call).generate(sink, attributes::unused, *context); 234 indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
235 << indent.inc() << "IntPtr info = e.arg.NativeHandle;\n"
236 << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
237 ).generate(sink, attributes::unused, *context);
224 } 238 }
225 bool operator()(attributes::complex_type_def const&) const 239 bool operator()(attributes::complex_type_def const& type) const
226 { 240 {
227 auto const& indent = current_indentation(*context); 241 auto const& indent = current_indentation(*context);
228 return as_generator(indent << "IntPtr info = e.arg.Handle;\n" 242 bool is_own = type.outer.base_qualifier & attributes::qualifier_info::is_own;
229 << indent << this->native_call).generate(sink, attributes::unused, *context); 243 std::string info_variable;
244
245 if (type.outer.base_type == "iterator")
246 info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToIterator(e.arg, ") + (is_own ? "true" : "false") + ");\n";
247 else if (type.outer.base_type == "accessor")
248 info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToAccessor(e.arg, ") + (is_own ? "true" : "false") + ");\n";
249 else if (type.outer.base_type == "array")
250 info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeArray(e.arg, ") + (is_own ? "true" : "false") + ");\n";
251 else if (type.outer.base_type == "list")
252 info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeList(e.arg, ") + (is_own ? "true" : "false") + ");\n";
253 else
254 info_variable = "IntPtr info = e.arg.Handle;\n";
255 return as_generator(indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
256 << indent.inc() << info_variable
257 << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
258 ).generate(sink, attributes::unused, *context);
230 } 259 }
231}; 260};
232 261
@@ -247,7 +276,7 @@ struct event_argument_wrapper_generator
247 276
248 std::string evt_name = name_helpers::managed_event_name(evt.name); 277 std::string evt_name = name_helpers::managed_event_name(evt.name);
249 278
250 if (!as_generator("/// <summary>Event argument wrapper for event <see cref=\"" 279 if (!as_generator(scope_tab << "/// <summary>Event argument wrapper for event <see cref=\""
251 << join_namespaces(evt.klass.namespaces, '.', managed_namespace) 280 << join_namespaces(evt.klass.namespaces, '.', managed_namespace)
252 << klass_interface_name(evt.klass) << "." << evt_name << "\"/>.\n" 281 << klass_interface_name(evt.klass) << "." << evt_name << "\"/>.\n"
253 ).generate(sink, nullptr, context)) 282 ).generate(sink, nullptr, context))
@@ -270,7 +299,7 @@ struct event_argument_wrapper_generator
270 { 299 {
271 300
272 if (!as_generator( 301 if (!as_generator(
273 lit("/// <para>Since EFL ") << evt.documentation.since << ".</para>\n" 302 scope_tab << lit("/// <para>Since EFL ") << evt.documentation.since << ".</para>\n"
274 ).generate(sink, nullptr, context)) 303 ).generate(sink, nullptr, context))
275 return false; 304 return false;
276 } 305 }
@@ -282,23 +311,23 @@ struct event_argument_wrapper_generator
282 } 311 }
283 } 312 }
284 313
285 if (!as_generator(lit("/// </summary>\n") 314 if (!as_generator(scope_tab << lit("/// </summary>\n")
286 << "[Efl.Eo.BindingEntity]\n" 315 << scope_tab << "[Efl.Eo.BindingEntity]\n"
287 << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n" 316 << scope_tab << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
288 << scope_tab << "/// <summary>Actual event payload.\n" 317 << scope_tab(2) << "/// <summary>Actual event payload.\n"
289 ).generate(sink, nullptr, context)) 318 ).generate(sink, nullptr, context))
290 return false; 319 return false;
291 320
292 if (since != "") 321 if (since != "")
293 { 322 {
294 if (!as_generator(scope_tab << "/// <para>Since EFL " << since << ".</para>\n").generate(sink, nullptr, context)) 323 if (!as_generator(scope_tab(2) << "/// <para>Since EFL " << since << ".</para>\n").generate(sink, nullptr, context))
295 return false; 324 return false;
296 } 325 }
297 326
298 if (!as_generator(scope_tab << "/// </summary>\n" 327 if (!as_generator(scope_tab(2) << "/// </summary>\n"
299 << scope_tab << "/// <value>" << documentation_string << "</value>\n" 328 << scope_tab(2) << "/// <value>" << documentation_string << "</value>\n"
300 << scope_tab << "public " << type << " arg { get; set; }\n" 329 << scope_tab(2) << "public " << type << " arg { get; set; }\n"
301 << "}\n\n" 330 << scope_tab << "}\n\n"
302 ).generate(sink, std::make_tuple(evt.documentation.summary, *etype), context)) 331 ).generate(sink, std::make_tuple(evt.documentation.summary, *etype), context))
303 return false; 332 return false;
304 333
@@ -325,14 +354,14 @@ struct event_declaration_generator
325 if (evt.type.is_engaged()) 354 if (evt.type.is_engaged())
326 wrapper_args_type = "<" + name_helpers::managed_event_args_name(evt) + ">"; 355 wrapper_args_type = "<" + name_helpers::managed_event_args_name(evt) + ">";
327 356
328 if (!as_generator(documentation(1)) 357 if (!as_generator(documentation(2))
329 .generate(sink, evt, context)) return false; 358 .generate(sink, evt, context)) return false;
330 if (evt.type.is_engaged()) 359 if (evt.type.is_engaged())
331 if (!as_generator( 360 if (!as_generator(
332 scope_tab << "/// <value><see cref=\"" << name_helpers::managed_event_args_name(evt) << "\"/></value>\n" 361 scope_tab(2) << "/// <value><see cref=\"" << name_helpers::managed_event_args_name(evt) << "\"/></value>\n"
333 ).generate(sink, evt, context)) return false; 362 ).generate(sink, evt, context)) return false;
334 if (!as_generator( 363 if (!as_generator(
335 scope_tab << "event EventHandler" << wrapper_args_type << " " << evt_name << ";\n" 364 scope_tab(2) << "event EventHandler" << wrapper_args_type << " " << evt_name << ";\n"
336 ).generate(sink, evt, context)) 365 ).generate(sink, evt, context))
337 return false; 366 return false;
338 367
@@ -352,6 +381,7 @@ struct event_definition_generator
352 if (blacklist::is_event_blacklisted(evt, context)) 381 if (blacklist::is_event_blacklisted(evt, context))
353 return true; 382 return true;
354 383
384 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
355 std::string managed_evt_name = name_helpers::managed_event_name(evt.name); 385 std::string managed_evt_name = name_helpers::managed_event_name(evt.name);
356 auto const& indent = current_indentation(context); 386 auto const& indent = current_indentation(context);
357 387
@@ -381,7 +411,7 @@ struct event_definition_generator
381 if (!etype.is_engaged()) 411 if (!etype.is_engaged())
382 { 412 {
383 auto event_call_site_sink = std::back_inserter(event_native_call); 413 auto event_call_site_sink = std::back_inserter(event_native_call);
384 if (!as_generator(indent.inc().inc() << "Efl.Eo.Globals.CallEventCallback(this.NativeHandle, desc, IntPtr.Zero);\n") 414 if (!as_generator(indent.inc().inc().inc() << "CallNativeEventCallback(" << library_name << ", \"_" << utils::to_uppercase(evt.c_name) << "\", IntPtr.Zero, null);\n")
385 .generate(event_call_site_sink, attributes::unused, context)) 415 .generate(event_call_site_sink, attributes::unused, context))
386 return false; 416 return false;
387 } 417 }
@@ -396,25 +426,25 @@ struct event_definition_generator
396 426
397 auto sub_context = change_indentation(indent.inc().inc(), context); 427 auto sub_context = change_indentation(indent.inc().inc(), context);
398 428
399 if (!as_generator(wrapper_args_type << " args = new " << wrapper_args_type << "();\n" 429 if (!as_generator(", info => new " << wrapper_args_type << "{ "
400 << scope_tab(6) << "args.arg = ").generate(arg_initializer_sink, attributes::unused, context)) 430 << "arg = ").generate(arg_initializer_sink, attributes::unused, context))
401 return false; 431 return false;
402 if (!(*etype).original_type.visit(unpack_event_args_visitor<decltype(arg_initializer_sink), decltype(sub_context)>{arg_initializer_sink, &sub_context, *etype})) 432 if (!(*etype).original_type.visit(unpack_event_args_visitor<decltype(arg_initializer_sink), decltype(sub_context)>{arg_initializer_sink, &sub_context, *etype}))
403 return false; 433 return false;
404 434
405 if (!(*etype).original_type.visit(pack_event_info_and_call_visitor<decltype(event_call_site_sink), decltype(sub_context)>{event_call_site_sink, &sub_context, *etype})) 435 if (!(*etype).original_type.visit(pack_event_info_and_call_visitor<decltype(event_call_site_sink), decltype(sub_context)>{event_call_site_sink, &sub_context, *etype, library_name, utils::to_uppercase(evt.c_name)}))
406 return false; 436 return false;
407 437
408 arg_initializer += ";\n"; 438 arg_initializer += " }";
409 439
410 event_args = arg_initializer; 440 event_args = arg_initializer;
411 } 441 }
412 442
413 if(!as_generator(documentation(1)).generate(sink, evt, context)) 443 if(!as_generator(documentation(2)).generate(sink, evt, context))
414 return false; 444 return false;
415 if (etype.is_engaged()) 445 if (etype.is_engaged())
416 if (!as_generator( 446 if (!as_generator(
417 scope_tab << "/// <value><see cref=\"" << wrapper_args_type << "\"/></value>\n" 447 scope_tab(2) << "/// <value><see cref=\"" << wrapper_args_type << "\"/></value>\n"
418 ).generate(sink, evt, context)) return false; 448 ).generate(sink, evt, context)) return false;
419 449
420 // Visible event declaration. Either a regular class member or an explicit interface implementation. 450 // Visible event declaration. Either a regular class member or an explicit interface implementation.
@@ -422,7 +452,7 @@ struct event_definition_generator
422 { 452 {
423 // Public event implementation. 453 // Public event implementation.
424 if (!as_generator( 454 if (!as_generator(
425 scope_tab << (!use_explicit_impl ? "public " : " ") << "event EventHandler" << wrapper_args_template << " " << (use_explicit_impl ? (klass_name + ".") : "") << managed_evt_name << "\n" 455 scope_tab(2) << (!use_explicit_impl ? "public " : " ") << "event EventHandler" << wrapper_args_template << " " << (use_explicit_impl ? (klass_name + ".") : "") << managed_evt_name << "\n"
426 ).generate(sink, attributes::unused, context)) 456 ).generate(sink, attributes::unused, context))
427 return false; 457 return false;
428 } 458 }
@@ -435,7 +465,7 @@ struct event_definition_generator
435 visibility += "new "; 465 visibility += "new ";
436 466
437 if (!as_generator( 467 if (!as_generator(
438 scope_tab << visibility << "event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << "\n" 468 scope_tab(2) << visibility << "event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << "\n"
439 ).generate(sink, attributes::unused, context)) 469 ).generate(sink, attributes::unused, context))
440 return false; 470 return false;
441 } 471 }
@@ -459,9 +489,10 @@ struct event_definition_generator
459 { 489 {
460 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename); 490 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
461 std::string upper_c_name = utils::to_uppercase(evt.c_name); 491 std::string upper_c_name = utils::to_uppercase(evt.c_name);
492 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
462 493
463 if (!as_generator( 494 if (!as_generator(
464 scope_tab << "/// <summary>Method to raise event "<< event_name << ".\n" 495 scope_tab(2) << "/// <summary>Method to raise event "<< event_name << ".\n"
465 ).generate(sink, nullptr, context)) 496 ).generate(sink, nullptr, context))
466 return false; 497 return false;
467 498
@@ -480,7 +511,7 @@ struct event_definition_generator
480 { 511 {
481 512
482 if (!as_generator( 513 if (!as_generator(
483 scope_tab << "/// <para>Since EFL " << evt.documentation.since << ".</para>\n" 514 scope_tab(2) << "/// <para>Since EFL " << evt.documentation.since << ".</para>\n"
484 ).generate(sink, nullptr, context)) 515 ).generate(sink, nullptr, context))
485 return false; 516 return false;
486 } 517 }
@@ -492,20 +523,22 @@ struct event_definition_generator
492 } 523 }
493 } 524 }
494 525
526 // Close summary
527 if (!as_generator(scope_tab(2) << "/// </summary>\n").generate(sink, nullptr, context))
528 return false;
529
530 if (evt.type.is_engaged())
531 {
532 if (!as_generator(scope_tab(2) << "/// <param name=\"e\">Event to raise.</param>\n"
533 ).generate(sink, nullptr, context))
534 return false;
535 }
536
495 if (!as_generator( 537 if (!as_generator(
496 scope_tab << "/// </summary>\n" 538 scope_tab(2) << (is_concrete ? "public" : "protected virtual") << " void On" << event_name << "(" << (!evt.type.is_engaged() ? "" : event_args_type + " e") << ")\n"
497 << scope_tab << "/// <param name=\"e\">Event to raise.</param>\n" 539 << scope_tab(2) << "{\n"
498 << scope_tab << "public void On" << event_name << "(" << event_args_type << " e)\n"
499 << scope_tab << "{\n"
500 << scope_tab << scope_tab << "var key = \"_" << upper_c_name << "\";\n"
501 << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(" << library_name << ", key);\n"
502 << scope_tab << scope_tab << "if (desc == IntPtr.Zero)\n"
503 << scope_tab << scope_tab << "{\n"
504 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
505 << scope_tab << scope_tab << scope_tab << "return;\n"
506 << scope_tab << scope_tab << "}\n\n"
507 << event_native_call 540 << event_native_call
508 << scope_tab << "}\n\n" 541 << scope_tab(2) << "}\n\n"
509 ).generate(sink, nullptr, context)) 542 ).generate(sink, nullptr, context))
510 return false; 543 return false;
511 544
@@ -523,35 +556,20 @@ struct event_definition_generator
523 attributes::klass_def klass(get_klass(evt.klass, unit), unit); 556 attributes::klass_def klass(get_klass(evt.klass, unit), unit);
524 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename); 557 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
525 return as_generator( 558 return as_generator(
526 scope_tab << "{\n" 559 scope_tab(2) << "{\n"
527 << scope_tab << scope_tab << "add\n" 560 << scope_tab(2) << scope_tab << "add\n"
528 << scope_tab << scope_tab << "{\n" 561 << scope_tab(2) << scope_tab << "{\n"//evt.type.is_engaged()
529 << scope_tab << scope_tab << scope_tab << "Efl.EventCb callerCb = (IntPtr data, ref Efl.Event.NativeStruct evt) =>\n" 562 << scope_tab(2) << scope_tab << scope_tab << "Efl.EventCb callerCb = GetInternalEventCallback(value"
530 << scope_tab << scope_tab << scope_tab << "{\n" 563 << (evt.type.is_engaged() ? event_args : "") << ");\n"
531 << scope_tab << scope_tab << scope_tab << scope_tab << "var obj = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(data).Target;\n" 564 << scope_tab(2) << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
532 << scope_tab << scope_tab << scope_tab << scope_tab << "if (obj != null)\n" 565 << scope_tab(2) << scope_tab << scope_tab << "AddNativeEventHandler(" << library_name << ", key, callerCb, value);\n"
533 << scope_tab << scope_tab << scope_tab << scope_tab << "{\n" 566 << scope_tab(2) << scope_tab << "}\n\n"
534 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << event_args 567 << scope_tab(2) << scope_tab << "remove\n"
535 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "try\n" 568 << scope_tab(2) << scope_tab << "{\n"
536 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "{\n" 569 << scope_tab(2) << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
537 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "value?.Invoke(obj, args);\n" 570 << scope_tab(2) << scope_tab << scope_tab << "RemoveNativeEventHandler(" << library_name << ", key, value);\n"
538 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n" 571 << scope_tab(2) << scope_tab << "}\n"
539 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "catch (Exception e)\n" 572 << scope_tab(2) << "}\n\n"
540 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "{\n"
541 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error(e.ToString());\n"
542 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);\n"
543 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
544 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
545 << scope_tab << scope_tab << scope_tab << "};\n\n"
546 << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
547 << scope_tab << scope_tab << scope_tab << "AddNativeEventHandler(" << library_name << ", key, callerCb, value);\n"
548 << scope_tab << scope_tab << "}\n\n"
549 << scope_tab << scope_tab << "remove\n"
550 << scope_tab << scope_tab << "{\n"
551 << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
552 << scope_tab << scope_tab << scope_tab << "RemoveNativeEventHandler(" << library_name << ", key, value);\n"
553 << scope_tab << scope_tab << "}\n"
554 << scope_tab << "}\n\n"
555 ).generate(sink, attributes::unused, context); 573 ).generate(sink, attributes::unused, context);
556 } 574 }
557}; 575};
diff --git a/src/bin/eolian_mono/eolian/mono/function_declaration.hh b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
index 734700c..d209f06 100644
--- a/src/bin/eolian_mono/eolian/mono/function_declaration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_FUNCTION_DECLARATION_HH 16#ifndef EOLIAN_MONO_FUNCTION_DECLARATION_HH
2#define EOLIAN_MONO_FUNCTION_DECLARATION_HH 17#define EOLIAN_MONO_FUNCTION_DECLARATION_HH
3 18
@@ -27,11 +42,11 @@ struct function_declaration_generator
27 if(f.scope != attributes::member_scope::scope_public) 42 if(f.scope != attributes::member_scope::scope_public)
28 return true; 43 return true;
29 44
30 if(!as_generator(documentation(1)).generate(sink, f, context)) 45 if(!as_generator(documentation(2)).generate(sink, f, context))
31 return false; 46 return false;
32 47
33 return as_generator 48 return as_generator
34 (scope_tab << eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n\n") 49 (scope_tab(2) << eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n\n")
35 .generate(sink, std::make_tuple(f.return_type, name_helpers::managed_method_name(f), f.parameters), context); 50 .generate(sink, std::make_tuple(f.return_type, name_helpers::managed_method_name(f), f.parameters), context);
36 } 51 }
37}; 52};
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index d17ac56..0c2adeb 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_FUNCTION_DEFINITION_HH 16#ifndef EOLIAN_MONO_FUNCTION_DEFINITION_HH
2#define EOLIAN_MONO_FUNCTION_DEFINITION_HH 17#define EOLIAN_MONO_FUNCTION_DEFINITION_HH
3 18
@@ -11,6 +26,7 @@
11#include "grammar/list.hpp" 26#include "grammar/list.hpp"
12#include "grammar/alternative.hpp" 27#include "grammar/alternative.hpp"
13#include "grammar/attribute_reorder.hpp" 28#include "grammar/attribute_reorder.hpp"
29#include "grammar/eps.hpp"
14#include "grammar/counter.hpp" 30#include "grammar/counter.hpp"
15#include "logging.hh" 31#include "logging.hh"
16#include "type.hh" 32#include "type.hh"
@@ -29,7 +45,7 @@ namespace eolian_mono {
29struct native_function_definition_generator 45struct native_function_definition_generator
30{ 46{
31 attributes::klass_def const* klass; 47 attributes::klass_def const* klass;
32 48
33 template <typename OutputIterator, typename Context> 49 template <typename OutputIterator, typename Context>
34 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 50 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
35 { 51 {
@@ -61,7 +77,7 @@ struct native_function_definition_generator
61 if(!as_generator 77 if(!as_generator
62 ( 78 (
63 indent << eolian_mono::marshall_annotation(true) << "\n" 79 indent << eolian_mono::marshall_annotation(true) << "\n"
64 << indent << "public delegate " 80 << indent << "internal delegate "
65 << eolian_mono::marshall_type(true) 81 << eolian_mono::marshall_type(true)
66 << " " 82 << " "
67 << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj") 83 << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj")
@@ -76,7 +92,7 @@ struct native_function_definition_generator
76 92
77 // Delegate holder (so it can't be collected). 93 // Delegate holder (so it can't be collected).
78 if(!as_generator 94 if(!as_generator
79 (indent << "public static readonly Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<" 95 (indent << "internal static readonly Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<"
80 << string << "_api_delegate>(Module, \"" << string << "\");\n\n") 96 << string << "_api_delegate>(Module, \"" << string << "\");\n\n")
81 .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context)) 97 .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context))
82 return false; 98 return false;
@@ -108,7 +124,8 @@ struct native_function_definition_generator
108 self = ""; 124 self = "";
109 125
110 if(!as_generator 126 if(!as_generator
111 (indent << "private static " 127 (indent << "[SuppressMessage(\"Microsoft.Reliability\", \"CA2000:DisposeObjectsBeforeLosingScope\", Justification = \"The instantiated objects can be stored in the called Managed API method.\")]\n"
128 << indent << "private static "
112 << eolian_mono::marshall_type(true) << " " 129 << eolian_mono::marshall_type(true) << " "
113 << string 130 << string
114 << "(System.IntPtr obj, System.IntPtr pd" 131 << "(System.IntPtr obj, System.IntPtr pd"
@@ -165,7 +182,7 @@ struct native_function_definition_generator
165 return true; 182 return true;
166 } 183 }
167}; 184};
168 185
169struct function_definition_generator 186struct function_definition_generator
170{ 187{
171 function_definition_generator(bool do_super = false) 188 function_definition_generator(bool do_super = false)
@@ -190,7 +207,7 @@ struct function_definition_generator
190 return false; 207 return false;
191 208
192 if(!as_generator 209 if(!as_generator
193 (documentation(1)).generate(sink, f, context)) 210 (documentation(2)).generate(sink, f, context))
194 return false; 211 return false;
195 212
196 std::string self = "this.NativeHandle"; 213 std::string self = "this.NativeHandle";
@@ -203,15 +220,15 @@ struct function_definition_generator
203 self = ""; 220 self = "";
204 221
205 if(!as_generator 222 if(!as_generator
206 (scope_tab << eolian_mono::function_scope_get(f) << ((do_super && !f.is_static) ? "virtual " : "") << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ") 223 (scope_tab(2) << eolian_mono::function_scope_get(f) << ((do_super && !f.is_static) ? "virtual " : "") << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
207 << ") {\n" 224 << ") {\n"
208 << scope_tab(2) << eolian_mono::function_definition_preamble() 225 << scope_tab(3) << eolian_mono::function_definition_preamble()
209 << klass_full_native_inherit_name(f.klass) << "." << string << "_ptr.Value.Delegate(" 226 << klass_full_native_inherit_name(f.klass) << "." << string << "_ptr.Value.Delegate("
210 << self 227 << self
211 << ((!f.is_static && (f.parameters.size() > 0)) ? "," : "") 228 << ((!f.is_static && (f.parameters.size() > 0)) ? ", " : "")
212 << (argument_invocation % ", ") << ");\n" 229 << (argument_invocation % ", ") << ");\n"
213 << scope_tab(2) << eolian_mono::function_definition_epilogue() 230 << scope_tab(3) << eolian_mono::function_definition_epilogue()
214 << scope_tab(1) << "}\n\n") 231 << scope_tab(2) << "}\n\n")
215 .generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.parameters, f, f.c_name, f.parameters, f), context)) 232 .generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.parameters, f, f.c_name, f.parameters, f), context))
216 return false; 233 return false;
217 234
@@ -268,11 +285,10 @@ struct property_extension_method_definition_generator
268 if (property.setter.is_engaged()) 285 if (property.setter.is_engaged())
269 { 286 {
270 attributes::type_def prop_type = property.setter->parameters[0].type; 287 attributes::type_def prop_type = property.setter->parameters[0].type;
271 if (!as_generator(scope_tab << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<" 288 if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.Ui.ItemFactory<T> fac) where T : "
272 << name_helpers::klass_full_concrete_or_interface_name(cls) 289 << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n"
273 << ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" 290 << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(\"" << property.name << "\", fac);\n"
274 << scope_tab << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(\"" << property.name << "\", fac);\n" 291 << scope_tab(2) << "}\n\n"
275 << scope_tab << "}\n\n"
276 ).generate(sink, std::make_tuple(prop_type, prop_type), context)) 292 ).generate(sink, std::make_tuple(prop_type, prop_type), context))
277 return false; 293 return false;
278 } 294 }
@@ -285,11 +301,11 @@ struct property_extension_method_definition_generator
285 if (property.setter.is_engaged()) 301 if (property.setter.is_engaged())
286 { 302 {
287 attributes::type_def prop_type = property.setter->parameters[0].type; 303 attributes::type_def prop_type = property.setter->parameters[0].type;
288 if (!as_generator(scope_tab << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.BindablePart<T> part, Efl.Csharp.ExtensionTag<" 304 if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.BindablePart<T> part) where T : "
289 << name_helpers::klass_full_concrete_or_interface_name(cls) 305 << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n"
290 << ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" 306 << scope_tab(2) << scope_tab << "Contract.Requires(part != null, nameof(part));\n"
291 << scope_tab << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(part.PartName, \"" << property.name << "\", part.Binder);\n" 307 << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(part.PartName, \"" << property.name << "\", part.Binder);\n"
292 << scope_tab << "}\n\n" 308 << scope_tab(2) << "}\n\n"
293 ).generate(sink, std::make_tuple(prop_type, prop_type), context)) 309 ).generate(sink, std::make_tuple(prop_type, prop_type), context))
294 return false; 310 return false;
295 } 311 }
@@ -307,6 +323,199 @@ property_extension_method_definition_generator property_extension_method_definit
307 323
308struct property_wrapper_definition_generator 324struct property_wrapper_definition_generator
309{ 325{
326 template <typename OutputIterator, typename Context>
327 bool generate_get_indexer(OutputIterator sink, attributes::property_def const& property, Context const& context
328 , std::string get_scope
329 , bool is_interface) const
330 {
331 if (is_interface)
332 {
333 if (!as_generator(scope_tab(3) << get_scope << "get;\n"
334 ).generate(sink, attributes::unused, context))
335 return false;
336 }
337 else
338 {
339 if (!as_generator(scope_tab(2) << scope_tab << get_scope << "get\n"
340 << scope_tab(2) << scope_tab << "{\n"
341 << scope_tab(2) << scope_tab(2) << "var i = new "
342 << name_helpers::property_concrete_indexer_name(property) << "();\n"
343 << scope_tab(2) << scope_tab(2) << "i.Self = this;\n"
344 << scope_tab(2) << scope_tab(2) << "return i;\n"
345 << scope_tab(2) << scope_tab << "}\n"
346 ).generate(sink, attributes::unused, context))
347 return false;
348 }
349
350 return true;
351 }
352
353 template <typename OutputIterator, typename Context, typename C1, typename C2>
354 bool generate_indexer(OutputIterator sink
355 , attributes::property_def const& property
356 , Context const& context
357 , std::string scope, std::string get_scope, std::string set_scope
358 , std::string class_name
359 , C1 keys, C2 values
360 , bool is_interface
361 , bool is_concrete_for_interface
362 , bool has_setter) const
363 {
364 if (is_interface)
365 return true;
366
367 auto size_not_one = [] (std::vector<attributes::parameter_def> k) { return k.size() != 1; };
368 auto type_or_tuple
369 =
370 (
371 (
372 attribute_conditional(size_not_one)["("]
373 << (type(false) % ", ")
374 << ")"
375 )
376 | *type(false)
377 )
378 ;
379
380 std::string parentship = "\n";
381
382 bool is_self_property = *implementing_klass == *klass_from_property;
383
384 if (!(is_self_property && !is_concrete_for_interface))
385 parentship = " : " + name_helpers::property_interface_indexer_name(property, *klass_from_property) + "\n";
386
387 if (!as_generator
388 (
389 scope_tab(2) << scope << "class " << name_helpers::property_concrete_indexer_name(property) << parentship
390 << scope_tab(2) << "{\n"
391 << scope_tab(3) << "public " << class_name << " Self {get; set;}\n"
392 << scope_tab(3) << "public "
393 << type_or_tuple << " this[" << type_or_tuple <<" i]\n"
394 << scope_tab(3) << "{\n"
395 ).generate(sink, make_tuple(values, values, keys, keys), context))
396 return false;
397
398 assert (!keys.empty());
399 std::vector<std::string> get_keys;
400 if(keys.size() != 1)
401 {
402 unsigned int i = 0;
403 for (auto&& key : keys)
404 {
405 static_cast<void>(key);
406 ++i;
407 get_keys.push_back("i.Item" + std::to_string(i));
408 }
409 }
410 else
411 {
412 get_keys.push_back ("i");
413 }
414 assert (!get_keys.empty());
415
416 generate_get(sink, property, context, get_scope, get_keys, values, is_interface, "Self.");
417 if (has_setter)
418 generate_set(sink, property, context, set_scope, get_keys, values, is_interface, "Self.");
419
420 if (!as_generator
421 (
422 scope_tab(3) << "}\n"
423 << scope_tab(2) << "};\n"
424 ).generate(sink, attributes::unused, context))
425 return false;
426 return true;
427 }
428 template <typename OutputIterator, typename Context, typename CK, typename CV>
429 bool generate_set(OutputIterator sink, attributes::property_def const& property, Context const& context
430 , std::string set_scope
431 , CK keys, CV values
432 , bool is_interface
433 , std::string name_prefix = "") const
434 {
435 using efl::eolian::grammar::counter;
436 if (is_interface)
437 {
438 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set;\n"
439 ).generate(sink, attributes::unused, context))
440 return false;
441 }
442 else if (values.size() == 1)
443 {
444 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set " << "{ " << name_prefix << name_helpers::managed_method_name(*property.setter) + "(" << *(string << ",") << "value); }\n"
445 ).generate(sink, keys, context))
446 return false;
447 }
448 else if (values.size() > 1)
449 {
450 if (!as_generator(
451 scope_tab(2) << scope_tab << set_scope << "set "
452 << ("{ " << name_prefix << name_helpers::managed_method_name(*property.setter) + "(")
453 << *(string << ",") << ((" value.Item" << counter(1)) % ", ")
454 << "); }\n"
455 ).generate(sink, std::make_tuple(keys, values), context))
456 return false;
457 }
458 return true;
459 }
460 template <typename OutputIterator, typename Context, typename CK, typename CV>
461 bool generate_get(OutputIterator sink, attributes::property_def const& property, Context const& context
462 , std::string get_scope
463 , CK keys, CV values
464 , bool is_interface
465 , std::string name_prefix = "") const
466 {
467 using efl::eolian::grammar::attribute_reorder;
468 using efl::eolian::grammar::attributes::parameter_direction;
469 using efl::eolian::grammar::attributes::parameter_def;
470
471 if (is_interface) // only declaration
472 {
473 if (!as_generator(scope_tab(2) << scope_tab << get_scope << "get;\n"
474 ).generate(sink, attributes::unused, context))
475 return false;
476 }
477 else
478 if (/*has_getter && */values.size() == 1)
479 {
480 if (!as_generator
481 (scope_tab(2) << scope_tab << get_scope
482 << "get " << "{ return " << name_prefix << name_helpers::managed_method_name(*property.getter)
483 << "(" << (string % ",") << "); }\n"
484 ).generate(sink, keys, context))
485 return false;
486 }
487 else if (/*has_getter && */values.size() > 1)
488 {
489 if (!as_generator
490 (scope_tab(2) << scope_tab << get_scope << "get "
491 << "{\n"
492 << *attribute_reorder<1, -1, 1>
493 (scope_tab(4) << type(true) << " _out_"
494 << argument(false) << " = default(" << type(true) << ");\n"
495 )
496 << scope_tab(4) << name_prefix << name_helpers::managed_method_name(*property.getter)
497 << "(" << *(string << ",") << (("out _out_" << argument(false)) % ", ") << ");\n"
498 << scope_tab(4) << "return (" << (("_out_"<< argument(false)) % ", ") << ");\n"
499 << scope_tab(3) << "}" << "\n"
500 ).generate(sink, std::make_tuple(values, keys, values, values), context))
501 return false;
502 }
503 // else if (values.size() == 1)
504 // {
505 // if (!as_generator
506 // (scope_tab << scope_tab << get_scope << "get "
507 // << "{\n"
508 // << *attribute_reorder<1, -1, 1>(scope_tab(3) << type(true) << " _out_" << argument(false) << " = default(" << type(true) << ");\n")
509 // << scope_tab(3) << name_prefix << name_helpers::managed_method_name(*property.getter)
510 // << "(" << *(string << ",") << (("out _out_" << argument(false)) % ",") << ");\n"
511 // << scope_tab(3) << "return " << (("_out_"<< argument(false)) % ",") << ";\n"
512 // << scope_tab(2) << "}" << "\n"
513 // ).generate(sink, std::make_tuple(values, keys, values, values), context))
514 // return false;
515 // }
516 return true;
517 }
518
310 template<typename OutputIterator, typename Context> 519 template<typename OutputIterator, typename Context>
311 bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const 520 bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
312 { 521 {
@@ -315,103 +524,127 @@ struct property_wrapper_definition_generator
315 using efl::eolian::grammar::attributes::parameter_direction; 524 using efl::eolian::grammar::attributes::parameter_direction;
316 using efl::eolian::grammar::attributes::parameter_def; 525 using efl::eolian::grammar::attributes::parameter_def;
317 526
318 if (blacklist::is_property_blacklisted(property, *implementing_klass, context)) 527 /// C(k) = keys count, C(v) = values count
319 return true; 528 /// /------------\ /------\.
529 /// |blacklisted?|---yes-----| skip |--------------\.
530 /// \------------/ \------/ |
531 /// | | |
532 /// no yes |
533 /// | | |
534 /// /---------\ /------------\ |
535 /// |is-static|----yes-----|is-interface| |
536 /// \---------/ \------------/ |
537 /// | | |
538 /// no no |
539 /// | | |
540 /// /--------\ /-----------\ |
541 /// |has-get?|---no-conc---|is-concrete|-----yes---/
542 /// \--------/ \-----------/
543 /// / \.
544 /// no yes
545 /// / \.
546 /// /----\ /--------------------------------------\.
547 /// |skip|-yes-|explicit return != Eina.Error or void |
548 /// \----/ \--------------------------------------/
549 /// |
550 /// no
551 /// |
552 /// /--------\.
553 /// |has-set?|
554 /// \--------/
555 /// / \.
556 /// no yes
557 /// / \.
558 /// /------\ /--------------------------------------\.
559 /// /------------------|no-set| |explicit return != Eina.Error or void |---- yes --\.
560 /// | \------/ \--------------------------------------/ |
561 /// | \------------|----------------------------------------------/
562 /// | no
563 /// | |
564 /// | /--------\.
565 /// | |has-both|
566 /// | \--------/
567 /// | |
568 /// | /-------------------\.
569 /// | |set-keys = get-keys|
570 /// | \-------------------/
571 /// | / |
572 /// | no |
573 /// | / |
574 /// | /----\ /-----------------------\.
575 /// | |skip|--no---|set-values = get-values|
576 /// | \----/ \-----------------------/
577 /// | /
578 /// | yes
579 /// | /
580 /// | /--------\.
581 /// \-------------------------| keys |
582 /// \--------/
583 /// / \.
584 /// 0 >0
585 /// / \.
586 /// /----------\ /----------\.
587 /// |no-indexer| | keys > 1 |
588 /// \----------/ \----------/
589 /// | / |
590 /// | no yes
591 /// | / |
592 /// | / |
593 /// | /---------\ /-------------------\.
594 /// | | indexer | | indexer tuple key |
595 /// | \---------/ \-------------------/
596 /// | / |
597 /// /--------\ |
598 /// | values |----------/
599 /// \--------/
600 /// / \.
601 /// 1 >1
602 /// / \.
603 /// /----------------\ /-------------\.
604 /// | no tuple value | | tuple value |
605 /// \----------------/ \-------------/
606 ///
607
608 auto has_wrapper = helpers::has_property_wrapper (property, implementing_klass, context);
609 bool has_getter = has_wrapper & helpers::has_property_wrapper_bit::has_getter;
610 if (!has_getter) return true;
611 bool has_setter = has_wrapper & helpers::has_property_wrapper_bit::has_setter;
612 bool has_indexer = has_wrapper & helpers::has_property_wrapper_bit::has_indexer;
320 613
321 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface; 614 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
322 bool is_static = (property.getter.is_engaged() && property.getter->is_static) 615 bool is_static = (property.getter.is_engaged() && property.getter->is_static)
323 || (property.setter.is_engaged() && property.setter->is_static); 616 || (property.setter.is_engaged() && property.setter->is_static);
324 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete; 617 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
618 bool is_concrete_for_interface = is_concrete
619 && (implementing_klass->type == attributes::class_type::interface_
620 || implementing_klass->type == attributes::class_type::mixin);
325 621
326 622 //if (name_helpers::klass_concrete_or_interface_name (*implementing_klass) == "IMapping")
327 if ((is_concrete || is_interface) && is_static) 623 if (false)
328 return true;
329
330 auto get_params = property.getter.is_engaged() ? property.getter->parameters.size() : 0;
331 //auto set_params = property.setter.is_engaged() ? property.setter->parameters.size() : 0;
332
333 // C# properties must have a single value.
334 //
335 // Single values in getters are automatically converted to return_type,
336 // meaning they should have 0 parameters.
337 //
338 // For setters, we ignore the return type - usually boolean.
339 // if (get_params > 0 || set_params > 1)
340 // return true;
341
342 if (property.getter
343 && std::find_if (property.getter->parameters.begin()
344 , property.getter->parameters.end()
345 , [] (parameter_def const& p)
346 {
347 return p.direction != parameter_direction::out;
348 }) != property.getter->parameters.end())
349 return true;
350 if (property.setter
351 && std::find_if (property.setter->parameters.begin()
352 , property.setter->parameters.end()
353 , [] (parameter_def const& p)
354 {
355 return p.direction != parameter_direction::in;
356 }) != property.setter->parameters.end())
357 return true;
358
359 if (property.getter && property.setter)
360 { 624 {
361 if (get_params != 0 && property.setter->parameters.size() != property.getter->parameters.size()) 625 if (!as_generator(grammar::lit("/// is interface ") << (int)is_interface
362 return true; 626 << " is static " << (int)is_static
627 << " is concrete " << (int)is_concrete
628 << " is concrete_for_interface " << (int)is_concrete_for_interface
629 << " klass_from_property->type " << (int)klass_from_property->type
630 << " has_setter " << (int)has_setter
631 << " property.setter->explicit_return_type != attributes::void_ " << (property.setter && property.setter->explicit_return_type != attributes::void_)
632 << " property.setter->keys != property.getter->keys " << (property.setter && property.setter->keys != property.getter->keys)
633 << " property.setter->values != property.getter->values " << (property.setter && property.setter->values != property.getter->values)
634 << " has_setter && property.setter->scope != attributes::member_scope::scope_public " << (property.setter && property.setter->scope != attributes::member_scope::scope_public)
635 << "\n")
636 .generate (sink, attributes::unused, context))
637 return false;
363 } 638 }
364 639
365 std::vector<attributes::parameter_def> parameters; 640 if (blacklist::is_property_blacklisted(property, context))
366 641 return true;
367 if (property.setter.is_engaged())
368 {
369 std::transform (property.setter->parameters.begin(), property.setter->parameters.end()
370 , std::back_inserter(parameters)
371 , [] (parameter_def p) -> parameter_def
372 {
373 //p.direction = efl::eolian::attributes::parameter_direction::in;
374 return p;
375 });
376 }
377 else if (property.getter.is_engaged())
378 {
379 // if getter has parameters, then we ignore return type, otherwise
380 // we use the return type.
381 if (get_params == 0)
382 parameters.push_back({parameter_direction::in
383 , property.getter->return_type, "propertyResult", {}
384 , property.getter->unit});
385 else
386 std::transform (property.getter->parameters.begin(), property.getter->parameters.end()
387 , std::back_inserter(parameters)
388 , [] (parameter_def p) -> parameter_def
389 {
390 p.direction = parameter_direction::in;
391 return p;
392 });
393 }
394 else
395 {
396 EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Property must have either a getter or a setter." << std::endl;
397 return false;
398 }
399
400 std::string dir_mod;
401 if (property.setter.is_engaged())
402 dir_mod = direction_modifier(property.setter->parameters[0]);
403 642
404 std::string managed_name = name_helpers::property_managed_name(property); 643 std::string managed_name = name_helpers::property_managed_name(property);
405 644
406 std::string scope = "public "; 645 std::string scope = "public ";
407 std::string get_scope = property.getter.is_engaged() ? eolian_mono::function_scope_get(*property.getter) : ""; 646 std::string get_scope = eolian_mono::function_scope_get(*property.getter);
408 bool is_get_public = get_scope == "public "; 647 std::string set_scope = has_setter ? eolian_mono::function_scope_get(*property.setter) : "";
409 std::string set_scope = property.setter.is_engaged() ? eolian_mono::function_scope_get(*property.setter) : "";
410 bool is_set_public = set_scope == "public ";
411
412 // No need to generate this wrapper as no accessor is public.
413 if (is_interface && (!is_get_public && !is_set_public))
414 return true;
415 648
416 // C# interface members are declared automatically as public 649 // C# interface members are declared automatically as public
417 if (is_interface) 650 if (is_interface)
@@ -426,114 +659,104 @@ struct property_wrapper_definition_generator
426 get_scope = ""; 659 get_scope = "";
427 set_scope = ""; 660 set_scope = "";
428 } 661 }
429 else if (!property.setter.is_engaged() || (get_scope == scope)) 662 else if (!has_setter || (get_scope == scope))
430 { 663 {
431 scope = get_scope; 664 scope = get_scope;
432 get_scope = ""; 665 get_scope = "";
433 } 666 }
434 else if (!property.getter.is_engaged() || (set_scope == scope)) 667
668 std::string virtual_mod = (is_static || is_interface || is_concrete) ? "" : "virtual ";
669
670 auto keys = property.getter->keys;
671 auto values = property.getter->values;
672 auto generated_values = values;
673 auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
674
675 if (has_indexer)
676 {
677 assert (!!implementing_klass);
678 generate_indexer (sink, property, context, scope, get_scope, set_scope
679 , klass_name, keys, values
680 , is_interface, is_concrete_for_interface, has_setter);
681
682 generated_values.clear();
683 if (!is_interface && *implementing_klass == *klass_from_property
684 && !is_concrete_for_interface)
435 { 685 {
436 scope = set_scope; 686 generated_values.push_back
437 set_scope = ""; 687 (attributes::parameter_def
688 {parameter_direction::in
689 , attributes::type_def
690 {
691 attributes::regular_type_def{name_helpers::property_concrete_indexer_name(property), {attributes::qualifier_info::is_none, ""}, {}}
692 , name_helpers::property_concrete_indexer_name(property)
693 , false, false, false, ""
694 }
695 , "indexer", {}, nullptr
696 });
697 }
698 else
699 {
700 generated_values.push_back
701 (attributes::parameter_def
702 {parameter_direction::in
703 , attributes::type_def
704 {
705 attributes::regular_type_def{name_helpers::klass_full_concrete_or_interface_name (*klass_from_property) + managed_name + "Indexer", {attributes::qualifier_info::is_none, ""}, {}}
706 , name_helpers::property_interface_indexer_name(property, *klass_from_property)
707 , false, false, false, ""
708 }
709 , "indexer", {}, nullptr
710 });
438 } 711 }
712 }
439 713
440 if (parameters.size() == 1) 714 if (generated_values.size() == 1)
441 { 715 {
442 if (!as_generator( 716 if (!as_generator(
443 documentation(1) 717 documentation(2)
444 << scope_tab << scope << (is_static ? "static " : "") << type(true) << " " << managed_name << " {\n" 718 << scope_tab(2) << scope << (is_static ? "static " : virtual_mod) << type(true) << " " << managed_name << " {\n"
445 ).generate(sink, std::make_tuple(property, parameters[0].type), context)) 719 ).generate(sink, std::make_tuple(property, generated_values[0].type), context))
446 return false; 720 return false;
447 } 721 }
448 else 722 else
449 { 723 {
450 if (!as_generator 724 if (!as_generator
451 ( 725 (
452 documentation(1) 726 documentation(2)
453 << scope_tab << scope << (is_static ? "static (" : "(") 727 << scope_tab(2) << scope << (is_static ? "static (" : "(")
454 << (attribute_reorder<1, -1>(type(true) /*<< " " << argument*/) % ", ") << ") " 728 << (attribute_reorder<1, -1>(type(true) /*<< " " << argument*/) % ", ") << ") "
455 << managed_name << " {\n" 729 << managed_name << " {\n"
456 ).generate(sink, std::make_tuple(property, parameters), context)) 730 ).generate(sink, std::make_tuple(property, generated_values), context))
457 return false; 731 return false;
458 } 732 }
459 733
460 if (property.getter.is_engaged() && is_interface) 734 if (has_indexer)
461 { 735 {
462 if (is_get_public) 736 generate_get_indexer (sink, property, context, get_scope, is_interface);
463 if (!as_generator(scope_tab << scope_tab << set_scope << "get;\n"
464 ).generate(sink, attributes::unused, context))
465 return false;
466 } 737 }
467 else if (property.getter.is_engaged() && get_params == 0/*parameters.size() == 1 && property.getter.is_engaged()*/) 738 else
468 {
469 if (!as_generator
470 (scope_tab << scope_tab << get_scope
471 << "get " << "{ return " + name_helpers::managed_method_name(*property.getter) + "(); }\n"
472 ).generate(sink, attributes::unused, context))
473 return false;
474 }
475 else if (parameters.size() >= 1 && property.getter)
476 { 739 {
477 if (!as_generator 740 std::vector<std::string> empty_keys;
478 (scope_tab << scope_tab << get_scope << "get " 741 generate_get(sink, property, context, get_scope, empty_keys, values, is_interface);
479 << "{\n"
480 << *attribute_reorder<1, -1, 1>
481 (scope_tab(3) << type(true) << " _out_"
482 << argument(false) << " = default(" << type(true) << ");\n"
483 )
484 << scope_tab(3) << name_helpers::managed_method_name(*property.getter)
485 << "(" << (("out _out_" << argument(false)) % ",") << ");\n"
486 << scope_tab(3) << "return (" << (("_out_"<< argument(false)) % ",") << ");\n"
487 << scope_tab(2) << "}" << "\n"
488 ).generate(sink, std::make_tuple(parameters, parameters, parameters), context))
489 return false;
490 }
491 // else if (parameters.size() == 1)
492 // {
493 // if (!as_generator
494 // (scope_tab << scope_tab << get_scope << "get "
495 // << "{\n"
496 // << *attribute_reorder<1, -1, 1>(scope_tab(3) << type(true) << " _out_" << argument(false) << " = default(" << type(true) << ");\n")
497 // << scope_tab(3) << name_helpers::managed_method_name(*property.getter)
498 // << "(" << (("out _out_" << argument(false)) % ",") << ");\n"
499 // << scope_tab(3) << "return " << (("_out_"<< argument(false)) % ",") << ";\n"
500 // << scope_tab(2) << "}" << "\n"
501 // ).generate(sink, std::make_tuple(parameters, parameters, parameters), context))
502 // return false;
503 // }
504 742
505 if (property.setter.is_engaged() && is_interface) 743 if (has_setter)
506 { 744 generate_set (sink, property, context, set_scope, empty_keys, values, is_interface);
507 if (is_set_public)
508 if (!as_generator(scope_tab << scope_tab << set_scope << "set;\n"
509 ).generate(sink, attributes::unused, context))
510 return false;
511 }
512 else if (parameters.size() == 1 && property.setter.is_engaged())
513 {
514 if (!as_generator(scope_tab << scope_tab << set_scope << "set " << "{ " + name_helpers::managed_method_name(*property.setter) + "(" + dir_mod + "value); }\n"
515 ).generate(sink, attributes::unused, context))
516 return false;
517 }
518 else if (parameters.size() > 1 && property.setter.is_engaged())
519 {
520 if (!as_generator(scope_tab << scope_tab << set_scope << "set " << ("{ " + name_helpers::managed_method_name(*property.setter) + "(" + dir_mod) << ((" value.Item" << counter(1)) % ", ") << "); }" << "\n"
521 ).generate(sink, parameters, context))
522 return false;
523 } 745 }
524 746
525 if (!as_generator(scope_tab << "}\n\n").generate(sink, attributes::unused, context)) 747 if (!as_generator(scope_tab(2) << "}\n\n").generate(sink, attributes::unused, context))
526 return false; 748 return false;
527 749
528 return true; 750 return true;
529 } 751 }
530 attributes::klass_def const* implementing_klass; 752 attributes::klass_def const* implementing_klass, *klass_from_property;
531}; 753};
532struct property_wrapper_definition_parameterized 754struct property_wrapper_definition_parameterized
533{ 755{
534 property_wrapper_definition_generator operator()(attributes::klass_def const& klass) const 756 property_wrapper_definition_generator operator()(attributes::klass_def const& klass
757 , attributes::klass_def const& prop_from_klass) const
535 { 758 {
536 return {&klass}; 759 return {&klass, &prop_from_klass};
537 } 760 }
538} const property_wrapper_definition; 761} const property_wrapper_definition;
539property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized) 762property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized)
@@ -541,6 +764,45 @@ property_wrapper_definition_generator as_generator(property_wrapper_definition_p
541 return {}; 764 return {};
542} 765}
543 766
767struct interface_property_indexer_definition_generator
768{
769 template<typename OutputIterator, typename Context>
770 bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
771 {
772 using efl::eolian::grammar::attribute_reorder;
773 using efl::eolian::grammar::counter;
774 using efl::eolian::grammar::attributes::parameter_direction;
775 using efl::eolian::grammar::attributes::parameter_def;
776
777 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
778
779 assert (is_interface);
780 auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
781 std::string managed_name = name_helpers::property_managed_name(property);
782
783 if (!as_generator
784 (scope_tab << "public interface " << name_helpers::property_interface_indexer_short_name(property, *implementing_klass) << "\n"
785 << scope_tab << "{\n"
786 << scope_tab << "}\n"
787 ).generate (sink, attributes::unused, context))
788 return false;
789
790 return true;
791 }
792 attributes::klass_def const* implementing_klass;
793};
794struct interface_property_indexer_definition_parameterized
795{
796 interface_property_indexer_definition_generator operator()(attributes::klass_def const& klass) const
797 {
798 return {&klass};
799 }
800} const interface_property_indexer_definition;
801interface_property_indexer_definition_generator as_generator(interface_property_indexer_definition_parameterized)
802{
803 return {};
804}
805
544} 806}
545 807
546namespace efl { namespace eolian { namespace grammar { 808namespace efl { namespace eolian { namespace grammar {
@@ -556,6 +818,10 @@ struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator>
556template <> 818template <>
557struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {}; 819struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
558template <> 820template <>
821struct is_eager_generator< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::true_type {};
822template <>
823struct is_eager_generator< ::eolian_mono::interface_property_indexer_definition_generator> : std::true_type {};
824template <>
559struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {}; 825struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
560template <> 826template <>
561struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {}; 827struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
@@ -567,6 +833,10 @@ template <>
567struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 833struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
568template <> 834template <>
569struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {}; 835struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
836template <>
837struct is_generator< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::true_type {};
838template <>
839struct is_generator< ::eolian_mono::interface_property_indexer_definition_generator> : std::true_type {};
570 840
571namespace type_traits { 841namespace type_traits {
572template <> 842template <>
@@ -585,8 +855,13 @@ template <>
585struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {}; 855struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
586template <> 856template <>
587struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {}; 857struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {};
858
859template <>
860struct attributes_needed< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::integral_constant<int, 1> {};
861template <>
862struct attributes_needed< ::eolian_mono::interface_property_indexer_definition_generator> : std::integral_constant<int, 1> {};
588} 863}
589 864
590} } } 865} } }
591 866
592#endif 867#endif
diff --git a/src/bin/eolian_mono/eolian/mono/function_helpers.hh b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
index 26146f7..a70df96 100644
--- a/src/bin/eolian_mono/eolian/mono/function_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_FUNCTION_DEFINITION_HELPERS_HH 16#ifndef EOLIAN_MONO_FUNCTION_DEFINITION_HELPERS_HH
2#define EOLIAN_MONO_FUNCTION_DEFINITION_HELPERS_HH 17#define EOLIAN_MONO_FUNCTION_DEFINITION_HELPERS_HH
3 18
@@ -102,7 +117,7 @@ struct function_definition_epilogue_generator
102 "Eina.Error.RaiseIfUnhandledException();\n" 117 "Eina.Error.RaiseIfUnhandledException();\n"
103 << *(convert_out_assign) 118 << *(convert_out_assign)
104 << *(convert_in_ptr_assign) 119 << *(convert_in_ptr_assign)
105 << scope_tab(2) << convert_return << "\n" 120 << scope_tab(3) << convert_return << "\n"
106 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context)) 121 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context))
107 return false; 122 return false;
108 123
@@ -172,6 +187,11 @@ inline std::string function_scope_get(attributes::function_def const& f)
172 case attributes::member_scope::scope_private: 187 case attributes::member_scope::scope_private:
173 return "private "; 188 return "private ";
174 case attributes::member_scope::scope_protected: 189 case attributes::member_scope::scope_protected:
190 // Efl.Part.part.get is protected in C to force developers to use `efl_part`.
191 // There is no such restriction in C# as the binding takes care of the returned
192 // object lifetime.
193 if (f.c_name == "efl_part_get")
194 return "public ";
175 return "protected "; 195 return "protected ";
176 case attributes::member_scope::scope_unknown: 196 case attributes::member_scope::scope_unknown:
177 // This should trigger a compilation error 197 // This should trigger a compilation error
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 721368f..3b50403 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_FUNCTION_POINTER_HPP 16#ifndef EOLIAN_MONO_FUNCTION_POINTER_HPP
2#define EOLIAN_MONO_FUNCTION_POINTER_HPP 17#define EOLIAN_MONO_FUNCTION_POINTER_HPP
3 18
@@ -51,19 +66,19 @@ struct function_pointer {
51 return false; 66 return false;
52 // "Internal" delegate, 1-to-1 with the Unamaged function type 67 // "Internal" delegate, 1-to-1 with the Unamaged function type
53 if (!as_generator(marshall_annotation(true) 68 if (!as_generator(marshall_annotation(true)
54 << "public delegate " << marshall_type(true) << " " << string // public? 69 << "internal delegate " << marshall_type(true) << " " << string // public?
55 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ");\n") 70 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ");\n")
56 .generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx)) 71 .generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx))
57 return false; 72 return false;
58 73
59 // Wrapper type, with callback matching the Unamanaged one 74 // Wrapper type, with callback matching the Unamanaged one
60 if (!as_generator("internal class " << f_name << "Wrapper : IDisposable\n" 75 if (!as_generator("internal class " << f_name << "Wrapper\n"
61 << "{\n\n" 76 << "{\n\n"
62 << scope_tab << "private " << f_name << "Internal _cb;\n" 77 << scope_tab << "private " << f_name << "Internal _cb;\n"
63 << scope_tab << "private IntPtr _cb_data;\n" 78 << scope_tab << "private IntPtr _cb_data;\n"
64 << scope_tab << "private EinaFreeCb _cb_free_cb;\n\n" 79 << scope_tab << "private Eina.Callbacks.EinaFreeCb _cb_free_cb;\n\n"
65 80
66 << scope_tab << "internal " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, EinaFreeCb _cb_free_cb)\n" 81 << scope_tab << "internal " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, Eina.Callbacks.EinaFreeCb _cb_free_cb)\n"
67 << scope_tab << "{\n" 82 << scope_tab << "{\n"
68 << scope_tab << scope_tab << "this._cb = _cb;\n" 83 << scope_tab << scope_tab << "this._cb = _cb;\n"
69 << scope_tab << scope_tab << "this._cb_data = _cb_data;\n" 84 << scope_tab << scope_tab << "this._cb_data = _cb_data;\n"
@@ -72,34 +87,13 @@ struct function_pointer {
72 87
73 << scope_tab << "~" << f_name << "Wrapper()\n" 88 << scope_tab << "~" << f_name << "Wrapper()\n"
74 << scope_tab << "{\n" 89 << scope_tab << "{\n"
75 << scope_tab << scope_tab << "Dispose(false);\n"
76 << scope_tab << "}\n\n"
77
78 << scope_tab << "protected virtual void Dispose(bool disposing)\n"
79 << scope_tab << "{\n"
80 << scope_tab << scope_tab << "if (this._cb_free_cb != null)\n" 90 << scope_tab << scope_tab << "if (this._cb_free_cb != null)\n"
81 << scope_tab << scope_tab << "{\n" 91 << scope_tab << scope_tab << "{\n"
82 << scope_tab << scope_tab << scope_tab << "if (disposing)\n" 92 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.ThreadSafeFreeCbExec(this._cb_free_cb, this._cb_data);\n"
83 << scope_tab << scope_tab << scope_tab << "{\n"
84 << scope_tab << scope_tab << scope_tab << scope_tab << "this._cb_free_cb(this._cb_data);\n"
85 << scope_tab << scope_tab << scope_tab << "}\n"
86 << scope_tab << scope_tab << scope_tab << "else\n"
87 << scope_tab << scope_tab << scope_tab << "{\n"
88 << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.ThreadSafeFreeCbExec(this._cb_free_cb, this._cb_data);\n"
89 << scope_tab << scope_tab << scope_tab << "}\n"
90 << scope_tab << scope_tab << scope_tab << "this._cb_free_cb = null;\n"
91 << scope_tab << scope_tab << scope_tab << "this._cb_data = IntPtr.Zero;\n"
92 << scope_tab << scope_tab << scope_tab << "this._cb = null;\n"
93 << scope_tab << scope_tab << "}\n" 93 << scope_tab << scope_tab << "}\n"
94 << scope_tab << "}\n\n" 94 << scope_tab << "}\n\n"
95 95
96 << scope_tab << "public void Dispose()\n" 96 << scope_tab << "internal " << type << " ManagedCb(" << (parameter % ", ") << ")\n"
97 << scope_tab << "{\n"
98 << scope_tab << scope_tab << "Dispose(true);\n"
99 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
100 << scope_tab << "}\n\n"
101
102 << scope_tab << "internal " << type << " ManagedCb(" << (parameter % ",") << ")\n"
103 << scope_tab << "{\n" 97 << scope_tab << "{\n"
104 << function_definition_preamble << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n" 98 << function_definition_preamble << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n"
105 << function_definition_epilogue 99 << function_definition_epilogue
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index cdcb903..bef9e21 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_FUNCTION_REGISTRATION_HH 16#ifndef EOLIAN_MONO_FUNCTION_REGISTRATION_HH
2#define EOLIAN_MONO_FUNCTION_REGISTRATION_HH 17#define EOLIAN_MONO_FUNCTION_REGISTRATION_HH
3 18
@@ -49,7 +64,7 @@ struct function_registration_generator
49 return false; 64 return false;
50 65
51 if(!as_generator( 66 if(!as_generator(
52 indent << "if (methods.FirstOrDefault(m => m.Name == \"" << string << "\") != null)\n" 67 indent << "if (methods.Contains(\"" << string << "\"))\n"
53 << indent << "{\n" 68 << indent << "{\n"
54 << indent << scope_tab << "descs.Add(new EflOpDescription() {" 69 << indent << scope_tab << "descs.Add(new EflOpDescription() {"
55#ifdef _WIN32 70#ifdef _WIN32
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index 985e373..2ac16b0 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -1,6 +1,23 @@
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 */
1#ifndef EOLIAN_MONO_GENERATION_CONTEXTS_HH 16#ifndef EOLIAN_MONO_GENERATION_CONTEXTS_HH
2#define EOLIAN_MONO_GENERATION_CONTEXTS_HH 17#define EOLIAN_MONO_GENERATION_CONTEXTS_HH
3 18
19#include <map>
20
4#include "grammar/context.hpp" 21#include "grammar/context.hpp"
5#include "grammar/indentation.hpp" 22#include "grammar/indentation.hpp"
6 23
@@ -9,6 +26,7 @@ namespace eolian_mono {
9struct class_context 26struct class_context
10{ 27{
11 enum wrapper_kind { 28 enum wrapper_kind {
29 none,
12 interface, 30 interface,
13 concrete, 31 concrete,
14 inherit, 32 inherit,
@@ -92,6 +110,12 @@ struct options_context {
92 std::string examples_dir; 110 std::string examples_dir;
93}; 111};
94 112
113template<typename Context>
114bool context_want_beta(Context const& context)
115{
116 return efl::eolian::grammar::context_find_tag<options_context>(context).want_beta;
117}
118
95} 119}
96 120
97#endif 121#endif
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 5c1db6d..049f263 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -1,7 +1,23 @@
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 */
1#ifndef EOLIAN_MONO_HELPERS_HH 16#ifndef EOLIAN_MONO_HELPERS_HH
2#define EOLIAN_MONO_HELPERS_HH 17#define EOLIAN_MONO_HELPERS_HH
3 18
4#include "grammar/klass_def.hpp" 19#include "grammar/klass_def.hpp"
20#include "grammar/context.hpp"
5#include "blacklist.hh" 21#include "blacklist.hh"
6#include "generation_contexts.hh" 22#include "generation_contexts.hh"
7#include "name_helpers.hh" 23#include "name_helpers.hh"
@@ -290,6 +306,106 @@ inline std::vector<attributes::constructor_def> reorder_constructors(std::vector
290 return constructors; 306 return constructors;
291} 307}
292 308
309enum class has_property_wrapper_bit
310{
311 has_none = 0
312 , has_getter = 1 << 0
313 , has_setter = 1 << 1
314 , has_indexer = 1 << 2
315 , has_key_tuple = 1 << 3
316 , has_value_tuple = 1 << 4
317 , has_set_error_check = 1 << 5
318 , has_get_error_check = 1 << 6
319};
320
321has_property_wrapper_bit& operator|=(has_property_wrapper_bit& self, has_property_wrapper_bit bit)
322{
323 self = static_cast<has_property_wrapper_bit>(static_cast<int>(self) | static_cast<int>(bit));
324 return self;
325}
326
327bool operator&(has_property_wrapper_bit self, has_property_wrapper_bit bit)
328{
329 return static_cast<int>(self) & static_cast<int>(bit);
330}
331
332template <typename Context>
333has_property_wrapper_bit has_property_wrapper(attributes::property_def const& property, attributes::klass_def const* implementing_klass
334 , Context const& context)
335{
336 using efl::eolian::grammar::context_find_tag;
337 has_property_wrapper_bit r = has_property_wrapper_bit::has_none;
338
339 if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
340 return r;
341
342 bool has_getter = property.getter.is_engaged();
343 bool has_setter = property.setter.is_engaged();
344
345 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
346 bool is_static = (property.getter.is_engaged() && property.getter->is_static)
347 || (has_setter && property.setter->is_static);
348 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
349
350 if (is_static)
351 {
352 if (is_interface) return r;
353 else if (is_concrete) return r;
354 }
355
356 // EINA_LOG_ERR("Generating property %s", name_helpers::property_managed_name(property).c_str());
357 // C# interface can have only
358 if (is_interface)
359 {
360 has_getter = has_getter && property.getter->scope == attributes::member_scope:: scope_public;
361 }
362
363 if (!has_getter)
364 {
365 return r;
366 }
367
368 if (property.getter->explicit_return_type != attributes::void_)
369 {
370 return r;
371 }
372 else if (has_setter)
373 {
374 if (property.setter->explicit_return_type != attributes::void_)
375 has_setter = false; // do not generate setter
376 else if (property.setter->keys != property.getter->keys)
377 has_setter = false;
378 else if (property.setter->values != property.getter->values)
379 has_setter = false;
380 }
381
382 if (is_interface)
383 {
384 if (property.getter->scope != attributes::member_scope::scope_public)
385 return r;
386 else if (has_setter && property.setter->scope != attributes::member_scope::scope_public)
387 has_setter = false;
388 }
389
390 if (has_getter)
391 r |= has_property_wrapper_bit::has_getter;
392 if (has_setter)
393 r |= has_property_wrapper_bit::has_setter;
394
395 if (property.getter->keys.size() == 1)
396 r |= has_property_wrapper_bit::has_indexer;
397 else if (property.getter->keys.size() > 1)
398 {
399 r |= has_property_wrapper_bit::has_indexer;
400 r |= has_property_wrapper_bit::has_key_tuple;
401 }
402
403 if (property.getter->values.size() > 1)
404 r |= has_property_wrapper_bit::has_value_tuple;
405
406 return r;
407}
408
293} // namespace helpers 409} // namespace helpers
294 410
295} // namespace eolian_mono 411} // namespace eolian_mono
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 65645d3..7fe60f0 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_CLASS_DEFINITION_HPP 16#ifndef EOLIAN_MONO_CLASS_DEFINITION_HPP
2#define EOLIAN_MONO_CLASS_DEFINITION_HPP 17#define EOLIAN_MONO_CLASS_DEFINITION_HPP
3 18
@@ -91,21 +106,25 @@ struct klass
91 name_helpers::klass_full_concrete_or_interface_name(cls)}, 106 name_helpers::klass_full_concrete_or_interface_name(cls)},
92 context); 107 context);
93 108
94 if(!as_generator(documentation).generate(sink, cls, iface_cxt)) 109 // Property wrappers
110 if (!as_generator(*(interface_property_indexer_definition(cls))).generate(sink, cls.properties, iface_cxt))
111 return false;
112
113 if(!as_generator(documentation(1)).generate(sink, cls, iface_cxt))
95 return false; 114 return false;
96 115
97 // Mark the interface with the proper native Efl_Class* getter 116 // Mark the interface with the proper native Efl_Class* getter
98 if(!as_generator(lit("[") << name_helpers::klass_full_native_inherit_name(cls) << "]\n") 117 if(!as_generator(scope_tab << lit("[") << name_helpers::klass_full_native_inherit_name(cls) << "]\n")
99 .generate(sink, attributes::unused, iface_cxt)) 118 .generate(sink, attributes::unused, iface_cxt))
100 return false; 119 return false;
101 120
102 if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt)) 121 if(!as_generator(scope_tab << "[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
103 return false; 122 return false;
104 123
105 using efl::eolian::grammar::lit; 124 using efl::eolian::grammar::lit;
106 if(!as_generator 125 if(!as_generator
107 ( 126 (
108 lit("public ") << (is_partial ? "partial ":"") 127 scope_tab << lit("public ") << (is_partial ? "partial ":"")
109 /*<< class_type*/ << "interface" /*<<*/ " " << string << " : " 128 /*<< class_type*/ << "interface" /*<<*/ " " << string << " : "
110 ) 129 )
111 .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt)) 130 .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
@@ -117,14 +136,14 @@ struct klass
117 continue; 136 continue;
118 137
119 if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_) 138 if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_)
120 if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt)) 139 if(!as_generator("\n" << scope_tab << string << ",").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
121 return false; 140 return false;
122 } 141 }
123 142
124 if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt)) 143 if(!as_generator("\n" << scope_tab(2) << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt))
125 return false; 144 return false;
126 145
127 if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt)) 146 if(!as_generator("\n" << scope_tab << "{\n").generate(sink, attributes::unused, iface_cxt))
128 return false; 147 return false;
129 148
130 if(!as_generator(*(function_declaration)).generate(sink, cls.functions, iface_cxt)) 149 if(!as_generator(*(function_declaration)).generate(sink, cls.functions, iface_cxt))
@@ -138,16 +157,16 @@ struct klass
138 157
139 for (auto &&p : cls.parts) 158 for (auto &&p : cls.parts)
140 if (!as_generator( 159 if (!as_generator(
141 documentation(1) 160 documentation(2)
142 << name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n" 161 << name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n"
143 ).generate(sink, p, iface_cxt)) 162 ).generate(sink, p, iface_cxt))
144 return false; 163 return false;
145 164
146 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, iface_cxt)) 165 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, iface_cxt))
147 return false; 166 return false;
148 167
149 // End of interface declaration 168 // End of interface declaration
150 if(!as_generator("}\n\n").generate(sink, attributes::unused, iface_cxt)) return false; 169 if(!as_generator(scope_tab << "}\n\n").generate(sink, attributes::unused, iface_cxt)) return false;
151 } 170 }
152 171
153 // Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events. 172 // Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events.
@@ -185,12 +204,12 @@ struct klass
185 // other classes that implement the interface. 204 // other classes that implement the interface.
186 if(!as_generator 205 if(!as_generator
187 ( 206 (
188 documentation 207 documentation(1)
189 << "public sealed " << (is_partial ? "partial ":"") << "class " << concrete_name << " :\n" 208 << scope_tab << "public sealed " << (is_partial ? "partial ":"") << "class " << concrete_name << " :\n"
190 << scope_tab << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "") << "\n" 209 << scope_tab(2) << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "")
191 << scope_tab << ", " << interface_name << "\n" 210 << ",\n" << scope_tab(2) << interface_name
192 << scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n" 211 << *(",\n" << scope_tab(2) << name_helpers::klass_full_concrete_or_interface_name) << "\n"
193 << "{\n" 212 << scope_tab << "{\n"
194 ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt)) 213 ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt))
195 return false; 214 return false;
196 215
@@ -199,27 +218,27 @@ struct klass
199 218
200 if (!as_generator 219 if (!as_generator
201 ( 220 (
202 scope_tab << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n" 221 scope_tab(2) << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
203 << scope_tab << "/// Do not call this constructor directly.</summary>\n" 222 << scope_tab(2) << "/// Do not call this constructor directly.</summary>\n"
204 << scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n" 223 << scope_tab(2) << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
205 << scope_tab << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n" 224 << scope_tab(2) << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n"
206 << scope_tab << "{\n" 225 << scope_tab(2) << "{\n"
207 << scope_tab << "}\n\n" 226 << scope_tab(2) << "}\n\n"
208 ) 227 )
209 .generate(sink, attributes::unused, concrete_cxt)) 228 .generate(sink, attributes::unused, concrete_cxt))
210 return false; 229 return false;
211 230
212 if (!as_generator 231 if (!as_generator
213 ( 232 (
214 scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename) 233 scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
215 << ")] internal static extern System.IntPtr\n" 234 << ")] internal static extern System.IntPtr\n"
216 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n" 235 << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
217 << scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << interface_name << "\"/> class.\n" 236 << scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << interface_name << "\"/> class.\n"
218 << scope_tab << "/// Internal usage: This is used when interacting with C code and should not be used directly.</summary>\n" 237 << scope_tab(2) << "/// Internal usage: This is used when interacting with C code and should not be used directly.</summary>\n"
219 << scope_tab << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n" 238 << scope_tab(2) << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
220 << scope_tab << "private " << concrete_name << "(Efl.Eo.Globals.WrappingHandle wh) : base(wh)\n" 239 << scope_tab(2) << "private " << concrete_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
221 << scope_tab << "{\n" 240 << scope_tab(2) << "{\n"
222 << scope_tab << "}\n\n" 241 << scope_tab(2) << "}\n\n"
223 ) 242 )
224 .generate(sink, attributes::unused, concrete_cxt)) 243 .generate(sink, attributes::unused, concrete_cxt))
225 return false; 244 return false;
@@ -244,13 +263,13 @@ struct klass
244 return false; 263 return false;
245 264
246 // Property wrappers 265 // Property wrappers
247 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt)) 266 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, concrete_cxt))
248 return false; 267 return false;
249 268
250 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt)) 269 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
251 { 270 {
252 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 271 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
253 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt)) 272 if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, concrete_cxt))
254 return false; 273 return false;
255 } 274 }
256 275
@@ -259,17 +278,17 @@ struct klass
259 278
260 // Copied from nativeinherit class, used when setting up providers. 279 // Copied from nativeinherit class, used when setting up providers.
261 if(!as_generator( 280 if(!as_generator(
262 scope_tab << "private static IntPtr GetEflClassStatic()\n" 281 scope_tab(2) << "private static IntPtr GetEflClassStatic()\n"
263 << scope_tab << "{\n" 282 << scope_tab(2) << "{\n"
264 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n" 283 << scope_tab(2) << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
265 << scope_tab << "}\n\n" 284 << scope_tab(2) << "}\n\n"
266 ).generate(sink, attributes::unused, concrete_cxt)) 285 ).generate(sink, attributes::unused, concrete_cxt))
267 return false; 286 return false;
268 287
269 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt))) 288 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt)))
270 return true; 289 return true;
271 290
272 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; 291 if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
273 } 292 }
274 293
275 // Inheritable class 294 // Inheritable class
@@ -282,10 +301,11 @@ struct klass
282 // Class header 301 // Class header
283 if(!as_generator 302 if(!as_generator
284 ( 303 (
285 documentation 304 documentation(1)
286 << "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n" 305 << scope_tab << "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
287 << "[Efl.Eo.BindingEntity]\n" 306 << scope_tab << "[Efl.Eo.BindingEntity]\n"
288 << "public " 307 << scope_tab << "[SuppressMessage(\"Microsoft.Naming\", \"CA1724:TypeNamesShouldNotMatchNamespaces\")]\n"
308 << scope_tab<< "public "
289 << (is_partial 309 << (is_partial
290 ? class_type == "class" 310 ? class_type == "class"
291 ? "partial class" 311 ? "partial class"
@@ -297,7 +317,7 @@ struct klass
297 << (root ? "Efl.Eo.EoWrapper" : "") // ... or root 317 << (root ? "Efl.Eo.EoWrapper" : "") // ... or root
298 << (inherit_interfaces.empty() ? "" : ", ") 318 << (inherit_interfaces.empty() ? "" : ", ")
299 << (klass_full_concrete_or_interface_name % ", ") // interfaces 319 << (klass_full_concrete_or_interface_name % ", ") // interfaces
300 << "\n{\n" 320 << "\n" << scope_tab << "{\n"
301 ) 321 )
302 .generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), inherit_cxt)) 322 .generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), inherit_cxt))
303 return false; 323 return false;
@@ -327,29 +347,29 @@ struct klass
327 return false; 347 return false;
328 348
329 // Property wrappers 349 // Property wrappers
330 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, inherit_cxt)) 350 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, inherit_cxt))
331 return false; 351 return false;
332 352
333 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt)) 353 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt))
334 { 354 {
335 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 355 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
336 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, inherit_cxt)) 356 if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, inherit_cxt))
337 return false; 357 return false;
338 } 358 }
339 359
340 // Copied from nativeinherit class, used when setting up providers. 360 // Copied from nativeinherit class, used when setting up providers.
341 if(!as_generator( 361 if(!as_generator(
342 scope_tab << "private static IntPtr GetEflClassStatic()\n" 362 scope_tab(2) << "private static IntPtr GetEflClassStatic()\n"
343 << scope_tab << "{\n" 363 << scope_tab(2) << "{\n"
344 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n" 364 << scope_tab(2) << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
345 << scope_tab << "}\n\n" 365 << scope_tab(2) << "}\n\n"
346 ).generate(sink, attributes::unused, inherit_cxt)) 366 ).generate(sink, attributes::unused, inherit_cxt))
347 return false; 367 return false;
348 368
349 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), inherit_cxt))) 369 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), inherit_cxt)))
350 return true; 370 return true;
351 371
352 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 372 if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
353 } 373 }
354 374
355 375
@@ -365,19 +385,36 @@ struct klass
365 std::copy(c.properties.begin(), c.properties.end(), std::back_inserter(implementable_properties)); 385 std::copy(c.properties.begin(), c.properties.end(), std::back_inserter(implementable_properties));
366 } 386 }
367 387
388 std::stringstream extension_method_stream;
389 std::ostream_iterator<char> extension_method_iterator(extension_method_stream);
390
391 if (!as_generator
392 (*property_extension_method_definition(cls)
393 << *part_extension_method_definition(cls))
394 .generate(extension_method_iterator, std::make_tuple(implementable_properties, cls.parts), context))
395 return false;
396
397 if (extension_method_stream.tellp() <= 0)
398 return true;
399
400 if (!name_helpers::open_namespaces(sink, cls.namespaces, context))
401 return false;
402
368 if(!as_generator 403 if(!as_generator
369 (lit("#if EFL_BETA\n") 404 (lit("#if EFL_BETA\n")
370 << "#pragma warning disable CS1591\n" // Disabling warnings as DocFx will hide these classes 405 << "#pragma warning disable CS1591\n" // Disabling warnings as DocFx will hide these classes
371 <<"public static class " << (string % "_") << name_helpers::klass_inherit_name(cls) 406 << scope_tab << "public static class " << name_helpers::klass_concrete_name(cls)
372 << "_ExtensionMethods {\n" 407 << "Extensions {\n"
373 << *(property_extension_method_definition(cls)) 408 << extension_method_stream.str()
374 << *(part_extension_method_definition(cls)) 409 << scope_tab << "}\n"
375 << "}\n"
376 << "#pragma warning restore CS1591\n" 410 << "#pragma warning restore CS1591\n"
377 << "#endif\n") 411 << "#endif\n")
378 .generate(sink, std::make_tuple(cls.namespaces, implementable_properties, cls.parts), context)) 412 .generate(sink, cls.namespaces, context))
379 return false; 413 return false;
380 414
415 if (!name_helpers::close_namespaces(sink, cls.namespaces, context))
416 return false;
417
381 return true; 418 return true;
382 } 419 }
383 420
@@ -394,7 +431,11 @@ struct klass
394 auto inherit_name = name_helpers::klass_inherit_name(cls); 431 auto inherit_name = name_helpers::klass_inherit_name(cls);
395 auto implementable_methods = helpers::get_all_registerable_methods(cls, context); 432 auto implementable_methods = helpers::get_all_registerable_methods(cls, context);
396 bool root = !helpers::has_regular_ancestor(cls); 433 bool root = !helpers::has_regular_ancestor(cls);
397 auto const& indent = current_indentation(inative_cxt); 434 auto const& indent = current_indentation(inative_cxt).inc();
435 std::string klass_since;
436
437 if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, indent, context))
438 return false;
398 439
399 std::string base_name; 440 std::string base_name;
400 if(!root) 441 if(!root)
@@ -406,8 +447,11 @@ struct klass
406 if(!as_generator 447 if(!as_generator
407 ( 448 (
408 indent << lit("/// <summary>Wrapper for native methods and virtual method delegates.\n") 449 indent << lit("/// <summary>Wrapper for native methods and virtual method delegates.\n")
409 << indent << "/// For internal use by generated code only.</summary>\n" 450 << indent << "/// For internal use by generated code only.\n"
410 << indent << "public new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" 451 << klass_since
452 << indent << "/// </summary>\n"
453 << indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n"
454 << indent << "internal new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n"
411 << indent << "{\n" 455 << indent << "{\n"
412 ).generate(sink, attributes::unused, inative_cxt)) 456 ).generate(sink, attributes::unused, inative_cxt))
413 return false; 457 return false;
@@ -422,9 +466,11 @@ struct klass
422 } 466 }
423 467
424 if(!as_generator( 468 if(!as_generator(
425 indent << scope_tab << "/// <summary>Gets the list of Eo operations to override.</summary>\n" 469 indent << scope_tab << "/// <summary>Gets the list of Eo operations to override.\n"
470 << klass_since
471 << indent << "/// </summary>\n"
426 << indent << scope_tab << "/// <returns>The list of Eo operations to be overload.</returns>\n" 472 << indent << scope_tab << "/// <returns>The list of Eo operations to be overload.</returns>\n"
427 << indent << scope_tab << "public override System.Collections.Generic.List<EflOpDescription> GetEoOps(System.Type type, bool includeInherited)\n" 473 << indent << scope_tab << "internal override System.Collections.Generic.List<EflOpDescription> GetEoOps(System.Type type, bool includeInherited)\n"
428 << indent << scope_tab << "{\n" 474 << indent << scope_tab << "{\n"
429 << indent << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<EflOpDescription>();\n" 475 << indent << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<EflOpDescription>();\n"
430 ) 476 )
@@ -470,11 +516,16 @@ struct klass
470 ).generate(sink, attributes::unused, inative_cxt)) 516 ).generate(sink, attributes::unused, inative_cxt))
471 return false; 517 return false;
472 518
519 if (!klass_since.empty())
520 klass_since = static_cast<std::string>(scope_tab(2)) + klass_since;
521
473 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces) 522 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces)
474 if(!as_generator( 523 if(!as_generator(
475 indent << scope_tab << "/// <summary>Returns the Eo class for the native methods of this class.</summary>\n" 524 indent << scope_tab << "/// <summary>Returns the Eo class for the native methods of this class.\n"
525 << klass_since
526 << indent << scope_tab << "/// </summary>\n"
476 << indent << scope_tab << "/// <returns>The native class pointer.</returns>\n" 527 << indent << scope_tab << "/// <returns>The native class pointer.</returns>\n"
477 << indent << scope_tab << "public override IntPtr GetEflClass()\n" 528 << indent << scope_tab << "internal override IntPtr GetEflClass()\n"
478 << indent << scope_tab << "{\n" 529 << indent << scope_tab << "{\n"
479 << indent << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n" 530 << indent << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
480 << indent << scope_tab << "}\n\n" 531 << indent << scope_tab << "}\n\n"
@@ -488,7 +539,7 @@ struct klass
488 << indent << scope_tab << "#pragma warning restore CA1707, CS1591, SA1300, SA1600\n\n") 539 << indent << scope_tab << "#pragma warning restore CA1707, CS1591, SA1300, SA1600\n\n")
489 .generate(sink, implementable_methods, change_indentation(indent.inc(), inative_cxt))) return false; 540 .generate(sink, implementable_methods, change_indentation(indent.inc(), inative_cxt))) return false;
490 541
491 if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false; 542 if(!as_generator(indent << "}\n").generate(sink, attributes::unused, inative_cxt)) return false;
492 } 543 }
493 return true; 544 return true;
494 } 545 }
@@ -503,21 +554,21 @@ struct klass
503 auto inherit_name = name_helpers::klass_concrete_name(cls); 554 auto inherit_name = name_helpers::klass_concrete_name(cls);
504 555
505 if(!as_generator( 556 if(!as_generator(
506 scope_tab << "/// <summary>Pointer to the native class description.</summary>\n" 557 scope_tab(2) << "/// <summary>Pointer to the native class description.</summary>\n"
507 << scope_tab << "public override System.IntPtr NativeClass\n" 558 << scope_tab(2) << "public override System.IntPtr NativeClass\n"
508 << scope_tab << "{\n" 559 << scope_tab(2) << "{\n"
509 << scope_tab << scope_tab << "get\n" 560 << scope_tab(2) << scope_tab << "get\n"
510 << scope_tab << scope_tab << "{\n" 561 << scope_tab(2) << scope_tab << "{\n"
511 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n" 562 << scope_tab(2) << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n"
512 << scope_tab << scope_tab << scope_tab << "{\n" 563 << scope_tab(2) << scope_tab << scope_tab << "{\n"
513 << scope_tab << scope_tab << scope_tab << scope_tab << "return GetEflClassStatic();\n" 564 << scope_tab(2) << scope_tab << scope_tab << scope_tab << "return GetEflClassStatic();\n"
514 << scope_tab << scope_tab << scope_tab << "}\n" 565 << scope_tab(2) << scope_tab << scope_tab << "}\n"
515 << scope_tab << scope_tab << scope_tab << "else\n" 566 << scope_tab(2) << scope_tab << scope_tab << "else\n"
516 << scope_tab << scope_tab << scope_tab << "{\n" 567 << scope_tab(2) << scope_tab << scope_tab << "{\n"
517 << scope_tab << scope_tab << scope_tab << scope_tab << "return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];\n" 568 << scope_tab(2) << scope_tab << scope_tab << scope_tab << "return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];\n"
518 << scope_tab << scope_tab << scope_tab << "}\n" 569 << scope_tab(2) << scope_tab << scope_tab << "}\n"
519 << scope_tab << scope_tab << "}\n" 570 << scope_tab(2) << scope_tab << "}\n"
520 << scope_tab << "}\n\n" 571 << scope_tab(2) << "}\n\n"
521 ).generate(sink, attributes::unused, context)) 572 ).generate(sink, attributes::unused, context))
522 return false; 573 return false;
523 574
@@ -530,9 +581,9 @@ struct klass
530 auto inherit_name = name_helpers::klass_concrete_name(cls); 581 auto inherit_name = name_helpers::klass_concrete_name(cls);
531 582
532 if(!as_generator( 583 if(!as_generator(
533 scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename) 584 scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
534 << ")] internal static extern System.IntPtr\n" 585 << ")] internal static extern System.IntPtr\n"
535 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n" 586 << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
536 ).generate(sink, attributes::unused, context)) 587 ).generate(sink, attributes::unused, context))
537 return false; 588 return false;
538 589
@@ -543,31 +594,41 @@ struct klass
543 return !blacklist::is_function_blacklisted(ctor.function, context); 594 return !blacklist::is_function_blacklisted(ctor.function, context);
544 }); 595 });
545 596
597 std::string klass_since;
598 if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, scope_tab(2), context))
599 return false;
600
546 // Public (API) constructors 601 // Public (API) constructors
547 if (!as_generator( 602 if (!as_generator(
548 scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.</summary>\n" 603 scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
549 << scope_tab << "/// <param name=\"parent\">Parent instance.</param>\n" 604 << klass_since
550 << *(documentation) 605 << scope_tab(2) << "/// </summary>\n"
606 << scope_tab(2) << "/// <param name=\"parent\">Parent instance.</param>\n"
607 << *(documentation(1))
551 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters. 608 // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
552 << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n" 609 << scope_tab(2) << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null")
553 << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") : " 610 << *(", " << constructor_param ) << ") : "
554 << "base(" << name_helpers::klass_get_name(cls) << "(), parent)\n" 611 << "base(" << name_helpers::klass_get_name(cls) << "(), parent)\n"
555 << scope_tab << "{\n" 612 << scope_tab(2) << "{\n"
556 << (*(scope_tab << scope_tab << constructor_invocation << "\n")) 613 << (*(scope_tab << scope_tab << constructor_invocation << "\n"))
557 << scope_tab << scope_tab << "FinishInstantiation();\n" 614 << scope_tab(2) << scope_tab << "FinishInstantiation();\n"
558 << scope_tab << "}\n\n" 615 << scope_tab(2) << "}\n\n"
559 << scope_tab << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n" 616 << scope_tab(2) << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
560 << scope_tab << "/// Do not call this constructor directly.</summary>\n" 617 << scope_tab(2) << "/// Do not call this constructor directly.\n"
561 << scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n" 618 << klass_since
562 << scope_tab << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n" 619 << scope_tab(2) << "/// </summary>\n"
563 << scope_tab << "{\n" 620 << scope_tab(2) << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
564 << scope_tab << "}\n\n" 621 << scope_tab(2) << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n"
565 << scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n" 622 << scope_tab(2) << "{\n"
566 << scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n" 623 << scope_tab(2) << "}\n\n"
567 << scope_tab << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n" 624 << scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
568 << scope_tab << "protected " << inherit_name << "(Efl.Eo.Globals.WrappingHandle wh) : base(wh)\n" 625 << scope_tab(2) << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n"
569 << scope_tab << "{\n" 626 << klass_since
570 << scope_tab << "}\n\n" 627 << scope_tab(2) << "/// </summary>\n"
628 << scope_tab(2) << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
629 << scope_tab(2) << "internal " << inherit_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
630 << scope_tab(2) << "{\n"
631 << scope_tab(2) << "}\n\n"
571 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context)) 632 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
572 return false; 633 return false;
573 634
@@ -577,25 +638,27 @@ struct klass
577 if (cls.type == attributes::class_type::abstract_) 638 if (cls.type == attributes::class_type::abstract_)
578 { 639 {
579 if (!as_generator( 640 if (!as_generator(
580 scope_tab << "[Efl.Eo.PrivateNativeClass]\n" 641 scope_tab(2) << "[Efl.Eo.PrivateNativeClass]\n"
581 << scope_tab << "private class " << inherit_name << "Realized : " << inherit_name << "\n" 642 << scope_tab(2) << "private class " << inherit_name << "Realized : " << inherit_name << "\n"
582 << scope_tab << "{\n" 643 << scope_tab(2) << "{\n"
583 << scope_tab << scope_tab << "private " << inherit_name << "Realized(Efl.Eo.Globals.WrappingHandle wh) : base(wh)\n" 644 << scope_tab(2) << scope_tab << "private " << inherit_name << "Realized(Efl.Eo.WrappingHandle wh) : base(wh)\n"
584 << scope_tab << scope_tab << "{\n" 645 << scope_tab(2) << scope_tab << "{\n"
585 << scope_tab << scope_tab << "}\n" 646 << scope_tab(2) << scope_tab << "}\n"
586 << scope_tab << "}\n" 647 << scope_tab(2) << "}\n"
587 ).generate(sink, attributes::unused, context)) 648 ).generate(sink, attributes::unused, context))
588 return false; 649 return false;
589 } 650 }
590 651
591 return as_generator( 652 return as_generator(
592 scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n" 653 scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
593 << scope_tab << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n" 654 << scope_tab(2) << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.\n"
594 << scope_tab << "/// <param name=\"baseKlass\">The pointer to the base native Eo class.</param>\n" 655 << klass_since
595 << scope_tab << "/// <param name=\"parent\">The Efl.Object parent of this instance.</param>\n" 656 << scope_tab(2) << "/// </summary>\n"
596 << scope_tab << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n" 657 << scope_tab(2) << "/// <param name=\"baseKlass\">The pointer to the base native Eo class.</param>\n"
597 << scope_tab << "{\n" 658 << scope_tab(2) << "/// <param name=\"parent\">The Efl.Object parent of this instance.</param>\n"
598 << scope_tab << "}\n\n" 659 << scope_tab(2) << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n"
660 << scope_tab(2) << "{\n"
661 << scope_tab(2) << "}\n\n"
599 ).generate(sink, attributes::unused, context); 662 ).generate(sink, attributes::unused, context);
600 } 663 }
601 664
diff --git a/src/bin/eolian_mono/eolian/mono/logging.hh b/src/bin/eolian_mono/eolian/mono/logging.hh
index d13c395..e5b297b 100644
--- a/src/bin/eolian_mono/eolian/mono/logging.hh
+++ b/src/bin/eolian_mono/eolian/mono/logging.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_LOGGING_HH 16#ifndef EOLIAN_MONO_LOGGING_HH
2#define EOLIAN_MONO_LOGGING_HH 17#define EOLIAN_MONO_LOGGING_HH
3 18
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 82bbd13..a9fc45d 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -1,3 +1,18 @@
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 */
1#ifndef EOLIAN_MONO_MARSHALL_ANNOTATION_IMPL_HH 16#ifndef EOLIAN_MONO_MARSHALL_ANNOTATION_IMPL_HH
2#define EOLIAN_MONO_MARSHALL_ANNOTATION_IMPL_HH 17#define EOLIAN_MONO_MARSHALL_ANNOTATION_IMPL_HH
3 18
@@ -6,25 +21,13 @@