eolian-mono: Add documentation generation support

This commit adds the "documentation" generator, which gets the
documentation_def attribute of the given item and generates xml comments
to be exported by MCS.

For items requiring some customization of the generated comments (e.g.
functions and its parameters), the helpers to generate the preamble
(summary), body (paragraphs) and epilogue (currently just the @since
tag) were added.

Currently we do not support converting Eolian references into xmldoc
references.

As we explicitly generate Get/Set methods for properties, for now the
generator tries to get the get/set specific documentation first. If it
is not present, fallback to the common docs.

Later this could be changed to generate the common one as paragraphs of
the Get/Set.

Also some generated code like the wrappers for calling C# methods
from C can be private. This will cleanup the introspection results
and warnings when generating documentation.

Due to this visibility change, the binbuf tests had to be changed
to add redirect calls to the native methods instead of directly
calling the DllImport'd methods.
This commit is contained in:
Lauro Moura 2017-12-06 21:03:55 -03:00 committed by Felipe Magno de Almeida
parent 0609c68e34
commit 46b202b86c
54 changed files with 1206 additions and 157 deletions

View File

@ -190,9 +190,11 @@ lib_efl_mono_libeflcustomexportsmono_la_DEPENDENCIES = @EFL_CUSTOM_EXPORTS_MONO_
#Efl Mono - C Sharp binding library
libefl_mono_dll_MCS_FLAGS = -doc:lib/efl_mono/libefl_mono.xml
lib/efl_mono/libefl_mono.dll: $(efl_mono_files_dist) lib/efl_mono/$(am__dirstamp) $(efl_mono_files_gen) lib/efl_mono/libefl_mono.dll.config
@rm -f lib/efl_mono/libefl_mono.dll
$(AM_V_MCS) $(MCS) $(MCS_FLAGS) -out:$@ -t:library $(filter %.cs, $(^))
$(AM_V_MCS) $(MCS) $(MCS_FLAGS) $(libefl_mono_dll_MCS_FLAGS) -out:$@ -t:library $(filter %.cs, $(^))
lib/efl_mono/libefl_mono.dll.config:
echo "<configuration>" > $@
@ -213,6 +215,7 @@ endif
EFL_INSTALL_EXEC_HOOK += \
$(MKDIR_P) $(efl_mono_dll_dest); \
cp -f $(builddir)/lib/efl_mono/libefl_mono.dll $(efl_mono_dll_dest)/libefl_mono.dll; \
cp -f $(builddir)/lib/efl_mono/libefl_mono.xml $(efl_mono_dll_dest)/libefl_mono.xml; \
$(MKDIR_P) $(DESTDIR)$(datadir)/efl_mono; \
cp -f $(builddir)/bindings/mono/efl_mono/efl_libs.csv $(DESTDIR)$(datadir)/efl_mono/efl_libs.csv;

View File

@ -94,6 +94,7 @@ tests/eolian_cxx/generic.c \
tests/eolian_cxx/name1_name2_type_generation.c \
tests/eolian_cxx/eolian_cxx_test_inheritance.cc \
tests/eolian_cxx/eolian_cxx_test_generate.cc \
tests/eolian_cxx/eolian_cxx_test_documentation.cc \
tests/eolian_cxx/eolian_cxx_test_cyclic.cc \
tests/eolian_cxx/complex.c \
tests/eolian_cxx/complex_cxx.cc \
@ -168,7 +169,7 @@ tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eolian_cxx\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/eolian_cxx\" \
-DPACKAGE_DATA_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_cxx\" \
@CHECK_CFLAGS@ @EOLIAN_CXX_CFLAGS@ @EINA_CXX_CFLAGS@ \
@EOLIAN_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ @ECORE_CFLAGS@ \

View File

@ -0,0 +1,201 @@
#ifndef EOLIAN_MONO_DOCUMENTATION_HPP
#define EOLIAN_MONO_DOCUMENTATION_HPP
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
#include "grammar/html_escaped_string.hpp"
#include "using_decl.hh"
#include "keyword.hh"
#include <Eina.h>
namespace eolian_mono {
struct documentation_generator
{
int scope_size = 0;
documentation_generator(int scope_size)
: scope_size(scope_size) {}
/// Tag generator helpers
template<typename OutputIterator, typename Context>
bool generate_tag(OutputIterator sink, std::string const& tag, std::string const &text, Context const& context) const
{
if (text.empty())
return true;
return as_generator( scope_tab(scope_size) << "///<" << tag << ">" << html_escaped_string << "</" << tag << ">\n").generate(sink, text, context);
}
template<typename OutputIterator, typename Context>
bool generate_tag_summary(OutputIterator sink, std::string const& text, Context const& context) const
{
return generate_tag(sink, "summary", text, context);
}
template<typename OutputIterator, typename Context>
bool generate_tag_para(OutputIterator sink, std::string const& text, Context const& context) const
{
return generate_tag(sink, "para", text, context);
}
template<typename OutputIterator, typename Context>
bool generate_tag_param(OutputIterator sink, std::string const& name, std::string const& text, Context const& context) const
{
return as_generator( scope_tab(scope_size) << "///<param name=\"" << name << "\">"
<< html_escaped_string << "</param>\n").generate(sink, text, context);
}
template<typename OutputIterator, typename Context>
bool generate_tag_return(OutputIterator sink, std::string const& text, Context const& context) const
{
return generate_tag(sink, "return", text, context);
}
// Actual exported generators
template<typename OutputIterator, typename Attribute, typename Context>
bool generate(OutputIterator sink, Attribute const& attr, Context const& context) const
{
return generate(sink, attr.documentation, context);
}
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::function_def const& func, Context const& context) const
{
if (func.type == attributes::function_type::prop_get || func.type == attributes::function_type::prop_set)
return generate_property(sink, func, context);
else
return generate_function(sink, func, context);
return true;
}
template<typename OutputIterator, typename Context>
bool generate_property(OutputIterator sink, attributes::function_def const& func, Context const& context) const
{
// First, try the get/set specific documentation
if (!func.documentation.summary.empty())
{
if (!generate(sink, func.documentation, context))
return false;
}
else // fallback to common property documentation
{
if (!generate(sink, func.property_documentation, context))
return false;
}
for (auto&& param : func.parameters)
if (!generate_parameter(sink, param, context))
return false;
if (!generate_tag_return(sink, func.return_documentation.summary, context))
return false;
return true;
}
template<typename OutputIterator, typename Context>
bool generate_function(OutputIterator sink, attributes::function_def const& func, Context const& context) const
{
if (!generate(sink, func.documentation, context))
return false;
for (auto&& param : func.parameters)
if (!generate_parameter(sink, param, context))
return false;
if (!generate_tag_return(sink, func.return_documentation.summary, context))
return false;
return true;
}
template<typename OutputIterator, typename Context>
bool generate_parameter(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
return generate_tag_param(sink, escape_keyword(param.param_name), param.documentation.summary, context);
}
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::documentation_def const& doc, Context const& context) const
{
if (!generate_preamble(sink, doc, context))
return false;
if (!generate_body(sink, doc, context))
return false;
if (!generate_epilogue(sink, doc, context))
return false;
return true;
}
template<typename OutputIterator, typename Context>
bool generate_preamble(OutputIterator sink, attributes::documentation_def const& doc, Context const context) const
{
return generate_tag_summary(sink, doc.summary, context);
}
template<typename OutputIterator, typename Context>
bool generate_body(OutputIterator sink, attributes::documentation_def const& doc, Context const context) const
{
for (auto&& para : doc.desc_paragraphs)
{
if (!generate_tag_para(sink, para, context))
return false;
}
return true;
}
template<typename OutputIterator, typename Context>
bool generate_epilogue(OutputIterator sink, attributes::documentation_def const& doc, Context const context) const
{
if (doc.since.empty())
return true;
if (!generate_tag_para(sink, doc.since, context))
return false;
return true;
}
};
struct documentation_terminal
{
documentation_generator operator()(int n) const
{
return documentation_generator(n);
}
} const documentation = {};
documentation_generator as_generator(documentation_terminal)
{
return documentation_generator(0);
}
} // namespace eolian_mono
namespace efl { namespace eolian { namespace grammar {
template<>
struct is_eager_generator<::eolian_mono::documentation_generator> : std::true_type {};
template<>
struct is_generator<::eolian_mono::documentation_generator> : std::true_type {};
template<>
struct is_generator<::eolian_mono::documentation_terminal> : std::true_type {};
namespace type_traits {
template<>
struct attributes_needed<struct ::eolian_mono::documentation_generator> : std::integral_constant<int, 1> {};
template<>
struct attributes_needed<struct ::eolian_mono::documentation_terminal> : std::integral_constant<int, 1> {};
}
} } }
#endif

View File

@ -22,6 +22,9 @@ struct enum_definition_generator
auto open_namespace = *("namespace " << string << " { ") << "\n";
if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
if(!as_generator(documentation).generate(sink, enum_, context))
return false;
if(!as_generator
(
"public enum " << string << "\n{\n"
@ -38,9 +41,9 @@ struct enum_definition_generator
name[0] = std::toupper(name[0]); // Hack to allow 'static' as a field name
if (!as_generator
(
string << " = " << string << ",\n"
documentation << string << " = " << string << ",\n"
)
.generate(sink, std::make_tuple(name, literal), context))
.generate(sink, std::make_tuple(*first, name, literal), context))
return false;
}

View File

@ -21,10 +21,13 @@ struct function_declaration_generator
{
if(is_function_blacklisted(f.c_name))
return true;
else
return as_generator
if(!as_generator(documentation).generate(sink, f, context))
return false;
return as_generator
(eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n")
.generate(sink, std::make_tuple(f.return_type, managed_method_name(f.name), f.parameters), context);
.generate(sink, std::make_tuple(f.return_type, managed_method_name(f.name), f.parameters), context);
}
};

