summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh29
-rw-r--r--src/bin/eolian_mono/eolian/mono/documentation.hh52
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh574
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh7
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh101
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh14
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh61
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh12
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc3
-rw-r--r--src/bindings/mono/efl_mono/GenericModel.cs14
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp2
-rw-r--r--src/tests/efl_mono/Eo.cs62
-rw-r--r--src/tests/efl_mono/dummy_event_manager.c6
-rw-r--r--src/tests/efl_mono/dummy_event_manager.eo2
-rw-r--r--src/tests/efl_mono/dummy_test_object.c31
-rw-r--r--src/tests/efl_mono/dummy_test_object.eo25
16 files changed, 225 insertions, 770 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index 70bc34a038..8d8de9d1bf 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -150,34 +150,9 @@ inline bool is_alias_blacklisted(attributes::alias_def const& alias, Context con
150 return name_helpers::alias_full_eolian_name(alias) == "Eina.Error"; 150 return name_helpers::alias_full_eolian_name(alias) == "Eina.Error";
151} 151}
152 152
153inline bool is_property_blacklisted(std::string const& name) 153inline bool is_property_blacklisted(std::string const&)
154{ 154{
155 auto properties = std::vector<std::string>{ 155 return false;
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);
181} 156}
182 157
183template<typename Context> 158template<typename Context>
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh
index db00ba8a0f..d009e4571d 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -21,7 +21,6 @@
21#include "grammar/html_escaped_string.hpp" 21#include "grammar/html_escaped_string.hpp"
22#include "using_decl.hh" 22#include "using_decl.hh"
23#include "name_helpers.hh" 23#include "name_helpers.hh"
24#include "helpers.hh"
25#include "generation_contexts.hh" 24#include "generation_contexts.hh"
26#include "blacklist.hh" 25#include "blacklist.hh"
27 26
@@ -77,11 +76,7 @@ struct documentation_generator
77 // The name_tail parameter is the last 4 chars of the original string, which 76 // The name_tail parameter is the last 4 chars of the original string, which
78 // could be ".set" or ".get" and in this case they are ignored by Eolian. 77 // could be ".set" or ".get" and in this case they are ignored by Eolian.
79 // We want them to know what the documentation intended to reference. 78 // We want them to know what the documentation intended to reference.
80 template<typename Context> 79 static std::string function_conversion(const ::Eolian_Object *klass, const ::Eolian_Function *function, std::string name_tail)
81 static std::string function_conversion(const ::Eolian_Object *klass
82 , const ::Eolian_Function *function
83 , std::string name_tail
84 , Context const& context)
85 { 80 {
86 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function); 81 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function);
87 const char* eo_name = ::eolian_function_name_get(function); 82 const char* eo_name = ::eolian_function_name_get(function);
@@ -127,27 +122,13 @@ struct documentation_generator
127 break; 122 break;
128 case ::EOLIAN_PROPERTY: 123 case ::EOLIAN_PROPERTY:
129 { 124 {
125 int getter_nkeys = property_num_keys(function, ::EOLIAN_PROP_GET);
126 int setter_nkeys = property_num_keys(function, ::EOLIAN_PROP_SET);
130 std::string short_name = name_helpers::property_managed_name(klass_d, eo_name); 127 std::string short_name = name_helpers::property_managed_name(klass_d, eo_name);
131 128 bool blacklisted = blacklist::is_property_blacklisted(name + "." + short_name);
132 // We need to replace the current class context with the context 129 // EO properties with keys or blacklisted are not converted into C# properties.
133 // from the class that originated this property. 130 // In these cases we refer to the getter method instead of the property.
134 class_context::wrapper_kind klass_kind; 131 if ((getter_nkeys > 0) || (setter_nkeys > 0) || (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;
151 else if (name_tail == ".get") name += ".Get" + short_name; 132 else if (name_tail == ".get") name += ".Get" + short_name;
152 else if (name_tail == ".set") name += ".Set" + short_name; 133 else if (name_tail == ".set") name += ".Set" + short_name;
153 else name += "." + short_name; 134 else name += "." + short_name;
@@ -184,13 +165,9 @@ struct documentation_generator
184 } 165 }
185 166
186 // Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag 167 // Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
187 template<typename Context> 168 static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail,
188 static std::string ref_conversion(const ::Eolian_Doc_Token *token 169 bool want_beta)
189 , const Eolian_State *state
190 , std::string name_tail
191 , Context const& context)
192 { 170 {
193 bool want_beta = context_want_beta(context);
194 const Eolian_Object *data, *data2; 171 const Eolian_Object *data, *data2;
195 ::Eolian_Object_Type type = 172 ::Eolian_Object_Type type =
196 ::eolian_doc_token_ref_resolve(token, state, &data, &data2); 173 ::eolian_doc_token_ref_resolve(token, state, &data, &data2);
@@ -218,7 +195,7 @@ struct documentation_generator
218 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2); 195 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
219 break; 196 break;
220 case ::EOLIAN_OBJECT_FUNCTION: 197 case ::EOLIAN_OBJECT_FUNCTION:
221 ref += function_conversion(data, (const ::Eolian_Function *)data2, name_tail, context); 198 ref += function_conversion(data, (const ::Eolian_Function *)data2, name_tail);
222 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2); 199 is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
223 break; 200 break;
224 case ::EOLIAN_OBJECT_CONSTANT: 201 case ::EOLIAN_OBJECT_CONSTANT:
@@ -250,8 +227,7 @@ struct documentation_generator
250 } 227 }
251 228
252 // Turns EO documentation syntax into C# triple-slash XML comment syntax 229 // Turns EO documentation syntax into C# triple-slash XML comment syntax
253 template<typename Context> 230 static std::string syntax_conversion(std::string text, const Eolian_State *state, bool want_beta)
254 static std::string syntax_conversion(std::string text, const Eolian_State *state, Context const& context)
255 { 231 {
256 std::string new_text, ref; 232 std::string new_text, ref;
257 ::Eolian_Doc_Token_Type previous_token_type = ::EOLIAN_DOC_TOKEN_UNKNOWN; 233 ::Eolian_Doc_Token_Type previous_token_type = ::EOLIAN_DOC_TOKEN_UNKNOWN;
@@ -290,7 +266,7 @@ struct documentation_generator
290 new_text += token_text; 266 new_text += token_text;
291 break; 267 break;
292 case ::EOLIAN_DOC_TOKEN_REF: 268 case ::EOLIAN_DOC_TOKEN_REF:
293 ref = ref_conversion(&token, state, name_tail, context); 269 ref = ref_conversion(&token, state, name_tail, want_beta);
294 if (ref != "") 270 if (ref != "")
295 { 271 {
296 if (utils::ends_with(ref, BETA_REF_SUFFIX)) 272 if (utils::ends_with(ref, BETA_REF_SUFFIX))
@@ -355,7 +331,7 @@ struct documentation_generator
355 if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context)) 331 if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context))
356 return false; 332 return false;
357 auto options = context_find_tag<options_context>(context); 333 auto options = context_find_tag<options_context>(context);
358 new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, context); 334 new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, options.want_beta);
359 335
360 std::string tabs; 336 std::string tabs;
361 as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context); 337 as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context);
@@ -677,7 +653,7 @@ struct documentation_string_generator
677 653
678 auto options = context_find_tag<options_context>(context); 654 auto options = context_find_tag<options_context>(context);
679 auto state = context_find_tag<eolian_state_context>(context).state; 655 auto state = context_find_tag<eolian_state_context>(context).state;
680 if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, context), context)) 656 if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, options.want_beta), context))
681 return false; 657 return false;
682 658
683 return true; 659 return true;
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 0c2adebe42..eff586b157 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -26,7 +26,6 @@
26#include "grammar/list.hpp" 26#include "grammar/list.hpp"
27#include "grammar/alternative.hpp" 27#include "grammar/alternative.hpp"
28#include "grammar/attribute_reorder.hpp" 28#include "grammar/attribute_reorder.hpp"
29#include "grammar/eps.hpp"
30#include "grammar/counter.hpp" 29#include "grammar/counter.hpp"
31#include "logging.hh" 30#include "logging.hh"
32#include "type.hh" 31#include "type.hh"
@@ -45,7 +44,7 @@ namespace eolian_mono {
45struct native_function_definition_generator 44struct native_function_definition_generator
46{ 45{
47 attributes::klass_def const* klass; 46 attributes::klass_def const* klass;
48 47
49 template <typename OutputIterator, typename Context> 48 template <typename OutputIterator, typename Context>
50 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 49 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
51 { 50 {
@@ -182,7 +181,7 @@ struct native_function_definition_generator
182 return true; 181 return true;
183 } 182 }
184}; 183};
185 184
186struct function_definition_generator 185struct function_definition_generator
187{ 186{
188 function_definition_generator(bool do_super = false) 187 function_definition_generator(bool do_super = false)
@@ -323,199 +322,6 @@ property_extension_method_definition_generator property_extension_method_definit
323 322
324struct property_wrapper_definition_generator 323struct property_wrapper_definition_generator
325{ 324{
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
519 template<typename OutputIterator, typename Context> 325 template<typename OutputIterator, typename Context>
520 bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const 326 bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
521 { 327 {
@@ -524,127 +330,103 @@ struct property_wrapper_definition_generator
524 using efl::eolian::grammar::attributes::parameter_direction; 330 using efl::eolian::grammar::attributes::parameter_direction;
525 using efl::eolian::grammar::attributes::parameter_def; 331 using efl::eolian::grammar::attributes::parameter_def;
526 332
527 /// C(k) = keys count, C(v) = values count 333 if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
528 /// /------------\ /------\. 334 return true;
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;
613 335
614 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface; 336 bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
615 bool is_static = (property.getter.is_engaged() && property.getter->is_static) 337 bool is_static = (property.getter.is_engaged() && property.getter->is_static)
616 || (property.setter.is_engaged() && property.setter->is_static); 338 || (property.setter.is_engaged() && property.setter->is_static);
617 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete; 339 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);
621 340
622 //if (name_helpers::klass_concrete_or_interface_name (*implementing_klass) == "IMapping") 341
623 if (false) 342 if ((is_concrete || is_interface) && is_static)
343 return true;
344
345 auto get_params = property.getter.is_engaged() ? property.getter->parameters.size() : 0;
346 //auto set_params = property.setter.is_engaged() ? property.setter->parameters.size() : 0;
347
348 // C# properties must have a single value.
349 //
350 // Single values in getters are automatically converted to return_type,
351 // meaning they should have 0 parameters.
352 //
353 // For setters, we ignore the return type - usually boolean.
354 // if (get_params > 0 || set_params > 1)
355 // return true;
356
357 if (property.getter
358 && std::find_if (property.getter->parameters.begin()
359 , property.getter->parameters.end()
360 , [] (parameter_def const& p)
361 {
362 return p.direction != parameter_direction::out;
363 }) != property.getter->parameters.end())
364 return true;
365 if (property.setter
366 && std::find_if (property.setter->parameters.begin()
367 , property.setter->parameters.end()
368 , [] (parameter_def const& p)
369 {
370 return p.direction != parameter_direction::in;
371 }) != property.setter->parameters.end())
372 return true;
373
374 if (property.getter && property.setter)
624 { 375 {
625 if (!as_generator(grammar::lit("/// is interface ") << (int)is_interface 376 if (get_params != 0 && property.setter->parameters.size() != property.getter->parameters.size())
626 << " is static " << (int)is_static 377 return true;
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;
638 } 378 }
639 379
640 if (blacklist::is_property_blacklisted(property, context)) 380 std::vector<attributes::parameter_def> parameters;
641 return true; 381
382 if (property.setter.is_engaged())
383 {
384 std::transform (property.setter->parameters.begin(), property.setter->parameters.end()
385 , std::back_inserter(parameters)
386 , [] (parameter_def p) -> parameter_def
387 {
388 //p.direction = efl::eolian::attributes::parameter_direction::in;
389 return p;
390 });
391 }
392 else if (property.getter.is_engaged())
393 {
394 // if getter has parameters, then we ignore return type, otherwise
395 // we use the return type.
396 if (get_params == 0)
397 parameters.push_back({parameter_direction::in
398 , property.getter->return_type, "propertyResult", {}
399 , property.getter->unit});
400 else
401 std::transform (property.getter->parameters.begin(), property.getter->parameters.end()
402 , std::back_inserter(parameters)
403 , [] (parameter_def p) -> parameter_def
404 {
405 p.direction = parameter_direction::in;
406 return p;
407 });
408 }
409 else
410 {
411 EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Property must have either a getter or a setter." << std::endl;
412 return false;
413 }
414
415 std::string dir_mod;
416 if (property.setter.is_engaged())
417 dir_mod = direction_modifier(property.setter->parameters[0]);
642 418
643 std::string managed_name = name_helpers::property_managed_name(property); 419 std::string managed_name = name_helpers::property_managed_name(property);
644 420
645 std::string scope = "public "; 421 std::string scope = "public ";
646 std::string get_scope = eolian_mono::function_scope_get(*property.getter); 422 std::string get_scope = property.getter.is_engaged() ? eolian_mono::function_scope_get(*property.getter) : "";
647 std::string set_scope = has_setter ? eolian_mono::function_scope_get(*property.setter) : ""; 423 bool is_get_public = get_scope == "public ";
424 std::string set_scope = property.setter.is_engaged() ? eolian_mono::function_scope_get(*property.setter) : "";
425 bool is_set_public = set_scope == "public ";
426
427 // No need to generate this wrapper as no accessor is public.
428 if (is_interface && (!is_get_public && !is_set_public))
429 return true;
648 430
649 // C# interface members are declared automatically as public 431 // C# interface members are declared automatically as public
650 if (is_interface) 432 if (is_interface)
@@ -659,64 +441,23 @@ struct property_wrapper_definition_generator
659 get_scope = ""; 441 get_scope = "";
660 set_scope = ""; 442 set_scope = "";
661 } 443 }
662 else if (!has_setter || (get_scope == scope)) 444 else if (!property.setter.is_engaged() || (get_scope == scope))
663 { 445 {
664 scope = get_scope; 446 scope = get_scope;
665 get_scope = ""; 447 get_scope = "";
666 } 448 }
667 449 else if (!property.getter.is_engaged() || (set_scope == scope))
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)
685 {
686 generated_values.push_back
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 { 450 {
700 generated_values.push_back 451 scope = set_scope;
701 (attributes::parameter_def 452 set_scope = "";
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 });
711 } 453 }
712 }
713 454
714 if (generated_values.size() == 1) 455 if (parameters.size() == 1)
715 { 456 {
716 if (!as_generator( 457 if (!as_generator(
717 documentation(2) 458 documentation(2)
718 << scope_tab(2) << scope << (is_static ? "static " : virtual_mod) << type(true) << " " << managed_name << " {\n" 459 << scope_tab(2) << scope << (is_static ? "static " : "") << type(true) << " " << managed_name << " {\n"
719 ).generate(sink, std::make_tuple(property, generated_values[0].type), context)) 460 ).generate(sink, std::make_tuple(property, parameters[0].type), context))
720 return false; 461 return false;
721 } 462 }
722 else 463 else
@@ -727,21 +468,73 @@ struct property_wrapper_definition_generator
727 << scope_tab(2) << scope << (is_static ? "static (" : "(") 468 << scope_tab(2) << scope << (is_static ? "static (" : "(")
728 << (attribute_reorder<1, -1>(type(true) /*<< " " << argument*/) % ", ") << ") " 469 << (attribute_reorder<1, -1>(type(true) /*<< " " << argument*/) % ", ") << ") "
729 << managed_name << " {\n" 470 << managed_name << " {\n"
730 ).generate(sink, std::make_tuple(property, generated_values), context)) 471 ).generate(sink, std::make_tuple(property, parameters), context))
731 return false; 472 return false;
732 } 473 }
733 474
734 if (has_indexer) 475 if (property.getter.is_engaged() && is_interface)
735 { 476 {
736 generate_get_indexer (sink, property, context, get_scope, is_interface); 477 if (is_get_public)
478 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "get;\n"
479 ).generate(sink, attributes::unused, context))
480 return false;
737 } 481 }
738 else 482 else if (property.getter.is_engaged() && get_params == 0/*parameters.size() == 1 && property.getter.is_engaged()*/)
739 { 483 {
740 std::vector<std::string> empty_keys; 484 if (!as_generator
741 generate_get(sink, property, context, get_scope, empty_keys, values, is_interface); 485 (scope_tab(2) << scope_tab << get_scope
486 << "get " << "{ return " + name_helpers::managed_method_name(*property.getter) + "(); }\n"
487 ).generate(sink, attributes::unused, context))
488 return false;
489 }
490 else if (parameters.size() >= 1 && property.getter)
491 {
492 if (!as_generator
493 (scope_tab(2) << scope_tab << get_scope << "get "
494 << "{\n"
495 << *attribute_reorder<1, -1, 1>
496 (scope_tab(4) << type(true) << " _out_"
497 << argument(false) << " = default(" << type(true) << ");\n"
498 )
499 << scope_tab(4) << name_helpers::managed_method_name(*property.getter)
500 << "(" << (("out _out_" << argument(false)) % ", ") << ");\n"
501 << scope_tab(4) << "return (" << (("_out_"<< argument(false)) % ", ") << ");\n"
502 << scope_tab(3) << "}" << "\n"
503 ).generate(sink, std::make_tuple(parameters, parameters, parameters), context))
504 return false;
505 }
506 // else if (parameters.size() == 1)
507 // {
508 // if (!as_generator
509 // (scope_tab << scope_tab << get_scope << "get "
510 // << "{\n"
511 // << *attribute_reorder<1, -1, 1>(scope_tab(3) << type(true) << " _out_" << argument(false) << " = default(" << type(true) << ");\n")
512 // << scope_tab(3) << name_helpers::managed_method_name(*property.getter)
513 // << "(" << (("out _out_" << argument(false)) % ",") << ");\n"
514 // << scope_tab(3) << "return " << (("_out_"<< argument(false)) % ",") << ";\n"
515 // << scope_tab(2) << "}" << "\n"
516 // ).generate(sink, std::make_tuple(parameters, parameters, parameters), context))
517 // return false;
518 // }
742 519
743 if (has_setter) 520 if (property.setter.is_engaged() && is_interface)
744 generate_set (sink, property, context, set_scope, empty_keys, values, is_interface); 521 {
522 if (is_set_public)
523 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set;\n"
524 ).generate(sink, attributes::unused, context))
525 return false;
526 }
527 else if (parameters.size() == 1 && property.setter.is_engaged())
528 {
529 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set " << "{ " + name_helpers::managed_method_name(*property.setter) + "(" + dir_mod + "value); }\n"
530 ).generate(sink, attributes::unused, context))
531 return false;
532 }
533 else if (parameters.size() > 1 && property.setter.is_engaged())
534 {
535 if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set " << ("{ " + name_helpers::managed_method_name(*property.setter) + "(" + dir_mod) << ((" value.Item" << counter(1)) % ", ") << "); }" << "\n"
536 ).generate(sink, parameters, context))
537 return false;
745 } 538 }
746 539
747 if (!as_generator(scope_tab(2) << "}\n\n").generate(sink, attributes::unused, context)) 540 if (!as_generator(scope_tab(2) << "}\n\n").generate(sink, attributes::unused, context))
@@ -749,14 +542,13 @@ struct property_wrapper_definition_generator
749 542
750 return true; 543 return true;
751 } 544 }
752 attributes::klass_def const* implementing_klass, *klass_from_property; 545 attributes::klass_def const* implementing_klass;
753}; 546};
754struct property_wrapper_definition_parameterized 547struct property_wrapper_definition_parameterized
755{ 548{
756 property_wrapper_definition_generator operator()(attributes::klass_def const& klass 549 property_wrapper_definition_generator operator()(attributes::klass_def const& klass) const
757 , attributes::klass_def const& prop_from_klass) const
758 { 550 {
759 return {&klass, &prop_from_klass}; 551 return {&klass};
760 } 552 }
761} const property_wrapper_definition; 553} const property_wrapper_definition;
762property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized) 554property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized)
@@ -764,45 +556,6 @@ property_wrapper_definition_generator as_generator(property_wrapper_definition_p
764 return {}; 556 return {};
765} 557}
766 558
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
806} 559}
807 560
808namespace efl { namespace eolian { namespace grammar { 561namespace efl { namespace eolian { namespace grammar {
@@ -818,10 +571,6 @@ struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator>
818template <> 571template <>
819struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {}; 572struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
820template <> 573template <>
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 <>
825struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {}; 574struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
826template <> 575template <>
827struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {}; 576struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
@@ -833,10 +582,6 @@ template <>
833struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 582struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
834template <> 583template <>
835struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {}; 584struct 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 {};
840 585
841namespace type_traits { 586namespace type_traits {
842template <> 587template <>
@@ -855,13 +600,8 @@ template <>
855struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {}; 600struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
856template <> 601template <>
857struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {}; 602struct 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> {};
863} 603}
864 604
865} } } 605} } }
866 606
867#endif 607#endif
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index 2ac16b0f61..f7376f056a 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -26,7 +26,6 @@ namespace eolian_mono {
26struct class_context 26struct class_context
27{ 27{
28 enum wrapper_kind { 28 enum wrapper_kind {
29 none,
30 interface, 29 interface,
31 concrete, 30 concrete,
32 inherit, 31 inherit,
@@ -110,12 +109,6 @@ struct options_context {
110 std::string examples_dir; 109 std::string examples_dir;
111}; 110};
112 111
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
119} 112}
120 113
121#endif 114#endif
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 049f263d80..b34a985749 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -17,7 +17,6 @@
17#define EOLIAN_MONO_HELPERS_HH 17#define EOLIAN_MONO_HELPERS_HH
18 18
19#include "grammar/klass_def.hpp" 19#include "grammar/klass_def.hpp"
20#include "grammar/context.hpp"
21#include "blacklist.hh" 20#include "blacklist.hh"
22#include "generation_contexts.hh" 21#include "generation_contexts.hh"
23#include "name_helpers.hh" 22#include "name_helpers.hh"
@@ -306,106 +305,6 @@ inline std::vector<attributes::constructor_def> reorder_constructors(std::vector
306 return constructors; 305 return constructors;
307} 306}
308 307
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
409} // namespace helpers 308} // namespace helpers
410 309
411} // namespace eolian_mono 310} // namespace eolian_mono
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 7fe60f0fcf..072ea6c143 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -106,10 +106,6 @@ struct klass
106 name_helpers::klass_full_concrete_or_interface_name(cls)}, 106 name_helpers::klass_full_concrete_or_interface_name(cls)},
107 context); 107 context);
108 108
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)) 109 if(!as_generator(documentation(1)).generate(sink, cls, iface_cxt))
114 return false; 110 return false;
115 111
@@ -162,7 +158,7 @@ struct klass
162 ).generate(sink, p, iface_cxt)) 158 ).generate(sink, p, iface_cxt))
163 return false; 159 return false;
164 160
165 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, iface_cxt)) 161 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, iface_cxt))
166 return false; 162 return false;
167 163
168 // End of interface declaration 164 // End of interface declaration
@@ -263,13 +259,13 @@ struct klass
263 return false; 259 return false;
264 260
265 // Property wrappers 261 // Property wrappers
266 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, concrete_cxt)) 262 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt))
267 return false; 263 return false;
268 264
269 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt)) 265 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
270 { 266 {
271 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 267 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
272 if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, concrete_cxt)) 268 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt))
273 return false; 269 return false;
274 } 270 }
275 271
@@ -347,13 +343,13 @@ struct klass
347 return false; 343 return false;
348 344
349 // Property wrappers 345 // Property wrappers
350 if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, inherit_cxt)) 346 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, inherit_cxt))
351 return false; 347 return false;
352 348
353 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt)) 349 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt))
354 { 350 {
355 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 351 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
356 if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, inherit_cxt)) 352 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, inherit_cxt))
357 return false; 353 return false;
358 } 354 }
359 355
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index bf0abb7863..7f71d9279b 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -334,6 +334,28 @@ inline std::string to_field_name(std::string const& in)
334 return utils::capitalize(in); 334 return utils::capitalize(in);
335} 335}
336 336
337
338
339template<typename T>
340inline std::string property_managed_name(T const& klass, std::string const& name)
341{
342 auto names = utils::split(name, '_');
343 // No need to escape keyword here as it will be capitalized and already
344 // namespaced inside the owner class.
345 auto managed_name = utils::to_pascal_case(names);
346 auto managed_klass_name = klass_concrete_or_interface_name(klass);
347
348 if (managed_name == "Type")
349 managed_name = managed_klass_name + managed_name;
350
351 return managed_name;
352}
353
354inline std::string property_managed_name(attributes::property_def const& property)
355{
356 return property_managed_name(property.klass, property.name);
357}
358
337inline std::string managed_part_name(attributes::part_def const& part) 359inline std::string managed_part_name(attributes::part_def const& part)
338{ 360{
339 std::vector<std::string> names = utils::split(part.name, '_'); 361 std::vector<std::string> names = utils::split(part.name, '_');
@@ -490,45 +512,6 @@ inline std::string translate_inherited_event_name(const attributes::event_def &e
490 return join_namespaces(klass.namespaces, '_') + klass_interface_name(klass) + "_" + managed_event_name(evt.name); 512 return join_namespaces(klass.namespaces, '_') + klass_interface_name(klass) + "_" + managed_event_name(evt.name);
491} 513}
492 514
493// Properties
494
495template<typename T>
496inline std::string property_managed_name(T const& klass, std::string const& name)
497{
498 auto names = utils::split(name, '_');
499 // No need to escape keyword here as it will be capitalized and already
500 // namespaced inside the owner class.
501 auto managed_name = utils::to_pascal_case(names);
502 auto managed_klass_name = klass_concrete_or_interface_name(klass);
503
504 if (managed_name == "Type")
505 managed_name = managed_klass_name + managed_name;
506
507 return managed_name;
508}
509
510inline std::string property_managed_name(attributes::property_def const& property)
511{
512 return property_managed_name(property.klass, property.name);
513}
514
515inline std::string property_concrete_indexer_name(attributes::property_def const& property)
516{
517 return property_managed_name(property) + "Indexer";
518}
519
520template<typename T>
521inline std::string property_interface_indexer_name(attributes::property_def const& property, T const& current_klass)
522{
523 return name_helpers::klass_full_interface_name(current_klass) + property_concrete_indexer_name(property);
524}
525
526template<typename T>
527inline std::string property_interface_indexer_short_name(attributes::property_def const& property, T const& current_klass)
528{
529 return name_helpers::klass_interface_name(current_klass) + property_concrete_indexer_name(property);
530}
531
532// Open/close namespaces 515// Open/close namespaces
533template<typename OutputIterator, typename Context> 516template<typename OutputIterator, typename Context>
534bool open_namespaces(OutputIterator sink, std::vector<std::string> namespaces, Context const& context) 517bool open_namespaces(OutputIterator sink, std::vector<std::string> namespaces, Context const& context)
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index 824dc0c927..abd94641ef 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -65,7 +65,7 @@ struct is_generator< ::eolian_mono::parameter_generator> : std::true_type {};
65 65
66namespace type_traits { 66namespace type_traits {
67template <> 67template <>
68struct attributes_needed< ::eolian_mono::parameter_generator> : std::integral_constant<int, 1> {}; 68struct attributes_needed< ::eolian_mono::parameter_generator> : std::integral_constant<int, 1> {};
69} 69}
70 70
71template <> 71template <>
@@ -75,9 +75,9 @@ struct is_generator< ::eolian_mono::marshall_parameter_generator> : std::true_ty
75 75
76namespace type_traits { 76namespace type_traits {
77template <> 77template <>
78struct attributes_needed< ::eolian_mono::marshall_parameter_generator> : std::integral_constant<int, 1> {}; 78struct attributes_needed< ::eolian_mono::marshall_parameter_generator> : std::integral_constant<int, 1> {};
79} 79}
80 80
81template <> 81template <>
82struct is_eager_generator< ::eolian_mono::argument_generator> : std::true_type {}; 82struct is_eager_generator< ::eolian_mono::argument_generator> : std::true_type {};
83template <> 83template <>
@@ -85,9 +85,9 @@ struct is_generator< ::eolian_mono::argument_generator> : std::true_type {};
85 85
86namespace type_traits { 86namespace type_traits {
87template <> 87template <>
88struct attributes_needed< ::eolian_mono::argument_generator> : std::integral_constant<int, 1> {}; 88struct attributes_needed< ::eolian_mono::argument_generator> : std::integral_constant<int, 1> {};
89} 89}
90 90
91template <> 91template <>
92struct is_eager_generator< ::eolian_mono::argument_invocation_generator> : std::true_type {}; 92struct is_eager_generator< ::eolian_mono::argument_invocation_generator> : std::true_type {};
93template <> 93template <>
@@ -1588,7 +1588,7 @@ struct native_convert_function_pointer_generator
1588 1588
1589struct constructor_parameter_name_generator 1589struct constructor_parameter_name_generator
1590{ 1590{
1591 1591
1592 template <typename OutputIterator, typename Context> 1592 template <typename OutputIterator, typename Context>
1593 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 1593 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
1594 { 1594 {
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index bf3874a414..1a96aaa826 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -183,14 +183,13 @@ run(options_type const& opts)
183 183
184 auto context = context_add_tag(eolian_mono::indentation_context{0}, 184 auto context = context_add_tag(eolian_mono::indentation_context{0},
185 context_add_tag(eolian_mono::eolian_state_context{opts.state}, 185 context_add_tag(eolian_mono::eolian_state_context{opts.state},
186 context_add_tag(eolian_mono::class_context{eolian_mono::class_context::none},
187 context_add_tag(eolian_mono::options_context{opts.want_beta, 186 context_add_tag(eolian_mono::options_context{opts.want_beta,
188 opts.examples_dir}, 187 opts.examples_dir},
189 context_add_tag(eolian_mono::library_context{opts.dllimport, 188 context_add_tag(eolian_mono::library_context{opts.dllimport,
190 opts.v_major, 189 opts.v_major,
191 opts.v_minor, 190 opts.v_minor,
192 opts.references_map}, 191 opts.references_map},
193 efl::eolian::grammar::context_null()))))); 192 efl::eolian::grammar::context_null()))));
194 193
195 EINA_ITERATOR_FOREACH(aliases, tp) 194 EINA_ITERATOR_FOREACH(aliases, tp)
196 { 195 {
diff --git a/src/bindings/mono/efl_mono/GenericModel.cs b/src/bindings/mono/efl_mono/GenericModel.cs
index faa2a2f099..8d7cc813a2 100644
--- a/src/bindings/mono/efl_mono/GenericModel.cs
+++ b/src/bindings/mono/efl_mono/GenericModel.cs
@@ -52,7 +52,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
52 /// <summary>Gets the value of the given property in the wrapped model.</summary> 52 /// <summary>Gets the value of the given property in the wrapped model.</summary>
53 /// <param name="property">The property of the model.</param> 53 /// <param name="property">The property of the model.</param>
54 /// <returns>The value of the property.</returns> 54 /// <returns>The value of the property.</returns>
55 public Eina.Value GetProperty(System.String property) 55 public Eina.Value GetProperty( System.String property)
56 { 56 {
57 return model.GetProperty(property); 57 return model.GetProperty(property);
58 } 58 }
@@ -62,7 +62,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
62 /// <param name="value">The value of the property.</param> 62 /// <param name="value">The value of the property.</param>
63 /// <returns>An <see cref="Eina.Future" /> that resolves when the property has 63 /// <returns>An <see cref="Eina.Future" /> that resolves when the property has
64 /// been set or reports an error if it could not be set.</returns> 64 /// been set or reports an error if it could not be set.</returns>
65 public Eina.Future SetProperty(System.String property, Eina.Value value) 65 public Eina.Future SetProperty( System.String property, Eina.Value value)
66 { 66 {
67 return model.SetProperty(property, value); 67 return model.SetProperty(property, value);
68 } 68 }
@@ -77,7 +77,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
77 /// <summary>Returns an <see cref="Eina.Future" /> that will resolve when the property is ready to be read.</summary> 77 /// <summary>Returns an <see cref="Eina.Future" /> that will resolve when the property is ready to be read.</summary>
78 /// <param name="property">The property of the model.</param> 78 /// <param name="property">The property of the model.</param>
79 /// <returns>An <see cref="Eina.Future" /> that resolves when the property is ready.</returns> 79 /// <returns>An <see cref="Eina.Future" /> that resolves when the property is ready.</returns>
80 public Eina.Future GetPropertyReady(System.String property) 80 public Eina.Future GetPropertyReady( System.String property)
81 { 81 {
82 return model.GetPropertyReady(property); 82 return model.GetPropertyReady(property);
83 } 83 }
@@ -87,7 +87,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
87 /// <param name="count">The size of the range.</param> 87 /// <param name="count">The size of the range.</param>
88 /// <returns>An <see cref="Eina.Future" /> that resolves to an 88 /// <returns>An <see cref="Eina.Future" /> that resolves to an
89 /// <see cref="Eina.Array&lt;T&gt;" /> of children models.</returns> 89 /// <see cref="Eina.Array&lt;T&gt;" /> of children models.</returns>
90 public Eina.Future GetChildrenSlice(uint start, uint count) 90 public Eina.Future GetChildrenSlice( uint start, uint count)
91 { 91 {
92 return model.GetChildrenSlice(start, count); 92 return model.GetChildrenSlice(start, count);
93 } 93 }
@@ -141,7 +141,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
141 /// <param name="token">The token for the task's cancellation.</param> 141 /// <param name="token">The token for the task's cancellation.</param>
142 /// <returns>Task that resolves when the property has been set or could not 142 /// <returns>Task that resolves when the property has been set or could not
143 /// be set.</returns> 143 /// be set.</returns>
144 public System.Threading.Tasks.Task<Eina.Value> SetPropertyAsync(System.String property, Eina.Value value, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) 144 public System.Threading.Tasks.Task<Eina.Value> SetPropertyAsync( System.String property, Eina.Value value, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
145 { 145 {
146 return model.SetPropertyAsync(property, value, token); 146 return model.SetPropertyAsync(property, value, token);
147 } 147 }
@@ -151,7 +151,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
151 /// <param name="token">The token for the task's cancellation.</param> 151 /// <param name="token">The token for the task's cancellation.</param>
152 /// <returns>Task that resolves when the given property is ready to be 152 /// <returns>Task that resolves when the given property is ready to be
153 /// read.</returns> 153 /// read.</returns>
154 public System.Threading.Tasks.Task<Eina.Value> GetPropertyReadyAsync(System.String property, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) 154 public System.Threading.Tasks.Task<Eina.Value> GetPropertyReadyAsync( System.String property, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
155 { 155 {
156 return model.GetPropertyReadyAsync(property, token); 156 return model.GetPropertyReadyAsync(property, token);
157 } 157 }
@@ -162,7 +162,7 @@ public class GenericModel<T> : Efl.Object, Efl.IModel
162 /// <param name="token">Token to notify the async operation of external request to cancel.</param> 162 /// <param name="token">Token to notify the async operation of external request to cancel.</param>
163 /// <returns>Task that resolves when the desired <see cref="Eina.Array&lt;T&gt;" /> of 163 /// <returns>Task that resolves when the desired <see cref="Eina.Array&lt;T&gt;" /> of
164 /// children models is ready.</returns> 164 /// children models is ready.</returns>
165 public System.Threading.Tasks.Task<Eina.Value> GetChildrenSliceAsync(uint start, uint count, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) 165 public System.Threading.Tasks.Task<Eina.Value> GetChildrenSliceAsync( uint start, uint count, System.Threading.CancellationToken token=default(System.Threading.CancellationToken))
166 { 166 {
167 return model.GetChildrenSliceAsync(start, count, token); 167 return model.GetChildrenSliceAsync(start, count, token);
168 } 168 }
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index 48b8b52c80..86fb61e8a3 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -897,7 +897,7 @@ struct function_def
897 } 897 }
898 else if(type == EOLIAN_PROP_GET) 898 else if(type == EOLIAN_PROP_GET)
899 { 899 {
900 for(auto v : values) 900 for(auto&& v : values)
901 { 901 {
902 v.direction = parameter_direction::out; 902 v.direction = parameter_direction::out;
903 parameters.push_back(v); 903 parameters.push_back(v);
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index af40bf12d8..7c580480ad 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -402,15 +402,15 @@ class TestCsharpProperties
402 obj.Dispose(); 402 obj.Dispose();
403 } 403 }
404 404
405 // public static void test_setter_only() 405 public static void test_setter_only()
406 // { 406 {
407 // var obj = new Dummy.TestObject(); 407 var obj = new Dummy.TestObject();
408 // int val = -1984; 408 int val = -1984;
409 409
410 // obj.SetterOnly = val; 410 obj.SetterOnly = val;
411 // Test.AssertEquals(val, obj.GetSetterOnly()); 411 Test.AssertEquals(val, obj.GetSetterOnly());
412 // obj.Dispose(); 412 obj.Dispose();
413 // } 413 }
414 414
415 public static void test_class_property() 415 public static void test_class_property()
416 { 416 {
@@ -436,52 +436,6 @@ class TestCsharpProperties
436 Test.AssertEquals(ret, (1, 2)); 436 Test.AssertEquals(ret, (1, 2));
437 obj.Dispose(); 437 obj.Dispose();
438 } 438 }
439
440 public static void test_csharp_keyed_multi_valued_prop()
441 {
442 var obj = new Dummy.TestObject();
443 obj.KeyedMultiValuedProp[100] = (1, 2);
444 Test.AssertEquals(obj.KeyedMultiValuedProp[100], (1, 2));
445 obj.Dispose();
446 }
447
448 public static void test_csharp_multi_keyed_multi_valued_prop()
449 {
450 var obj = new Dummy.TestObject();
451 obj.MultiKeyedMultiValuedProp[(100, 101)] = (1, 2);
452 Test.AssertEquals(obj.MultiKeyedMultiValuedProp[(100, 101)], (1, 2));
453 obj.Dispose();
454 }
455
456 public static void test_csharp_multi_prop()
457 {
458 var obj = new Dummy.TestObject();
459 obj.MultiKeyedMultiValuedProp[(100, 101)] = (1, 2);
460 obj.KeyedMultiValuedProp[100] = (1, 2);
461 Test.AssertEquals(obj.KeyedMultiValuedProp[100],
462 obj.MultiKeyedMultiValuedProp[(100, 101)]);
463 int a1, b1, a2, b2;
464#if __MonoCS__
465 (int a, int b) t1 = obj.MultiKeyedMultiValuedProp[(100, 101)];
466 (a1, b1) = (t1.Item1, t1.Item2);
467 (int a, int b) t2 = obj.KeyedMultiValuedProp[100];
468 (a2, b2) = (t2.Item1, t2.Item2);
469#else
470 (a1, b1) = obj.MultiKeyedMultiValuedProp[(100, 101)];
471 (a2, b2) = obj.KeyedMultiValuedProp[100];
472#endif
473 Test.AssertEquals(a1, a2);
474 Test.AssertEquals(b1, b2);
475 var i = (100, 101);
476 var j = 100;
477 Test.AssertEquals(obj.KeyedMultiValuedProp[j],
478 obj.MultiKeyedMultiValuedProp[i]);
479 obj.MultiKeyedMultiValuedProp[i] = (1, 3);
480 obj.KeyedMultiValuedProp[j] = obj.MultiKeyedMultiValuedProp[i];
481 Test.AssertEquals(obj.KeyedMultiValuedProp[j],
482 obj.MultiKeyedMultiValuedProp[i]);
483
484 }
485} 439}
486 440
487class TestEoGrandChildrenFinalize 441class TestEoGrandChildrenFinalize
diff --git a/src/tests/efl_mono/dummy_event_manager.c b/src/tests/efl_mono/dummy_event_manager.c
index 813622929a..62bdd05c7f 100644
--- a/src/tests/efl_mono/dummy_event_manager.c
+++ b/src/tests/efl_mono/dummy_event_manager.c
@@ -43,12 +43,6 @@ _dummy_event_manager_emitter_set(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *
43 pd->emitter = emitter; 43 pd->emitter = emitter;
44} 44}
45 45
46static Efl_Object*
47_dummy_event_manager_emitter_get(EINA_UNUSED Eo const *obj, Dummy_Event_Manager_Data *pd)
48{
49 return pd->emitter;
50}
51
52static Eina_Bool 46static Eina_Bool
53_dummy_event_manager_emit_with_int(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *pd, int data) 47_dummy_event_manager_emit_with_int(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *pd, int data)
54{ 48{
diff --git a/src/tests/efl_mono/dummy_event_manager.eo b/src/tests/efl_mono/dummy_event_manager.eo
index 5c8b1d0791..b16f7b92cb 100644
--- a/src/tests/efl_mono/dummy_event_manager.eo
+++ b/src/tests/efl_mono/dummy_event_manager.eo
@@ -4,6 +4,8 @@ class Dummy.Event_Manager extends Efl.Object {
4 4
5 methods { 5 methods {
6 @property emitter { 6 @property emitter {
7 set {
8 }
7 values { 9 values {
8 emitter: Efl.Object @move; 10 emitter: Efl.Object @move;
9 } 11 }
diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c
index 19539906f4..b87aff1cd4 100644
--- a/src/tests/efl_mono/dummy_test_object.c
+++ b/src/tests/efl_mono/dummy_test_object.c
@@ -16,7 +16,6 @@
16 16
17#define DUMMY_TEST_IFACE_PROTECTED 17#define DUMMY_TEST_IFACE_PROTECTED
18 18
19#include <assert.h>
20#include "libefl_mono_native_test.h" 19#include "libefl_mono_native_test.h"
21 20
22typedef struct Dummy_Test_Object_Data 21typedef struct Dummy_Test_Object_Data
@@ -4613,36 +4612,6 @@ void _dummy_test_object_multi_valued_prop_set(Eo* obj EINA_UNUSED, Dummy_Test_Ob
4613 pd->prop2 = prop2; 4612 pd->prop2 = prop2;
4614} 4613}
4615 4614
4616void _dummy_test_object_keyed_multi_valued_prop_get(Eo const* obj EINA_UNUSED, Dummy_Test_Object_Data* pd, int prop_key1, int* prop1, int* prop2)
4617{
4618 assert (prop_key1 == 100);
4619 *prop1 = pd->prop1;
4620 *prop2 = pd->prop2;
4621}
4622
4623void _dummy_test_object_keyed_multi_valued_prop_set(Eo* obj EINA_UNUSED, Dummy_Test_Object_Data* pd, int prop_key1, int prop1, int prop2)
4624{
4625 assert (prop_key1 == 100);
4626 pd->prop1 = prop1;
4627 pd->prop2 = prop2;
4628}
4629
4630void _dummy_test_object_multi_keyed_multi_valued_prop_get(Eo const* obj EINA_UNUSED, Dummy_Test_Object_Data* pd, int prop_key1, int prop_key2, int* prop1, int* prop2)
4631{
4632 assert (prop_key1 == 100);
4633 assert (prop_key2 == 101);
4634 *prop1 = pd->prop1;
4635 *prop2 = pd->prop2;
4636}
4637
4638void _dummy_test_object_multi_keyed_multi_valued_prop_set(Eo* obj EINA_UNUSED, Dummy_Test_Object_Data* pd, int prop_key1, int prop_key2, int prop1, int prop2)
4639{
4640 assert (prop_key1 == 100);
4641 assert (prop_key2 == 101);
4642 pd->prop1 = prop1;
4643 pd->prop2 = prop2;
4644}
4645
4646/* Class Properties */ 4615/* Class Properties */
4647static int _dummy_test_object_klass_prop = 0; 4616static int _dummy_test_object_klass_prop = 0;
4648 4617
diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo
index 37c08cb495..cf2ae7ce03 100644
--- a/src/tests/efl_mono/dummy_test_object.eo
+++ b/src/tests/efl_mono/dummy_test_object.eo
@@ -1581,31 +1581,6 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
1581 } 1581 }
1582 } 1582 }
1583 1583
1584 @property keyed_multi_valued_prop {
1585 get {}
1586 set {}
1587 keys {
1588 key1: int;
1589 }
1590 values {
1591 prop1: int;
1592 prop2: int;
1593 }
1594 }
1595
1596 @property multi_keyed_multi_valued_prop {
1597 get {}
1598 set {}
1599 keys {
1600 key1: int;
1601 key2: int;
1602 }
1603 values {
1604 prop1: int;
1605 prop2: int;
1606 }
1607 }
1608
1609 @property klass_prop @static { 1584 @property klass_prop @static {
1610 get {} 1585 get {}
1611 set {} 1586 set {}