forked from enlightenment/efl
csharp: generate helper constructors for structs.
Summary: C# does not have a literal form for structs (like C++'s {} aggregate initialization). Before this commit the user would need to explicitly instantiate a struct and assign the required values to it, like: eina.Size2D size; size.W = width; size.H = height; widget.SetSize(size); As a workaround, this commit generates helper constructor with parameters corresponding to the struct fields in the order they are declared. These parameters have default values if one does not want to explicitly initialize all fields directly. With these constructs, the above code could be translated to: widget.SetSize(new eina.Size2D(width, height)); It should be noted that the constructed struct will live on the managed memory (GC) instead of the stack. Test Plan: run "make check" Reviewers: felipealmeida Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D5838 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
34673ab983
commit
067a8baffa
|
@ -78,6 +78,7 @@ bin_eolian_mono_eolian_mono_SOURCES = \
|
|||
bin/eolian_mono/eolian/mono/function_registration.hh \
|
||||
bin/eolian_mono/eolian/mono/enum_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/struct_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/struct_fields.hh \
|
||||
bin/eolian_mono/eolian/mono/parameter.hh \
|
||||
bin/eolian_mono/eolian/mono/utils.hh \
|
||||
bin/eolian_mono/eolian/mono/using_decl.hh \
|
||||
|
|
|
@ -76,6 +76,12 @@ inline bool need_pointer_conversion(attributes::regular_type_def const* regular)
|
|||
return false;
|
||||
}
|
||||
|
||||
inline std::string to_field_name(std::string const& in)
|
||||
{
|
||||
std::string field_name = in;
|
||||
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
|
||||
return field_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "keyword.hh"
|
||||
#include "using_decl.hh"
|
||||
#include "documentation.hh"
|
||||
#include "struct_fields.hh"
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
|
@ -24,13 +25,6 @@ inline std::string binding_struct_internal_name(attributes::struct_def const& st
|
|||
return struct_.cxx_name + "_StructInternal";
|
||||
}
|
||||
|
||||
inline std::string to_field_name(std::string const& in)
|
||||
{
|
||||
std::string field_name = in;
|
||||
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
|
||||
return field_name;
|
||||
}
|
||||
|
||||
struct struct_definition_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
|
@ -70,6 +64,21 @@ struct struct_definition_generator
|
|||
if (!as_generator("///<summary>Placeholder field</summary>\npublic IntPtr field;\n").generate(sink, nullptr, context))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Constructor with default parameters for easy struct initialization
|
||||
auto struct_name = binding_struct_name(struct_);
|
||||
if(!as_generator(
|
||||
scope_tab << "///<summary>Constructor for " << string << ".</summary>\n"
|
||||
<< scope_tab << "public " << string << "(\n"
|
||||
<< ((scope_tab << scope_tab << field_argument_default) % ",\n")
|
||||
<< scope_tab << ")\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< *(scope_tab << scope_tab << field_argument_assignment << ";\n")
|
||||
<< scope_tab << "}\n")
|
||||
.generate(sink, std::make_tuple(struct_name, struct_name, struct_.fields, struct_.fields), context))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef EOLIAN_MONO_STRUCT_FIELDS_HH
|
||||
#define EOLIAN_MONO_STRUCT_FIELDS_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "helpers.hh"
|
||||
#include "type.hh"
|
||||
#include "keyword.hh"
|
||||
#include "using_decl.hh"
|
||||
#include "documentation.hh"
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
struct field_argument_default_generator
|
||||
{
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
|
||||
{
|
||||
if (!as_generator(type << " " << string << "=default(" << type << ")")
|
||||
.generate(sink, std::make_tuple(field.type, to_field_name(field.name), field.type), context))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
} const field_argument_default {};
|
||||
|
||||
struct field_argument_assignment_generator
|
||||
{
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
|
||||
{
|
||||
if (!as_generator("this." << string << " = " << string)
|
||||
.generate(sink, std::make_tuple(to_field_name(field.name), to_field_name(field.name)), context))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
} const field_argument_assignment {};
|
||||
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template<>
|
||||
struct is_eager_generator< ::eolian_mono::field_argument_default_generator> : std::true_type {};
|
||||
template<>
|
||||
struct is_generator< ::eolian_mono::field_argument_default_generator> : std::true_type {};
|
||||
|
||||
template<>
|
||||
struct is_eager_generator< ::eolian_mono::field_argument_assignment_generator> : std::true_type {};
|
||||
template<>
|
||||
struct is_generator< ::eolian_mono::field_argument_assignment_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::field_argument_default_generator> : std::integral_constant<int, 1> {};
|
||||
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::field_argument_assignment_generator> : std::integral_constant<int, 1> {};
|
||||
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
|
|
@ -245,6 +245,17 @@ class TestStructs
|
|||
checkZeroedStructComplex(complex);
|
||||
}
|
||||
|
||||
public static void parameter_initialization()
|
||||
{
|
||||
var simple = new test.StructSimple(0x1, 0x2, (char)0x3, 0x4, 0x5);
|
||||
Test.AssertEquals(0x1, simple.Fbyte);
|
||||
Test.AssertEquals(0x2, simple.Fubyte);
|
||||
Test.AssertEquals(0x3, simple.Fchar);
|
||||
Test.AssertEquals(0x4, simple.Fshort);
|
||||
Test.AssertEquals(0x5, simple.Fushort);
|
||||
Test.AssertEquals(0, simple.Fint);
|
||||
}
|
||||
|
||||
// As parameters
|
||||
|
||||
public static void simple_in()
|
||||
|
|
Loading…
Reference in New Issue