View File

@ -15,6 +15,7 @@
#include "marshall_type.hh"
#include "parameter.hh"
#include "keyword.hh"
#include "documentation.hh"
#include "using_decl.hh"
#include "generation_contexts.hh"
@ -34,7 +35,7 @@ struct native_function_definition_generator
if(!as_generator
("\n\n" << scope_tab
<< eolian_mono::marshall_native_annotation(true)
<< " public delegate "
<< " private delegate "
<< eolian_mono::marshall_type(true)
<< " "
<< string
@ -50,7 +51,7 @@ struct native_function_definition_generator
if(!as_generator
(scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")] "
<< eolian_mono::marshall_native_annotation(true)
<< " public static extern "
<< " private static extern "
<< eolian_mono::marshall_type(true)
<< " " << string
<< "(System.IntPtr obj"
@ -68,7 +69,7 @@ struct native_function_definition_generator
if(!as_generator
(scope_tab
<< " public static "
<< " private static "
<< eolian_mono::marshall_type(true) << " "
<< string
<< "(System.IntPtr obj, System.IntPtr pd"
@ -108,7 +109,7 @@ struct native_function_definition_generator
return false;
if(!as_generator
(scope_tab << "public static "
(scope_tab << "private static "
<< string
<< "_delegate "
<< string << "_static_delegate = new " << string << "_delegate(" << string << "NativeInherit." << string << ");\n"
@ -137,7 +138,7 @@ struct function_definition_generator
if(!as_generator
("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n"
<< scope_tab << eolian_mono::marshall_annotation(true)
<< " public static extern "
<< " private static extern "
<< eolian_mono::marshall_type(true)
<< " " << string
<< "(System.IntPtr obj"
@ -153,6 +154,10 @@ struct function_definition_generator
if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
return false;
if(!as_generator
(documentation(1)).generate(sink, f, context))
return false;
if(!as_generator
(scope_tab << (do_super ? "virtual " : "") << "public " << return_type << " " << string << "(" << (parameter % ", ")
<< ") {\n "

View File

@ -6,6 +6,8 @@
#include <vector>
#include <string>
#include "documentation.hh"
namespace eolian_mono {
// Blacklist structs that require some kind of manual binding.
@ -36,25 +38,26 @@ struct function_pointer {
if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false;
// C# visible delegate
if (!as_generator("public delegate " << type << " " << string
if (!as_generator(documentation
<< "public delegate " << type << " " << string
<< "(" << (parameter % ", ") << ");\n")
.generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context))
.generate(sink, std::make_tuple(f, f.return_type, escape_keyword(f.name), f.parameters), context))
return false;
// "Internal" delegate, 1-to-1 with the Unamaged function type
if (!as_generator("public delegate " << type << " " << string // public?
if (!as_generator("internal delegate " << type << " " << string // public?
<< "Internal(IntPtr data, " << (parameter % ", ") << ");\n")
.generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context))
return false;
std::string f_name = escape_keyword(f.name);
// Wrapper type, with callback matching the Unamanaged one
if (!as_generator("public class " << f_name << "Wrapper\n"
if (!as_generator("internal class " << f_name << "Wrapper\n"
<< "{\n\n"
<< scope_tab << "private " << f_name << "Internal _cb;\n"
<< scope_tab << "private IntPtr _cb_data;\n"
<< scope_tab << "private Eina_Free_Cb _cb_free_cb;\n\n"
<< scope_tab << "public " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, Eina_Free_Cb _cb_free_cb)\n"
<< scope_tab << "internal " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, Eina_Free_Cb _cb_free_cb)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "this._cb = _cb;\n"
<< scope_tab << scope_tab << "this._cb_data = _cb_data;\n"
@ -67,12 +70,12 @@ struct function_pointer {
<< scope_tab << scope_tab << scope_tab << "this._cb_free_cb(this._cb_data);\n"
<< scope_tab << "}\n\n"
<< scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n"
<< scope_tab << "internal " << type << " ManagedCb(" << (parameter % ",") << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation_no_conversion % ", ") << ");\n"
<< scope_tab << "}\n\n"
<< scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
<< scope_tab << "internal static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
<< scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"

View File

@ -14,6 +14,7 @@
#include "function_definition.hh"
#include "function_registration.hh"
#include "function_declaration.hh"
#include "documentation.hh"
#include "grammar/string.hpp"
#include "grammar/attribute_replace.hpp"
#include "grammar/integral.hpp"
@ -30,7 +31,8 @@ template <typename OutputIterator, typename Context>
static bool generate_static_cast_method(OutputIterator sink, const std::string &class_name, Context const &context)
{
return as_generator(
scope_tab << "public static " << class_name << " static_cast(efl.Object obj)\n"
scope_tab << "///<summary>Casts obj into an instance of this type.</summary>\n"
<< scope_tab << "public static " << class_name << " static_cast(efl.Object obj)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "if (obj == null)\n"
<< scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n"
@ -43,13 +45,15 @@ template <typename OutputIterator, typename Context>
static bool generate_equals_method(OutputIterator sink, Context const &context)
{
return as_generator(
scope_tab << "public override bool Equals(object obj)\n"
scope_tab << "///<summary>Verifies if the given object is equals to this.</summary>\n"
<< scope_tab << "public override bool Equals(object obj)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var other = obj as efl.Object;\n"
<< scope_tab << scope_tab << "if (other == null)\n"
<< scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << "return this.raw_handle == other.raw_handle;\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Gets the hash code for this object based on the native pointer it points to.</summary>\n"
<< scope_tab << "public override int GetHashCode()\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "return this.raw_handle.ToInt32();\n"
@ -156,8 +160,12 @@ struct klass
std::replace(evt_name.begin(), evt_name.end(), ',', '_');
std::string arg_type = (*etype).original_type.visit(get_csharp_type_visitor{});
if (!as_generator("///<summary>Event argument wrapper for event " << string << ".</summary>\n"
).generate(sink, evt_name, context))
return false;
if (!as_generator("public class " << evt_name << "_Args : EventArgs {\n"
<< scope_tab << "///<summary>Actual event payload.</summary>\n"
<< scope_tab << "public " << arg_type << " arg { get; set; }\n"
<< "}\n").generate(sink, NULL, context))
return false;
@ -166,6 +174,10 @@ struct klass
// Interface class
{
auto iface_cxt = context_add_tag(class_context{class_context::interface}, context);
if(!as_generator(documentation).generate(sink, cls, iface_cxt))
return false;
if(!as_generator
(
"public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : "
@ -199,6 +211,10 @@ struct klass
if (etype.is_engaged())
wrapper_args_type = "<" + evt_name + "_Args>";
if (!as_generator(documentation(1)).generate(sink, e, iface_cxt))
return false;
//FIXME Add a way to generate camelcase names
if (!as_generator(
scope_tab << "event EventHandler" << wrapper_args_type << " "
@ -218,19 +234,26 @@ struct klass
auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context);
if(!as_generator
(
"public class " << string << "Concrete : " << string << "\n{\n"
documentation
<< "sealed public class " << string << "Concrete : " << string << "\n{\n"
<< scope_tab << "System.IntPtr handle;\n"
<< scope_tab << "///<summary>Pointer to the native instance.</summary>\n"
<< scope_tab << "public System.IntPtr raw_handle {\n"
<< scope_tab << scope_tab << "get { return handle; }\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Pointer to the native class description.</summary>\n"
<< scope_tab << "public System.IntPtr raw_klass {\n"
<< scope_tab << scope_tab << "get { return efl.eo.Globals.efl_class_get(handle); }\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n"
<< scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n"
<< scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
<< ")] static extern System.IntPtr\n"
<< ")] private static extern System.IntPtr\n"
<< scope_tab << scope_tab << class_get_name << "();\n"
<< (class_type == "class" ? "" : "/*")
<< scope_tab << "///<summary>Creates a new instance.</summary>\n"
<< scope_tab << "///<param>Parent instance.</param>\n"
<< scope_tab << "///<param>Delegate to call constructing methods that should be run inside the constructor.</param>\n"
<< scope_tab << "public " << string << "Concrete(efl.Object parent = null, ConstructingMethod init_cb=null)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "System.IntPtr klass = " << class_get_name << "();\n"
@ -246,22 +269,26 @@ struct klass
<< scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
<< scope_tab << "}\n"
<< (class_type == "class" ? "" : "*/")
<< scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
<< scope_tab << "public " << string << "Concrete(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"
<< scope_tab << "///<summary>Destructor.</summary>\n"
<< scope_tab << "~" << string << "Concrete()\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "Dispose(false);\n"
<< scope_tab << "}\n"
<< scope_tab << "protected virtual void Dispose(bool disposing)\n"
<< scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
<< scope_tab << "protected void Dispose(bool disposing)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n"
<< scope_tab << scope_tab << scope_tab << "efl.eo.Globals.efl_unref(handle);\n"
<< scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
<< scope_tab << "public void Dispose()\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "Dispose(true);\n"
@ -269,7 +296,7 @@ struct klass
<< scope_tab << "}\n"
)
.generate(sink
, std::make_tuple(
, std::make_tuple( cls,
cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name
, cls.cxx_name, cls.namespaces, cls.eolian_name, cls.cxx_name
, cls.cxx_name)
@ -304,22 +331,29 @@ struct klass
if(!as_generator
(
"public " << class_type << " " << string << "Inherit : " << string << "\n{\n"
documentation
<< "public " << class_type << " " << string << "Inherit : " << string << "\n{\n"
<< scope_tab << "System.IntPtr handle;\n"
<< scope_tab << "public static System.IntPtr klass = System.IntPtr.Zero;\n"
<< scope_tab << "internal static System.IntPtr klass = System.IntPtr.Zero;\n"
<< scope_tab << "private static readonly object klassAllocLock = new object();\n"
<< scope_tab << (cls_has_string_return ? ("public Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();") : "") << "\n"
<< scope_tab << (cls_has_stringshare_return ? ("public Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();") : "") << "\n"
<< scope_tab << (cls_has_string_return ? ("internal Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();") : "") << "\n"
<< scope_tab << (cls_has_stringshare_return ? ("internal Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();") : "") << "\n"
<< scope_tab << "///<summary>Pointer to the native instance.</summary>\n"
<< scope_tab << "public System.IntPtr raw_handle {\n"
<< scope_tab << scope_tab << "get { return handle; }\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Pointer to the native class description.</summary>\n"
<< scope_tab << "public System.IntPtr raw_klass {\n"
<< scope_tab << scope_tab << "get { return klass; }\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n"
<< scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n"
<< scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(inherit_cxt).actual_library_name(cls.filename)
<< ")] static extern System.IntPtr\n"
<< ")] private static extern System.IntPtr\n"
<< scope_tab << scope_tab << class_get_name << "();\n"
<< scope_tab << "///<summary>Creates a new instance.</summary>\n"
<< scope_tab << "///<param>Parent instance.</param>\n"
<< scope_tab << "///<param>Delegate to call constructing methods that should be run inside the constructor.</param>\n"
<< scope_tab << "public " << string << "Inherit(efl.Object parent = null, ConstructingMethod init_cb=null)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "if (klass == System.IntPtr.Zero) {\n"
@ -339,10 +373,12 @@ struct klass
<< scope_tab << scope_tab << "register_event_proxies();\n"
<< scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Destructor.</summary>\n"
<< scope_tab << "~" << string << "Inherit()\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "Dispose(false);\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
<< scope_tab << "protected virtual void Dispose(bool disposing)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n"
@ -350,6 +386,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
<< scope_tab << "public void Dispose()\n"
<< scope_tab << "{\n"
<< scope_tab << (cls_has_string_return ? "efl.eo.Globals.free_dict_values(cached_strings);" : "") << "\n"
@ -360,7 +397,7 @@ struct klass
)
.generate(sink
, std::make_tuple(
cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name
cls, cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name
, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name, cls.cxx_name
, cls.cxx_name)
, inherit_cxt))
@ -399,7 +436,7 @@ struct klass
auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context);
if(!as_generator
(
"public " << class_type << " " << string << "NativeInherit {\n"
"internal " << class_type << " " << string << "NativeInherit {\n"
<< scope_tab << "public static byte class_initializer(IntPtr klass)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "Efl_Op_Description[] descs = new Efl_Op_Description[" << grammar::int_ << "];\n"
@ -528,7 +565,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << "efl.kw_event.Description desc = new efl.kw_event.Description(key);\n"
<< scope_tab << scope_tab << scope_tab << "bool result = efl.eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evt_delegate, System.IntPtr.Zero);\n"
<< scope_tab << scope_tab << scope_tab << "if (!result) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to add event proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to add event proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
@ -544,12 +581,12 @@ struct klass
<< scope_tab << scope_tab << scope_tab << "efl.kw_event.Description desc = new efl.kw_event.Description(key);\n"
<< scope_tab << scope_tab << scope_tab << "bool result = efl.eo.Globals.efl_event_callback_del(handle, desc, evt_delegate, System.IntPtr.Zero);\n"
<< scope_tab << scope_tab << scope_tab << "if (!result) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to remove event proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to remove event proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
<< scope_tab << scope_tab << "} else if (event_count == 0) {\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Trying to remove proxy for event ${key} when there is nothing registered.\");\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Trying to remove proxy for event {key} when there is nothing registered.\");\n"
<< scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << "} \n"
<< scope_tab << scope_tab << "event_cb_count[key]--;\n"
@ -586,8 +623,12 @@ struct klass
// Marshal.PtrToStructure for value types
// Wrapper event declaration
if(!as_generator(documentation(1)).generate(sink, e, context))
return false;
if(!as_generator(
scope_tab << "protected event EventHandler" << wrapper_args_template << " " << upper_name << ";\n"
<< scope_tab << "///<summary>Method to raise event "<< event_name << ".</summary>\n"
<< scope_tab << "protected void On_" << event_name << "(" << wrapper_args_type << " e)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n"
@ -596,13 +637,13 @@ struct klass
<< scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n"
<< scope_tab << "}\n"
<< scope_tab << "public void on_" << event_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n"
<< scope_tab << "private void on_" << event_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n"
<< scope_tab << "{\n"
<< scope_tab << event_args
<< scope_tab << scope_tab << "try {\n"
<< scope_tab << scope_tab << scope_tab << "On_" << event_name << "(args);\n"
<< scope_tab << scope_tab << "} catch (Exception e) {\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Warning(e.ToString());\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n"
<< scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
@ -618,7 +659,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << event_name << "_delegate))\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << upper_name << " += value;\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Error adding proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
<< scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << "remove {\n"
@ -627,7 +668,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << event_name << "_delegate))\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << upper_name << " -= value;\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Error removing proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n")
@ -672,8 +713,12 @@ struct klass
wrapper_args_type << "EventArgs";
}
if (!as_generator(documentation(1)).generate(sink, e, context))
return false;
if (!as_generator(
scope_tab << "protected event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << ";\n"
<< scope_tab << "///<summary>Method to raise event "<< wrapper_evt_name << ".</summary>\n"
<< scope_tab << "protected void On_" << wrapper_evt_name << "(" << wrapper_args_type.str() << " e)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n"
@ -683,13 +728,13 @@ struct klass
<< scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n"
<< scope_tab << "}\n"
<< scope_tab << "efl.Event_Cb evt_" << wrapper_evt_name << "_delegate;\n"
<< scope_tab << "protected void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)"
<< scope_tab << "private void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)"
<< scope_tab << "{\n"
<< scope_tab << event_args
<< scope_tab << scope_tab << "try {\n"
<< scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
<< scope_tab << scope_tab << "} catch (Exception e) {\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Warning(e.ToString());\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n"
<< scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
@ -703,7 +748,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " += value;\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Error adding proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
<< scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << "remove {\n"
@ -712,7 +757,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " -= value;\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Error removing proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n")

View File

@ -10,6 +10,7 @@
#include "type.hh"
#include "keyword.hh"
#include "using_decl.hh"
#include "documentation.hh"
namespace eolian_mono {
@ -35,6 +36,9 @@ struct struct_definition_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
if(!as_generator(documentation).generate(sink, struct_, context))
return false;
if(!as_generator
(
"[StructLayout(LayoutKind.Sequential)]\n"
@ -46,11 +50,14 @@ struct struct_definition_generator
// iterate struct fields
for (auto const& field : struct_.fields)
{
auto field_name = field.name;
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
if (!as_generator
(
" public " << type << " " << string << ";\n"
documentation(1)
<< scope_tab(1) << "public " << type << " " << string << ";\n"
)
.generate(sink, std::make_tuple(field.type, to_field_name(field.name)), context))
.generate(sink, std::make_tuple(field, field.type, to_field_name(field.name)), context))
return false;
}
@ -79,7 +86,7 @@ struct struct_internal_definition_generator
if (!as_generator
(
"[StructLayout(LayoutKind.Sequential)]\n"
"public struct " << string << "\n{\n"
"internal struct " << string << "\n{\n"
)
.generate(sink, binding_struct_internal_name(struct_), context))
return false;
@ -97,11 +104,11 @@ struct struct_internal_definition_generator
|| regular->base_type == "stringshare"
|| regular->base_type == "any_value_ptr")))
{
if (!as_generator(" public System.IntPtr " << string << ";\n")
if (!as_generator(" internal System.IntPtr " << string << ";\n")
.generate(sink, field_name, context))
return false;
}
else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
else if (!as_generator(eolian_mono::marshall_annotation(false) << " internal " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
return false;
}
@ -112,7 +119,7 @@ struct struct_internal_definition_generator
// those 'mini-amd64.c condition fields not met' crashes.
if (struct_.fields.size() == 0)
{
if (!as_generator("public IntPtr field;\n").generate(sink, nullptr, context))
if (!as_generator("internal IntPtr field;\n").generate(sink, nullptr, context))
return false;
}
@ -330,7 +337,7 @@ struct struct_binding_conversion_functions_generator
// Open conversion class
if (!as_generator
(
"public static class " << string << "_StructConvertion\n{\n"
"internal static class " << string << "_StructConvertion\n{\n"
)
.generate(sink, struct_.cxx_name, context))
return false;
@ -338,7 +345,7 @@ struct struct_binding_conversion_functions_generator
// to internal
if (!as_generator
(
scope_tab << "public static " << string << " ToInternal(" << string << " _external_struct)\n"
scope_tab << "internal static " << string << " ToInternal(" << string << " _external_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _internal_struct = new " << string << "();\n\n"
)
@ -366,7 +373,7 @@ struct struct_binding_conversion_functions_generator
// to external
if (!as_generator
(
scope_tab << "public static " << string << " ToExternal(" << string << " _internal_struct)\n"
scope_tab << "internal static " << string << " ToExternal(" << string << " _internal_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
)

View File

@ -1,11 +1,19 @@
#ifndef EOLIAN_MONO_USING_DECL_HH
#define EOLIAN_MONO_USING_DECL_HH
#include <grammar/generator.hpp>
#include <grammar/context.hpp>
#include <grammar/kleene.hpp>
#include <grammar/integral.hpp>
#include <grammar/string.hpp>
#include <grammar/html_escaped_string.hpp>
namespace eolian_mono {
namespace grammar = efl::eolian::grammar;
using efl::eolian::grammar::as_generator;
using efl::eolian::grammar::string;
using efl::eolian::grammar::html_escaped_string;
using efl::eolian::grammar::operator<<;
using efl::eolian::grammar::operator%;
using efl::eolian::grammar::operator*;

View File

@ -1,3 +1,4 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Threading;

View File

@ -1,3 +1,4 @@
#pragma warning disable 1591
namespace efl {

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Text;
using System.Runtime.InteropServices;
@ -12,7 +14,7 @@ public delegate void Eina_Free_Cb(IntPtr data);
}
public static class NativeCustomExportFunctions
internal static class NativeCustomExportFunctions
{
[DllImport(efl.Libs.CustomExports)] public static extern void
efl_mono_native_free(IntPtr ptr);

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,4 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
#define CODE_ANALYSIS
using System;
@ -708,7 +710,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
Setup(containerType, subtype, step);
}
/// <summary>Constructor to build value from Values_Natives passed by value from C
/// <summary>Constructor to build value from Values_Natives passed by value from C.</summary>
public Value(Value_Native value)
{
this.Handle = MemoryNative.Alloc(Marshal.SizeOf(typeof(Value_Native)));
@ -721,13 +723,13 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
this.Ownership = ValueOwnership.Managed;
}
/// <summary>Implicit conversion from managed value to native struct representation
/// <summary>Implicit conversion from managed value to native struct representation.</summary>
public static implicit operator Value_Native(Value v)
{
return v.GetNative();
}
/// <summary>
/// <summary>Implicit conversion from native struct representation to managed wrapper.</summary>
public static implicit operator Value(Value_Native v)
{
return new Value(v);

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,6 @@
#pragma warning disable 1591
using System.Runtime.InteropServices;
using static eldbus.EldbusObjectNativeFunctions;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,4 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;

View File

@ -1,32 +1,47 @@
#pragma warning disable 1591
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
///<summary>Eo class description, passed to efl_class_new.</summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct ClassDescription
{
///<summary>Current Eo version.</summary>
public uint version;
///<summary>Name of the class.</summary>
[MarshalAs(UnmanagedType.LPStr)] public String name;
///<summary>Class type.</summary>
public int class_type;
///<summary>Size of data (private + protected + public) per instance.</summary>
public UIntPtr data_size;
///<summary>Initializer for the class.</summary>
public IntPtr class_initializer;
///<summary>Constructor of the class.</summary>
public IntPtr class_constructor;
///<summary>Destructor of the class.</summary>
public IntPtr class_destructor;
}
///<summary>Description of an Eo API operation.</summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct Efl_Op_Description
{
///<summary>The EAPI function offering this op. (String with the name of the function on Windows)</summary>
public IntPtr api_func;
///<summary>The static function to be called for this op</summary>
public IntPtr func;
}
///<summary>List of operations on a given Object.</summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct Efl_Object_Ops
{
public IntPtr descs; /**< The op descriptions array of size count. */
public UIntPtr count; /**< Number of op descriptions. */
///<summary>The op descriptions array of size count.</summary>
public IntPtr descs;
///<summary>Number of op descriptions.</summary>
public UIntPtr count;
};
[StructLayout(LayoutKind.Sequential)]
@ -262,28 +277,45 @@ namespace evas {
/* Copied from Evas_Legacy.h */
public enum Text_Style_Type
{
Plain = 0, /**< plain, standard text */
Shadow, /**< text with shadow underneath */
Outline, /**< text with an outline */
SoftOutline, /**< text with a soft outline */
Glow, /**< text with a glow effect */
OutlineShadow, /**< text with both outline and shadow effects */
FarShadow, /**< text with (far) shadow underneath */
OutlineSoftShadow, /**< text with outline and soft shadow effects combined */
SoftShadow, /**< text with (soft) shadow underneath */
FarSoftShadow, /**< text with (far soft) shadow underneath */
///<summary> plain, standard text.</summary>
Plain = 0,
///<summary> text with shadow underneath.</summary>
Shadow,
///<summary> text with an outline.</summary>
Outline,
///<summary> text with a soft outline.</summary>
SoftOutline,
///<summary> text with a glow effect.</summary>
Glow,
///<summary> text with both outline and shadow effects.</summary>
OutlineShadow,
///<summary> text with (far) shadow underneath.</summary>
FarShadow,
///<summary> text with outline and soft shadow effects combined.</summary>
OutlineSoftShadow,
///<summary> text with (soft) shadow underneath.</summary>
SoftShadow,
///<summary> text with (far soft) shadow underneath.</summary>
FarSoftShadow,
// Shadow direction modifiers
ShadowDirectionBottomRight = 0 /* 0 >> 4 */, /**< shadow growing to bottom right */
ShadowDirectionBottom= 16 /* 1 >> 4 */, /**< shadow growing to the bottom */
ShadowDirectionBottomLeft = 32 /* 2 >> 4 */, /**< shadow growing to bottom left */
ShadowDirectionLeft = 48 /* 3 >> 4 */, /**< shadow growing to the left */
ShadowDirectionTopLeft = 64 /* 4 >> 4 */, /**< shadow growing to top left */
ShadowDirectionTop = 80 /* 5 >> 4 */, /**< shadow growing to the top */
ShadowDirectionTopRight = 96 /* 6 >> 4 */, /**< shadow growing to top right */
ShadowDirectionRight = 112 /* 7 >> 4 */ /**< shadow growing to the right */
///<summary> shadow growing to bottom right.</summary>
ShadowDirectionBottomRight = 0 /* 0 >> 4 */,
///<summary> shadow growing to the bottom.</summary>
ShadowDirectionBottom= 16 /* 1 >> 4 */,
///<summary> shadow growing to bottom left.</summary>
ShadowDirectionBottomLeft = 32 /* 2 >> 4 */,
///<summary> shadow growing to the left.</summary>
ShadowDirectionLeft = 48 /* 3 >> 4 */,
///<summary> shadow growing to top left.</summary>
ShadowDirectionTopLeft = 64 /* 4 >> 4 */,
///<summary> shadow growing to the top.</summary>
ShadowDirectionTop = 80 /* 5 >> 4 */,
///<summary> shadow growing to top right.</summary>
ShadowDirectionTopRight = 96 /* 6 >> 4 */,
///<summary> shadow growing to the right.</summary>
ShadowDirectionRight = 112 /* 7 >> 4 */
};
// Copied from Evas_Common.h
//
@ -292,47 +324,83 @@ public enum Text_Style_Type
public enum Callback_Type
{
EVAS_CALLBACK_MOUSE_IN = 0, /**< Mouse In Event */
EVAS_CALLBACK_MOUSE_OUT, /**< Mouse Out Event */
EVAS_CALLBACK_MOUSE_DOWN, /**< Mouse Button Down Event */
EVAS_CALLBACK_MOUSE_UP, /**< Mouse Button Up Event */
EVAS_CALLBACK_MOUSE_MOVE, /**< Mouse Move Event */
EVAS_CALLBACK_MOUSE_WHEEL, /**< Mouse Wheel Event */
EVAS_CALLBACK_MULTI_DOWN, /**< Multi-touch Down Event */
EVAS_CALLBACK_MULTI_UP, /**< Multi-touch Up Event */
EVAS_CALLBACK_MULTI_MOVE, /**< Multi-touch Move Event */
EVAS_CALLBACK_FREE, /**< Object Being Freed (Called after Del) */
EVAS_CALLBACK_KEY_DOWN, /**< Key Press Event */
EVAS_CALLBACK_KEY_UP, /**< Key Release Event */
EVAS_CALLBACK_FOCUS_IN, /**< Focus In Event */
EVAS_CALLBACK_FOCUS_OUT, /**< Focus Out Event */
EVAS_CALLBACK_SHOW, /**< Show Event */
EVAS_CALLBACK_HIDE, /**< Hide Event */
EVAS_CALLBACK_MOVE, /**< Move Event */
EVAS_CALLBACK_RESIZE, /**< Resize Event */
EVAS_CALLBACK_RESTACK, /**< Restack Event */
EVAS_CALLBACK_DEL, /**< Object Being Deleted (called before Free) */
EVAS_CALLBACK_HOLD, /**< Events go on/off hold */
EVAS_CALLBACK_CHANGED_SIZE_HINTS, /**< Size hints changed event */
EVAS_CALLBACK_IMAGE_PRELOADED, /**< Image has been preloaded */
EVAS_CALLBACK_CANVAS_FOCUS_IN, /**< Canvas got focus as a whole */
EVAS_CALLBACK_CANVAS_FOCUS_OUT, /**< Canvas lost focus as a whole */
EVAS_CALLBACK_RENDER_FLUSH_PRE, /**< Called after render update regions have
* been calculated, but only if update regions exist */
EVAS_CALLBACK_RENDER_FLUSH_POST, /**< Called after render update regions have
* been sent to the display server, but only
* if update regions existed for the most recent frame */
EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, /**< Canvas object got focus */
EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT, /**< Canvas object lost focus */
EVAS_CALLBACK_IMAGE_UNLOADED, /**< Image data has been unloaded (by some mechanism in Evas that throw out original image data) */
EVAS_CALLBACK_RENDER_PRE, /**< Called just before rendering starts on the canvas target. @since 1.2 */
EVAS_CALLBACK_RENDER_POST, /**< Called just after rendering stops on the canvas target. @since 1.2 */
EVAS_CALLBACK_IMAGE_RESIZE, /**< Image size is changed. @since 1.8 */
EVAS_CALLBACK_DEVICE_CHANGED, /**< Devices added, removed or changed on canvas. @since 1.8 */
EVAS_CALLBACK_AXIS_UPDATE, /**< Input device changed value on some axis. @since 1.13 */
EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE, /**< Canvas viewport resized. @since 1.15 */
EVAS_CALLBACK_LAST /**< Sentinel value to indicate last enum field during
* iteration */
///<summary> Mouse In Event.</summary>
EVAS_CALLBACK_MOUSE_IN = 0,
///<summary> Mouse Out Event.</summary>
EVAS_CALLBACK_MOUSE_OUT,
///<summary> Mouse Button Down Event.</summary>
EVAS_CALLBACK_MOUSE_DOWN,
///<summary> Mouse Button Up Event.</summary>
EVAS_CALLBACK_MOUSE_UP,
///<summary> Mouse Move Event.</summary>
EVAS_CALLBACK_MOUSE_MOVE,
///<summary> Mouse Wheel Event.</summary>
EVAS_CALLBACK_MOUSE_WHEEL,
///<summary> Multi-touch Down Event.</summary>
EVAS_CALLBACK_MULTI_DOWN,
///<summary> Multi-touch Up Event.</summary>
EVAS_CALLBACK_MULTI_UP,
///<summary> Multi-touch Move Event.</summary>
EVAS_CALLBACK_MULTI_MOVE,
///<summary> Object Being Freed (Called after Del).</summary>
EVAS_CALLBACK_FREE,
///<summary> Key Press Event.</summary>
EVAS_CALLBACK_KEY_DOWN,
///<summary> Key Release Event.</summary>
EVAS_CALLBACK_KEY_UP,
///<summary> Focus In Event.</summary>
EVAS_CALLBACK_FOCUS_IN,
///<summary> Focus Out Event.</summary>
EVAS_CALLBACK_FOCUS_OUT,
///<summary> Show Event.</summary>
EVAS_CALLBACK_SHOW,
///<summary> Hide Event.</summary>
EVAS_CALLBACK_HIDE,
///<summary> Move Event.</summary>
EVAS_CALLBACK_MOVE,
///<summary> Resize Event.</summary>
EVAS_CALLBACK_RESIZE,
///<summary> Restack Event.</summary>
EVAS_CALLBACK_RESTACK,
///<summary> Object Being Deleted (called before Free).</summary>
EVAS_CALLBACK_DEL,
///<summary> Events go on/off hold.</summary>
EVAS_CALLBACK_HOLD,
///<summary> Size hints changed event.</summary>
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
///<summary> Image has been preloaded.</summary>
EVAS_CALLBACK_IMAGE_PRELOADED,
///<summary> Canvas got focus as a whole.</summary>
EVAS_CALLBACK_CANVAS_FOCUS_IN,
///<summary> Canvas lost focus as a whole.</summary>
EVAS_CALLBACK_CANVAS_FOCUS_OUT,
///<summary>Called after render update regions have been calculated,
/// but only if update regions exist.</summary>
EVAS_CALLBACK_RENDER_FLUSH_PRE,
///<summary>Called after render update regions have
/// been sent to the display server, but only
/// if update regions existed for the most recent frame.</summary>
EVAS_CALLBACK_RENDER_FLUSH_POST,
///<summary> Canvas object got focus.</summary>
EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
///<summary> Canvas object lost focus.</summary>
EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
///<summary> Image data has been unloaded (by some mechanism in Evas that throw out original image data).</summary>
EVAS_CALLBACK_IMAGE_UNLOADED,
///<summary> Called just before rendering starts on the canvas target. @since 1.2.</summary>
EVAS_CALLBACK_RENDER_PRE,
///<summary> Called just after rendering stops on the canvas target. @since 1.2.</summary>
EVAS_CALLBACK_RENDER_POST,
///<summary> Image size is changed. @since 1.8.</summary>
EVAS_CALLBACK_IMAGE_RESIZE,
///<summary> Devices added, removed or changed on canvas. @since 1.8.</summary>
EVAS_CALLBACK_DEVICE_CHANGED,
///<summary> Input device changed value on some axis. @since 1.13.</summary>
EVAS_CALLBACK_AXIS_UPDATE,
///<summary> Canvas viewport resized. @since 1.15.</summary>
EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
///<summary>Sentinel value to indicate last enum field during iteration.</summary>
EVAS_CALLBACK_LAST
};
}

View File

@ -30,7 +30,7 @@ public class ExampleEoInherit01
int given = 111;
// Call the C# override from the C method
example.NumberwrapperConcrete.example_numberwrapper_number_set(inheritObj.raw_handle, given);
inheritObj.CallNumberSet(given);
WriteLine($"Override successfully called? {inheritObj.derivedCalled}!\n");

View File

@ -52,6 +52,11 @@ void _example_numberwrapper_number_set(EINA_UNUSED Eo *obj, Example_Numberwrappe
pd->number = n;
}
void _example_numberwrapper_number_set_call(Eo *obj, EINA_UNUSED Example_Numberwrapper_Data *pd, int n)
{
example_numberwrapper_number_set(obj, n);
}
int _example_numberwrapper_number_get(EINA_UNUSED Eo *obj, Example_Numberwrapper_Data *pd)
{
return pd->number;

View File

@ -17,6 +17,12 @@ class Example.Numberwrapper (Efl.Object) {
}
}
number_set_call {
params {
n: int;
}
}
number_callback_set {
params {
cb: NumberCb;

View File

@ -24,6 +24,24 @@ struct eolian_init
}
};
struct eolian_state
{
Eolian *value;
eolian_state()
{
value = ::eolian_new();
}
~eolian_state()
{
::eolian_free(value);
}
inline Eolian_Unit const* as_unit() const
{
return (Eolian_Unit const*)value;
}
};
} }
#endif // EOLIAN_CXX_LIB_HH

View File

@ -113,7 +113,7 @@ struct function_definition_generator
if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false;
if(f.return_type != attributes::void_
&& !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", f.unit})
&& !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", attributes::documentation_def{}, f.unit})
<< " __return_value = "
).generate(sink, attributes::unused, ctx)) return false;

View File

@ -0,0 +1,51 @@
#ifndef EOLIAN_CXX_HTML_ESCAPED_STRING_HH
#define EOLIAN_CXX_HTML_ESCAPED_STRING_HH
#include <cstdlib>
#include <cstring>
#include "grammar/generator.hpp"
#include "grammar/attributes.hpp"
#include "grammar/string.hpp"
namespace efl { namespace eolian { namespace grammar {
struct html_escaped_string_generator
{
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, std::string const& input, Context const& context) const
{
std::string out;
out.reserve(input.size());
for (size_t pos = 0; pos != input.size(); ++pos)
{
switch(input[pos])
{
case '&': out.append("&amp;"); break;
case '\"': out.append("&quot;"); break;
case '\'': out.append("&apos;"); break;
case '<': out.append("&lt;"); break;
case '>': out.append("&gt;"); break;
default: out.append(&input[pos], 1); break;
}
}
return as_generator(string).generate(sink, out, context);
}
};
struct html_escaped_string_generator const html_escaped_string = {};
template <>
struct is_eager_generator<html_escaped_string_generator> : std::true_type {};
template <>
struct is_generator<html_escaped_string_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed<html_escaped_string_generator> : std::integral_constant<int, 1> {};
}
} } }
#endif

View File

@ -167,6 +167,49 @@ inline bool operator<(klass_name const& lhs, klass_name const& rhs)
, rhs.type));
}
struct documentation_def
{
std::string summary;
std::string description;
std::string since;
std::vector<std::string> desc_paragraphs;
documentation_def() {}
documentation_def(std::string summary, std::string description, std::string since)
: summary(summary), description(description), since(since)
{}
documentation_def(Eolian_Documentation const* eolian_doc)
{
const char *str;
if (!eolian_doc)
return;
str = eolian_documentation_summary_get(eolian_doc);
if (str)
summary = str;
str = eolian_documentation_description_get(eolian_doc);
if (str)
description = str;
str = eolian_documentation_since_get(eolian_doc);
if (str)
since = str;
efl::eina::ptr_list<const char> l(eolian_documentation_string_split(description.c_str()));
for (auto&& i : l)
desc_paragraphs.push_back({&i});
}
friend inline bool operator==(documentation_def const& lhs, documentation_def const& rhs)
{
return lhs.summary == rhs.summary
&& lhs.description == rhs.description
&& lhs.since == rhs.since;
}
};
template <>
struct tuple_element<0ul, klass_name>
{
@ -394,21 +437,24 @@ struct parameter_def
parameter_direction direction;
type_def type;
std::string param_name;
documentation_def documentation;
Eolian_Unit const* unit;
friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs)
{
return lhs.direction == rhs.direction
&& lhs.type == rhs.type
&& lhs.param_name == rhs.param_name;
&& lhs.param_name == rhs.param_name
&& lhs.documentation == rhs.documentation;
}
friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs)
{
return !(lhs == rhs);
}
parameter_def(parameter_direction direction, type_def type, std::string param_name, Eolian_Unit const* unit)
: direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), unit(unit) {}
parameter_def(parameter_direction direction, type_def type, std::string param_name,
documentation_def documentation, Eolian_Unit const* unit)
: direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), documentation(documentation), unit(unit) {}
parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit)
: type( ::eolian_parameter_type_get(param), unit, EOLIAN_C_TYPE_PARAM)
, param_name( ::eolian_parameter_name_get(param)), unit(unit)
@ -429,6 +475,8 @@ struct parameter_def
}
if( ::eolian_parameter_is_optional(param))
type.original_type.visit(detail::add_optional_qualifier_visitor{});
documentation = eolian_parameter_documentation_get(param);
}
};
@ -467,6 +515,16 @@ template <int I>
typename tuple_element<I, parameter_def>::type& get(parameter_def& p)
{ return tuple_element<I, parameter_def>::get(p); }
enum class function_type
{
unresolved,
property,
prop_set,
prop_get,
method,
function_pointer
};
struct function_def
{
type_def return_type;
@ -474,9 +532,12 @@ struct function_def
std::vector<parameter_def> parameters;
std::string c_name;
std::string filename;
documentation_def documentation;
documentation_def return_documentation;
documentation_def property_documentation;
function_type type;
bool is_beta;
bool is_protected;
bool is_function_pointer;
bool is_static;
Eolian_Unit const* unit;
@ -487,9 +548,12 @@ struct function_def
&& lhs.parameters == rhs.parameters
&& lhs.c_name == rhs.c_name
&& lhs.filename == rhs.filename
&& lhs.documentation == rhs.documentation
&& lhs.return_documentation == rhs.return_documentation
&& lhs.property_documentation == rhs.property_documentation
&& lhs.type == rhs.type
&& lhs.is_beta == rhs.is_beta
&& lhs.is_protected == rhs.is_protected
&& lhs.is_function_pointer == rhs.is_function_pointer
&& lhs.is_static == rhs.is_static;
}
friend inline bool operator!=(function_def const& lhs, function_def const& rhs)
@ -501,13 +565,20 @@ struct function_def
std::vector<parameter_def> const& _parameters,
std::string const& _c_name,
std::string _filename,
documentation_def _documentation,
documentation_def _return_documentation,
documentation_def _property_documentation,
function_type _type,
bool _is_beta = false,
bool _is_protected = false,
bool _is_function_pointer = false,
Eolian_Unit const* unit = nullptr)
: return_type(_return_type), name(_name), parameters(_parameters),
c_name(_c_name), filename(_filename), is_beta(_is_beta), is_protected(_is_protected),
is_function_pointer(_is_function_pointer), unit(unit) {}
c_name(_c_name), filename(_filename), documentation(_documentation),
return_documentation(_return_documentation),
property_documentation(_property_documentation),
type(_type),
is_beta(_is_beta), is_protected(_is_protected),
unit(unit) {}
function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit)
: return_type(void_), unit(unit)
@ -572,6 +643,40 @@ struct function_def
is_beta = eolian_function_is_beta(function);
is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
is_static = eolian_function_is_class(function);
return_documentation = eolian_function_return_documentation_get(function, type);
Eolian_Implement const* implement = eolian_function_implement_get(function);
if (!implement)
return;
documentation = eolian_implement_documentation_get(implement, type);
if (type == EOLIAN_PROP_GET || type == EOLIAN_PROP_SET)
property_documentation = eolian_implement_documentation_get(implement, EOLIAN_PROPERTY);
switch (type)
{
case EOLIAN_UNRESOLVED:
this->type = function_type::unresolved;
break;
case EOLIAN_PROPERTY:
this->type = function_type::property;
break;
case EOLIAN_PROP_GET:
this->type = function_type::prop_get;
break;
case EOLIAN_PROP_SET:
this->type = function_type::prop_set;
break;
case EOLIAN_METHOD:
this->type = function_type::method;
break;
case EOLIAN_FUNCTION_POINTER:
this->type = function_type::function_pointer;
break;
}
}
std::string template_statement() const
@ -677,6 +782,7 @@ struct event_def
eina::optional<type_def> type;
std::string name, c_name;
bool beta, protect;
documentation_def documentation;
friend inline bool operator==(event_def const& lhs, event_def const& rhs)
{
@ -684,21 +790,25 @@ struct event_def
&& lhs.name == rhs.name
&& lhs.c_name == rhs.c_name
&& lhs.beta == rhs.beta
&& lhs.protect == rhs.protect;
&& lhs.protect == rhs.protect
&& lhs.documentation == rhs.documentation;
}
friend inline bool operator!=(event_def const& lhs, event_def const& rhs)
{
return !(lhs == rhs);
}
event_def(type_def type, std::string name, std::string c_name, bool beta, bool protect)
: type(type), name(name), c_name(c_name), beta(beta), protect(protect) {}
event_def(type_def type, std::string name, std::string c_name, bool beta, bool protect,
documentation_def documentation)
: type(type), name(name), c_name(c_name), beta(beta), protect(protect)
, documentation(documentation) {}
event_def(Eolian_Event const* event, Eolian_Unit const* unit)
: type( ::eolian_event_type_get(event) ? eina::optional<type_def>{{::eolian_event_type_get(event), unit, EOLIAN_C_TYPE_DEFAULT}} : eina::optional<type_def>{})
, name( ::eolian_event_name_get(event))
, c_name( ::eolian_event_c_name_get(event))
, beta( ::eolian_event_is_beta(event))
, protect( ::eolian_event_scope_get(event) == EOLIAN_SCOPE_PROTECTED){}
, protect( ::eolian_event_scope_get(event) == EOLIAN_SCOPE_PROTECTED)
, documentation( ::eolian_event_documentation_get(event)) {}
};
template <>
@ -768,6 +878,7 @@ struct klass_def
std::string eolian_name;
std::string cxx_name;
std::string filename;
documentation_def documentation;
std::vector<std::string> namespaces;
std::vector<function_def> functions;
std::set<klass_name, compare_klass_name_by_name> inherits;
@ -802,12 +913,14 @@ struct klass_def
}
klass_def(std::string eolian_name, std::string cxx_name, std::string filename
, documentation_def documentation
, std::vector<std::string> namespaces
, std::vector<function_def> functions
, std::set<klass_name, compare_klass_name_by_name> inherits
, class_type type
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
, documentation(documentation)
, namespaces(namespaces)
, functions(functions), inherits(inherits), type(type)
, immediate_inherits(immediate_inherits)
@ -915,6 +1028,8 @@ struct klass_def
events.push_back({&*event_iterator, unit});
} catch(std::exception const&) {}
}
documentation = eolian_class_documentation_get(klass);
}
// TODO memoize the return?
@ -956,6 +1071,7 @@ struct enum_value_def
value_def value;
std::string name;
std::string c_name;
documentation_def documentation;
enum_value_def(Eolian_Enum_Type_Field const* enum_field, Eolian_Unit const* unit)
{
@ -963,6 +1079,7 @@ struct enum_value_def
c_name = eolian_typedecl_enum_field_c_name_get(enum_field);
auto exp = eolian_typedecl_enum_field_value_get(enum_field, EINA_TRUE);
value = eolian_expression_eval(unit, exp, EOLIAN_MASK_INT); // FIXME hardcoded int
documentation = eolian_typedecl_enum_field_documentation_get(enum_field);
}
};
@ -972,6 +1089,7 @@ struct enum_def
std::string cxx_name;
std::vector<std::string> namespaces;
std::vector<enum_value_def> fields;
documentation_def documentation;
enum_def(Eolian_Typedecl const* enum_obj, Eolian_Unit const* unit)
{
@ -989,6 +1107,8 @@ struct enum_def
enum_value_def field_def(&*field_iterator, unit);
this->fields.push_back(field_def);
}
documentation = ::eolian_typedecl_documentation_get(enum_obj);
}
};
@ -996,6 +1116,7 @@ struct struct_field_def
{
type_def type;
std::string name;
documentation_def documentation;
struct_field_def(Eolian_Struct_Type_Field const* struct_field, Eolian_Unit const* unit)
{
@ -1003,6 +1124,7 @@ struct struct_field_def
try {
type.set(eolian_typedecl_struct_field_type_get(struct_field), unit, EOLIAN_C_TYPE_DEFAULT);
} catch(std::runtime_error const&) { /* Silently skip pointer fields*/ }
documentation = ::eolian_typedecl_struct_field_documentation_get(struct_field);
}
};
@ -1013,6 +1135,7 @@ struct struct_def
std::string cxx_name;
std::vector<std::string> namespaces;
std::vector<struct_field_def> fields;
documentation_def documentation;
struct_def(Eolian_Typedecl const* struct_obj, Eolian_Unit const* unit)
{
@ -1029,6 +1152,8 @@ struct struct_def
struct_field_def field_def(&*field_iterator, unit);
this->fields.push_back(field_def);
}
documentation = ::eolian_typedecl_documentation_get(struct_obj);
}
};
@ -1137,7 +1262,7 @@ template <>
struct is_tuple<attributes::parameter_def> : std::true_type {};
template <>
struct is_tuple<attributes::event_def> : std::true_type {};
}
} } }

View File

@ -26,7 +26,7 @@ struct literal_generator
const char* string;
};
literal_generator as_generator(char const* literal) { return literal; }
inline literal_generator as_generator(char const* literal) { return literal; }
struct {
literal_generator operator()(const char* literal) const
@ -164,7 +164,7 @@ struct is_generator<string_generator_terminal> : std::true_type {};
template <>
struct is_generator<std::string> : std::true_type {};
string_generator as_generator(string_generator_terminal)
inline string_generator as_generator(string_generator_terminal)
{
return string_generator{};
}
@ -181,7 +181,7 @@ struct attributes_needed<string_replace_generator> : std::integral_constant<int,
namespace std {
::efl::eolian::grammar::specific_string_generator as_generator(std::string string)
inline ::efl::eolian::grammar::specific_string_generator as_generator(std::string string)
{
return ::efl::eolian::grammar::specific_string_generator{string};
}

View File

@ -510,7 +510,7 @@ class TestEinaBinbuf
{
var t = new NativeInheritImpl();
var binbuf = new eina.Binbuf(base_seq, (uint)base_seq.Length);
Test.Assert(NativeInheritImpl.test_testing_eina_binbuf_in(t.raw_handle, binbuf.Handle));
Test.Assert(t.CallEinaBinbufIn(binbuf));
Test.Assert(t.binbuf_in_flag);
Test.Assert(binbuf.Own);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33}));
@ -523,7 +523,7 @@ class TestEinaBinbuf
var t = new NativeInheritImpl();
var binbuf = new eina.Binbuf(base_seq, (uint)base_seq.Length);
binbuf.Own = false;
Test.Assert(NativeInheritImpl.test_testing_eina_binbuf_in_own(t.raw_handle, binbuf.Handle));
Test.Assert(t.CallEinaBinbufInOwn(binbuf));
Test.Assert(t.binbuf_in_own_flag);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33}));
binbuf.Dispose();
@ -534,11 +534,8 @@ class TestEinaBinbuf
public static void test_inherit_eina_binbuf_out()
{
var t = new NativeInheritImpl();
IntPtr bb_hdl;
Test.Assert(NativeInheritImpl.test_testing_eina_binbuf_out(t.raw_handle, out bb_hdl));
eina.Binbuf binbuf = t.CallEinaBinbufOut();
Test.Assert(t.binbuf_out_flag);
Test.Assert(bb_hdl != IntPtr.Zero);
var binbuf = new eina.Binbuf(bb_hdl, false);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{33}));
binbuf.Reset();
Test.Assert(binbuf.Append(base_seq));
@ -550,11 +547,8 @@ class TestEinaBinbuf
public static void test_inherit_eina_binbuf_out_own()
{
var t = new NativeInheritImpl();
IntPtr bb_hdl;
Test.Assert(NativeInheritImpl.test_testing_eina_binbuf_out_own(t.raw_handle, out bb_hdl));
eina.Binbuf binbuf = t.CallEinaBinbufOutOwn();
Test.Assert(t.binbuf_out_own_flag);
Test.Assert(bb_hdl != IntPtr.Zero);
var binbuf = new eina.Binbuf(bb_hdl, true);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{33}));
binbuf.Reset();
Test.Assert(binbuf.Append(base_seq));
@ -566,10 +560,8 @@ class TestEinaBinbuf
public static void test_inherit_eina_binbuf_return()
{
var t = new NativeInheritImpl();
IntPtr bb_hdl = NativeInheritImpl.test_testing_eina_binbuf_return(t.raw_handle);
var binbuf = t.CallEinaBinbufReturn();
Test.Assert(t.binbuf_return_flag);
Test.Assert(bb_hdl != IntPtr.Zero);
var binbuf = new eina.Binbuf(bb_hdl, false);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{33}));
binbuf.Reset();
Test.Assert(binbuf.Append(base_seq));
@ -581,10 +573,8 @@ class TestEinaBinbuf
public static void test_inherit_eina_binbuf_return_own()
{
var t = new NativeInheritImpl();
IntPtr bb_hdl = NativeInheritImpl.test_testing_eina_binbuf_return_own(t.raw_handle);
var binbuf = t.CallEinaBinbufReturnOwn();
Test.Assert(t.binbuf_return_own_flag);
Test.Assert(bb_hdl != IntPtr.Zero);
var binbuf = new eina.Binbuf(bb_hdl, true);
Test.Assert(binbuf.GetBytes().SequenceEqual(new byte[]{33}));
binbuf.Reset();
Test.Assert(binbuf.Append(base_seq));
@ -681,7 +671,7 @@ class TestEinaSlice
{
var t = new NativeInheritImpl();
var slc = new eina.Slice(pinnedPtr, (UIntPtr)3);
Test.Assert(NativeInheritImpl.test_testing_eina_slice_in(t.raw_handle, slc));
Test.Assert(t.EinaSliceIn(slc));
Test.Assert(t.slice_in_flag);
}
@ -694,7 +684,7 @@ class TestEinaSlice
var slc = new eina.Rw_Slice(ptr, (UIntPtr)3);
var t = new NativeInheritImpl();
Test.Assert(NativeInheritImpl.test_testing_eina_rw_slice_in(t.raw_handle, slc));
Test.Assert(t.EinaRwSliceIn(slc));
Test.Assert(t.rw_slice_in_flag);
Test.Assert(slc.GetBytes().SequenceEqual(base_seq));
@ -706,7 +696,7 @@ class TestEinaSlice
{
var t = new NativeInheritImpl();
var slc = new eina.Slice();
Test.Assert(NativeInheritImpl.test_testing_eina_slice_out(t.raw_handle, ref slc));
Test.Assert(t.EinaSliceOut(ref slc));
Test.Assert(t.slice_out_flag);
Test.Assert(slc.Mem != IntPtr.Zero);
Test.Assert(slc.Length == base_seq.Length);
@ -717,7 +707,7 @@ class TestEinaSlice
{
var t = new NativeInheritImpl();
var slc = new eina.Rw_Slice();
Test.Assert(NativeInheritImpl.test_testing_eina_rw_slice_out(t.raw_handle, ref slc));
Test.Assert(t.EinaRwSliceOut(ref slc));
Test.Assert(t.rw_slice_out_flag);
Test.Assert(slc.Mem != IntPtr.Zero);
Test.Assert(slc.Length == base_seq.Length);

View File

@ -6,21 +6,32 @@ namespace TestSuite
class TestEoEvents
{
public bool called = false;
public bool correct_sender = false;
protected void callback(object sender, EventArgs e) {
called = true;
efl.Object obj = sender as efl.Object;
if (obj != null)
{
obj.SetName("loop_called");
correct_sender = true;
}
}
protected void another_callback(object sender, EventArgs e) { }
public static void callback_add_event()
{
efl.Loop loop = new efl.LoopConcrete();
loop.SetName("loop");
TestEoEvents listener = new TestEoEvents();
loop.CALLBACK_ADD += listener.callback;
Test.Assert(!listener.called);
Test.Assert(!listener.correct_sender);
Test.AssertEquals("loop", loop.GetName());
loop.IDLE += listener.another_callback;
Test.Assert(listener.called);
Test.Assert(listener.correct_sender);
Test.AssertEquals("loop_called", loop.GetName());
}
}
}

View File

@ -307,6 +307,11 @@ Eina_Bool _test_testing_eina_binbuf_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Tes
return r;
}
Eina_Bool _test_testing_call_eina_binbuf_in(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Eina_Binbuf *binbuf)
{
return test_testing_eina_binbuf_in(obj, binbuf);
}
Eina_Binbuf *_binbuf_in_own_to_check = NULL;
Eina_Bool _test_testing_eina_binbuf_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Eina_Binbuf *binbuf)
@ -319,6 +324,11 @@ Eina_Bool _test_testing_eina_binbuf_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test
return r;
}
Eina_Bool _test_testing_call_eina_binbuf_in_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Eina_Binbuf *binbuf)
{
return test_testing_eina_binbuf_in_own(obj, binbuf);
}
Eina_Bool _test_testing_check_binbuf_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
if (!_binbuf_in_own_to_check) return EINA_FALSE;
@ -339,6 +349,13 @@ Eina_Bool _test_testing_eina_binbuf_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Te
return EINA_TRUE;
}
Eina_Binbuf *_test_testing_call_eina_binbuf_out(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
Eina_Binbuf *binbuf = NULL;
test_testing_eina_binbuf_out(obj, &binbuf);
return binbuf;
}
Eina_Bool _test_testing_check_binbuf_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
if (!_binbuf_out_to_check) return EINA_FALSE;
@ -353,6 +370,13 @@ Eina_Bool _test_testing_eina_binbuf_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Tes
return EINA_TRUE;
}
Eina_Binbuf *_test_testing_call_eina_binbuf_out_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
Eina_Binbuf *binbuf = NULL;
test_testing_eina_binbuf_out_own(obj, &binbuf);
return binbuf;
}
Eina_Binbuf *_binbuf_return_to_check = NULL;
Eina_Binbuf *_test_testing_eina_binbuf_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
@ -363,6 +387,11 @@ Eina_Binbuf *_test_testing_eina_binbuf_return(EINA_UNUSED Eo *obj, EINA_UNUSED T
return binbuf;
}
Eina_Binbuf *_test_testing_call_eina_binbuf_return(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
return test_testing_eina_binbuf_return(obj);
}
Eina_Bool _test_testing_check_binbuf_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
if (!_binbuf_return_to_check) return EINA_FALSE;
@ -376,6 +405,12 @@ Eina_Binbuf *_test_testing_eina_binbuf_return_own(EINA_UNUSED Eo *obj, EINA_UNUS
return binbuf;
}
Eina_Binbuf *_test_testing_call_eina_binbuf_return_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
return test_testing_eina_binbuf_return_own(obj);
}
static const int base_seq_int[] = {0x0,0x2A,0x42};
static const unsigned int base_seq_int_size = EINA_C_ARRAY_LENGTH(base_seq_int);
static const int modified_seq_int[] = {0x0,0x2A,0x42,42,43,33};

