eolian: implement new syntax for inheritance

This new syntax separates the parent class from extensions, in
a familiar way to similar to e.g. Java. Since changing everything
at once is a lot of effort, implement it alongside for the time
being.
This commit is contained in:
Daniel Kolesa 2018-11-22 17:17:29 +01:00
parent 14ce54c303
commit c8e0a1d2e2
32 changed files with 81 additions and 48 deletions

View File

@ -4,7 +4,7 @@ struct Efl.Loop_Arguments {
initialization: bool; [[Set to $true when the program should initialize its internal state. This happen once per process instance.]] initialization: bool; [[Set to $true when the program should initialize its internal state. This happen once per process instance.]]
} }
class Efl.Loop (Efl.Task) class Efl.Loop extends Efl.Task
{ {
[[The Efl Main Loop [[The Efl Main Loop

View File

@ -1,4 +1,4 @@
abstract Efl.Class () abstract Efl.Class
{ {
[[Abstract Efl class]] [[Abstract Efl class]]
data: null; data: null;

View File

@ -1,4 +1,4 @@
interface Efl.Interface () interface Efl.Interface
{ {
[[An interface for other interfaces to inherit from. [[An interface for other interfaces to inherit from.
This is useful when you want to create interfaces and mixins that expose This is useful when you want to create interfaces and mixins that expose

View File

@ -8,7 +8,7 @@ struct Efl.Event_Description {
restart: bool; [[$true if when the event is triggered again from a callback it'll start from where it was]] restart: bool; [[$true if when the event is triggered again from a callback it'll start from where it was]]
} }
abstract Efl.Object () abstract Efl.Object
{ {
[[Abstract Efl object class]] [[Abstract Efl object class]]
eo_prefix: efl; eo_prefix: efl;

View File

@ -1,4 +1,4 @@
abstract Efl.Object_Override () abstract Efl.Object_Override
{ {
[[A special class to pass to #eo_super() when using #eo_override() [[A special class to pass to #eo_super() when using #eo_override()

View File

@ -25,14 +25,15 @@ enum Tokens
#define KEYWORDS KW(class), KW(const), KW(enum), KW(return), KW(struct), \ #define KEYWORDS KW(class), KW(const), KW(enum), KW(return), KW(struct), \
\ \
KW(abstract), KW(constructor), KW(constructors), KW(data), \ KW(abstract), KW(constructor), KW(constructors), KW(data), \
KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), KW(free), \ KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), \
KW(get), KW(implements), KW(import), KW(interface), KW(keys), KW(legacy), \ KW(extends), KW(free), KW(get), KW(implements), KW(import), KW(interface), \
KW(legacy_prefix), KW(methods), KW(mixin), KW(params), KW(parse), KW(parts), \ KW(keys), KW(legacy), KW(legacy_prefix), KW(methods), KW(mixin), KW(params), \
KW(ptr), KW(set), KW(type), KW(values), KW(var), KWAT(auto), KWAT(beta), \ KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), \
KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), KWAT(extern), \ \
KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), KWAT(nullable), \ KWAT(auto), KWAT(beta), KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), \
KWAT(optional), KWAT(out), KWAT(owned), KWAT(private), KWAT(property), \ KWAT(extern), KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), \
KWAT(protected), KWAT(restart), KWAT(pure_virtual), \ KWAT(nullable), KWAT(optional), KWAT(out), KWAT(owned), KWAT(private), \
KWAT(property), KWAT(protected), KWAT(restart), KWAT(pure_virtual), \
KWAT(warn_unused), \ KWAT(warn_unused), \
\ \
KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \ KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \

View File

@ -2043,23 +2043,49 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
} }
eo_lexer_context_pop(ls); eo_lexer_context_pop(ls);
eo_lexer_dtor_pop(ls); eo_lexer_dtor_pop(ls);
Eina_Bool is_reg = (type == EOLIAN_CLASS_REGULAR) || (type == EOLIAN_CLASS_ABSTRACT);
if (ls->t.token != '{') if (ls->t.token != '{')
{ {
line = ls->line_number; line = ls->line_number;
col = ls->column; col = ls->column;
check_next(ls, '('); Eina_Strbuf *ibuf = eina_strbuf_new();
if (ls->t.token != ')') eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf);
/* new inherits syntax, keep alongside old for now */
if (ls->t.kw == KW_extends || (is_reg && (ls->t.kw == KW_implements)))
{ {
Eina_Strbuf *ibuf = eina_strbuf_new(); Eina_Bool ext = (ls->t.kw == KW_extends);
eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf); eo_lexer_get(ls);
_inherit_dep(ls, ibuf, if (is_reg && ext)
(type == EOLIAN_CLASS_REGULAR) || (type == EOLIAN_CLASS_ABSTRACT)); {
while (test_next(ls, ',')) /* regular class can have a parent, but just one */
_inherit_dep(ls, ibuf, EINA_FALSE); _inherit_dep(ls, ibuf, EINA_TRUE);
eo_lexer_dtor_pop(ls); /* if not followed by implements, we're done */
if (ls->t.kw != KW_implements)
{
eo_lexer_dtor_pop(ls);
goto inherit_done;
}
eo_lexer_get(ls);
}
do
_inherit_dep(ls, ibuf, EINA_FALSE);
while (test_next(ls, ','));
} }
check_match(ls, ')', '(', line, col); else
{
check_next(ls, '(');
if (ls->t.token != ')')
{
_inherit_dep(ls, ibuf, is_reg);
while (test_next(ls, ','))
_inherit_dep(ls, ibuf, EINA_FALSE);
}
check_match(ls, ')', '(', line, col);
}
eo_lexer_dtor_pop(ls);
} }
inherit_done:
line = ls->line_number; line = ls->line_number;
col = ls->column; col = ls->column;
check_next(ls, '{'); check_next(ls, '{');

View File

@ -1,4 +1,4 @@
class Benchmark_Object (Efl.Object) class Benchmark_Object extends Efl.Object
{ {
data: null; data: null;
methods { methods {

View File

@ -1,6 +1,6 @@
import eina_types; import eina_types;
class Test.Child (Test.Testing) { class Test.Child extends Test.Testing {
implements { implements {
class.constructor; class.constructor;

View File

@ -1,4 +1,4 @@
class Test.Numberwrapper (Efl.Object) { class Test.Numberwrapper extends Efl.Object {
methods { methods {
@property number { @property number {
get { get {

View File

@ -91,7 +91,7 @@ function Test.FormatCb {
} }
}; };
class Test.Testing (Efl.Object, Efl.Part) { class Test.Testing extends Efl.Object implements Efl.Part {
parts { parts {
part1: Test.Testing; [[ Part number one. ]] part1: Test.Testing; [[ Part number one. ]]

View File

@ -1,4 +1,4 @@
class Simple (Efl.Object) class Simple extends Efl.Object
{ {
data: null; data: null;
implements { implements {

View File

@ -1,4 +1,7 @@
class Focus.Test(Efl.Object, Efl.Ui.Focus.Object, Efl.Gfx.Entity) { class Focus.Test
extends Efl.Object
implements Efl.Ui.Focus.Object, Efl.Gfx.Entity
{
methods { methods {
test_size { test_size {
params { params {

View File

@ -1,4 +1,7 @@
class Focus.Test.Sub.Main(Efl.Object, Efl.Ui.Focus.Object, Efl.Ui.Focus.Manager_Sub) { class Focus.Test.Sub.Main
extends Efl.Object
implements Efl.Ui.Focus.Object, Efl.Ui.Focus.Manager_Sub
{
implements { implements {
Efl.Ui.Focus.Object.focus_manager { get; } Efl.Ui.Focus.Object.focus_manager { get; }
Efl.Ui.Focus.Object.focus_parent { get; } Efl.Ui.Focus.Object.focus_parent { get; }

View File

@ -1,4 +1,4 @@
class Ctor_Dtor (Base) { class Ctor_Dtor extends Base {
methods { methods {
custom_constructor_1 { custom_constructor_1 {
params { params {

View File

@ -1,4 +1,4 @@
class nmsp1.class1 (nmsp1.nmsp11.class2, nmsp2.class1, no_nmsp) class nmsp1.class1 extends nmsp1.nmsp11.class2 implements nmsp2.class1, no_nmsp
{ {
implements { implements {
nmsp1.nmsp11.class2.a { set; } nmsp1.nmsp11.class2.a { set; }

View File

@ -1,4 +1,4 @@
class Object_Impl (Base) { class Object_Impl extends Base {
methods { methods {
@property a { @property a {
set { set {

View File

@ -1,4 +1,4 @@
class Object_Impl_Add (Base) { class Object_Impl_Add extends Base {
data: Object_Impl_Data; data: Object_Impl_Data;
methods { methods {

View File

@ -1,4 +1,4 @@
class Override (Base) { class Override extends Base {
methods { methods {
@property a { @property a {
set @pure_virtual { set @pure_virtual {

View File

@ -1,4 +1,4 @@
class Parts (Override, Base) { class Parts extends Override implements Base {
parts { parts {
part1: Override; [[Part 1]] part1: Override; [[Part 1]]
part2: Base; [[Part 2]] part2: Base; [[Part 2]]

View File

@ -1,4 +1,4 @@
class Generated_Future (Efl.Object) class Generated_Future extends Efl.Object
{ {
methods { methods {
} }

View File

@ -1,4 +1,4 @@
class A (Efl.Object) class A extends Efl.Object
{ {
data: A_Data; data: A_Data;
implements { implements {

View File

@ -1,4 +1,4 @@
class B (A) class B extends A
{ {
data: B_Data; data: B_Data;
implements { implements {

View File

@ -1,4 +1,4 @@
class C (A) class C extends A
{ {
data: C_Data; data: C_Data;
implements { implements {

View File

@ -4,7 +4,7 @@ struct Callback_Event
field2: list<int*>; field2: list<int*>;
} }
class Callback (Efl.Object) class Callback extends Efl.Object
{ {
data: Callback_Data; data: Callback_Data;
events { events {

View File

@ -1,4 +1,4 @@
class Complex (Efl.Object) class Complex extends Efl.Object
{ {
data: Complex_Data; data: Complex_Data;
methods { methods {

View File

@ -1,4 +1,4 @@
class D (B, C) class D extends B implements C
{ {
data: D_Data; data: D_Data;
implements { implements {

View File

@ -5,7 +5,7 @@ struct Generic.Event
field2: list<ptr(int)>; field2: list<ptr(int)>;
} }
class Generic (Efl.Object) class Generic extends Efl.Object
{ {
data: Generic_Data; data: Generic_Data;
methods { methods {

View File

@ -1,4 +1,4 @@
class Name1.Name2.Type_Generation (Efl.Object) class Name1.Name2.Type_Generation extends Efl.Object
{ {
data: Type_Generation_Data; data: Type_Generation_Data;
methods { methods {

View File

@ -1,4 +1,4 @@
class Simple (Efl.Object) class Simple extends Efl.Object
{ {
data: null; data: null;
methods { methods {

View File

@ -1,4 +1,4 @@
class Constructor_Method_Class (Efl.Object) class Constructor_Method_Class extends Efl.Object
{ {
data: Constructor_Method_Class_Data; data: Constructor_Method_Class_Data;
methods { methods {

View File

@ -10,7 +10,7 @@ struct Test.Struct_Ex {
value_enum: Test.Enum_Ex; value_enum: Test.Enum_Ex;
} }
class Test.Object (Efl.Object) { class Test.Object extends Efl.Object {
methods { methods {
method_integral_in_a_check { method_integral_in_a_check {
[[ tests integral in ]] [[ tests integral in ]]