uqbar-project / wollok

Wollok Programming Language
GNU General Public License v3.0
60 stars 16 forks source link

[validator] Check mixin combination with mixins calling super() #965

Closed javierfernandes closed 7 years ago

javierfernandes commented 8 years ago

I believe that we don't have all the neccesary "abstract class instantiation checks" when it comes to combining mixins. In particular mixins calling super (used for chaining, like stackable mixins)

mixin M {
    method aNumber() = super() + 2
}

// ERROR ! M requires a base implementation for aNumber()
class C mixed with M {}
javierfernandes commented 8 years ago

Currently in runtime it fails like this Example:

            mixin Organic {
                method dehydratate() = super() + " an organic"
            }

            class Tomato mixed with Organic {}

            program tomatoEater {
                const t = new Tomato()
                t.dehydratate()
            }

Error

wollok.lang.MessageNotUnderstoodException: a Tomato[] (WollokObject) does not understand dehydratate()
    at __synthetic0.Organic.dehydratate() [__synthetic0.wpgm]
    at  [__synthetic0.wpgm]

Note that the stack chain is clear. The error was not in the program call, the object received the message, executed the mixin method, and then this tried to propagate the message to super, which is a Tomate, and doesn't understand that message. Maybe it should be better to have an specific error like "Mixin called super but method doesn't exist in chain" or something. But I found this fair enough as it is right now. At least it doesn't blow up the whole interpreter or show a java exception :P

javierfernandes commented 8 years ago

Another example that must be validated

mixin Doctor {
    method name = "Dr. " + super()
}

class A mixed with Doctor {
}

Class A must be marked as with error. Since this combination is invalid. The mixin requires a "name" method up in the hierarchy but there is none.

On the other hand on this context

mixin Doctor {
    method name() = "Dr. " + super()
}

mixin Named {
     method name() = "a name"
}

This is valid

class A mixed with Named and Doctor {
}

But this is NOT !

class A mixed with Doctor and Named  {
}

Because of the order !