forked from enlightenment/efl
efl_csharp: add constant variable generation to C# binding (constants)
Reviewers: lauromoura, q66, bu5hm4n, zmike, cedric, felipealmeida, segfaultxavi Reviewed By: segfaultxavi Subscribers: segfaultxavi, cedric, #reviewers, #committers Tags: #efl_language_bindings Differential Revision: https://phab.enlightenment.org/D8048
This commit is contained in:
parent
a25c0d7137
commit
f78be36dfe
|
@ -82,6 +82,7 @@ bin_eolian_mono_eolian_mono_SOURCES = \
|
|||
bin/eolian_mono/eolian/mono/part_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/struct_fields.hh \
|
||||
bin/eolian_mono/eolian/mono/parameter.hh \
|
||||
bin/eolian_mono/eolian/mono/variable_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/utils.hh \
|
||||
bin/eolian_mono/eolian/mono/using_decl.hh \
|
||||
bin/eolian_mono/eolian/mono/marshall_type.hh \
|
||||
|
|
|
@ -14,6 +14,7 @@ struct class_context
|
|||
enums,
|
||||
function_ptr,
|
||||
alias,
|
||||
variables,
|
||||
};
|
||||
wrapper_kind current_wrapper_kind;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef EOLIAN_MONO_VARIABLE_DEFINITION_HH
|
||||
#define EOLIAN_MONO_VARIABLE_DEFINITION_HH
|
||||
|
||||
#include <Eina.hh>
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
#include "logging.hh"
|
||||
#include "type.hh"
|
||||
#include "name_helpers.hh"
|
||||
#include "helpers.hh"
|
||||
#include "function_helpers.hh"
|
||||
#include "marshall_type.hh"
|
||||
#include "parameter.hh"
|
||||
#include "documentation.hh"
|
||||
#include "using_decl.hh"
|
||||
#include "generation_contexts.hh"
|
||||
#include "blacklist.hh"
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
|
||||
struct constant_definition_generator
|
||||
{
|
||||
template<typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::variable_def constant, Context context) const
|
||||
{
|
||||
// Open partial class
|
||||
if (!name_helpers::open_namespaces(sink, constant.namespaces, context))
|
||||
return false;
|
||||
|
||||
if (!as_generator("public partial class Constants {\n").generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
|
||||
std::string literal;
|
||||
if (constant.expression_value.type == EOLIAN_EXPR_NULL)
|
||||
literal = "null";
|
||||
else if (constant.expression_value.type == EOLIAN_EXPR_BOOL)
|
||||
literal = (constant.expression_value.value.b ? "true" : "false");
|
||||
else
|
||||
{
|
||||
auto lit = ::eolian_expression_value_to_literal(&constant.expression_value);
|
||||
if (!lit)
|
||||
return false;
|
||||
literal = lit;
|
||||
::eina_stringshare_del(lit);
|
||||
}
|
||||
|
||||
// declare variable
|
||||
if (!as_generator(scope_tab(1)
|
||||
<< "public static readonly " << type
|
||||
<< " " << utils::remove_all(constant.name, '_')
|
||||
<< " = " << literal << ";\n")
|
||||
.generate(sink, constant.base_type, context))
|
||||
return false;
|
||||
|
||||
// FIXME missing documentation generator
|
||||
|
||||
// Close partial class
|
||||
if (!as_generator("}\n").generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
|
||||
if (!name_helpers::close_namespaces(sink, constant.namespaces, context))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
} const constant_definition;
|
||||
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <>
|
||||
struct is_eager_generator< ::eolian_mono::constant_definition_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::constant_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::constant_definition_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -33,6 +33,7 @@
|
|||
#include <eolian/mono/marshall_annotation.hh>
|
||||
#include <eolian/mono/function_pointer.hh>
|
||||
#include <eolian/mono/alias_definition.hh>
|
||||
#include <eolian/mono/variable_definition.hh>
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
|
@ -168,6 +169,20 @@ run(options_type const& opts)
|
|||
}
|
||||
}
|
||||
|
||||
// Constants
|
||||
{
|
||||
auto var_cxt = context_add_tag(class_context{class_context::variables}, context);
|
||||
for (efl::eina::iterator<const Eolian_Variable> var_iterator( ::eolian_state_constants_by_file_get(opts.state, basename_input.c_str()))
|
||||
, var_last; var_iterator != var_last; ++var_iterator)
|
||||
{
|
||||
efl::eolian::grammar::attributes::variable_def var(&*var_iterator, opts.unit);
|
||||
if (!eolian_mono::constant_definition.generate(iterator, var, var_cxt))
|
||||
{
|
||||
throw std::runtime_error("Failed to generate enum");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (klass)
|
||||
{
|
||||
efl::eolian::grammar::attributes::klass_def klass_def(klass, opts.unit);
|
||||
|
|
|
@ -91,6 +91,14 @@ inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
|
|||
}
|
||||
}
|
||||
|
||||
enum class variable_type
|
||||
{
|
||||
unknown,
|
||||
constant,
|
||||
global
|
||||
};
|
||||
|
||||
|
||||
struct type_def;
|
||||
bool operator==(type_def const& rhs, type_def const& lhs);
|
||||
bool operator!=(type_def const& rhs, type_def const& lhs);
|
||||
|
@ -857,6 +865,62 @@ struct property_def
|
|||
}
|
||||
};
|
||||
|
||||
struct variable_def
|
||||
{
|
||||
std::string name;
|
||||
std::string full_name;
|
||||
type_def base_type;
|
||||
documentation_def documentation;
|
||||
variable_type type;
|
||||
std::vector<std::string> namespaces;
|
||||
Eolian_Value expression_value;
|
||||
bool is_extern : 1;
|
||||
|
||||
friend inline bool operator==(variable_def const& lhs, variable_def const& rhs)
|
||||
{
|
||||
return lhs.name == rhs.name
|
||||
&& lhs.full_name == rhs.full_name
|
||||
&& lhs.base_type == rhs.base_type
|
||||
&& lhs.documentation == rhs.documentation
|
||||
&& lhs.type == rhs.type
|
||||
&& lhs.namespaces == rhs.namespaces
|
||||
&& lhs.expression_value.type == rhs.expression_value.type
|
||||
&& lhs.expression_value.value.ll == rhs.expression_value.value.ll
|
||||
&& lhs.is_extern == rhs.is_extern;
|
||||
}
|
||||
|
||||
friend inline bool operator!=(variable_def const& lhs, variable_def const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
variable_def() = default;
|
||||
variable_def(Eolian_Variable const* variable, Eolian_Unit const* unit)
|
||||
: name(::eolian_variable_short_name_get(variable))
|
||||
, full_name(::eolian_variable_name_get(variable))
|
||||
, base_type(::eolian_variable_base_type_get(variable), unit, ::EOLIAN_C_TYPE_DEFAULT)
|
||||
, documentation(::eolian_variable_documentation_get(variable))
|
||||
, type(static_cast<variable_type>(::eolian_variable_type_get(variable)))
|
||||
, expression_value()
|
||||
, is_extern(::eolian_variable_is_extern(variable))
|
||||
{
|
||||
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_variable_namespaces_get(variable))
|
||||
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
|
||||
{
|
||||
this->namespaces.push_back((&*namespace_iterator));
|
||||
}
|
||||
|
||||
if (this->type == variable_type::constant)
|
||||
{
|
||||
auto expr = ::eolian_variable_value_get(variable);
|
||||
if (!expr)
|
||||
throw std::runtime_error("Could not get constant variable value expression");
|
||||
|
||||
this->expression_value = ::eolian_expression_eval_type(expr, ::eolian_variable_base_type_get(variable));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// template <int N>
|
||||
// struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
|
||||
|
|
|
@ -190,6 +190,24 @@ class TestTypedefs
|
|||
}
|
||||
}
|
||||
|
||||
class TestVariables
|
||||
{
|
||||
public static void test_constant_variables()
|
||||
{
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarBool, true);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarInt, -32766);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarUInt, 65533U);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarLong, -2147483644L);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarULong, 4294967288UL);
|
||||
//Test.AssertEquals(Dummy.Constants.ConstvarLLong, -9223372036854775800); // TODO
|
||||
//Test.AssertEquals(Dummy.Constants.ConstvarULLong, 18446744073709551615);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarFloat, 16777211.0f);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarDouble, 9007199254740988.0);
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarChar, '!');
|
||||
Test.AssertEquals(Dummy.Constants.ConstvarString, "test_str");
|
||||
}
|
||||
}
|
||||
|
||||
class TestEoAccessors
|
||||
{
|
||||
public static void basic_eo_accessors()
|
||||
|
|
|
@ -2,6 +2,18 @@ import eina_types;
|
|||
|
||||
type Dummy.MyInt: int;
|
||||
|
||||
const Dummy.Constvar_Bool : bool = true;
|
||||
const Dummy.Constvar_Int : int = -32766;
|
||||
const Dummy.Constvar_UInt : uint = 65533U;
|
||||
const Dummy.Constvar_Long : long = -2147483644L;
|
||||
const Dummy.Constvar_ULong : ulong = 4294967288UL;
|
||||
const Dummy.Constvar_LLong : llong = -9223372036854775800LL;
|
||||
const Dummy.Constvar_ULLong : ullong = 18446744073709551615ULL;
|
||||
const Dummy.Constvar_Float : float = 16777211.0f;
|
||||
const Dummy.Constvar_Double : double = 9007199254740988.0;
|
||||
const Dummy.Constvar_Char : char = '!';
|
||||
const Dummy.Constvar_String : string = "test_str";
|
||||
|
||||
enum Dummy.SampleEnum {
|
||||
v0,
|
||||
v1,
|
||||
|
|
Loading…
Reference in New Issue