TIBET + ECMA Classes

wins

  • Leverage existing knowledge of the ECMA class system.
  • Fully integrates with TIBET's type system.

concepts

TIBET has a powerful and mature type system that has a very large prebuilt set of types. In addition to providing a simple, single hierarchy inheritance system, it also provides:

  1. The ability to mutate types outside of the file where it is being defined to take on additional capabilities.

  2. A sophisticated multiple inheritance system that leverages both the C3 linearization algorithm and a programmer controllable traits system that allow sophisticated mixin capability.

  3. A meta-object protocol and real metatype objects that model the entire system in a well organized structure, providing many hooks into the type system itself for customization.

That being said, some developers may be more comfortable developing with ECMA class system. TIBET provides a mechanism to define subtypes to TIBET types by using ECMA class syntax.

cookbook

Subtyping a TIBET type by using the ECMA class syntax.

Let's create a subtype of TIBET's TP.gui.Point type by using ECMA class syntax:

'use strict';

//  The 'defineNativeClass' method is defined on all types in the TIBET type
//  system and creates a TIBET type by allowing the author to use ECMA class
//  syntax that is familiar to them.

TP.gui.Point.defineNativeClass(
    'TP.test.NativeE6PointClass',
    class extends Object {
        constructor(x, y) {
            //  The constructor is TIBET's equivalent of the private 'alloc'
            //  method. It will eventually invoke the 'init' method below. Every
            //  TIBET type has an overrideable 'init' method to do instance
            //  initialization.
            super(x, y);
        }

        static testClassMethod() {
            //  This is a 'class' (i.e. static) method. Call it by using:
            //  TP.test.NativeE6PointClass.testClassMethod()
        }

        static constructFromPolar(radius, angle) {
            //  This is a 'class' method that calls 'up' to a type-level method
            //  of the TIBET super type we're inheriting from.
            return super.constructFromPolar(radius, angle);
        }

        init(x, y) {
            //  An implementation of the TIBET 'init' method.

            //  Super invokes the 'init' method of the super type that we're
            //  inheriting from (in this case, TP.gui.Point). It is customary
            //  (although not required) to 'call up' in TIBET when initializing
            //  objects to make sure that the supertype can perform
            //  initialization as well. Therefore, this is a very good practice.
            super.init(x, y);
        }

        testInstanceMethod() {
            //  This is a 'class' (i.e. static) method. Call it by invoking it
            //  against an instance of TP.test.NativeE6PointClass using:
            //  <nativeE6PointClassInst>.testClassMethod()
        }

        add(aPoint) {
            //  Super invokes the 'add' method of the super type that we're
            //  inheriting from (in this case, TP.gui.Point).
            super.add(aPoint.addToX(10));
        }
    }
);

Note how you can use the 'call super' semantics of this class to invoke the methods that you inherited from the TIBET supertype. These will call the 'type' or 'instance' side methods, respectively.

Also, you can omit the extends Object portion if you're not calling super() from the ECMA class constructor function. Since the "class" supplied after the extends statement is not used by TIBET anyway, it is only there for syntactic purposes (because ECMAScript 6 parsers require it). The following is just as valid a class:

TP.lang.Object.defineNativeClass(
    'TP.test.NativeE6Class',
    class {
        constructor() {
        }

        static testClassMethod() {
        }

        init() {
        }

        testInstanceMethod() {
        }
    }
);

code

The defineNativeClass method is part of TIBET's meta-object protocol and is defined in ~lib/src/tibet/kernel/TIBETInheritance.js.