felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2f0a20b6887ee868f5a72ff38b9789b08e61630f

commit 2f0a20b6887ee868f5a72ff38b9789b08e61630f
Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br>
Date:   Fri Aug 23 14:27:28 2019 -0300

    eolian-mono: Add support for partial classes
    
    Summary:
    Add the -p command to eolian to create a class as a partial
    class. Create a list in meson build of Eolian files that should be
    built with partial classes.
    
    This allows creating more specific method overloads for C#, manually,
    by generating the class as partial and adding in manual binding the
    partial class with the new methods and properties.
    
    T8034
    
    Reviewers: segfaultxavi, lauromoura, woohyun, Jaehyun_Cho
    
    Reviewed By: lauromoura
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D9690
---
 src/bin/eolian_mono/eolian/mono/klass.hh | 29 +++++++++++++++++++++++++----
 src/bin/eolian_mono/eolian_mono.cc       | 14 +++++++++++---
 src/bindings/mono/meson.build            | 10 +++++++++-
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh 
b/src/bin/eolian_mono/eolian/mono/klass.hh
index 819497a655..f1b89abc71 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -50,6 +50,11 @@ is_inherit_context(Context const& context)
    return context_find_tag<class_context>(context).current_wrapper_kind == 
class_context::inherit;
 }
 
+enum partial_class
+{
+ class_partial = 1
+};
+
 struct klass
 {
    template <typename OutputIterator, typename Context>
@@ -109,9 +114,11 @@ struct klass
        if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, 
attributes::unused, iface_cxt))
          return false;
 
+       using efl::eolian::grammar::lit;
        if(!as_generator
         (
-         "public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : "
+         lit("public ") << (is_partial ? "partial ":"")
+         /*<< class_type*/ << "interface" /*<<*/ " " << string << " : "
          )
         .generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
          return false;
@@ -191,7 +198,7 @@ struct klass
          if(!as_generator
             (
              documentation
-             << "sealed public class " << concrete_name << " :\n"
+             << "sealed public " << (is_partial ? "partial ":"") << " class " 
<< concrete_name << " :\n"
              << scope_tab << (root ? "Efl.Eo.EoWrapper" : "") << 
(klass_full_concrete_or_interface_name % "") << "\n"
              << scope_tab << ", " << interface_name << "\n"
              << scope_tab << *(", " << 
name_helpers::klass_full_concrete_or_interface_name) << "\n"
@@ -284,7 +291,14 @@ struct klass
              documentation
              << "[" << name_helpers::klass_full_native_inherit_name(cls) << 
"]\n"
              << "[Efl.Eo.BindingEntity]\n"
-             << "public " << class_type << " " << 
name_helpers::klass_concrete_name(cls) << " : "
+             << "public "
+             << (is_partial
+                 ? class_type == "class"
+                 ? "partial class"
+                 : "abstract partial class"
+                 : class_type
+                )
+             << " " << name_helpers::klass_concrete_name(cls) << " : "
              << (klass_full_concrete_or_interface_name % ",") // classes
              << (root ? "Efl.Eo.EoWrapper" : "") // ... or root
              << (inherit_interfaces.empty() ? "" : ", ")
@@ -600,9 +614,16 @@ struct klass
        }
      return true;
    }
+
+  bool is_partial;
+
+  klass const operator()(partial_class) const
+  {
+    return klass{true};
+  }
 };
 
-struct klass const klass = {};
+struct klass const klass = {false};
 
 }
 
diff --git a/src/bin/eolian_mono/eolian_mono.cc 
b/src/bin/eolian_mono/eolian_mono.cc
index e22acb9ce1..42f8034a03 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -50,6 +50,7 @@ struct options_type
    int v_major;
    int v_minor;
    bool want_beta;
+   bool want_partial;
    std::map<const std::string, std::string> references_map;
 };
 
@@ -192,8 +193,9 @@ run(options_type const& opts)
        efl::eolian::grammar::attributes::klass_def klass_def(klass, opts.unit);
        std::vector<efl::eolian::grammar::attributes::klass_def> 
klasses{klass_def};
 
-       if (!eolian_mono::klass
-         .generate(iterator, klass_def, context))
+       auto klass_gen = !opts.want_partial ? eolian_mono::klass
+         : eolian_mono::klass(eolian_mono::class_partial);
+       if (!klass_gen.generate(iterator, klass_def, context))
          {
             throw std::runtime_error("Failed to generate class");
          }
@@ -297,6 +299,7 @@ _usage(const char *progname)
      << "  -v, --version           Print the version." << std::endl
      << "  -b, --beta              Enable @beta methods." << std::endl
      << "  -e, --example-dir <dir> Folder to search for example files." << 
std::endl
+     << "  -p, --partial           Create class as a partial class" << 
std::endl
      << "  -h, --help              Print this help." << std::endl;
    exit(EXIT_FAILURE);
 }
@@ -328,9 +331,10 @@ opts_get(int argc, char **argv)
        { "references", required_argument, 0, 'r'},
        { "beta", no_argument, 0, 'b'},
        { "example-dir", required_argument, 0,  'e' },
+       { "partial", no_argument, 0,  'p' },
        { 0,           0,                 0,   0  }
      };
-   const char* options = "I:D:o:c:M:m:ar:vhbe:";
+   const char* options = "I:D:o:c:M:m:ar:vhbpe:";
 
    int c, idx;
    while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
@@ -391,6 +395,10 @@ opts_get(int argc, char **argv)
              opts.examples_dir = optarg;
              if (!opts.examples_dir.empty() && opts.examples_dir.back() != 
'/') opts.examples_dir += "/";
           }
+        else if (c == 'p')
+          {
+             opts.want_partial = true;
+          }
      }
    if (optind == argc-1)
      {
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index 8a87da9572..c0f04c3b37 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -82,6 +82,10 @@ blacklisted_files = [
   'elm_atspi_app_object.eo',
 ]
 
+manual_inheritance_files = [
+  'efl_object.eo'
+]
+
 beta_option = []
 if (get_option('mono-beta'))
    beta_option = '-b'
@@ -105,13 +109,17 @@ foreach lib : mono_sublibs
       subdir_file_location = join_paths(file_location, eo_file_subdir)
       foreach mono_gen_file : mono_pub_eo_files
         if not blacklisted_files.contains(mono_gen_file)
+          partial = []
+          if manual_inheritance_files.contains(mono_gen_file)
+            partial = '-p'
+          endif
           mono_generator_target += 
custom_target('eolian_mono_gen_'+mono_gen_file.underscorify()+'',
             input : join_paths(subdir_file_location, mono_gen_file),
             output : [mono_gen_file + '.cs'],
             command : [eolian_mono_gen, beta_option, '-I', 
meson.current_source_dir(), eolian_include_directories,
                                        '--dllimport', package_name,
                                        '-o', 
join_paths(meson.current_build_dir(), mono_gen_file + '.cs'),
-                                       '-e', get_option('mono-examples-dir'),
+                                       '-e', get_option('mono-examples-dir'), 
partial,
                                        '@INPUT@'])
         endif
       endforeach

-- 


Reply via email to