From 18ab4f2eec444bbef11605bd0e2ba057709cbb7e Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 17 Jan 2019 17:13:55 +0100 Subject: [PATCH] eolian: disallow pure virtual on non-abstract/mixin classes --- src/lib/eolian/database_validate.c | 46 +------------------- src/lib/eolian/eo_parser.c | 16 ++++--- src/tests/eolian/data/base.eo | 2 +- src/tests/eolian/data/nmsp1_nmsp11_class2.eo | 2 +- src/tests/eolian/data/object_impl.eo | 2 +- src/tests/eolian/data/override.eo | 2 +- src/tests/eolian/data/override_ref.c | 2 +- 7 files changed, 16 insertions(+), 56 deletions(-) diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index 69e71aeb8f..61fa18e607 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -13,7 +13,6 @@ typedef struct _Validate_State Eina_Bool warned; Eina_Bool event_redef; Eina_Bool unimplemented; - Eina_Bool pure_virtual; } Validate_State; static Eina_Bool @@ -408,48 +407,6 @@ _validate_function(Validate_State *vals, Eolian_Function *func, Eina_Hash *nhash if (!_validate_doc(func->set_return_doc)) return EINA_FALSE; - if (!vals->pure_virtual) - goto final; - - Eolian_Implement *impl = func->impl; - - /* pure virtual methods are ok for abstracts/mixins as well as ifaces - * in ifaces they are implicit, in regulars and abstracts explicit - */ - if (!impl || (impl->klass->type != EOLIAN_CLASS_REGULAR)) - goto final; - - if (func->type == EOLIAN_METHOD && impl->get_pure_virtual) - { - _eo_parser_log(&func->base, - "pure virtual function '%s' in a non-abstract class '%s'", - func->base.name, impl->implklass->base.name); - return EINA_FALSE; - } - else if (func->type == EOLIAN_PROPERTY && - impl->get_pure_virtual && impl->set_pure_virtual) - { - _eo_parser_log(&func->base, - "pure virtual property '%s' in a non-abstract class '%s'", - func->base.name, impl->implklass->base.name); - return EINA_FALSE; - } - else if (impl->get_pure_virtual) - { - _eo_parser_log(&func->base, - "pure virtual getter '%s' in a non-abstract class '%s'", - func->base.name, impl->implklass->base.name); - return EINA_FALSE; - } - else if (impl->set_pure_virtual) - { - _eo_parser_log(&func->set_base, - "pure virtual setter '%s' in a non-abstract class '%s'", - func->base.name, impl->implklass->base.name); - return EINA_FALSE; - } - -final: /* just for now, when dups become errors there will be no need to check */ if (!oobj && nhash) eina_hash_add(nhash, &func->base.name, &func->base); @@ -1262,8 +1219,7 @@ database_validate(const Eolian_Unit *src) Validate_State vals = { EINA_FALSE, !!getenv("EOLIAN_EVENT_REDEF_WARN"), - !!getenv("EOLIAN_CLASS_UNIMPLEMENTED_WARN"), - !!getenv("EOLIAN_PURE_VIRTUAL_WARN") + !!getenv("EOLIAN_CLASS_UNIMPLEMENTED_WARN") }; /* do an initial pass to refill inherits */ diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 172df12bd9..0ea2944ea4 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -1016,6 +1016,13 @@ parse_params(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout, check_match(ls, '}', '{', line, col); } +static void +check_abstract_pure_virtual(Eo_Lexer *ls) +{ + if ((ls->klass->type != EOLIAN_CLASS_ABSTRACT) && (ls->klass->type != EOLIAN_CLASS_MIXIN)) + eo_lexer_syntax_error(ls, "@pure_virtual only allowed in abstract classes or mixins"); +} + static void parse_accessor(Eo_Lexer *ls, Eolian_Function *prop) { @@ -1047,8 +1054,7 @@ parse_accessor(Eo_Lexer *ls, Eolian_Function *prop) for (;;) switch (ls->t.kw) { case KW_at_pure_virtual: - if (ls->klass->type == EOLIAN_CLASS_INTERFACE) - eo_lexer_syntax_error(ls, "@pure_virtual is implicit in interfaces"); + check_abstract_pure_virtual(ls); CASE_LOCK(ls, virtp, "pure_virtual qualifier"); if (is_get) prop->impl->get_pure_virtual = EINA_TRUE; else prop->impl->set_pure_virtual = EINA_TRUE; @@ -1222,8 +1228,7 @@ parse_property(Eo_Lexer *ls) eo_lexer_get(ls); break; case KW_at_pure_virtual: - if (ls->klass->type == EOLIAN_CLASS_INTERFACE) - eo_lexer_syntax_error(ls, "@pure_virtual is implicit in interfaces"); + check_abstract_pure_virtual(ls); CASE_LOCK(ls, virtp, "pure_virtual qualifier"); eo_lexer_get(ls); break; @@ -1393,8 +1398,7 @@ parse_method(Eo_Lexer *ls) eo_lexer_get(ls); break; case KW_at_pure_virtual: - if (ls->klass->type == EOLIAN_CLASS_INTERFACE) - eo_lexer_syntax_error(ls, "@pure_virtual is implicit in interfaces"); + check_abstract_pure_virtual(ls); CASE_LOCK(ls, virtp, "pure_virtual qualifier"); eo_lexer_get(ls); break; diff --git a/src/tests/eolian/data/base.eo b/src/tests/eolian/data/base.eo index 1576573406..4f1b93d518 100644 --- a/src/tests/eolian/data/base.eo +++ b/src/tests/eolian/data/base.eo @@ -1,4 +1,4 @@ -class Base { +abstract Base { methods { @property z { values { diff --git a/src/tests/eolian/data/nmsp1_nmsp11_class2.eo b/src/tests/eolian/data/nmsp1_nmsp11_class2.eo index 13750e5f46..40c7b854b9 100644 --- a/src/tests/eolian/data/nmsp1_nmsp11_class2.eo +++ b/src/tests/eolian/data/nmsp1_nmsp11_class2.eo @@ -1,4 +1,4 @@ -class nmsp1.nmsp11.class2 +abstract nmsp1.nmsp11.class2 { methods { @property a { diff --git a/src/tests/eolian/data/object_impl.eo b/src/tests/eolian/data/object_impl.eo index e646a70ea4..9cbaed4f6e 100644 --- a/src/tests/eolian/data/object_impl.eo +++ b/src/tests/eolian/data/object_impl.eo @@ -1,4 +1,4 @@ -class Object_Impl extends Base { +abstract Object_Impl extends Base { methods { @property a { set { diff --git a/src/tests/eolian/data/override.eo b/src/tests/eolian/data/override.eo index 440dc2125b..221e12fc84 100644 --- a/src/tests/eolian/data/override.eo +++ b/src/tests/eolian/data/override.eo @@ -1,4 +1,4 @@ -class Override extends Base { +abstract Override extends Base { methods { @property a { set @pure_virtual { diff --git a/src/tests/eolian/data/override_ref.c b/src/tests/eolian/data/override_ref.c index a4b0c90d25..c177272ee3 100644 --- a/src/tests/eolian/data/override_ref.c +++ b/src/tests/eolian/data/override_ref.c @@ -92,7 +92,7 @@ _override_class_initializer(Efl_Class *klass) static const Efl_Class_Description _override_class_desc = { EO_VERSION, "Override", - EFL_CLASS_TYPE_REGULAR, + EFL_CLASS_TYPE_REGULAR_NO_INSTANT, sizeof(Override_Data), _override_class_initializer, NULL,