summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Paulo Taylor Ienczak Zanette <joao.tiz@expertisesolutions.com.br>2019-12-12 18:32:31 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-12-12 18:45:20 -0300
commitca3a9133757841b0bfb65cd5862ac5ea0886626e (patch)
treef25ee6f4cde1506b9d423ab037ccff8677cb2d24
parent4c77ee6843807cb0e27d73153203eec6ea42b8fb (diff)
csharp: Implement Deconstruct for structs.
Summary: Usage example: ``` var (x, y) = somePos2D; ``` Not available on Mono environment due to [`mcs` not implementing it](https://github.com/mono/mono/blob/a3de0304a190c54124df3486ce9c34b6262787a8/mcs/mcs/tuples.cs#L590). To keep tests from breaking because of it, a `MONO` preprocessor variable is defined and checked during test compilation. Ref T8489. Reviewers: brunobelo, lauromoura, segfaultxavi Reviewed By: lauromoura Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T8489 Differential Revision: https://phab.enlightenment.org/D10809
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh58
-rw-r--r--src/bindings/mono/meson.build3
-rw-r--r--src/tests/efl_mono/Structs.cs10
3 files changed, 70 insertions, 1 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 0308533..403778f 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -464,6 +464,61 @@ struct struct_definition_generator
464 } 464 }
465 465
466 template <typename OutputIterator, typename Context> 466 template <typename OutputIterator, typename Context>
467 bool generate_deconstruct_method(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
468 {
469 auto const& indent = current_indentation(context);
470 auto struct_name = binding_struct_name(struct_);
471
472 if (!as_generator(
473 indent << scope_tab << "/// <summary>Unpacks " << struct_name << " into tuple.\n"
474 << indent << scope_tab << "/// <para>Since EFL 1.24.</para>\n"
475 << indent << scope_tab << "/// </summary>\n"
476 << indent << scope_tab << "public void Deconstruct(\n"
477 ).generate(sink, attributes::unused, context))
478 return false;
479
480 // parameters
481 {
482 auto i = 0u;
483 for (auto const& field : struct_.fields)
484 {
485 auto field_name = name_helpers::to_field_name(field.name);
486
487 auto suffix = i == struct_.fields.size() - 1 ? "\n" : ",\n";
488
489 if (!as_generator(
490 indent << scope_tab << scope_tab << "out " << type << " " << field_name << suffix
491 ).generate(sink, std::make_tuple(field.type), context))
492 return false;
493
494 ++i;
495 }
496 }
497
498 if (!as_generator(
499 indent << scope_tab << ")\n"
500 << indent << scope_tab << "{\n"
501 ).generate(sink, attributes::unused, context))
502 return false;
503
504 // assigments
505 for (auto const& field : struct_.fields)
506 {
507 auto field_name = name_helpers::to_field_name(field.name);
508
509 if (!as_generator(
510 indent << scope_tab << scope_tab << field_name << " = this." << field_name << ";\n"
511 ).generate(sink, attributes::unused, context))
512 return false;
513 }
514
515 // the end
516 return as_generator(
517 indent << scope_tab << "}\n"
518 ).generate(sink, attributes::unused, context);
519 }
520
521 template <typename OutputIterator, typename Context>
467 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const 522 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
468 { 523 {
469 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "struct_definition_generator: " << struct_.cxx_name << std::endl; 524 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "struct_definition_generator: " << struct_.cxx_name << std::endl;
@@ -537,6 +592,9 @@ struct struct_definition_generator
537 592
538 if (!generate_implicit_operator(struct_, sink, context)) 593 if (!generate_implicit_operator(struct_, sink, context))
539 return false; 594 return false;
595
596 if (!generate_deconstruct_method(sink, struct_, context))
597 return false;
540 } 598 }
541 599
542 std::string since_line; 600 std::string since_line;
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index 86cef4d..f98aa5e 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -199,12 +199,13 @@ if (get_option('dotnet'))
199 ) 199 )
200 200
201else 201else
202 extra_cs_args += '-d:MONO'
202 203
203 efl_mono = library('efl_mono', 204 efl_mono = library('efl_mono',
204 mono_generator_target + mono_files + [efl_src], 205 mono_generator_target + mono_files + [efl_src],
205 install : true, 206 install : true,
206 install_dir : efl_mono_install_dir, 207 install_dir : efl_mono_install_dir,
207 cs_args : extra_cs_args + ['-doc:' + efl_mono_xml_doc, '-warnaserror+'] 208 cs_args : extra_cs_args + ['-doc:' + efl_mono_xml_doc, '-warnaserror+'],
208 ) 209 )
209 210
210 meson.add_install_script(join_paths(meson.source_root(), 'meson', 'meson_csharp_docs.sh'), 211 meson.add_install_script(join_paths(meson.source_root(), 'meson', 'meson_csharp_docs.sh'),
diff --git a/src/tests/efl_mono/Structs.cs b/src/tests/efl_mono/Structs.cs
index 521d39b..1e3dc30 100644
--- a/src/tests/efl_mono/Structs.cs
+++ b/src/tests/efl_mono/Structs.cs
@@ -419,6 +419,16 @@ internal class TestStructEquality
419 Test.AssertNotEquals(a.GetHashCode(), c.GetHashCode()); 419 Test.AssertNotEquals(a.GetHashCode(), c.GetHashCode());
420 Test.AssertNotEquals(a.GetHashCode(), singleDifferentField.GetHashCode()); 420 Test.AssertNotEquals(a.GetHashCode(), singleDifferentField.GetHashCode());
421 } 421 }
422
423#if !MONO
424 public static void test_deconstruct() {
425 var p = new Eina.Position2D(1, 2);
426 var (x, y) = p;
427
428 Test.AssertEquals(x, 1);
429 Test.AssertEquals(y, 2);
430 }
431#endif
422} 432}
423 433
424internal class TestStructTuples 434internal class TestStructTuples