summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-12-17 22:36:33 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-12-18 22:12:17 -0300
commit518a6cc57d15d2de754d019f7f4c41686aad91a8 (patch)
treed19ffad3c284035b566f17ad23dfe54e1cb165e6
parent28271776d8a10cfe5c7cc0acc0c864d2bff5b458 (diff)
WIP: Generating fields in interface indexersdevs/lauromoura/D10791-indexers
Needs to sort out the generation of indexer types for the fields of non-public interface properties that are generated in concrete classes. (Mainly the if/else around function_definition.hh 690)
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh78
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh22
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_common.cs2
4 files changed, 77 insertions, 27 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index 70bc34a..a66f7a8 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -165,7 +165,7 @@ inline bool is_property_blacklisted(std::string const& name)
165 // Setter returns a future 165 // Setter returns a future
166 , "Efl.IModel.Property" 166 , "Efl.IModel.Property"
167 // Protected 167 // Protected
168 , "Efl.Access.IAction.ActionName" 168 // , "Efl.Access.IAction.ActionName"
169 , "Efl.Access.IAction.ActionLocalizedName" 169 , "Efl.Access.IAction.ActionLocalizedName"
170 , "Efl.Access.IComponent.Extents" 170 , "Efl.Access.IComponent.Extents"
171 , "Efl.Access.IText.AccessSelection" 171 , "Efl.Access.IText.AccessSelection"
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 86eb2db..423d61c 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -356,7 +356,6 @@ struct property_wrapper_definition_generator
356 , attributes::property_def const& property 356 , attributes::property_def const& property
357 , Context const& context 357 , Context const& context
358 , std::string scope, std::string get_scope, std::string set_scope 358 , std::string scope, std::string get_scope, std::string set_scope
359 , std::string class_name
360 , C1 keys, C2 values 359 , C1 keys, C2 values
361 , bool is_interface 360 , bool is_interface
362 , bool is_concrete_for_interface 361 , bool is_concrete_for_interface
@@ -380,16 +379,15 @@ struct property_wrapper_definition_generator
380 379
381 std::string parentship = "\n"; 380 std::string parentship = "\n";
382 381
383 bool is_self_property = *implementing_klass == *klass_from_property; 382 if (helpers::is_impl_of_interface_property_indexer(property, *klass_from_property, *implementing_klass, context))
384
385 if (!(is_self_property && !is_concrete_for_interface))
386 parentship = " : " + name_helpers::property_interface_indexer_name(property, *klass_from_property) + "\n"; 383 parentship = " : " + name_helpers::property_interface_indexer_name(property, *klass_from_property) + "\n";
387 384
385 auto klass_from_property_name = name_helpers::klass_full_concrete_or_interface_name(*klass_from_property);
388 if (!as_generator 386 if (!as_generator
389 ( 387 (
390 scope_tab << scope << "class " << name_helpers::property_concrete_indexer_name(property) << parentship 388 scope_tab << scope << "class " << name_helpers::property_concrete_indexer_name(property) << parentship
391 << scope_tab << "{\n" 389 << scope_tab << "{\n"
392 << scope_tab(2) << "public " << class_name << " Self {get; set;}\n" 390 << scope_tab(2) << "public " << klass_from_property_name << " Self {get; set;}\n"
393 << scope_tab(2) << "public " 391 << scope_tab(2) << "public "
394 << type_or_tuple << " this[" << type_or_tuple <<" i]\n" 392 << type_or_tuple << " this[" << type_or_tuple <<" i]\n"
395 << scope_tab(2) << "{\n" 393 << scope_tab(2) << "{\n"
@@ -675,41 +673,44 @@ struct property_wrapper_definition_generator
675 673
676 if (has_indexer) 674 if (has_indexer)
677 { 675 {
676 // The generated indexer wraps the actual property values inside the indexer, so a call like
677 // `obj.IndexedProperty[key] = value` calls the `[key]` indexer method in the indexer class.
678 // That said, we need to replace the property values with the indexer.
678 assert (!!implementing_klass); 679 assert (!!implementing_klass);
679 generate_indexer (sink, property, context, scope, get_scope, set_scope 680 generate_indexer (sink, property, context
680 , klass_name, keys, values 681 , scope, get_scope, set_scope
682 , keys, values
681 , is_interface, is_concrete_for_interface, has_setter); 683 , is_interface, is_concrete_for_interface, has_setter);
682 684
683 generated_values.clear(); 685 generated_values.clear();
686 std::string base_type_name;
687 std::string c_type;
688
689 // FIXME this selection needs to be sorted out.
684 if (!is_interface && *implementing_klass == *klass_from_property 690 if (!is_interface && *implementing_klass == *klass_from_property
685 && !is_concrete_for_interface) 691 && !is_concrete_for_interface)
692 // if (!is_interface && !helpers::is_impl_of_interface_property_indexer(property, *klass_from_property, *implementing_klass, context))
686 { 693 {
687 generated_values.push_back 694 base_type_name = name_helpers::property_concrete_indexer_name(property);
688 (attributes::parameter_def 695 c_type = name_helpers::property_concrete_indexer_name(property);
689 {parameter_direction::in
690 , attributes::type_def
691 {
692 attributes::regular_type_def{name_helpers::property_concrete_indexer_name(property), {attributes::qualifier_info::is_none, ""}, {}}
693 , name_helpers::property_concrete_indexer_name(property)
694 , false, false, false, ""
695 }
696 , "indexer", {}, nullptr
697 });
698 } 696 }
699 else 697 else
700 { 698 {
701 generated_values.push_back 699 base_type_name = name_helpers::property_interface_indexer_name(property, *klass_from_property);
700 c_type = name_helpers::property_interface_indexer_name(property, *klass_from_property);
701 }
702
703 generated_values.push_back
702 (attributes::parameter_def 704 (attributes::parameter_def
703 {parameter_direction::in 705 {parameter_direction::in
704 , attributes::type_def 706 , attributes::type_def
705 { 707 {
706 attributes::regular_type_def{name_helpers::klass_full_concrete_or_interface_name (*klass_from_property) + managed_name + "Indexer", {attributes::qualifier_info::is_none, ""}, {}} 708 attributes::regular_type_def{base_type_name, {attributes::qualifier_info::is_none, ""}, {}}
707 , name_helpers::property_interface_indexer_name(property, *klass_from_property) 709 , c_type
708 , false, false, false, "" 710 , false, false, false, ""
709 } 711 }
710 , "indexer", {}, nullptr 712 , "indexer", {}, nullptr
711 }); 713 });
712 }
713 } 714 }
714 715
715 if (generated_values.size() == 1) 716 if (generated_values.size() == 1)
@@ -781,11 +782,42 @@ struct interface_property_indexer_definition_generator
781 auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass); 782 auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
782 std::string managed_name = name_helpers::property_managed_name(property); 783 std::string managed_name = name_helpers::property_managed_name(property);
783 784
785 auto has_wrapper = helpers::has_property_wrapper(property, implementing_klass, context);
786 // EINA_LOG_ERR("Wrapper bit for property %s of implementing class %s is 0x%X", managed_name.c_str(),
787 // implementing_klass->eolian_name.c_str(), (unsigned int) has_wrapper);
788 if (!(has_wrapper & helpers::has_property_wrapper_bit::has_getter))
789 return true;
790
791 if (!(has_wrapper & helpers::has_property_wrapper_bit::has_indexer))
792 return true;
793
794 auto keys = property.getter->keys;
795 auto values = property.getter->values;
796
797 // Helper generator expressions
798 auto size_not_one = [] (std::vector<attributes::parameter_def> k) { return k.size() != 1; };
799 auto type_or_tuple
800 =
801 (
802 (
803 attribute_conditional(size_not_one)["("]
804 << (type(false) % ", ")
805 << ")"
806 )
807 | *type(false)
808 )
809 ;
810
784 if (!as_generator 811 if (!as_generator
785 ("public interface " << name_helpers::property_interface_indexer_short_name(property, *implementing_klass) << "\n" 812 ("public interface " << name_helpers::property_interface_indexer_short_name(property, *implementing_klass) << "\n"
786 << "{\n" 813 << "{\n"
814 << scope_tab << klass_name << " Self {get; set;}\n"
815 << scope_tab << type_or_tuple << " this[" << type_or_tuple << " i]\n"
816 << scope_tab << "{\n"
817 << scope_tab(2) << "get;\n"
818 << scope_tab << "}\n"
787 << "}\n" 819 << "}\n"
788 ).generate (sink, attributes::unused, context)) 820 ).generate (sink, std::make_tuple(values, values, keys, keys), context))
789 return false; 821 return false;
790 822
791 return true; 823 return true;
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 049f263..625e5d2 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -29,6 +29,7 @@ namespace helpers {
29/* General helpers, not related directly with generating strings (those go in the name_helpers.hh). */ 29/* General helpers, not related directly with generating strings (those go in the name_helpers.hh). */
30 30
31namespace attributes = efl::eolian::grammar::attributes; 31namespace attributes = efl::eolian::grammar::attributes;
32namespace grammar = efl::eolian::grammar;
32 33
33inline bool need_struct_conversion(attributes::regular_type_def const* regular) 34inline bool need_struct_conversion(attributes::regular_type_def const* regular)
34{ 35{
@@ -353,8 +354,7 @@ has_property_wrapper_bit has_property_wrapper(attributes::property_def const& pr
353 else if (is_concrete) return r; 354 else if (is_concrete) return r;
354 } 355 }
355 356
356 // EINA_LOG_ERR("Generating property %s", name_helpers::property_managed_name(property).c_str()); 357 // C# interface can have only public methods.
357 // C# interface can have only
358 if (is_interface) 358 if (is_interface)
359 { 359 {
360 has_getter = has_getter && property.getter->scope == attributes::member_scope:: scope_public; 360 has_getter = has_getter && property.getter->scope == attributes::member_scope:: scope_public;
@@ -406,6 +406,24 @@ has_property_wrapper_bit has_property_wrapper(attributes::property_def const& pr
406 return r; 406 return r;
407} 407}
408 408
409template<typename Context>
410bool is_impl_of_interface_property_indexer(attributes::property_def const& property
411 , attributes::klass_def const& klass_from_property
412 , attributes::klass_def const& implementing_klass
413 , Context const& context)
414{
415 bool is_self_property = implementing_klass == klass_from_property;
416
417 // EINA_LOG_ERR("Generating indexer for property %s", name_helpers::property_managed_name(property).c_str());
418 if (is_self_property)
419 return false;
420 bool original_klass_is_interface = helpers::is_managed_interface(klass_from_property);
421 auto iface_context = grammar::context_add_tag(class_context{class_context::interface}, context);
422
423 auto wrapper_bit = helpers::has_property_wrapper(property, &klass_from_property, iface_context);
424 return wrapper_bit & helpers::has_property_wrapper_bit::has_indexer;
425}
426
409} // namespace helpers 427} // namespace helpers
410 428
411} // namespace eolian_mono 429} // namespace eolian_mono
diff --git a/src/bindings/mono/eldbus_mono/eldbus_common.cs b/src/bindings/mono/eldbus_mono/eldbus_common.cs
index 2606fe9..9bece88 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_common.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_common.cs
@@ -40,7 +40,7 @@ public static class Timeout
40/// <summary> 40/// <summary>
41/// The path to an object. 41/// The path to an object.
42/// <para>Since EFL 1.23.</para> 42/// <para>Since EFL 1.23.</para>
43/// </summary> 43/// /// </summary>
44[StructLayout(LayoutKind.Sequential)] 44[StructLayout(LayoutKind.Sequential)]
45public struct ObjectPath : IEquatable<ObjectPath> 45public struct ObjectPath : IEquatable<ObjectPath>
46{ 46{