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.]]
}
class Efl.Loop (Efl.Task)
class Efl.Loop extends Efl.Task
{
[[The Efl Main Loop

View File

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

View File

@ -1,4 +1,4 @@
interface Efl.Interface ()
interface Efl.Interface
{
[[An interface for other interfaces to inherit from.
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]]
}
abstract Efl.Object ()
abstract Efl.Object
{
[[Abstract Efl object class]]
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()

View File

@ -25,14 +25,15 @@ enum Tokens
#define KEYWORDS KW(class), KW(const), KW(enum), KW(return), KW(struct), \
\
KW(abstract), KW(constructor), KW(constructors), KW(data), \
KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), KW(free), \
KW(get), KW(implements), KW(import), KW(interface), KW(keys), KW(legacy), \
KW(legacy_prefix), KW(methods), KW(mixin), KW(params), KW(parse), KW(parts), \
KW(ptr), KW(set), KW(type), KW(values), KW(var), KWAT(auto), KWAT(beta), \
KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), KWAT(extern), \
KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), KWAT(nullable), \
KWAT(optional), KWAT(out), KWAT(owned), KWAT(private), KWAT(property), \
KWAT(protected), KWAT(restart), KWAT(pure_virtual), \
KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), \
KW(extends), KW(free), KW(get), KW(implements), KW(import), KW(interface), \
KW(keys), KW(legacy), KW(legacy_prefix), KW(methods), KW(mixin), KW(params), \
KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), \
\
KWAT(auto), KWAT(beta), KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), \
KWAT(extern), KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), \
KWAT(nullable), KWAT(optional), KWAT(out), KWAT(owned), KWAT(private), \
KWAT(property), KWAT(protected), KWAT(restart), KWAT(pure_virtual), \
KWAT(warn_unused), \
\
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_dtor_pop(ls);
Eina_Bool is_reg = (type == EOLIAN_CLASS_REGULAR) || (type == EOLIAN_CLASS_ABSTRACT);
if (ls->t.token != '{')
{
line = ls->line_number;
col = ls->column;
check_next(ls, '(');
if (ls->t.token != ')')
Eina_Strbuf *ibuf = eina_strbuf_new();
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();
eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf);
_inherit_dep(ls, ibuf,
(type == EOLIAN_CLASS_REGULAR) || (type == EOLIAN_CLASS_ABSTRACT));
while (test_next(ls, ','))
_inherit_dep(ls, ibuf, EINA_FALSE);
eo_lexer_dtor_pop(ls);
Eina_Bool ext = (ls->t.kw == KW_extends);
eo_lexer_get(ls);
if (is_reg && ext)
{
/* regular class can have a parent, but just one */
_inherit_dep(ls, ibuf, EINA_TRUE);
/* 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;
col = ls->column;
check_next(ls, '{');

View File

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

View File

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

View File

@ -1,4 +1,4 @@
class Test.Numberwrapper (Efl.Object) {
class Test.Numberwrapper extends Efl.Object {
methods {
@property number {
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 {
part1: Test.Testing; [[ Part number one. ]]

View File

@ -1,4 +1,4 @@
class Simple (Efl.Object)
class Simple extends Efl.Object
{
data: null;
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 {
test_size {
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 {
Efl.Ui.Focus.Object.focus_manager { get; }
Efl.Ui.Focus.Object.focus_parent { get; }

View File

@ -1,4 +1,4 @@
class Ctor_Dtor (Base) {
class Ctor_Dtor extends Base {
methods {
custom_constructor_1 {
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 {
nmsp1.nmsp11.class2.a { set; }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
class Simple (Efl.Object)
class Simple extends Efl.Object
{
data: null;
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;
methods {

View File

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