summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_Efl_Mono.am2
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh23
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh13
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh52
-rw-r--r--src/bin/eolian_mono/eolian/mono/utils.hh13
-rw-r--r--src/tests/efl_mono/Parts.cs41
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c26
-rw-r--r--src/tests/efl_mono/test_testing.eo8
8 files changed, 172 insertions, 6 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 7c2930d52b..f608676fa9 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -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/part_definition.hh \
bin/eolian_mono/eolian/mono/struct_fields.hh \
bin/eolian_mono/eolian/mono/parameter.hh \
bin/eolian_mono/eolian/mono/utils.hh \
@@ -424,6 +425,7 @@ tests_efl_mono_efl_mono_SOURCES = \
tests/efl_mono/Evas.cs \
tests/efl_mono/Events.cs \
tests/efl_mono/FunctionPointers.cs \
+ tests/efl_mono/Parts.cs \
tests/efl_mono/Strings.cs \
tests/efl_mono/Structs.cs \
tests/efl_mono/TestUtils.cs \
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index d1bebeee14..bdfdbb182c 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -2,6 +2,13 @@
#define EOLIAN_MONO_HELPERS_HH
#include "grammar/klass_def.hpp"
+#include "utils.hh"
+
+/* General helper functions for the main generators.
+ *
+ * These range from blacklisting structures to 'nano-generators' (functions that receive
+ * a binding-specifict structure and returns a string).
+ */
namespace eolian_mono {
@@ -102,9 +109,19 @@ inline bool need_pointer_conversion(attributes::regular_type_def const* regular)
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;
+ return utils::capitalize(in);
+}
+
+inline std::string klass_name_to_csharp(attributes::klass_name const& clsname)
+{
+ std::ostringstream output;
+
+ for (auto namesp : clsname.namespaces)
+ output << utils::to_lowercase(namesp) << ".";
+
+ output << clsname.eolian_name;
+
+ return output.str();
}
}
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index f0c73b3aaf..7de2f2b47b 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -15,6 +15,7 @@
#include "function_registration.hh"
#include "function_declaration.hh"
#include "documentation.hh"
+#include "part_definition.hh"
#include "grammar/string.hpp"
#include "grammar/attribute_replace.hpp"
#include "grammar/integral.hpp"
@@ -239,6 +240,10 @@ struct klass
return false;
}
+ for (auto &&p : cls.parts)
+ if (!as_generator( klass_name_to_csharp(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n").generate(sink, attributes::unused, iface_cxt))
+ return false;
+
// End of interface declaration
if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false;
}
@@ -331,6 +336,10 @@ struct klass
if (!generate_events_registration(sink, cls, concrete_cxt))
return false;
+ // Parts
+ if(!as_generator(*(part_definition))
+ .generate(sink, cls.get_all_parts(), concrete_cxt)) return false;
+
// Concrete function definitions
if(!as_generator(*(function_definition))
.generate(sink, methods, concrete_cxt)) return false;
@@ -431,6 +440,10 @@ struct klass
if (!generate_events_registration(sink, cls, inherit_cxt))
return false;
+ // Parts
+ if(!as_generator(*(part_definition))
+ .generate(sink, cls.get_all_parts(), inherit_cxt)) return false;
+
// Inherit function definitions
if(!as_generator(*(function_definition(true)))
.generate(sink, methods, inherit_cxt)) return false;
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
new file mode 100644
index 0000000000..83222c9ed4
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -0,0 +1,52 @@
+#ifndef EOLIAN_MONO_PART_DEFINITION_HH
+#define EOLIAN_MONO_PART_DEFINITION_HH
+
+#include <Eina.hh>
+
+#include "grammar/generator.hpp"
+#include "grammar/klass_def.hpp"
+#include "grammar/indentation.hpp"
+
+#include "utils.hh"
+#include "documentation.hh"
+
+namespace eolian_mono {
+
+struct part_definition_generator
+{
+ template <typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::part_def const& part, Context const& context) const
+ {
+ std::string part_klass_name = klass_name_to_csharp(part.klass);
+ return as_generator(scope_tab << documentation
+ << scope_tab << "public " << part_klass_name << " " << utils::capitalize(part.name) << "\n"
+ << scope_tab << "{\n"
+ << scope_tab << scope_tab << "get\n"
+ << scope_tab << scope_tab << "{\n"
+ << scope_tab << scope_tab << scope_tab << "efl.Object obj = efl_part(raw_handle, \"" << part.name << "\");\n"
+ << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << "Concrete.static_cast(obj);\n"
+ << scope_tab << scope_tab << "}\n"
+ << scope_tab << "}\n"
+ ).generate(sink, part.documentation, context);
+ }
+
+} const part_definition {};
+
+}
+
+namespace efl { namespace eolian { namespace grammar {
+
+template <>
+struct is_eager_generator< ::eolian_mono::part_definition_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::part_definition_generator> : std::true_type {};
+
+namespace type_traits {
+template <>
+struct attributes_needed< ::eolian_mono::part_definition_generator> : std::integral_constant<int, 1> {};
+
+}
+} } }
+
+#endif
+
diff --git a/src/bin/eolian_mono/eolian/mono/utils.hh b/src/bin/eolian_mono/eolian/mono/utils.hh
index 3e48e518b5..6be2076caa 100644
--- a/src/bin/eolian_mono/eolian/mono/utils.hh
+++ b/src/bin/eolian_mono/eolian/mono/utils.hh
@@ -4,19 +4,28 @@
#include <string>
#include <algorithm>
+/* Compared to the helpers.hh header, these functions are lower level, not dealing with
+ * binding-specific structures or knowledge */
+
namespace eolian_mono { namespace utils {
// Helper method to avoid multiple as_generator calls when mixing case strings
- std::string to_uppercase(std::string s)
+ inline std::string to_uppercase(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
}
- std::string to_lowercase(std::string s)
+ inline std::string to_lowercase(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}
+ inline std::string capitalize(std::string const &s)
+ {
+ std::string ret = s;
+ ret[0] = std::toupper(ret[0]);
+ return ret;
+ }
} }
#endif
diff --git a/src/tests/efl_mono/Parts.cs b/src/tests/efl_mono/Parts.cs
new file mode 100644
index 0000000000..b6ed9a882c
--- /dev/null
+++ b/src/tests/efl_mono/Parts.cs
@@ -0,0 +1,41 @@
+#define CODE_ANALYSIS
+
+#pragma warning disable 1591
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace TestSuite {
+
+
+[SuppressMessage("Gendarme.Rules.Portability", "DoNotHardcodePathsRule")]
+public static class TestParts
+{
+ public static void basic_part_test()
+ {
+ test.Testing t = new test.TestingConcrete();
+ do_part_test(t);
+ }
+
+ private class Child : test.TestingInherit
+ {
+ public Child() : base(null) {}
+ }
+
+ public static void inherited_part_test() {
+ var t = new Child();
+ do_part_test(t);
+ }
+
+ private static void do_part_test(test.Testing t)
+ {
+ var p1 = t.Part1;
+ var p2 = t.Part2;
+ Test.Assert(p1 is test.Testing);
+ Test.AssertEquals("part1", p1.GetName());
+ Test.Assert(p2 is test.Testing);
+ Test.AssertEquals("part2", p2.GetName());
+ }
+}
+
+}
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index 04fd12053f..19fe984022 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -34,6 +34,8 @@
#include "test_numberwrapper.eo.h"
#include "test_testing.eo.h"
+#include <interfaces/efl_part.eo.h>
+
#define EQUAL(a, b) ((a) == (b) ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s)", __FILE__, __LINE__, __FUNCTION__), fflush(stderr), 0))
#define STR_EQUAL(a, b) (strcmp((a), (b)) == 0 ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s) '%s' != '%s'", __FILE__, __LINE__, __FUNCTION__, (a), (b)), fflush(stderr), 0))
@@ -46,6 +48,8 @@ typedef struct Test_Testing_Data
Eina_Value *stored_value;
Test_StructSimple stored_struct;
int stored_int;
+ Eo *part1;
+ Eo *part2;
} Test_Testing_Data;
typedef struct Test_Numberwrapper_Data
@@ -3714,6 +3718,28 @@ void _test_testing_emit_event_with_obj(Eo *obj, EINA_UNUSED Test_Testing_Data *p
efl_event_callback_legacy_call(obj, TEST_TESTING_EVENT_EVT_WITH_OBJ, data);
}
+Efl_Object *_test_testing_efl_part_part(const Eo *obj, Test_Testing_Data *pd, const char *name)
+{
+ if (!strcmp(name, "part1"))
+ {
+ if (pd->part1 == NULL)
+ {
+ pd->part1 = efl_add(TEST_TESTING_CLASS, obj, efl_name_set(efl_added, "part1"));
+ }
+ return pd->part1;
+ }
+ else if (!strcmp(name, "part2"))
+ {
+ if (pd->part2 == NULL)
+ {
+ pd->part2 = efl_add(TEST_TESTING_CLASS, obj, efl_name_set(efl_added, "part2"));
+ }
+ return pd->part2;
+ }
+ else
+ return NULL;
+}
+
#include "test_testing.eo.c"
#include "test_numberwrapper.eo.c"
diff --git a/src/tests/efl_mono/test_testing.eo b/src/tests/efl_mono/test_testing.eo
index c2d3edcd2e..90d512e763 100644
--- a/src/tests/efl_mono/test_testing.eo
+++ b/src/tests/efl_mono/test_testing.eo
@@ -81,7 +81,12 @@ function Test.SimpleCb {
return: int;
};
-class Test.Testing (Efl.Object) {
+class Test.Testing (Efl.Object, Efl.Part) {
+
+ parts {
+ part1: Test.Testing; [[ Part number one. ]]
+ part2: Test.Testing; [[ Part number two. ]]
+ }
methods {
return_object {
return: Test.Testing;
@@ -1547,6 +1552,7 @@ class Test.Testing (Efl.Object) {
implements {
class.constructor;
class.destructor;
+ Efl.Part.part;
}
events {
evt,with,string @hot: string;