View File

@ -254,12 +254,27 @@ class Test.Testing (Efl.Object) {
return: bool;
}
call_eina_binbuf_in {
params {
@in binbuf: ptr(Eina.Binbuf);
}
return: bool;
}
eina_binbuf_in_own {
params {
@in binbuf: ptr(Eina.Binbuf) @owned;
}
return: bool;
}
call_eina_binbuf_in_own {
params {
@in str: ptr(Eina.Binbuf) @owned;
}
return: bool;
}
check_binbuf_in_own {
return: bool;
}
@ -270,6 +285,11 @@ class Test.Testing (Efl.Object) {
}
return: bool;
}
call_eina_binbuf_out {
return: ptr(Eina.Binbuf);
}
check_binbuf_out {
return: bool;
}
@ -281,9 +301,18 @@ class Test.Testing (Efl.Object) {
return: bool;
}
call_eina_binbuf_out_own {
return: ptr(Eina.Binbuf) @owned;
}
eina_binbuf_return {
return: ptr(Eina.Binbuf);
}
call_eina_binbuf_return {
return: ptr(Eina.Binbuf);
}
check_binbuf_return {
return: bool;
}
@ -292,6 +321,10 @@ class Test.Testing (Efl.Object) {
return: ptr(Eina.Binbuf) @owned;
}
call_eina_binbuf_return_own {
return: ptr(Eina.Binbuf) @owned;
}
/* Eina Array */
/* Integer */

