forked from enlightenment/efl
eolian-mono: Provide constructor parameters based on the constructors
section of the Eo files. Reviewers: woohyun, segfaultxavi, bu5hm4n, felipealmeida Reviewed By: segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7789
This commit is contained in:
parent
e414450404
commit
0223bb29df
|
@ -84,6 +84,29 @@ struct documentation_generator
|
|||
return name;
|
||||
}
|
||||
|
||||
static std::string function_conversion(attributes::function_def const& func)
|
||||
{
|
||||
attributes::klass_def klass(get_klass(func.klass, func.unit), func.unit);
|
||||
std::string name = name_helpers::klass_full_concrete_or_interface_name(klass);
|
||||
switch (func.type)
|
||||
{
|
||||
// managed_method_name takes care of reordering the function name so the get/set goes first
|
||||
// for properties
|
||||
case attributes::function_type::method:
|
||||
case attributes::function_type::prop_set:
|
||||
case attributes::function_type::prop_get:
|
||||
if (blacklist::is_function_blacklisted(func.c_name))return "";
|
||||
name += ".";
|
||||
name += name_helpers::managed_method_name(klass.eolian_name, func.name);
|
||||
break;
|
||||
default:
|
||||
// No need to deal with property as function_defs are converted to get/set when building a given klass_def.
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
|
||||
static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail)
|
||||
{
|
||||
|
@ -299,6 +322,31 @@ struct documentation_generator
|
|||
{
|
||||
return generate_tag_summary(sink, doc.full_text, context);
|
||||
}
|
||||
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context const& context) const
|
||||
{
|
||||
// Not sure if this is the best way to generate a reference outside the full doc generator.
|
||||
auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
|
||||
auto func = ctor.function;
|
||||
auto eolian_klass = get_klass(func.klass, unit);
|
||||
attributes::klass_def klass(eolian_klass, unit);
|
||||
std::string summary;
|
||||
|
||||
if (func.type == attributes::function_type::prop_set)
|
||||
summary = func.property_documentation.summary;
|
||||
else
|
||||
summary = func.documentation.summary;
|
||||
|
||||
for (auto &¶m : ctor.function.parameters)
|
||||
{
|
||||
if (!as_generator(
|
||||
scope_tab << "///<param name=\"" << constructor_parameter_name(ctor) << "\">" << summary << " See <see cref=\"" << function_conversion(func) << "\"/></param>\n"
|
||||
).generate(sink, param, context))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct documentation_terminal
|
||||
|
|
|
@ -221,6 +221,12 @@ inline bool is_unique_event(attributes::event_def const& evt
|
|||
});
|
||||
}
|
||||
|
||||
inline std::vector<attributes::constructor_def> reorder_constructors(std::vector<attributes::constructor_def> constructors)
|
||||
{
|
||||
auto is_required = [](attributes::constructor_def const& ctr) { return !ctr.is_optional; };
|
||||
std::stable_partition(constructors.begin(), constructors.end(), is_required);
|
||||
return constructors;
|
||||
}
|
||||
|
||||
} // namespace helpers
|
||||
|
||||
|
|
|
@ -220,15 +220,16 @@ struct klass
|
|||
if (!generate_fields(sink, cls, concrete_cxt))
|
||||
return false;
|
||||
|
||||
bool root = !helpers::has_regular_ancestor(cls);
|
||||
if (!as_generator
|
||||
(
|
||||
scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
|
||||
<< ")] internal static extern System.IntPtr\n"
|
||||
<< scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
|
||||
<< scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
|
||||
<< scope_tab << "public " << concrete_name << "(System.IntPtr raw)\n"
|
||||
<< scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
|
||||
<< scope_tab << "public " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "handle = raw;\n"
|
||||
<< scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
|
||||
<< scope_tab << scope_tab << "register_event_proxies();\n"
|
||||
<< scope_tab << "}\n"
|
||||
)
|
||||
|
@ -503,48 +504,44 @@ struct klass
|
|||
).generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
|
||||
auto constructors = helpers::reorder_constructors(cls.get_all_constructors());
|
||||
|
||||
if (!root)
|
||||
{
|
||||
return as_generator(
|
||||
// Public (API) constructors
|
||||
if (!as_generator(
|
||||
scope_tab << "///<summary>Creates a new instance.</summary>\n"
|
||||
<< scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
|
||||
<< scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
|
||||
<< scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : "
|
||||
"base(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
|
||||
<< *(documentation)
|
||||
// For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
|
||||
<< scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n"
|
||||
<< scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n"
|
||||
<< scope_tab << scope_tab << (root ? "this" : "base") << "(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "if (init_cb != null) {\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< *(scope_tab << scope_tab << constructor_invocation << "\n" )
|
||||
<< scope_tab << scope_tab << "FinishInstantiation();\n"
|
||||
<< scope_tab << "}\n"
|
||||
|
||||
<< scope_tab << "///<summary>Internal constructor to forward the wrapper initialization to the root class.</summary>\n"
|
||||
<< scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(klass_name, base_klass, managed_type, parent) {}\n"
|
||||
|
||||
<< scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
|
||||
<< scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
|
||||
<< scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
|
||||
<< scope_tab << scope_tab << "register_event_proxies();\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
|
||||
return false;
|
||||
|
||||
// Internal constructors
|
||||
if (!root)
|
||||
{
|
||||
return as_generator(
|
||||
scope_tab << "///<summary>Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n"
|
||||
<< scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(klass_name, base_klass, managed_type, parent) {}\n"
|
||||
).generate(sink, attributes::unused, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Detailed constructors go only in root classes.
|
||||
return as_generator(
|
||||
scope_tab << "///<summary>Creates a new instance.</summary>\n"
|
||||
<< scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
|
||||
<< scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
|
||||
<< scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "if (init_cb != null) {\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << scope_tab << "FinishInstantiation();\n"
|
||||
<< scope_tab << "}\n"
|
||||
|
||||
<< scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
|
||||
/// Actual root costructor that creates class and instantiates
|
||||
scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n"
|
||||
<< scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
|
||||
|
@ -574,12 +571,6 @@ struct klass
|
|||
<< scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
|
||||
<< scope_tab << "}\n"
|
||||
|
||||
<< scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
|
||||
<< scope_tab << "public " << inherit_name << "(System.IntPtr raw)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "handle = raw;\n"
|
||||
<< scope_tab << scope_tab << "register_event_proxies();\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, attributes::unused, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,12 @@ inline std::string managed_method_name(std::string const& klass, std::string con
|
|||
return candidate;
|
||||
}
|
||||
|
||||
inline std::string managed_name(std::string const& name, char separator='_')
|
||||
{
|
||||
auto tokens = utils::split(name, separator);
|
||||
return utils::to_pascal_case(tokens);
|
||||
}
|
||||
|
||||
inline std::string managed_method_name(attributes::function_def const& f)
|
||||
{
|
||||
return managed_method_name(f.klass.eolian_name, f.name);
|
||||
|
@ -420,7 +426,12 @@ bool close_namespaces(OutputIterator sink, std::vector<std::string> const& names
|
|||
return as_generator(close_namespace).generate(sink, namespaces, context);
|
||||
}
|
||||
|
||||
std::string constructor_managed_name(std::string full_name)
|
||||
{
|
||||
auto tokens = utils::split(full_name, '.');
|
||||
|
||||
return managed_name(tokens.at(tokens.size()-1));
|
||||
}
|
||||
|
||||
} // namespace name_helpers
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "helpers.hh"
|
||||
#include "marshall_type.hh"
|
||||
|
@ -34,6 +35,10 @@ namespace eolian_mono {
|
|||
struct native_convert_return_variable_generator;
|
||||
struct convert_function_pointer_generator;
|
||||
struct native_convert_function_pointer_generator;
|
||||
struct constructor_param_generator;
|
||||
struct constructor_invocation_generator;
|
||||
struct constructor_parameter_name_generator;
|
||||
struct constructor_parameter_name_paremeterized;
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
@ -232,6 +237,38 @@ template <>
|
|||
struct attributes_needed< ::eolian_mono::native_convert_function_pointer_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
template <>
|
||||
struct is_eager_generator< ::eolian_mono::constructor_param_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::constructor_param_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::constructor_param_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
template <>
|
||||
struct is_eager_generator< ::eolian_mono::constructor_invocation_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::constructor_invocation_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::constructor_invocation_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
template <>
|
||||
struct is_eager_generator< ::eolian_mono::constructor_parameter_name_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::constructor_parameter_name_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::constructor_parameter_name_paremeterized> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::constructor_parameter_name_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
namespace eolian_mono {
|
||||
|
@ -1436,6 +1473,89 @@ struct native_convert_function_pointer_generator
|
|||
|
||||
} const native_convert_function_pointer {};
|
||||
|
||||
struct constructor_parameter_name_generator
|
||||
{
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
auto target_name = name_helpers::constructor_managed_name(ctor.name);
|
||||
|
||||
// Only multi-valued constructing methods get their actual parameter names
|
||||
if (ctor.function.parameters.size() > 1)
|
||||
target_name += '_' + param.param_name;
|
||||
|
||||
auto name = name_helpers::managed_name(target_name);
|
||||
name[0] = std::tolower(name[0]);
|
||||
|
||||
return as_generator(string).generate(sink, name, context);
|
||||
}
|
||||
|
||||
attributes::constructor_def const& ctor;
|
||||
};
|
||||
|
||||
struct constructor_parameter_name_parameterized
|
||||
{
|
||||
constructor_parameter_name_generator const operator()(attributes::constructor_def const& ctor) const
|
||||
{
|
||||
return {ctor};
|
||||
}
|
||||
} const constructor_parameter_name;
|
||||
|
||||
// Generates the parameters for the given constructor
|
||||
// If the constructor receives multiple parameters, they get the name
|
||||
// of the constructor plus the name of the parameter (e.g. DefineParentData, DefineIndex)
|
||||
struct constructor_param_generator
|
||||
{
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context context) const
|
||||
{
|
||||
auto params = ctor.function.parameters;
|
||||
|
||||
if (!as_generator(
|
||||
efl::eolian::grammar::attribute_reorder<1, -1>
|
||||
(type(false, ctor.is_optional) << " " << constructor_parameter_name(ctor) << (ctor.is_optional ? " = null" : "")) % ","
|
||||
).generate(sink, params, context))
|
||||
return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
} const constructor_param;
|
||||
|
||||
// Generates the invocation of the given parameter
|
||||
struct constructor_invocation_generator
|
||||
{
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context context) const
|
||||
{
|
||||
auto params = ctor.function.parameters;
|
||||
if (!as_generator(
|
||||
"if (" <<
|
||||
(efl::eolian::grammar::attribute_reorder<-1>
|
||||
("Efl.Eo.Globals.ParamHelperCheck(" << constructor_parameter_name(ctor) << ")") % "||") << ")\n"
|
||||
<< scope_tab << scope_tab << scope_tab << name_helpers::managed_method_name(ctor.function) << "("
|
||||
).generate(sink, params, context))
|
||||
return false;
|
||||
|
||||
size_t idx = 0;
|
||||
|
||||
for (auto&& param : params)
|
||||
{
|
||||
idx++;
|
||||
if (!as_generator(
|
||||
"Efl.Eo.Globals.GetParamHelper(" << constructor_parameter_name(ctor) << ")" << ((idx < params.size()) ? ", " : "")
|
||||
).generate(sink, param, context))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!as_generator(");").generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} const constructor_invocation;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,29 +14,29 @@ struct visitor_generate;
|
|||
|
||||
struct type_generator
|
||||
{
|
||||
type_generator(bool is_return = false)
|
||||
: is_return(is_return) {}
|
||||
type_generator(bool is_return = false, bool is_optional = false)
|
||||
: is_return(is_return), is_optional(is_optional) {}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
||||
{
|
||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
|
||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr, is_optional});
|
||||
}
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_optional});
|
||||
}
|
||||
|
||||
bool is_return;
|
||||
bool is_return, is_optional;
|
||||
};
|
||||
|
||||
struct type_terminal
|
||||
{
|
||||
type_generator const operator()(bool is_return) const
|
||||
type_generator const operator()(bool is_return, bool is_optional = false) const
|
||||
{
|
||||
return type_generator(is_return);
|
||||
return type_generator(is_return, is_optional);
|
||||
}
|
||||
} const type = {};
|
||||
|
||||
|
|
|
@ -34,6 +34,20 @@ attributes::regular_type_def replace_base_integer(attributes::regular_type_def v
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
attributes::regular_type_def replace_base_opt_integer(attributes::regular_type_def v)
|
||||
{
|
||||
bool s = std::is_signed<T>::value;
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1: return s ? replace_base_type(v, " sbyte?") : replace_base_type(v, " byte?");
|
||||
case 2: return s ? replace_base_type(v, " short?") : replace_base_type(v, " ushort?");
|
||||
case 4: return s ? replace_base_type(v, " int?") : replace_base_type(v, " uint?");
|
||||
case 8: return s ? replace_base_type(v, " long?") : replace_base_type(v, " ulong?");
|
||||
default: return v;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
|
||||
{
|
||||
|
@ -63,6 +77,7 @@ struct visitor_generate
|
|||
bool is_out;
|
||||
bool is_return;
|
||||
bool is_ptr;
|
||||
mutable bool is_optional;
|
||||
|
||||
typedef visitor_generate<OutputIterator, Context> visitor_type;
|
||||
typedef bool result_type;
|
||||
|
@ -76,6 +91,40 @@ struct visitor_generate
|
|||
eina::optional<bool> has_own;
|
||||
std::function<attributes::type_def::variant_type()> function;
|
||||
}
|
||||
const optional_match_table[] =
|
||||
{
|
||||
// signed primitives
|
||||
{"byte", nullptr, [&] { return replace_base_type(regular, " sbyte?"); }}
|
||||
, {"float", nullptr, [&] { return replace_base_type(regular, " float?"); }}
|
||||
, {"double", nullptr, [&] { return replace_base_type(regular, " double?"); }}
|
||||
, {"bool", nullptr, [&] { return replace_base_type(regular, " bool?"); }}
|
||||
, {"short", nullptr, [&] { return replace_base_opt_integer<short>(regular); }}
|
||||
, {"int", nullptr, [&] { return replace_base_opt_integer<int>(regular); }}
|
||||
, {"long", nullptr, [&] { return replace_base_opt_integer<long>(regular); }}
|
||||
, {"llong", nullptr, [&] { return replace_base_opt_integer<long long>(regular); }}
|
||||
, {"int8", nullptr, [&] { return replace_base_type(regular, " sbyte?"); }}
|
||||
, {"int16", nullptr, [&] { return replace_base_type(regular, " short?"); }}
|
||||
, {"int32", nullptr, [&] { return replace_base_type(regular, " int?"); }}
|
||||
, {"int64", nullptr, [&] { return replace_base_type(regular, " long?"); }}
|
||||
, {"ssize", nullptr, [&] { return replace_base_opt_integer<ssize_t>(regular); }}
|
||||
// unsigned primitives
|
||||
, {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte?"); }}
|
||||
, {"ushort", nullptr, [&] { return replace_base_opt_integer<unsigned short>(regular); }}
|
||||
, {"uint", nullptr, [&] { return replace_base_opt_integer<unsigned int>(regular); }}
|
||||
, {"ulong", nullptr, [&] { return replace_base_opt_integer<unsigned long>(regular); }}
|
||||
, {"ullong", nullptr, [&] { return replace_base_opt_integer<unsigned long long>(regular); }}
|
||||
, {"uint8", nullptr, [&] { return replace_base_type(regular, " byte?"); }}
|
||||
, {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort?"); }}
|
||||
, {"uint32", nullptr, [&] { return replace_base_type(regular, " uint?"); }}
|
||||
, {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong?"); }}
|
||||
, {"size", nullptr, [&] { return replace_base_opt_integer<size_t>(regular); }}
|
||||
|
||||
, {"ptrdiff", nullptr, [&] { return replace_base_opt_integer<ptrdiff_t>(regular); }}
|
||||
, {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
|
||||
, {"uintptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
|
||||
, {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
|
||||
};
|
||||
struct match
|
||||
const match_table[] =
|
||||
{
|
||||
// signed primitives
|
||||
|
@ -153,6 +202,29 @@ struct visitor_generate
|
|||
};
|
||||
std::string full_type_name = name_helpers::type_full_eolian_name(regular);
|
||||
if(eina::optional<bool> b = call_match
|
||||
(optional_match_table
|
||||
, [&] (match const& m)
|
||||
{
|
||||
return is_optional
|
||||
&& (!m.name || *m.name == regular.base_type || *m.name == full_type_name)
|
||||
&& (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
|
||||
;
|
||||
}
|
||||
, [&] (attributes::type_def::variant_type const& v)
|
||||
{
|
||||
return v.visit(*this); // we want to keep is_out info
|
||||
}))
|
||||
{
|
||||
return *b;
|
||||
}
|
||||
else if (is_optional && (regular.is_struct() || regular.is_enum() || regular.is_struct_opaque()))
|
||||
{
|
||||
attributes::regular_type_def r = regular;
|
||||
r.base_type.push_back('?');
|
||||
is_optional = false;
|
||||
return (*this)(r);
|
||||
}
|
||||
else if(eina::optional<bool> b = call_match
|
||||
(match_table
|
||||
, [&] (match const& m)
|
||||
{
|
||||
|
|
|
@ -157,6 +157,23 @@ public class Globals {
|
|||
|
||||
public delegate byte class_initializer(IntPtr klass);
|
||||
|
||||
public static T GetParamHelper<T>(Nullable<T> v) where T : struct
|
||||
{
|
||||
return v.Value;
|
||||
}
|
||||
public static U GetParamHelper<U>(U v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
public static bool ParamHelperCheck<T>(Nullable<T> v) where T : struct
|
||||
{
|
||||
return v.HasValue;
|
||||
}
|
||||
public static bool ParamHelperCheck<U>(U v)
|
||||
{
|
||||
return v != null;
|
||||
}
|
||||
|
||||
public static IntPtr register_class(String class_name, IntPtr base_klass, System.Type type)
|
||||
{
|
||||
ClassDescription description;
|
||||
|
|
|
@ -114,43 +114,6 @@ class TestEoNames
|
|||
}
|
||||
}
|
||||
|
||||
class TestEoConstructingMethods
|
||||
{
|
||||
public static void constructing_method()
|
||||
{
|
||||
bool called = false;
|
||||
string name = "Test object";
|
||||
var obj = new Dummy.TestObject(null, (Dummy.TestObject a) => {
|
||||
called = true;
|
||||
Console.WriteLine("callback: obj NativeHandle: {0:x}", a.NativeHandle);
|
||||
a.SetName(name);
|
||||
});
|
||||
|
||||
Test.Assert(called);
|
||||
Test.AssertEquals(name, obj.GetName());
|
||||
}
|
||||
|
||||
private class Derived : Dummy.TestObject
|
||||
{
|
||||
public Derived(Dummy.TestObject parent = null,
|
||||
Dummy.TestObject.ConstructingMethod cb = null) : base(parent, cb) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void constructing_method_inherit()
|
||||
{
|
||||
bool called = false;
|
||||
string name = "Another test object";
|
||||
Derived obj = new Derived(null, (Dummy.TestObject a) => {
|
||||
called = true;
|
||||
a.SetComment(name);
|
||||
});
|
||||
|
||||
Test.Assert(called);
|
||||
Test.AssertEquals(name, obj.GetComment());
|
||||
}
|
||||
}
|
||||
|
||||
class TestEoParent
|
||||
{
|
||||
public static void basic_parent()
|
||||
|
@ -365,6 +328,9 @@ class TestEoGrandChildrenFinalize
|
|||
|
||||
public sealed class GrandChild : Dummy.Child
|
||||
{
|
||||
|
||||
public GrandChild() : base(null, "", 0.0) { }
|
||||
|
||||
public int receivedValue = 0;
|
||||
public override Efl.Object FinalizeAdd()
|
||||
{
|
||||
|
@ -380,4 +346,27 @@ class TestEoGrandChildrenFinalize
|
|||
}
|
||||
}
|
||||
|
||||
class TestConstructors
|
||||
{
|
||||
public static void test_simple_constructor()
|
||||
{
|
||||
int iface_prop = 42;
|
||||
string a = "LFE";
|
||||
double b = 3.14;
|
||||
var obj = new Dummy.Child(null, a, b, iface_prop);
|
||||
Test.AssertEquals(iface_prop, obj.IfaceProp);
|
||||
|
||||
obj = new Dummy.Child(parent: null, ifaceProp : iface_prop, doubleParamsA : a, doubleParamsB : b);
|
||||
Test.AssertEquals(iface_prop, obj.IfaceProp);
|
||||
}
|
||||
|
||||
public static void test_optional_constructor()
|
||||
{
|
||||
string a = "LFE";
|
||||
double b = 3.14;
|
||||
var obj = new Dummy.Child(null, a, b);
|
||||
Test.Assert(!obj.GetIfaceWasSet());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -168,11 +168,10 @@ class TestEoEvents
|
|||
{
|
||||
int received = 0;
|
||||
int sent = 42;
|
||||
var obj = new Dummy.TestObject(null, (Dummy.TestObject t) => {
|
||||
t.EvtWithIntEvt += (object sender, Dummy.TestObjectEvtWithIntEvt_Args e) => {
|
||||
received = e.arg;
|
||||
};
|
||||
});
|
||||
var obj = new Dummy.TestObject();
|
||||
obj.EvtWithIntEvt += (object sender, Dummy.TestObjectEvtWithIntEvt_Args e) => {
|
||||
received = e.arg;
|
||||
};
|
||||
|
||||
obj.EmitEventWithInt(sent);
|
||||
|
||||
|
|
|
@ -2,8 +2,29 @@ import eina_types;
|
|||
|
||||
class Dummy.Child extends Dummy.Test_Object {
|
||||
|
||||
methods {
|
||||
double_params {
|
||||
params {
|
||||
@in a: string;
|
||||
@in b: double;
|
||||
}
|
||||
}
|
||||
|
||||
@property iface_was_set {
|
||||
get {}
|
||||
values {
|
||||
data: bool;
|
||||
}
|
||||
}
|
||||
}
|
||||
constructors {
|
||||
Dummy.Test_Iface.iface_prop @optional;
|
||||
.double_params;
|
||||
}
|
||||
implements {
|
||||
Dummy.Test_Iface.iface_prop { get; set; }
|
||||
class.constructor;
|
||||
class.destructor;
|
||||
Efl.Object.constructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,10 @@ typedef struct Dummy_Numberwrapper_Data
|
|||
|
||||
typedef struct Dummy_Child_Data
|
||||
{
|
||||
int iface_prop;
|
||||
const char* a;
|
||||
double b;
|
||||
Eina_Bool iface_was_set;
|
||||
} Dummy_Child_Data;
|
||||
|
||||
typedef struct Dummy_Inherit_Helper_Data
|
||||
|
@ -3936,6 +3940,42 @@ int _dummy_test_object_dummy_test_iface_iface_prop_get(EINA_UNUSED const Eo *obj
|
|||
}
|
||||
|
||||
/// Dummy.Child
|
||||
|
||||
static Efl_Object *
|
||||
_dummy_child_efl_object_constructor(Eo *obj, Dummy_Child_Data *pd)
|
||||
{
|
||||
efl_constructor(efl_super(obj, DUMMY_CHILD_CLASS));
|
||||
|
||||
pd->iface_prop = 1984;
|
||||
pd->iface_was_set = EINA_FALSE;
|
||||
return obj;
|
||||
}
|
||||
|
||||
void _dummy_child_dummy_test_iface_iface_prop_set(EINA_UNUSED Eo *obj, Dummy_Child_Data *pd, int value)
|
||||
{
|
||||
pd->iface_prop = value;
|
||||
pd->iface_was_set = EINA_TRUE;
|
||||
}
|
||||
|
||||
int _dummy_child_dummy_test_iface_iface_prop_get(EINA_UNUSED const Eo *obj, Dummy_Child_Data *pd)
|
||||
{
|
||||
return pd->iface_prop;
|
||||
}
|
||||
|
||||
void _dummy_child_double_params(EINA_UNUSED Eo* obj, Dummy_Child_Data *pd, const char* a, double b)
|
||||
{
|
||||
if (pd->a)
|
||||
free((void*)pd->a);
|
||||
pd->a = malloc(sizeof(char)*(strlen(a) + 1));
|
||||
strcpy((char*)pd->a, a);
|
||||
|
||||
pd->b = b;
|
||||
}
|
||||
|
||||
Eina_Bool _dummy_child_iface_was_set_get(EINA_UNUSED const Eo* obj, Dummy_Child_Data *pd)
|
||||
{
|
||||
return pd->iface_was_set;
|
||||
}
|
||||
EOLIAN static void
|
||||
_dummy_child_class_constructor(Efl_Class *klass)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue