{
return name == "Efl.Input.Key.Key"
|| name == "Efl.Input.Hold.Hold"
- || name == "Efl.Text.Text";
+ || name == "Efl.IText.Text";
}
template<typename Context>
}
template<typename Context>
+inline bool is_property_blacklisted(attributes::property_def const& property,
+ attributes::klass_def const& implementing_class,
+ Context context)
+{
+ std::string property_name = name_helpers::property_managed_name(property);
+ std::string klass_name = name_helpers::klass_concrete_or_interface_name(implementing_class);
+
+ // This property wrapper is invalidated as it would clash with the implementing
+ // class constructor. CS
+ if (property_name == klass_name)
+ return true;
+
+ return is_property_blacklisted(property, context);
+}
+
+template<typename Context>
inline bool is_class_blacklisted(attributes::klass_def const& cls, Context context)
{
auto options = efl::eolian::grammar::context_find_tag<options_context>(context);
return n;
}
+ // Gets the eolian ref for the given class, prepending I for interfaces.
+ static std::string object_ref_conversion(const Eolian_Object *cls)
+ {
+ auto klass_type = ::eolian_class_type_get((const Eolian_Class *)cls);
+ auto full_eolian_name = name_helpers::managed_namespace(::eolian_object_name_get(cls));
+ if (klass_type == EOLIAN_CLASS_MIXIN || klass_type == EOLIAN_CLASS_INTERFACE)
+ {
+ size_t pos = full_eolian_name.rfind(".");
+ if (pos == std::string::npos)
+ pos = 0;
+ else
+ pos++;
+ full_eolian_name.insert(pos, "I");
+ }
+ return full_eolian_name;
+ }
+
+
// Turns a function name from EO convention to EFL# convention.
// The name_tail parameter is the last 4 chars of the original string, which
// could be ".set" or ".get" and in this case they are ignored by Eolian.
{
::Eolian_Function_Type ftype = ::eolian_function_type_get(function);
const char* eo_name = ::eolian_function_name_get(function);
- std::string name = name_helpers::managed_namespace(::eolian_object_name_get(klass));
+ std::string name = object_ref_conversion(klass);
switch(ftype)
{
case ::EOLIAN_METHOD:
if (blacklist::is_struct_blacklisted(ref)) return "";
break;
case ::EOLIAN_OBJECT_EVENT:
- ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
+ ref = object_ref_conversion(data);
ref += ".";
ref += name_helpers::managed_event_name(::eolian_object_name_get(data2));
break;
// If the reference cannot be resolved, just return an empty string and
// it won't be converted into a <see> tag.
break;
+ case ::EOLIAN_OBJECT_CLASS:
+ ref = object_ref_conversion(data);
+ break;
default:
ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
break;
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::property_def const& property, Context context) const
{
- if (blacklist::is_property_blacklisted(property, context))
+ if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
return true;
bool interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
return true;
}
+ attributes::klass_def const* implementing_klass;
+};
+struct property_wrapper_definition_parameterized
+{
+ property_wrapper_definition_generator operator()(attributes::klass_def const& klass) const
+ {
+ return {&klass};
+ }
} const property_wrapper_definition;
+property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized)
+{
+ return {};
+}
}
template <>
struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
template <>
+struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
+template <>
struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
struct is_generator< ::eolian_mono::function_definition_parameterized> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
namespace type_traits {
template <>
template <>
struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
+template <>
+struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {};
}
} } }
).generate(sink, p, iface_cxt))
return false;
- if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, iface_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, iface_cxt))
return false;
// End of interface declaration
return false;
// Property wrappers
- if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, concrete_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt))
return false;
for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
{
attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
- if (!as_generator(*(property_wrapper_definition)).generate(sink, c.properties, concrete_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt))
return false;
}
return false;
// Property wrappers
- if (!as_generator(*(property_wrapper_definition)).generate(sink, cls.properties, inherit_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, inherit_cxt))
return false;
for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt))
{
attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
- if (!as_generator(*(property_wrapper_definition)).generate(sink, c.properties, inherit_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, inherit_cxt))
return false;
}
template <typename T>
std::string operator()(T const& klass) const
{
- return utils::remove_all(klass.eolian_name, '_');
+ std::string name = utils::remove_all(klass.eolian_name, '_');
+ if (klass.type == attributes::class_type::mixin || klass.type == attributes::class_type::interface_)
+ return "I" + name;
+ else
+ return name;
}
template <typename OutputIterator, typename Attr, typename Context>
template<typename T>
inline std::string klass_concrete_name(T const& klass)
{
- std::string name = utils::remove_all(klass.eolian_name, '_');
- if (klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_)
- return name;
- return name + "Concrete";
+ if (klass.type == attributes::class_type::mixin || klass.type == attributes::class_type::interface_)
+ return klass_interface_name(klass) + "Concrete";
+
+ return utils::remove_all(klass.eolian_name, '_');
+}
+
+template<typename T>
+inline std::string klass_concrete_or_interface_name(T const& klass)
+{
+ switch(klass.type)
+ {
+ case attributes::class_type::abstract_:
+ case attributes::class_type::regular:
+ return klass_concrete_name(klass);
+ default:
+ return klass_interface_name(klass);
+ }
}
struct klass_full_concrete_name_generator
inline std::string managed_event_args_short_name(attributes::event_def const& evt)
{
std::string ret;
- ret = klass_interface_name(evt.klass);
+ ret = klass_concrete_or_interface_name(evt.klass);
return ret + name_helpers::managed_event_name(evt.name) + "_Args";
}
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "get\n"
<< scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.PartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
+ << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
<< scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
namespace Efl { namespace Eo {
public class Globals {
+
+ /// <summary>Represents the type of the native Efl_Class.</summary>
+ public enum EflClassType {
+ /// <summary>Regular EFL classes.</summary>
+ Regular = 0,
+ /// <summary>Non-instantiable efl classes (i.e. Abstracts).</summary>
+ RegularNoInstant,
+ /// <summary>Interface types.</summary>
+ Interface,
+ /// <summary>Mixins types.</summary>
+ Mixin,
+ /// <summary>Invalid class type.</summary>
+ Invalid
+ }
+
[return: MarshalAs(UnmanagedType.U1)]
public delegate bool efl_object_init_delegate();
public static FunctionWrapper<efl_object_init_delegate> efl_object_init_ptr =
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass);
public delegate IntPtr efl_class_get_delegate(IntPtr obj);
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj);
+ [DllImport(efl.Libs.Eo)] public static extern EflClassType efl_class_type_get(IntPtr klass);
public delegate IntPtr dlerror_delegate();
[DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
string name = Eina.StringConversion.NativeUtf8ToManagedString(namePtr)
.Replace("_", ""); // Convert Efl C name to C# name
+ var klass_type = Efl.Eo.Globals.efl_class_type_get(klass);
+
+ // When converting to managed, interfaces and mixins gets the 'I' prefix.
+ if (klass_type == Efl.Eo.Globals.EflClassType.Interface || klass_type == Efl.Eo.Globals.EflClassType.Mixin)
+ {
+ var pos = name.LastIndexOf(".");
+ name = name.Insert(pos + 1, "I"); // -1 if not found, inserts at 0 normally
+ }
+
var curr_asm = typeof(IWrapper).Assembly;
t = curr_asm.GetType(name);
if (t == null)
using System;
using System.Linq;
+using System.Collections.Generic;
namespace TestSuite
{
public static void test_iface_property()
{
int val = -33;
- Dummy.TestIface iface = new Dummy.TestObject();
+ Dummy.ITestIface iface = new Dummy.TestObject();
iface.IfaceProp = val;
Test.AssertEquals(val, iface.IfaceProp);
}
public static void test_iface_concrete_methods()
{
var obj = new Dummy.TestObject();
- Dummy.TestIface iface = Dummy.TestIfaceConcrete.static_cast(obj);
+ Dummy.ITestIface iface = Dummy.ITestIfaceConcrete.static_cast(obj);
iface.IfaceProp = 1970;
Test.AssertEquals(iface.IfaceProp, 1970);
Test.AssertEquals(provider.GetNumber(), 1999);
}
+ private class ProviderHolder : Dummy.TestObject
+ {
+ private Dummy.TestObject provider;
+ public string ProviderName
+ {
+ get
+ {
+ return "MyProvider";
+ }
+ }
+
+ public ProviderHolder() : base(null)
+ {
+ this.provider = new Dummy.TestObject(this);
+ this.provider.Name = this.ProviderName;
+ this.provider.IfaceProp = 1997;
+ }
+
+ public override Efl.Object FindProvider(System.Type type)
+ {
+ Console.WriteLine("Called FindProvider");
+ if (type == typeof(Dummy.ITestIface))
+ {
+ return this.provider;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
public static void test_find_provider_iface()
{
- var obj = new Dummy.TestObject();
- Dummy.TestIface provider = Dummy.TestIfaceConcrete.static_cast(obj.FindProvider(typeof(Dummy.TestIface)));
- Test.AssertEquals(provider.GetIfaceProp(), 1997);
+ var obj = new ProviderHolder();
+
+ var provider = obj.CallFindProvider(typeof(Efl.Object));
+ Test.AssertNull(provider, msg : "Unkonw provider must be null");
+
+ provider = obj.CallFindProviderForIface();
+ Test.AssertNotNull(provider, msg : "Provider of ITestIFace must not be null");
+ Test.AssertEquals(provider.Name, obj.ProviderName, "Provider name does not match expected");
+
}
}
}
}
- internal class Inherit2 : Dummy.TestObject, Dummy.InheritIface
+ internal class Inherit2 : Dummy.TestObject, Dummy.IInheritIface
{
override public void IntOut (int x, out int y)
{
if (reference != null)
throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}");
}
+
+ /// <summary> Asserts if the given reference is not null.</summary>
+ public static void AssertNotNull(object reference, String msg = "Reference is null",
+ [CallerLineNumber] int line = 0,
+ [CallerFilePath] string file = null,
+ [CallerMemberName] string member = null)
+ {
+ if (reference == null)
+ throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}");
+ }
}
get_setter_only {
return: int;
}
+
+ call_find_provider {
+ params {
+ @in type: const(Efl.Class);
+ }
+ return: Efl.Object;
+ }
+
+ call_find_provider_for_iface {
+ return: Efl.Object;
+ }
}
implements {
class.constructor;
return efl_provider_find(efl_super(obj, DUMMY_TEST_OBJECT_CLASS), klass);
}
+Efl_Object *_dummy_test_object_call_find_provider(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, const Efl_Class *type)
+{
+ printf("CALLING FIND PROVIDER FROM C");
+ return efl_provider_find(obj, type);
+}
+
+Efl_Object *_dummy_test_object_call_find_provider_for_iface(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd)
+{
+ printf("CALLING FIND PROVIDER FROM C");
+ return efl_provider_find(obj, DUMMY_TEST_IFACE_INTERFACE);
+}
+
/// Dummy.Child
static Efl_Object *