2017-11-23 16:50:16 -08:00
|
|
|
#ifndef EOLIAN_MONO_FUNCTION_REGISTRATION_HH
|
|
|
|
#define EOLIAN_MONO_FUNCTION_REGISTRATION_HH
|
|
|
|
|
|
|
|
#include <Eina.hh>
|
|
|
|
|
|
|
|
#include "grammar/generator.hpp"
|
|
|
|
#include "grammar/klass_def.hpp"
|
|
|
|
|
|
|
|
#include "grammar/indentation.hpp"
|
|
|
|
#include "grammar/list.hpp"
|
|
|
|
#include "grammar/alternative.hpp"
|
|
|
|
#include "grammar/attribute_reorder.hpp"
|
2018-04-27 14:08:25 -07:00
|
|
|
#include "logging.hh"
|
2017-11-23 16:50:16 -08:00
|
|
|
#include "type.hh"
|
|
|
|
#include "marshall_type.hh"
|
|
|
|
#include "parameter.hh"
|
|
|
|
#include "using_decl.hh"
|
|
|
|
#include "generation_contexts.hh"
|
2018-04-16 12:26:13 -07:00
|
|
|
#include "blacklist.hh"
|
2017-11-23 16:50:16 -08:00
|
|
|
|
|
|
|
namespace eolian_mono {
|
|
|
|
|
2019-01-17 04:33:09 -08:00
|
|
|
// template <typename I>
|
2017-11-23 16:50:16 -08:00
|
|
|
struct function_registration_generator
|
|
|
|
{
|
2019-01-17 04:33:09 -08:00
|
|
|
// I index_generator;
|
2017-11-23 16:50:16 -08:00
|
|
|
attributes::klass_def const* klass;
|
|
|
|
|
|
|
|
template <typename OutputIterator, typename Context>
|
|
|
|
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
|
|
|
|
{
|
2018-04-27 14:08:25 -07:00
|
|
|
EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_registration_generator: " << f.name << std::endl;
|
2019-04-23 02:48:03 -07:00
|
|
|
auto const& indent = current_indentation(context);
|
|
|
|
|
2019-01-17 04:43:57 -08:00
|
|
|
if(blacklist::is_function_blacklisted(f, context) || f.is_static) // Static methods aren't overrideable
|
2017-11-23 16:50:16 -08:00
|
|
|
return true;
|
2018-12-14 14:39:09 -08:00
|
|
|
|
csharp: Skip non-public members from interfaces
Summary:
Eolian allows non-public members in interfaces and mixins (usually
@protected). As both kinds are converted to C# interfaces, this
causes problem as non-public members are forbidden in C# interfaces.
This commit changes eolian_mono by removing those members from the C#
interfaces. If a generated class implements the interface, the method is
generated as if it were a protected member of the class directly.
For mixed properties like `Efl.Io.Reader.CanRead { get; set @protected; }`,
the interface has only the public getter and the the implementing class has both
the public getter and the protected setter.
With this, C# devs won't be able to directly implement protected Eo
methods from interfaces. (But this really does not make sense from the
C# point of view).
ref T7494
Reviewers: segfaultxavi, felipealmeida, YOhoho
Reviewed By: YOhoho
Subscribers: cedric, brunobelo, Jaehyun_Cho, #reviewers, woohyun, #committers
Tags: #efl
Maniphest Tasks: T7494
Differential Revision: https://phab.enlightenment.org/D9800
2019-09-10 15:30:46 -07:00
|
|
|
// We do not generate registration wrappers for non public interface/mixin members in their concrete classes.
|
|
|
|
// They go in the first concrete/abstract implementation.
|
|
|
|
if(blacklist::is_non_public_interface_member(f, *klass))
|
|
|
|
return true;
|
|
|
|
|
2018-12-14 14:39:09 -08:00
|
|
|
if(!as_generator(
|
2019-04-23 02:48:03 -07:00
|
|
|
indent << "if (" << f.c_name << "_static_delegate == null)\n"
|
|
|
|
<< indent << "{\n"
|
|
|
|
<< indent << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" << escape_keyword(f.name) << ");\n"
|
|
|
|
<< indent << "}\n\n"
|
2018-12-14 14:39:09 -08:00
|
|
|
).generate(sink, attributes::unused, context))
|
|
|
|
return false;
|
|
|
|
|
2019-04-23 02:48:03 -07:00
|
|
|
if(!as_generator(
|
|
|
|
indent << "if (methods.FirstOrDefault(m => m.Name == \"" << string << "\") != null)\n"
|
|
|
|
<< indent << "{\n"
|
|
|
|
<< indent << scope_tab << "descs.Add(new Efl_Op_Description() {"
|
2017-11-23 16:50:16 -08:00
|
|
|
#ifdef _WIN32
|
2019-01-17 04:33:09 -08:00
|
|
|
<< "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
|
2017-11-23 16:50:16 -08:00
|
|
|
#else
|
2019-04-23 02:48:03 -07:00
|
|
|
<< "api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(Module.Module, \"" << string << "\")"
|
2017-11-23 16:50:16 -08:00
|
|
|
#endif
|
2019-04-23 02:48:03 -07:00
|
|
|
<< ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate) });\n"
|
|
|
|
<< indent << "}\n\n"
|
2017-11-23 16:50:16 -08:00
|
|
|
)
|
2019-04-09 07:16:17 -07:00
|
|
|
.generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.c_name, f.c_name), context))
|
2017-11-23 16:50:16 -08:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct function_registration_parameterized
|
|
|
|
{
|
2019-01-17 04:33:09 -08:00
|
|
|
function_registration_generator operator()(attributes::klass_def const& klass) const
|
2017-11-23 16:50:16 -08:00
|
|
|
{
|
2019-01-17 04:33:09 -08:00
|
|
|
return {&klass};
|
2017-11-23 16:50:16 -08:00
|
|
|
}
|
|
|
|
} const function_registration;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace efl { namespace eolian { namespace grammar {
|
|
|
|
|
2019-01-17 04:33:09 -08:00
|
|
|
template <>
|
|
|
|
struct is_eager_generator< ::eolian_mono::function_registration_generator> : std::true_type {};
|
|
|
|
template <>
|
|
|
|
struct is_generator< ::eolian_mono::function_registration_generator> : std::true_type {};
|
2017-11-23 16:50:16 -08:00
|
|
|
|
|
|
|
namespace type_traits {
|
|
|
|
|
2019-01-17 04:33:09 -08:00
|
|
|
template <>
|
|
|
|
struct attributes_needed< ::eolian_mono::function_registration_generator> : std::integral_constant<int, 1> {};
|
2017-11-23 16:50:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
} } }
|
|
|
|
|
|
|
|
#endif
|