summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYeongjong Lee <yj34.lee@samsung.com>2020-01-23 07:30:13 +0900
committerWooHyun Jung <wh0705.jung@samsung.com>2020-01-23 07:30:14 +0900
commit97098dcc50b62e51dad3469619ed55242ca01a80 (patch)
tree33d372fef1f883a12f4172ceb9ab07223ca28805
parent5137f6d143c681fcf4f53e4e45df8af1a538ae75 (diff)
csharp: cleanup concrete class
Summary: Concrete class is only used to call static member of NativeMethod. they don't need any inheritance and implementation of c functions. Depends on D9893 Test Plan: ninja test Reviewers: lauromoura, felipealmeida Subscribers: Jaehyun_Cho, woohyun, segfaultxavi, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9894
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh108
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh17
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh3
-rw-r--r--src/bindings/mono/eina_mono/eina_container_common.cs24
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs12
-rw-r--r--src/tests/efl_mono/Eo.cs32
-rw-r--r--src/tests/efl_mono/dummy_test_object.c22
-rw-r--r--src/tests/efl_mono/dummy_test_object.eo17
9 files changed, 106 insertions, 131 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index 7405f8c2e1..b6cb4aa511 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -131,7 +131,7 @@ struct unpack_event_args_visitor
131 } 131 }
132 bool operator()(grammar::attributes::klass_name const& cls) const 132 bool operator()(grammar::attributes::klass_name const& cls) const
133 { 133 {
134 return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context); 134 return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_interface_name(cls) + ")").generate(sink, attributes::unused, *context);
135 } 135 }
136 bool operator()(attributes::complex_type_def const& types) const 136 bool operator()(attributes::complex_type_def const& types) const
137 { 137 {
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 072ea6c143..da6fd6d45c 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -193,98 +193,9 @@ struct klass
193 auto concrete_cxt = context_add_tag(class_context{class_context::concrete, 193 auto concrete_cxt = context_add_tag(class_context{class_context::concrete,
194 name_helpers::klass_full_concrete_or_interface_name(cls)}, 194 name_helpers::klass_full_concrete_or_interface_name(cls)},
195 context); 195 context);
196 auto concrete_name = name_helpers::klass_concrete_name(cls);
197 auto interface_name = name_helpers::klass_interface_name(cls);
198 196
199 // We can't make these internal yet as they have methods that are used by 197 if(!generate_native_inherit_class(sink, cls, change_indentation(indent, concrete_cxt)))
200 // other classes that implement the interface.
201 if(!as_generator
202 (
203 documentation(1)
204 << scope_tab << "public sealed " << (is_partial ? "partial ":"") << "class " << concrete_name << " :\n"
205 << scope_tab(2) << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "")
206 << ",\n" << scope_tab(2) << interface_name
207 << *(",\n" << scope_tab(2) << name_helpers::klass_full_concrete_or_interface_name) << "\n"
208 << scope_tab << "{\n"
209 ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt))
210 return false;
211
212 if (!generate_fields(sink, cls, concrete_cxt))
213 return false;
214
215 if (!as_generator
216 (
217 scope_tab(2) << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
218 << scope_tab(2) << "/// Do not call this constructor directly.</summary>\n"
219 << scope_tab(2) << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
220 << scope_tab(2) << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n"
221 << scope_tab(2) << "{\n"
222 << scope_tab(2) << "}\n\n"
223 )
224 .generate(sink, attributes::unused, concrete_cxt))
225 return false;
226
227 if (!as_generator
228 (
229 scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
230 << ")] internal static extern System.IntPtr\n"
231 << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
232 << scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << interface_name << "\"/> class.\n"
233 << scope_tab(2) << "/// Internal usage: This is used when interacting with C code and should not be used directly.</summary>\n"
234 << scope_tab(2) << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
235 << scope_tab(2) << "private " << concrete_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
236 << scope_tab(2) << "{\n"
237 << scope_tab(2) << "}\n\n"
238 )
239 .generate(sink, attributes::unused, concrete_cxt))
240 return false;
241
242 if (!generate_events(sink, cls, concrete_cxt))
243 return false;
244
245 if (!as_generator(lit("#pragma warning disable CS0628\n")).generate(sink, attributes::unused, concrete_cxt))
246 return false;
247
248 // Parts
249 if(!as_generator(*(part_definition))
250 .generate(sink, cls.parts, concrete_cxt)) return false;
251
252 // Concrete function definitions
253 auto implemented_methods = helpers::get_all_implementable_methods(cls, concrete_cxt);
254 if(!as_generator(*(function_definition))
255 .generate(sink, implemented_methods, concrete_cxt)) return false;
256
257 // Async wrappers
258 if(!as_generator(*(async_function_definition)).generate(sink, implemented_methods, concrete_cxt))
259 return false;
260
261 // Property wrappers
262 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt))
263 return false;
264
265 for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
266 {
267 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
268 if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt))
269 return false;
270 }
271
272 if (!as_generator(lit("#pragma warning restore CS0628\n")).generate(sink, attributes::unused, concrete_cxt))
273 return false;
274
275 // Copied from nativeinherit class, used when setting up providers.
276 if(!as_generator(
277 scope_tab(2) << "private static IntPtr GetEflClassStatic()\n"
278 << scope_tab(2) << "{\n"
279 << scope_tab(2) << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
280 << scope_tab(2) << "}\n\n"
281 ).generate(sink, attributes::unused, concrete_cxt))
282 return false;
283
284 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt)))
285 return true; 198 return true;
286
287 if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
288 } 199 }
289 200
290 // Inheritable class 201 // Inheritable class
@@ -427,6 +338,7 @@ struct klass
427 auto inherit_name = name_helpers::klass_inherit_name(cls); 338 auto inherit_name = name_helpers::klass_inherit_name(cls);
428 auto implementable_methods = helpers::get_all_registerable_methods(cls, context); 339 auto implementable_methods = helpers::get_all_registerable_methods(cls, context);
429 bool root = !helpers::has_regular_ancestor(cls); 340 bool root = !helpers::has_regular_ancestor(cls);
341 bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
430 auto const& indent = current_indentation(inative_cxt).inc(); 342 auto const& indent = current_indentation(inative_cxt).inc();
431 std::string klass_since; 343 std::string klass_since;
432 344
@@ -447,11 +359,23 @@ struct klass
447 << klass_since 359 << klass_since
448 << indent << "/// </summary>\n" 360 << indent << "/// </summary>\n"
449 << indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n" 361 << indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n"
450 << indent << "internal new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" 362 << indent << "internal " << (is_concrete ? "" : "new ") << "class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n"
451 << indent << "{\n" 363 << indent << "{\n"
452 ).generate(sink, attributes::unused, inative_cxt)) 364 ).generate(sink, attributes::unused, inative_cxt))
453 return false; 365 return false;
454 366
367 if(is_concrete)
368 {
369 if (!as_generator
370 (
371 scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
372 << ")] internal static extern System.IntPtr\n"
373 << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
374 )
375 .generate(sink, attributes::unused, inative_cxt))
376 return false;
377 }
378
455 if(implementable_methods.size() >= 1) 379 if(implementable_methods.size() >= 1)
456 { 380 {
457 if(!as_generator( 381 if(!as_generator(
@@ -502,7 +426,7 @@ struct klass
502 ).generate(sink, attributes::unused, inative_cxt)) 426 ).generate(sink, attributes::unused, inative_cxt))
503 return false; 427 return false;
504 428
505 if (!root || context_find_tag<class_context>(context).current_wrapper_kind != class_context::concrete) 429 if (!root || !is_concrete)
506 if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type, false));\n").generate(sink, attributes::unused, inative_cxt)) 430 if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type, false));\n").generate(sink, attributes::unused, inative_cxt))
507 return false; 431 return false;
508 432
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index 7f71d9279b..ae958ba623 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -399,9 +399,7 @@ struct klass_full_interface_name_generator
399template<typename T> 399template<typename T>
400inline std::string klass_concrete_name(T const& klass) 400inline std::string klass_concrete_name(T const& klass)
401{ 401{
402 return utils::remove_all(klass.eolian_name, '_') + ((klass.type == attributes::class_type::mixin 402 return utils::remove_all(klass.eolian_name, '_');
403 || klass.type == attributes::class_type::interface_)
404 ? "Concrete" : "");
405} 403}
406 404
407template<typename T> 405template<typename T>
@@ -467,14 +465,19 @@ inline std::string klass_inherit_name(T const& klass)
467} 465}
468 466
469template<typename T> 467template<typename T>
470inline std::string klass_native_inherit_name(EINA_UNUSED T const& klass) 468inline std::string klass_native_inherit_name(T const& klass)
471{ 469{
472 return "NativeMethods"; 470 return ((klass.type == attributes::class_type::mixin
471 || klass.type == attributes::class_type::interface_) ? klass_interface_name(klass) : "") + "NativeMethods";
473} 472}
474 473
475template<typename T> 474template<typename T>
476inline std::string klass_full_native_inherit_name(T const& klass) 475inline std::string klass_full_native_inherit_name(T const& klass)
477{ 476{
477 if(klass.type == attributes::class_type::mixin
478 || klass.type == attributes::class_type::interface_)
479 return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_native_inherit_name(klass);
480
478 return klass_full_concrete_name(klass) + "." + klass_native_inherit_name(klass); 481 return klass_full_concrete_name(klass) + "." + klass_native_inherit_name(klass);
479} 482}
480 483
@@ -487,6 +490,10 @@ inline std::string klass_get_name(T const& clsname)
487template<typename T> 490template<typename T>
488inline std::string klass_get_full_name(T const& clsname) 491inline std::string klass_get_full_name(T const& clsname)
489{ 492{
493 if(clsname.type == attributes::class_type::mixin
494 || clsname.type == attributes::class_type::interface_)
495 return klass_get_name(clsname);
496
490 return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname); 497 return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname);
491} 498}
492 499
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 176b5518d7..1f4152aa74 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -190,11 +190,10 @@ struct to_external_field_convert_generator
190 if (klass) 190 if (klass)
191 { 191 {
192 auto interface_name = name_helpers::klass_full_interface_name(*klass); 192 auto interface_name = name_helpers::klass_full_interface_name(*klass);
193 auto concrete_name = name_helpers::klass_full_concrete_name(*klass);
194 if (!as_generator( 193 if (!as_generator(
195 "\n" 194 "\n"
196 << indent << scope_tab << scope_tab << "_external_struct." << string 195 << indent << scope_tab << scope_tab << "_external_struct." << string
197 << " = (" << concrete_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n" 196 << " = (" << interface_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n"
198 ).generate(sink, std::make_tuple(field_name, field_name), context)) 197 ).generate(sink, std::make_tuple(field_name, field_name), context))
199 return false; 198 return false;
200 } 199 }
diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs
index 192469a033..a07153e51a 100644
--- a/src/bindings/mono/eina_mono/eina_container_common.cs
+++ b/src/bindings/mono/eina_mono/eina_container_common.cs
@@ -1003,22 +1003,6 @@ internal static class TraitFunctions
1003 1003
1004 private static IDictionary<System.Type, object> register = new Dictionary<System.Type, object>(); 1004 private static IDictionary<System.Type, object> register = new Dictionary<System.Type, object>();
1005 1005
1006 private static System.Type AsEflInstantiableType(System.Type type)
1007 {
1008 if (!IsEflObject(type))
1009 {
1010 return null;
1011 }
1012
1013 if (type.IsInterface)
1014 {
1015 string fullName = type.FullName + "Concrete";
1016 return type.Assembly.GetType(fullName); // That was our best guess...
1017 }
1018
1019 return type; // Not interface, so it should be a concrete.
1020 }
1021
1022 public static object RegisterTypeTraits<T>() 1006 public static object RegisterTypeTraits<T>()
1023 { 1007 {
1024 Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}"); 1008 Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
@@ -1026,14 +1010,6 @@ internal static class TraitFunctions
1026 var type = typeof(T); 1010 var type = typeof(T);
1027 if (IsEflObject(type)) 1011 if (IsEflObject(type))
1028 { 1012 {
1029 System.Type concrete = AsEflInstantiableType(type);
1030 if (concrete == null || !type.IsAssignableFrom(concrete))
1031 {
1032 throw new Exception("Failed to get a suitable concrete class for this type.");
1033 }
1034
1035 // No need to pass concrete as the traits class will use reflection to get the actually most
1036 // derived type returned.
1037 traits = new EflObjectElementTraits<T>(); 1013 traits = new EflObjectElementTraits<T>();
1038 } 1014 }
1039 else if (IsString(type)) 1015 else if (IsString(type))
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index 780735fcca..ceae250bc9 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -1221,14 +1221,12 @@ internal static class ClassRegister
1221 1221
1222 if (objectType.IsInterface) 1222 if (objectType.IsInterface)
1223 { 1223 {
1224 // Try to get the *Concrete class 1224 // Try to get the *NativeMethods class
1225 var assembly = objectType.Assembly; 1225 var nativeMethods = (Efl.Eo.NativeClass)System.Attribute.GetCustomAttributes(objectType)?.FirstOrDefault(attr => attr is Efl.Eo.NativeClass);
1226 objectType = assembly.GetType(objectType.FullName + "Concrete"); 1226 if (nativeMethods == null)
1227
1228 if (objectType == null)
1229 {
1230 return IntPtr.Zero; 1227 return IntPtr.Zero;
1231 } 1228
1229 return nativeMethods.GetEflClass();
1232 } 1230 }
1233 1231
1234 var method = objectType.GetMethod("GetEflClassStatic", 1232 var method = objectType.GetMethod("GetEflClassStatic",
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index 70e9d29c16..8d00155e10 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -385,6 +385,16 @@ class TestEoMultipleChildClasses
385 385
386class TestCsharpProperties 386class TestCsharpProperties
387{ 387{
388
389 private class MyObject : Dummy.TestObject
390 {
391 public MyObject(Efl.Object parent = null) : base(parent)
392 {
393 }
394 private MyObject(ConstructingHandle ch) : base(ch)
395 {
396 }
397 }
388 public static void test_csharp_properties() 398 public static void test_csharp_properties()
389 { 399 {
390 var obj = new Dummy.TestObject(); 400 var obj = new Dummy.TestObject();
@@ -428,6 +438,28 @@ class TestCsharpProperties
428 iface.Dispose(); 438 iface.Dispose();
429 } 439 }
430 440
441 public static void test_iface_value_property()
442 {
443 var obj = new Dummy.TestObject();
444 var prop = new MyObject();
445
446 obj.IfaceValueProp = prop;
447 Test.AssertEquals(obj.IfaceValueProp, prop);
448
449 obj.Dispose();
450 prop.Dispose();
451 }
452
453 public static void test_iface_value_from_c()
454 {
455 var obj = new Dummy.TestObject();
456
457 obj.SetIfaceKlassProp(typeof(MyObject));
458 Test.AssertEquals(obj.IfaceValueFromC.GetType(), typeof(MyObject));
459
460 obj.Dispose();
461 }
462
431 public static void test_csharp_multi_valued_prop() 463 public static void test_csharp_multi_valued_prop()
432 { 464 {
433 var obj = new Dummy.TestObject(); 465 var obj = new Dummy.TestObject();
diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c
index b87aff1cd4..687737a4aa 100644
--- a/src/tests/efl_mono/dummy_test_object.c
+++ b/src/tests/efl_mono/dummy_test_object.c
@@ -38,6 +38,8 @@ typedef struct Dummy_Test_Object_Data
38 int prop1; 38 int prop1;
39 int prop2; 39 int prop2;
40 Eo *hidden_object; 40 Eo *hidden_object;
41 Dummy_Test_Iface *iface_value_prop;
42 Efl_Class *iface_klass;
41 43
42 // Containers passed to C# as iterator/accessors 44 // Containers passed to C# as iterator/accessors
43 Eina_Array *out_array; 45 Eina_Array *out_array;
@@ -4784,6 +4786,26 @@ Eo *_dummy_test_object_hidden_object_get(EINA_UNUSED const Eo *obj, Dummy_Test_O
4784 return pd->hidden_object; 4786 return pd->hidden_object;
4785} 4787}
4786 4788
4789Dummy_Test_Iface *_dummy_test_object_iface_value_prop_get(EINA_UNUSED const Eo *obj, Dummy_Test_Object_Data *pd)
4790{
4791 return pd->iface_value_prop;
4792}
4793
4794void _dummy_test_object_iface_value_prop_set(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd, Dummy_Test_Iface *prop)
4795{
4796 pd->iface_value_prop = prop;
4797}
4798
4799void _dummy_test_object_iface_klass_prop_set(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd, Efl_Class *klass)
4800{
4801 pd->iface_klass = klass;
4802}
4803
4804Dummy_Test_Iface *_dummy_test_object_iface_value_from_c_get(const Eo *obj, Dummy_Test_Object_Data *pd)
4805{
4806 return efl_add(pd->iface_klass, (Eo*)obj);
4807}
4808
4787// Inherit 4809// Inherit
4788int _dummy_inherit_helper_receive_dummy_and_call_int_out(Dummy_Test_Object *x) 4810int _dummy_inherit_helper_receive_dummy_and_call_int_out(Dummy_Test_Object *x)
4789{ 4811{
diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo
index cf2ae7ce03..ee24e5ef9b 100644
--- a/src/tests/efl_mono/dummy_test_object.eo
+++ b/src/tests/efl_mono/dummy_test_object.eo
@@ -1664,6 +1664,23 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
1664 obj: Efl.Object; 1664 obj: Efl.Object;
1665 } 1665 }
1666 } 1666 }
1667 @property iface_value_prop {
1668 values {
1669 prop: Dummy.Test_Iface;
1670 }
1671 }
1672 @property iface_klass_prop {
1673 set {}
1674 values {
1675 klass: Efl.Class;
1676 }
1677 }
1678 @property iface_value_from_c {
1679 get {}
1680 values {
1681 prop: Dummy.Test_Iface;
1682 }
1683 }
1667 } 1684 }
1668 implements { 1685 implements {
1669 Efl.Object.constructor; 1686 Efl.Object.constructor;