forked from enlightenment/efl
WIP: Generating fields in interface indexers
Needs to sort out the generation of indexer types for the fields of non-public interface properties that are generated in concrete classes. (Mainly the if/else around function_definition.hh 690)
This commit is contained in:
parent
28271776d8
commit
518a6cc57d
|
@ -165,7 +165,7 @@ inline bool is_property_blacklisted(std::string const& name)
|
|||
// Setter returns a future
|
||||
, "Efl.IModel.Property"
|
||||
// Protected
|
||||
, "Efl.Access.IAction.ActionName"
|
||||
// , "Efl.Access.IAction.ActionName"
|
||||
, "Efl.Access.IAction.ActionLocalizedName"
|
||||
, "Efl.Access.IComponent.Extents"
|
||||
, "Efl.Access.IText.AccessSelection"
|
||||
|
|
|
@ -356,7 +356,6 @@ struct property_wrapper_definition_generator
|
|||
, attributes::property_def const& property
|
||||
, Context const& context
|
||||
, std::string scope, std::string get_scope, std::string set_scope
|
||||
, std::string class_name
|
||||
, C1 keys, C2 values
|
||||
, bool is_interface
|
||||
, bool is_concrete_for_interface
|
||||
|
@ -380,16 +379,15 @@ struct property_wrapper_definition_generator
|
|||
|
||||
std::string parentship = "\n";
|
||||
|
||||
bool is_self_property = *implementing_klass == *klass_from_property;
|
||||
|
||||
if (!(is_self_property && !is_concrete_for_interface))
|
||||
if (helpers::is_impl_of_interface_property_indexer(property, *klass_from_property, *implementing_klass, context))
|
||||
parentship = " : " + name_helpers::property_interface_indexer_name(property, *klass_from_property) + "\n";
|
||||
|
||||
auto klass_from_property_name = name_helpers::klass_full_concrete_or_interface_name(*klass_from_property);
|
||||
if (!as_generator
|
||||
(
|
||||
scope_tab << scope << "class " << name_helpers::property_concrete_indexer_name(property) << parentship
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab(2) << "public " << class_name << " Self {get; set;}\n"
|
||||
<< scope_tab(2) << "public " << klass_from_property_name << " Self {get; set;}\n"
|
||||
<< scope_tab(2) << "public "
|
||||
<< type_or_tuple << " this[" << type_or_tuple <<" i]\n"
|
||||
<< scope_tab(2) << "{\n"
|
||||
|
@ -675,41 +673,44 @@ struct property_wrapper_definition_generator
|
|||
|
||||
if (has_indexer)
|
||||
{
|
||||
// The generated indexer wraps the actual property values inside the indexer, so a call like
|
||||
// `obj.IndexedProperty[key] = value` calls the `[key]` indexer method in the indexer class.
|
||||
// That said, we need to replace the property values with the indexer.
|
||||
assert (!!implementing_klass);
|
||||
generate_indexer (sink, property, context, scope, get_scope, set_scope
|
||||
, klass_name, keys, values
|
||||
generate_indexer (sink, property, context
|
||||
, scope, get_scope, set_scope
|
||||
, keys, values
|
||||
, is_interface, is_concrete_for_interface, has_setter);
|
||||
|
||||
generated_values.clear();
|
||||
std::string base_type_name;
|
||||
std::string c_type;
|
||||
|
||||
// FIXME this selection needs to be sorted out.
|
||||
if (!is_interface && *implementing_klass == *klass_from_property
|
||||
&& !is_concrete_for_interface)
|
||||
// if (!is_interface && !helpers::is_impl_of_interface_property_indexer(property, *klass_from_property, *implementing_klass, context))
|
||||
{
|
||||
generated_values.push_back
|
||||
(attributes::parameter_def
|
||||
{parameter_direction::in
|
||||
, attributes::type_def
|
||||
{
|
||||
attributes::regular_type_def{name_helpers::property_concrete_indexer_name(property), {attributes::qualifier_info::is_none, ""}, {}}
|
||||
, name_helpers::property_concrete_indexer_name(property)
|
||||
, false, false, false, ""
|
||||
}
|
||||
, "indexer", {}, nullptr
|
||||
});
|
||||
base_type_name = name_helpers::property_concrete_indexer_name(property);
|
||||
c_type = name_helpers::property_concrete_indexer_name(property);
|
||||
}
|
||||
else
|
||||
{
|
||||
generated_values.push_back
|
||||
base_type_name = name_helpers::property_interface_indexer_name(property, *klass_from_property);
|
||||
c_type = name_helpers::property_interface_indexer_name(property, *klass_from_property);
|
||||
}
|
||||
|
||||
generated_values.push_back
|
||||
(attributes::parameter_def
|
||||
{parameter_direction::in
|
||||
, attributes::type_def
|
||||
{
|
||||
attributes::regular_type_def{name_helpers::klass_full_concrete_or_interface_name (*klass_from_property) + managed_name + "Indexer", {attributes::qualifier_info::is_none, ""}, {}}
|
||||
, name_helpers::property_interface_indexer_name(property, *klass_from_property)
|
||||
attributes::regular_type_def{base_type_name, {attributes::qualifier_info::is_none, ""}, {}}
|
||||
, c_type
|
||||
, false, false, false, ""
|
||||
}
|
||||
, "indexer", {}, nullptr
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (generated_values.size() == 1)
|
||||
|
@ -781,11 +782,42 @@ struct interface_property_indexer_definition_generator
|
|||
auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
|
||||
std::string managed_name = name_helpers::property_managed_name(property);
|
||||
|
||||
auto has_wrapper = helpers::has_property_wrapper(property, implementing_klass, context);
|
||||
// EINA_LOG_ERR("Wrapper bit for property %s of implementing class %s is 0x%X", managed_name.c_str(),
|
||||
// implementing_klass->eolian_name.c_str(), (unsigned int) has_wrapper);
|
||||
if (!(has_wrapper & helpers::has_property_wrapper_bit::has_getter))
|
||||
return true;
|
||||
|
||||
if (!(has_wrapper & helpers::has_property_wrapper_bit::has_indexer))
|
||||
return true;
|
||||
|
||||
auto keys = property.getter->keys;
|
||||
auto values = property.getter->values;
|
||||
|
||||
// Helper generator expressions
|
||||
auto size_not_one = [] (std::vector<attributes::parameter_def> k) { return k.size() != 1; };
|
||||
auto type_or_tuple
|
||||
=
|
||||
(
|
||||
(
|
||||
attribute_conditional(size_not_one)["("]
|
||||
<< (type(false) % ", ")
|
||||
<< ")"
|
||||
)
|
||||
| *type(false)
|
||||
)
|
||||
;
|
||||
|
||||
if (!as_generator
|
||||
("public interface " << name_helpers::property_interface_indexer_short_name(property, *implementing_klass) << "\n"
|
||||
<< "{\n"
|
||||
<< scope_tab << klass_name << " Self {get; set;}\n"
|
||||
<< scope_tab << type_or_tuple << " this[" << type_or_tuple << " i]\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab(2) << "get;\n"
|
||||
<< scope_tab << "}\n"
|
||||
<< "}\n"
|
||||
).generate (sink, attributes::unused, context))
|
||||
).generate (sink, std::make_tuple(values, values, keys, keys), context))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace helpers {
|
|||
/* General helpers, not related directly with generating strings (those go in the name_helpers.hh). */
|
||||
|
||||
namespace attributes = efl::eolian::grammar::attributes;
|
||||
namespace grammar = efl::eolian::grammar;
|
||||
|
||||
inline bool need_struct_conversion(attributes::regular_type_def const* regular)
|
||||
{
|
||||
|
@ -353,8 +354,7 @@ has_property_wrapper_bit has_property_wrapper(attributes::property_def const& pr
|
|||
else if (is_concrete) return r;
|
||||
}
|
||||
|
||||
// EINA_LOG_ERR("Generating property %s", name_helpers::property_managed_name(property).c_str());
|
||||
// C# interface can have only
|
||||
// C# interface can have only public methods.
|
||||
if (is_interface)
|
||||
{
|
||||
has_getter = has_getter && property.getter->scope == attributes::member_scope:: scope_public;
|
||||
|
@ -406,6 +406,24 @@ has_property_wrapper_bit has_property_wrapper(attributes::property_def const& pr
|
|||
return r;
|
||||
}
|
||||
|
||||
template<typename Context>
|
||||
bool is_impl_of_interface_property_indexer(attributes::property_def const& property
|
||||
, attributes::klass_def const& klass_from_property
|
||||
, attributes::klass_def const& implementing_klass
|
||||
, Context const& context)
|
||||
{
|
||||
bool is_self_property = implementing_klass == klass_from_property;
|
||||
|
||||
// EINA_LOG_ERR("Generating indexer for property %s", name_helpers::property_managed_name(property).c_str());
|
||||
if (is_self_property)
|
||||
return false;
|
||||
bool original_klass_is_interface = helpers::is_managed_interface(klass_from_property);
|
||||
auto iface_context = grammar::context_add_tag(class_context{class_context::interface}, context);
|
||||
|
||||
auto wrapper_bit = helpers::has_property_wrapper(property, &klass_from_property, iface_context);
|
||||
return wrapper_bit & helpers::has_property_wrapper_bit::has_indexer;
|
||||
}
|
||||
|
||||
} // namespace helpers
|
||||
|
||||
} // namespace eolian_mono
|
||||
|
|
|
@ -40,7 +40,7 @@ public static class Timeout
|
|||
/// <summary>
|
||||
/// The path to an object.
|
||||
/// <para>Since EFL 1.23.</para>
|
||||
/// </summary>
|
||||
/// /// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ObjectPath : IEquatable<ObjectPath>
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue