forked from enlightenment/efl
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
This commit is contained in:
parent
b4a6444473
commit
2f0a20b688
|
@ -50,6 +50,11 @@ is_inherit_context(Context const& context)
|
||||||
return context_find_tag<class_context>(context).current_wrapper_kind == class_context::inherit;
|
return context_find_tag<class_context>(context).current_wrapper_kind == class_context::inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum partial_class
|
||||||
|
{
|
||||||
|
class_partial = 1
|
||||||
|
};
|
||||||
|
|
||||||
struct klass
|
struct klass
|
||||||
{
|
{
|
||||||
template <typename OutputIterator, typename Context>
|
template <typename OutputIterator, typename Context>
|
||||||
|
@ -109,9 +114,11 @@ struct klass
|
||||||
if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
|
if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
using efl::eolian::grammar::lit;
|
||||||
if(!as_generator
|
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))
|
.generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
|
||||||
return false;
|
return false;
|
||||||
|
@ -191,7 +198,7 @@ struct klass
|
||||||
if(!as_generator
|
if(!as_generator
|
||||||
(
|
(
|
||||||
documentation
|
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 << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "") << "\n"
|
||||||
<< scope_tab << ", " << interface_name << "\n"
|
<< scope_tab << ", " << interface_name << "\n"
|
||||||
<< scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n"
|
<< scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n"
|
||||||
|
@ -284,7 +291,14 @@ struct klass
|
||||||
documentation
|
documentation
|
||||||
<< "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
|
<< "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
|
||||||
<< "[Efl.Eo.BindingEntity]\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
|
<< (klass_full_concrete_or_interface_name % ",") // classes
|
||||||
<< (root ? "Efl.Eo.EoWrapper" : "") // ... or root
|
<< (root ? "Efl.Eo.EoWrapper" : "") // ... or root
|
||||||
<< (inherit_interfaces.empty() ? "" : ", ")
|
<< (inherit_interfaces.empty() ? "" : ", ")
|
||||||
|
@ -600,9 +614,16 @@ struct klass
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_partial;
|
||||||
|
|
||||||
|
klass const operator()(partial_class) const
|
||||||
|
{
|
||||||
|
return klass{true};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct klass const klass = {};
|
struct klass const klass = {false};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct options_type
|
||||||
int v_major;
|
int v_major;
|
||||||
int v_minor;
|
int v_minor;
|
||||||
bool want_beta;
|
bool want_beta;
|
||||||
|
bool want_partial;
|
||||||
std::map<const std::string, std::string> references_map;
|
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);
|
efl::eolian::grammar::attributes::klass_def klass_def(klass, opts.unit);
|
||||||
std::vector<efl::eolian::grammar::attributes::klass_def> klasses{klass_def};
|
std::vector<efl::eolian::grammar::attributes::klass_def> klasses{klass_def};
|
||||||
|
|
||||||
if (!eolian_mono::klass
|
auto klass_gen = !opts.want_partial ? eolian_mono::klass
|
||||||
.generate(iterator, klass_def, context))
|
: eolian_mono::klass(eolian_mono::class_partial);
|
||||||
|
if (!klass_gen.generate(iterator, klass_def, context))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to generate class");
|
throw std::runtime_error("Failed to generate class");
|
||||||
}
|
}
|
||||||
|
@ -297,6 +299,7 @@ _usage(const char *progname)
|
||||||
<< " -v, --version Print the version." << std::endl
|
<< " -v, --version Print the version." << std::endl
|
||||||
<< " -b, --beta Enable @beta methods." << std::endl
|
<< " -b, --beta Enable @beta methods." << std::endl
|
||||||
<< " -e, --example-dir <dir> Folder to search for example files." << 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;
|
<< " -h, --help Print this help." << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -328,9 +331,10 @@ opts_get(int argc, char **argv)
|
||||||
{ "references", required_argument, 0, 'r'},
|
{ "references", required_argument, 0, 'r'},
|
||||||
{ "beta", no_argument, 0, 'b'},
|
{ "beta", no_argument, 0, 'b'},
|
||||||
{ "example-dir", required_argument, 0, 'e' },
|
{ "example-dir", required_argument, 0, 'e' },
|
||||||
|
{ "partial", no_argument, 0, 'p' },
|
||||||
{ 0, 0, 0, 0 }
|
{ 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;
|
int c, idx;
|
||||||
while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
|
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;
|
opts.examples_dir = optarg;
|
||||||
if (!opts.examples_dir.empty() && opts.examples_dir.back() != '/') opts.examples_dir += "/";
|
if (!opts.examples_dir.empty() && opts.examples_dir.back() != '/') opts.examples_dir += "/";
|
||||||
}
|
}
|
||||||
|
else if (c == 'p')
|
||||||
|
{
|
||||||
|
opts.want_partial = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (optind == argc-1)
|
if (optind == argc-1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,10 @@ blacklisted_files = [
|
||||||
'elm_atspi_app_object.eo',
|
'elm_atspi_app_object.eo',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
manual_inheritance_files = [
|
||||||
|
'efl_object.eo'
|
||||||
|
]
|
||||||
|
|
||||||
beta_option = []
|
beta_option = []
|
||||||
if (get_option('mono-beta'))
|
if (get_option('mono-beta'))
|
||||||
beta_option = '-b'
|
beta_option = '-b'
|
||||||
|
@ -105,13 +109,17 @@ foreach lib : mono_sublibs
|
||||||
subdir_file_location = join_paths(file_location, eo_file_subdir)
|
subdir_file_location = join_paths(file_location, eo_file_subdir)
|
||||||
foreach mono_gen_file : mono_pub_eo_files
|
foreach mono_gen_file : mono_pub_eo_files
|
||||||
if not blacklisted_files.contains(mono_gen_file)
|
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()+'',
|
mono_generator_target += custom_target('eolian_mono_gen_'+mono_gen_file.underscorify()+'',
|
||||||
input : join_paths(subdir_file_location, mono_gen_file),
|
input : join_paths(subdir_file_location, mono_gen_file),
|
||||||
output : [mono_gen_file + '.cs'],
|
output : [mono_gen_file + '.cs'],
|
||||||
command : [eolian_mono_gen, beta_option, '-I', meson.current_source_dir(), eolian_include_directories,
|
command : [eolian_mono_gen, beta_option, '-I', meson.current_source_dir(), eolian_include_directories,
|
||||||
'--dllimport', package_name,
|
'--dllimport', package_name,
|
||||||
'-o', join_paths(meson.current_build_dir(), mono_gen_file + '.cs'),
|
'-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@'])
|
'@INPUT@'])
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
Loading…
Reference in New Issue