View File

@ -0,0 +1,86 @@
struct Foo {
[[This is struct Foo.
It does stuff.
Note: This is a note.
This is a longer description for struct Foo.
Warning: This is a warning. You can only use Warning: and
Note: at the beginning of a paragraph.
This is another paragraph.
@since 1.66
]]
field1: int; [[Field documentation.]]
field2: float;
field3: short; [[Another field documentation.]]
}
enum Bar {
[[Docs for enum Bar.]]
blah = 0,
foo = 1, [[Docs for foo.]]
bar = 2 [[Docs for bar.]]
}
type Alias: Bar; [[Docs for typedef.
More docs for typedef.
See @Bar. @since 2.0
]]
var pants: int = 150; [[Docs for var.]]
struct Opaque; [[Opaque struct docs. See @Foo for another struct.]]
class Docs {
[[Docs for class.
More docs for class. Testing references now.
@Foo
@Bar
@Alias
@pants
@.meth
@.prop
@.prop.get
@.prop.set
@Foo.field1
@Bar.foo
@Docs
@since 1.17
]]
legacy_prefix: docs;
methods {
meth {
[[Method documentation.]]
params {
@in a: int; [[Param documentation.]]
@out b: float;
@out c: long; [[Another param documentation.]]
}
return: int; [[Return documentation.]]
}
@property prop {
[[Property common documentation.
@since 1.18
]]
get {
[[Get documentation.]]
}
set {
[[Set documentation.]]
}
values {
val: int; [[Value documentation.]]
}
}
}
events {
clicked; [[Event docs.]]
}
}

