summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-03-21 14:38:45 -0300
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-03-21 14:48:33 -0300
commit0881d1524b6d3996a29b68820690f97821116585 (patch)
treec3fa39f72ad50b7f6ac0a0eb8652ba539af1c5a3
parentf36d8b9bb1792730bc96c2cf07126361ccfe4ebe (diff)
efl-csharp: Add back I prefix for interfaces.
Summary: Conforming to C# coding conventions. For properties, now we only generate a wrapper if its name does not clash with the name of the class that would be implementing it. Fixes T7751 Reviewers: vitor.sousa, felipealmeida, segfaultxavi Reviewed By: vitor.sousa, segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7751 Differential Revision: https://phab.enlightenment.org/D8397
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh18
-rw-r--r--src/bin/eolian_mono/eolian/mono/documentation.hh25
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh20
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh10
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh29
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh2
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs25
-rw-r--r--src/tests/efl_mono/Eo.cs49
-rw-r--r--src/tests/efl_mono/Inheritance.cs2
-rw-r--r--src/tests/efl_mono/TestUtils.cs10
-rw-r--r--src/tests/efl_mono/dummy_test_object.eo11
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c12
12 files changed, 191 insertions, 22 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index 2b9d8ad4bf..77be1c0da8 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -115,7 +115,7 @@ inline bool is_property_blacklisted(std::string const& name)
115{ 115{
116 return name == "Efl.Input.Key.Key" 116 return name == "Efl.Input.Key.Key"
117 || name == "Efl.Input.Hold.Hold" 117 || name == "Efl.Input.Hold.Hold"
118 || name == "Efl.Text.Text"; 118 || name == "Efl.IText.Text";
119} 119}
120 120
121template<typename Context> 121template<typename Context>
@@ -133,6 +133,22 @@ inline bool is_property_blacklisted(attributes::property_def const& property, Co
133} 133}
134 134
135template<typename Context> 135template<typename Context>
136inline bool is_property_blacklisted(attributes::property_def const& property,
137 attributes::klass_def const& implementing_class,
138 Context context)
139{
140 std::string property_name = name_helpers::property_managed_name(property);
141 std::string klass_name = name_helpers::klass_concrete_or_interface_name(implementing_class);
142
143 // This property wrapper is invalidated as it would clash with the implementing
144 // class constructor. CS
145 if (property_name == klass_name)
146 return true;
147
148 return is_property_blacklisted(property, context);
149}
150
151template<typename Context>
136inline bool is_class_blacklisted(attributes::klass_def const& cls, Context context) 152inline bool is_class_blacklisted(attributes::klass_def const& cls, Context context)
137{ 153{
138 auto options = efl::eolian::grammar::context_find_tag<options_context>(context); 154 auto options = efl::eolian::grammar::context_find_tag<options_context>(context);
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh
index 6d9399bb3a..1d65bcb076 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -37,6 +37,24 @@ struct documentation_generator
37 return n; 37 return n;
38 } 38 }
39 39
40 // Gets the eolian ref for the given class, prepending I for interfaces.
41 static std::string object_ref_conversion(const Eolian_Object *cls)
42 {
43 auto klass_type = ::eolian_class_type_get((const Eolian_Class *)cls);
44 auto full_eolian_name = name_helpers::managed_namespace(::eolian_object_name_get(cls));
45 if (klass_type == EOLIAN_CLASS_MIXIN || klass_type == EOLIAN_CLASS_INTERFACE)
46 {
47 size_t pos = full_eolian_name.rfind(".");
48 if (pos == std::string::npos)
49 pos = 0;
50 else
51 pos++;
52 full_eolian_name.insert(pos, "I");
53 }
54 return full_eolian_name;
55 }
56
57
40 // Turns a function name from EO convention to EFL# convention. 58 // Turns a function name from EO convention to EFL# convention.
41 // The name_tail parameter is the last 4 chars of the original string, which 59 // The name_tail parameter is the last 4 chars of the original string, which
42 // could be ".set" or ".get" and in this case they are ignored by Eolian. 60 // could be ".set" or ".get" and in this case they are ignored by Eolian.
@@ -45,7 +63,7 @@ struct documentation_generator
45 { 63 {
46 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function); 64 ::Eolian_Function_Type ftype = ::eolian_function_type_get(function);
47 const char* eo_name = ::eolian_function_name_get(function); 65 const char* eo_name = ::eolian_function_name_get(function);
48 std::string name = name_helpers::managed_namespace(::eolian_object_name_get(klass)); 66 std::string name = object_ref_conversion(klass);
49 switch(ftype) 67 switch(ftype)
50 { 68 {
51 case ::EOLIAN_METHOD: 69 case ::EOLIAN_METHOD:
@@ -123,7 +141,7 @@ struct documentation_generator
123 if (blacklist::is_struct_blacklisted(ref)) return ""; 141 if (blacklist::is_struct_blacklisted(ref)) return "";
124 break; 142 break;
125 case ::EOLIAN_OBJECT_EVENT: 143 case ::EOLIAN_OBJECT_EVENT:
126 ref = name_helpers::managed_namespace(::eolian_object_name_get(data)); 144 ref = object_ref_conversion(data);
127 ref += "."; 145 ref += ".";
128 ref += name_helpers::managed_event_name(::eolian_object_name_get(data2)); 146 ref += name_helpers::managed_event_name(::eolian_object_name_get(data2));
129 break; 147 break;
@@ -151,6 +169,9 @@ struct documentation_generator
151 // If the reference cannot be resolved, just return an empty string and 169 // If the reference cannot be resolved, just return an empty string and
152 // it won't be converted into a <see> tag. 170 // it won't be converted into a <see> tag.
153 break; 171 break;
172 case ::EOLIAN_OBJECT_CLASS:
173 ref = object_ref_conversion(data);
174 break;
154 default: 175 default:
155 ref = name_helpers::managed_namespace(::eolian_object_name_get(data)); 176 ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
156 break; 177 break;
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 67dfcc0ce4..465a8fee71 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -219,7 +219,7 @@ struct property_wrapper_definition_generator
219 template<typename OutputIterator, typename Context> 219 template<typename OutputIterator, typename Context>
220 bool generate(OutputIterator sink, attributes::property_def const& property, Context context) const 220 bool generate(OutputIterator sink, attributes::property_def const& property, Context context) const
221 { 221 {
222 if (blacklist::is_property_blacklisted(property, context)) 222 if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
223 return true; 223 return true;
224 224
225 bool interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface; 225 bool interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
@@ -281,7 +281,19 @@ struct property_wrapper_definition_generator
281 281
282 return true; 282 return true;
283 } 283 }
284 attributes::klass_def const* implementing_klass;
285};
286struct property_wrapper_definition_parameterized
287{
288 property_wrapper_definition_generator operator()(attributes::klass_def const& klass) const
289 {
290 return {&klass};
291 }
284} const property_wrapper_definition; 292} const property_wrapper_definition;
293property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized)
294{
295 return {};
296}
285 297
286} 298}
287 299
@@ -294,6 +306,8 @@ struct is_eager_generator< ::eolian_mono::native_function_definition_generator>
294template <> 306template <>
295struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 307struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
296template <> 308template <>
309struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
310template <>
297struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {}; 311struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
298template <> 312template <>
299struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {}; 313struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
@@ -301,6 +315,8 @@ template <>
301struct is_generator< ::eolian_mono::function_definition_parameterized> : std::true_type {}; 315struct is_generator< ::eolian_mono::function_definition_parameterized> : std::true_type {};
302template <> 316template <>
303struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {}; 317struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
318template <>
319struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
304 320
305namespace type_traits { 321namespace type_traits {
306template <> 322template <>
@@ -314,6 +330,8 @@ struct attributes_needed< ::eolian_mono::native_function_definition_generator> :
314 330
315template <> 331template <>
316struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {}; 332struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
333template <>
334struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {};
317} 335}
318 336
319} } } 337} } }
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 71228edb8f..20045de39b 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -177,7 +177,7 @@ struct klass
177 ).generate(sink, p, iface_cxt)) 177 ).generate(sink, p, iface_cxt))
178 return false; 178 return false;
179 179
180 if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, iface_cxt)) 180 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, iface_cxt))
181 return false; 181 return false;
182 182
183 // End of interface declaration 183 // End of interface declaration
@@ -272,13 +272,13 @@ struct klass
272 return false; 272 return false;
273 273
274 // Property wrappers 274 // Property wrappers
275 if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, concrete_cxt)) 275 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt))
276 return false; 276 return false;
277 277
278 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt)) 278 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
279 { 279 {
280 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 280 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
281 if (!as_generator(*(property_wrapper_definition)).generate(sink, c.properties, concrete_cxt)) 281 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt))
282 return false; 282 return false;
283 } 283 }
284 284
@@ -353,13 +353,13 @@ struct klass
353 return false; 353 return false;
354 354
355 // Property wrappers 355 // Property wrappers
356 if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, inherit_cxt)) 356 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, inherit_cxt))
357 return false; 357 return false;
358 358
359 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt)) 359 for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt))
360 { 360 {
361 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); 361 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
362 if (!as_generator(*(property_wrapper_definition)).generate(sink, c.properties, inherit_cxt)) 362 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, inherit_cxt))
363 return false; 363 return false;
364 } 364 }
365 365
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index 074fd4f7ed..698976446e 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -278,7 +278,11 @@ struct klass_interface_name_generator
278 template <typename T> 278 template <typename T>
279 std::string operator()(T const& klass) const 279 std::string operator()(T const& klass) const
280 { 280 {
281 return utils::remove_all(klass.eolian_name, '_'); 281 std::string name = utils::remove_all(klass.eolian_name, '_');
282 if (klass.type == attributes::class_type::mixin || klass.type == attributes::class_type::interface_)
283 return "I" + name;
284 else
285 return name;
282 } 286 }
283 287
284 template <typename OutputIterator, typename Attr, typename Context> 288 template <typename OutputIterator, typename Attr, typename Context>
@@ -306,10 +310,23 @@ struct klass_full_interface_name_generator
306template<typename T> 310template<typename T>
307inline std::string klass_concrete_name(T const& klass) 311inline std::string klass_concrete_name(T const& klass)
308{ 312{
309 std::string name = utils::remove_all(klass.eolian_name, '_'); 313 if (klass.type == attributes::class_type::mixin || klass.type == attributes::class_type::interface_)
310 if (klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_) 314 return klass_interface_name(klass) + "Concrete";
311 return name; 315
312 return name + "Concrete"; 316 return utils::remove_all(klass.eolian_name, '_');
317}
318
319template<typename T>
320inline std::string klass_concrete_or_interface_name(T const& klass)
321{
322 switch(klass.type)
323 {
324 case attributes::class_type::abstract_:
325 case attributes::class_type::regular:
326 return klass_concrete_name(klass);
327 default:
328 return klass_interface_name(klass);
329 }
313} 330}
314 331
315struct klass_full_concrete_name_generator 332struct klass_full_concrete_name_generator
@@ -408,7 +425,7 @@ inline std::string managed_event_name(std::string const& name)
408inline std::string managed_event_args_short_name(attributes::event_def const& evt) 425inline std::string managed_event_args_short_name(attributes::event_def const& evt)
409{ 426{
410 std::string ret; 427 std::string ret;
411 ret = klass_interface_name(evt.klass); 428 ret = klass_concrete_or_interface_name(evt.klass);
412 return ret + name_helpers::managed_event_name(evt.name) + "_Args"; 429 return ret + name_helpers::managed_event_name(evt.name) + "_Args";
413} 430}
414 431
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
index 2a8d2e1b00..7894086f95 100644
--- a/src/bin/eolian_mono/eolian/mono/part_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -27,7 +27,7 @@ struct part_definition_generator
27 << scope_tab << "{\n" 27 << scope_tab << "{\n"
28 << scope_tab << scope_tab << "get\n" 28 << scope_tab << scope_tab << "get\n"
29 << scope_tab << scope_tab << "{\n" 29 << scope_tab << scope_tab << "{\n"
30 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.PartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n" 30 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
31 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n" 31 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
32 << scope_tab << scope_tab << "}\n" 32 << scope_tab << scope_tab << "}\n"
33 << scope_tab << "}\n" 33 << scope_tab << "}\n"
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index 13f82cf090..3120dbbbf7 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -12,6 +12,21 @@ using EoG = Efl.Eo.Globals;
12namespace Efl { namespace Eo { 12namespace Efl { namespace Eo {
13 13
14public class Globals { 14public class Globals {
15
16 /// <summary>Represents the type of the native Efl_Class.</summary>
17 public enum EflClassType {
18 /// <summary>Regular EFL classes.</summary>
19 Regular = 0,
20 /// <summary>Non-instantiable efl classes (i.e. Abstracts).</summary>
21 RegularNoInstant,
22 /// <summary>Interface types.</summary>
23 Interface,
24 /// <summary>Mixins types.</summary>
25 Mixin,
26 /// <summary>Invalid class type.</summary>
27 Invalid
28 }
29
15 [return: MarshalAs(UnmanagedType.U1)] 30 [return: MarshalAs(UnmanagedType.U1)]
16 public delegate bool efl_object_init_delegate(); 31 public delegate bool efl_object_init_delegate();
17 public static FunctionWrapper<efl_object_init_delegate> efl_object_init_ptr = 32 public static FunctionWrapper<efl_object_init_delegate> efl_object_init_ptr =
@@ -155,6 +170,7 @@ public class Globals {
155 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass); 170 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass);
156 public delegate IntPtr efl_class_get_delegate(IntPtr obj); 171 public delegate IntPtr efl_class_get_delegate(IntPtr obj);
157 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj); 172 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj);
173 [DllImport(efl.Libs.Eo)] public static extern EflClassType efl_class_type_get(IntPtr klass);
158 public delegate IntPtr dlerror_delegate(); 174 public delegate IntPtr dlerror_delegate();
159 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror(); 175 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
160 176
@@ -542,6 +558,15 @@ public static class ClassRegister
542 string name = Eina.StringConversion.NativeUtf8ToManagedString(namePtr) 558 string name = Eina.StringConversion.NativeUtf8ToManagedString(namePtr)
543 .Replace("_", ""); // Convert Efl C name to C# name 559 .Replace("_", ""); // Convert Efl C name to C# name
544 560
561 var klass_type = Efl.Eo.Globals.efl_class_type_get(klass);
562
563 // When converting to managed, interfaces and mixins gets the 'I' prefix.
564 if (klass_type == Efl.Eo.Globals.EflClassType.Interface || klass_type == Efl.Eo.Globals.EflClassType.Mixin)
565 {
566 var pos = name.LastIndexOf(".");
567 name = name.Insert(pos + 1, "I"); // -1 if not found, inserts at 0 normally
568 }
569
545 var curr_asm = typeof(IWrapper).Assembly; 570 var curr_asm = typeof(IWrapper).Assembly;
546 t = curr_asm.GetType(name); 571 t = curr_asm.GetType(name);
547 if (t == null) 572 if (t == null)
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index 95f9b7e1d8..578ad10790 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -1,5 +1,6 @@
1using System; 1using System;
2using System.Linq; 2using System.Linq;
3using System.Collections.Generic;
3 4
4namespace TestSuite 5namespace TestSuite
5{ 6{
@@ -327,7 +328,7 @@ class TestCsharpProperties
327 public static void test_iface_property() 328 public static void test_iface_property()
328 { 329 {
329 int val = -33; 330 int val = -33;
330 Dummy.TestIface iface = new Dummy.TestObject(); 331 Dummy.ITestIface iface = new Dummy.TestObject();
331 iface.IfaceProp = val; 332 iface.IfaceProp = val;
332 Test.AssertEquals(val, iface.IfaceProp); 333 Test.AssertEquals(val, iface.IfaceProp);
333 } 334 }
@@ -429,7 +430,7 @@ class TestInterfaceConcrete
429 public static void test_iface_concrete_methods() 430 public static void test_iface_concrete_methods()
430 { 431 {
431 var obj = new Dummy.TestObject(); 432 var obj = new Dummy.TestObject();
432 Dummy.TestIface iface = Dummy.TestIfaceConcrete.static_cast(obj); 433 Dummy.ITestIface iface = Dummy.ITestIfaceConcrete.static_cast(obj);
433 434
434 iface.IfaceProp = 1970; 435 iface.IfaceProp = 1970;
435 Test.AssertEquals(iface.IfaceProp, 1970); 436 Test.AssertEquals(iface.IfaceProp, 1970);
@@ -447,11 +448,49 @@ class TestProvider
447 Test.AssertEquals(provider.GetNumber(), 1999); 448 Test.AssertEquals(provider.GetNumber(), 1999);
448 } 449 }
449 450
451 private class ProviderHolder : Dummy.TestObject
452 {
453 private Dummy.TestObject provider;
454 public string ProviderName
455 {
456 get
457 {
458 return "MyProvider";
459 }
460 }
461
462 public ProviderHolder() : base(null)
463 {
464 this.provider = new Dummy.TestObject(this);
465 this.provider.Name = this.ProviderName;
466 this.provider.IfaceProp = 1997;
467 }
468
469 public override Efl.Object FindProvider(System.Type type)
470 {
471 Console.WriteLine("Called FindProvider");
472 if (type == typeof(Dummy.ITestIface))
473 {
474 return this.provider;
475 }
476 else
477 {
478 return null;
479 }
480 }
481 }
482
450 public static void test_find_provider_iface() 483 public static void test_find_provider_iface()
451 { 484 {
452 var obj = new Dummy.TestObject(); 485 var obj = new ProviderHolder();
453 Dummy.TestIface provider = Dummy.TestIfaceConcrete.static_cast(obj.FindProvider(typeof(Dummy.TestIface))); 486
454 Test.AssertEquals(provider.GetIfaceProp(), 1997); 487 var provider = obj.CallFindProvider(typeof(Efl.Object));
488 Test.AssertNull(provider, msg : "Unkonw provider must be null");
489
490 provider = obj.CallFindProviderForIface();
491 Test.AssertNotNull(provider, msg : "Provider of ITestIFace must not be null");
492 Test.AssertEquals(provider.Name, obj.ProviderName, "Provider name does not match expected");
493
455 } 494 }
456} 495}
457 496
diff --git a/src/tests/efl_mono/Inheritance.cs b/src/tests/efl_mono/Inheritance.cs
index 344c6da71f..befdd3a7b4 100644
--- a/src/tests/efl_mono/Inheritance.cs
+++ b/src/tests/efl_mono/Inheritance.cs
@@ -20,7 +20,7 @@ class TestInheritance
20 } 20 }
21 } 21 }
22 22
23 internal class Inherit2 : Dummy.TestObject, Dummy.InheritIface 23 internal class Inherit2 : Dummy.TestObject, Dummy.IInheritIface
24 { 24 {
25 override public void IntOut (int x, out int y) 25 override public void IntOut (int x, out int y)
26 { 26 {
diff --git a/src/tests/efl_mono/TestUtils.cs b/src/tests/efl_mono/TestUtils.cs
index 615a8f3c6d..e7daf0559d 100644
--- a/src/tests/efl_mono/TestUtils.cs
+++ b/src/tests/efl_mono/TestUtils.cs
@@ -186,6 +186,16 @@ public static class Test
186 if (reference != null) 186 if (reference != null)
187 throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}"); 187 throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}");
188 } 188 }
189
190 /// <summary> Asserts if the given reference is not null.</summary>
191 public static void AssertNotNull(object reference, String msg = "Reference is null",
192 [CallerLineNumber] int line = 0,
193 [CallerFilePath] string file = null,
194 [CallerMemberName] string member = null)
195 {
196 if (reference == null)
197 throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}");
198 }
189} 199}
190 200
191 201
diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo
index ed63eaee64..5475c81c3c 100644
--- a/src/tests/efl_mono/dummy_test_object.eo
+++ b/src/tests/efl_mono/dummy_test_object.eo
@@ -1388,6 +1388,17 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
1388 get_setter_only { 1388 get_setter_only {
1389 return: int; 1389 return: int;
1390 } 1390 }
1391
1392 call_find_provider {
1393 params {
1394 @in type: const(Efl.Class);
1395 }
1396 return: Efl.Object;
1397 }
1398
1399 call_find_provider_for_iface {
1400 return: Efl.Object;
1401 }
1391 } 1402 }
1392 implements { 1403 implements {
1393 class.constructor; 1404 class.constructor;
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index 7e3bffe111..7b4dd1a77f 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -3929,6 +3929,18 @@ Eo * _dummy_test_object_efl_object_provider_find(EINA_UNUSED const Eo *obj, Dumm
3929 return efl_provider_find(efl_super(obj, DUMMY_TEST_OBJECT_CLASS), klass); 3929 return efl_provider_find(efl_super(obj, DUMMY_TEST_OBJECT_CLASS), klass);
3930} 3930}
3931 3931
3932Efl_Object *_dummy_test_object_call_find_provider(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, const Efl_Class *type)
3933{
3934 printf("CALLING FIND PROVIDER FROM C");
3935 return efl_provider_find(obj, type);
3936}
3937
3938Efl_Object *_dummy_test_object_call_find_provider_for_iface(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd)
3939{
3940 printf("CALLING FIND PROVIDER FROM C");
3941 return efl_provider_find(obj, DUMMY_TEST_IFACE_INTERFACE);
3942}
3943
3932/// Dummy.Child 3944/// Dummy.Child
3933 3945
3934static Efl_Object * 3946static Efl_Object *