View File

@ -13,6 +13,7 @@ static const Efl_Test_Case etc[] = {
{ "Eolian-Cxx Inheritance", eolian_cxx_test_inheritance },
{ "Eolian-Cxx Binding", eolian_cxx_test_binding },
{ "Eolian-Cxx Cyclic", eolian_cxx_test_cyclic },
{ "Eolian-Cxx Documentation", eolian_cxx_test_documentation },
{ NULL, NULL }
};

View File

@ -10,5 +10,6 @@ void eolian_cxx_test_address_of(TCase* tc);
void eolian_cxx_test_inheritance(TCase* tc);
void eolian_cxx_test_binding(TCase* tc);
void eolian_cxx_test_cyclic(TCase* tc);
void eolian_cxx_test_documentation(TCase* tc);
#endif /* _EOLIAN_CXX_SUITE_H */

View File

@ -0,0 +1,289 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <iostream>
#include <cassert>
#include <iterator>
#include <algorithm>
#include <Eina.hh>
#include <Eolian_Cxx.hh>
#include "eolian_cxx_suite.h"
#include "grammar/klass_def.hpp"
using efl::eolian::grammar::attributes::klass_def;
using efl::eolian::grammar::attributes::documentation_def;
using efl::eolian::grammar::attributes::function_def;
using efl::eolian::grammar::attributes::enum_def;
using efl::eolian::grammar::attributes::struct_def;
klass_def init_test_data(efl::eolian::eolian_state const& state)
{
ck_assert(::eolian_directory_scan(state.value, PACKAGE_DATA_DIR));
ck_assert(::eolian_all_eot_files_parse(state.value));
ck_assert(::eolian_file_parse(state.value, PACKAGE_DATA_DIR"/docs.eo"));
const Eolian_Class *c_klass = ::eolian_class_get_by_name(state.as_unit(), "Docs");
ck_assert_ptr_ne(c_klass, NULL);
klass_def klass(c_klass, state.as_unit());
return klass;
}
START_TEST(eolian_cxx_test_class_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
documentation_def doc = klass.documentation;
ck_assert_str_eq(doc.summary.c_str(), "Docs for class.");
ck_assert_str_eq(doc.description.c_str(),
"More docs for class. Testing references now. "
"@Foo "
"@Bar "
"@Alias "
"@pants "
"@Docs.meth "
"@Docs.prop "
"@Docs.prop.get "
"@Docs.prop.set "
"@Foo.field1 "
"@Bar.foo "
"@Docs");
ck_assert_str_eq(doc.since.c_str(), "1.17");
}
END_TEST
START_TEST(eolian_cxx_test_function_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
function_def func = *std::find_if(klass.functions.begin(), klass.functions.end(),
[](const function_def& f) {
return f.name == "meth";
});
documentation_def doc = func.documentation;
ck_assert_str_eq(doc.summary.c_str(), "Method documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17"); // Since is inherited from parent if not present, except when no doc is present ofr this member.
doc = func.return_documentation;
ck_assert_str_eq(doc.summary.c_str(), "Return documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17");
auto param_iter = func.parameters.begin();
// a int
doc = param_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Param documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17");
param_iter++;
// b float (no doc)
doc = param_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
param_iter++;
// c long
doc = param_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Another param documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17");
}
END_TEST
START_TEST(eolian_cxx_test_property_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
auto func_iter = std::find_if(klass.functions.begin(), klass.functions.end(),
[](const function_def& f) {
return f.name == "prop_get";
});
ck_assert_msg(func_iter != klass.functions.end(), "Failed to find prop_get function");
function_def func = *func_iter;
documentation_def doc = func.property_documentation;
ck_assert_str_eq(doc.summary.c_str(), "Property common documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.18");
doc = func.documentation; // Actual getdocumentation.
ck_assert_str_eq(doc.summary.c_str(), "Get documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17"); // Members inherit from parent *class*
func_iter = std::find_if(klass.functions.begin(), klass.functions.end(),
[](const function_def& f) {
return f.name == "prop_set";
});
ck_assert_msg(func_iter != klass.functions.end(), "Failed to find prop_set function");
func = *func_iter;
doc = func.documentation; // Actual getdocumentation.
ck_assert_str_eq(doc.summary.c_str(), "Set documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17"); // Members inherit from parent *class*
}
END_TEST
START_TEST(eolian_cxx_test_event_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
auto event = klass.events.front();
documentation_def doc = event.documentation;
ck_assert_str_eq(doc.summary.c_str(), "Event docs.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "1.17"); // Members inherit from parent *class*
}
END_TEST
START_TEST(eolian_cxx_test_enum_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
auto unit = eolian_state.as_unit();
enum_def _enum(::eolian_typedecl_enum_get_by_name(unit, "Bar"), unit);
documentation_def doc = _enum.documentation;
ck_assert_str_eq(doc.summary.c_str(), "Docs for enum Bar.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
// fields
auto field_iter = _enum.fields.begin();
// blah - no docs
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
field_iter++;
// foo - docs
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Docs for foo.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
field_iter++;
// bar - docs
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Docs for bar.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
}
END_TEST
START_TEST(eolian_cxx_test_struct_docs)
{
efl::eina::eina_init eina_init;
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def klass = init_test_data(eolian_state);
auto unit = eolian_state.as_unit();
struct_def _struct(::eolian_typedecl_struct_get_by_name(unit, "Foo"), unit);
documentation_def doc = _struct.documentation;
ck_assert_str_eq(doc.summary.c_str(), "This is struct Foo. "
"It does stuff.");
ck_assert_str_eq(doc.description.c_str(),
"Note: This is a note.\n"
"\n"
"This is a longer description for struct Foo.\n"
"\n"
"Warning: This is a warning. You can only use Warning: and "
"Note: at the beginning of a paragraph.\n"
"\n"
"This is another paragraph.");
ck_assert_str_eq(doc.since.c_str(), "1.66");
std::vector<std::string> ref_paragraphs = {
"Note: This is a note.",
"This is a longer description for struct Foo.",
"Warning: This is a warning. You can only use Warning: and "
"Note: at the beginning of a paragraph.",
"This is another paragraph."
};
auto paragraph_it = doc.desc_paragraphs.begin();
auto ref_paragraph_it = ref_paragraphs.begin();
while (ref_paragraph_it != ref_paragraphs.end())
{
ck_assert_str_eq(paragraph_it->c_str(), ref_paragraph_it->c_str());
paragraph_it++;
ref_paragraph_it++;
}
ck_assert(paragraph_it == doc.desc_paragraphs.end());
// fields
auto field_iter = _struct.fields.begin();
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Field documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
field_iter++;
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
field_iter++;
doc = field_iter->documentation;
ck_assert_str_eq(doc.summary.c_str(), "Another field documentation.");
ck_assert_str_eq(doc.description.c_str(), "");
ck_assert_str_eq(doc.since.c_str(), "");
}
END_TEST
void
eolian_cxx_test_documentation(TCase* tc)
{
tcase_add_test(tc, eolian_cxx_test_class_docs);
tcase_add_test(tc, eolian_cxx_test_function_docs);
tcase_add_test(tc, eolian_cxx_test_property_docs);
tcase_add_test(tc, eolian_cxx_test_event_docs);
tcase_add_test(tc, eolian_cxx_test_enum_docs);
tcase_add_test(tc, eolian_cxx_test_struct_docs);
}