Class Es6ToEs3ClassSideInheritance

  • All Implemented Interfaces:
    CompilerPass, HotSwapCompilerPass

    public final class Es6ToEs3ClassSideInheritance
    extends java.lang.Object
    implements HotSwapCompilerPass
    Rewrites static inheritance to explicitly copy inherited properties from superclass to subclass so that the typechecker knows the subclass has those properties.

    For example, the main transpilation passes will convert this ES6 code:

       class Foo { static f() {} }
       class Bar extends Foo {}
     
    to this ES3 code:
       function Foo() {}
       Foo.f = function() {};
       function Bar() {}
       $jscomp.inherits(Bar, Foo);
     
    and then this class will convert that to
       function Foo() {}
       Foo.f = function() {};
       function Bar() {}
       $jscomp.inherits(Bar, Foo);
       Bar.f = Foo.f;
     
    Additionally, there are getter and setter fields which are transpiled from:
       class Foo { static get prop() { return 1; } }
       class Bar extends Foo {}
     
    to:
       var Foo = function() {};
       Foo.prop; // stub declaration so that the type checker knows about prop
       Object.defineProperties(Foo, {prop:{get:function() { return 1; }}});
    
       var Bar = function() {};
       $jscomp.inherits(Bar, Foo);
     
    The stub declaration of Foo.prop needs to be duplicated for Bar so that the type checker knows that Bar also has this property. (ES5 clases don't have class-side inheritance).
       var Bar = function() {};
       Bar.prop;
       $jscomp.inherits(Bar, Foo);
     

    In order to gather the type checker declarations, this pass gathers all GETPROPs on a class. In order to determine which of these are the stub declarations it filters them based on names discovered in Object.defineProperties. Unfortunately, we cannot simply gather the defined properties because they don't have the type information (JSDoc). The type information is stored on the stub declarations so we must gather both to transpile correctly.

    TODO(tdeegan): In the future the type information for getter/setter properties could be stored in the defineProperties functions. It would reduce the complexity of this pass significantly.

    • Constructor Detail

      • Es6ToEs3ClassSideInheritance

        public Es6ToEs3ClassSideInheritance​(AbstractCompiler compiler)
    • Method Detail

      • process

        public void process​(Node externs,
                            Node root)
        Description copied from interface: CompilerPass
        Process the JS with root node root. Can modify the contents of each Node tree
        Specified by:
        process in interface CompilerPass
        Parameters:
        externs - Top of external JS tree
        root - Top of JS tree
      • hotSwapScript

        public void hotSwapScript​(Node scriptRoot,
                                  Node originalRoot)
        Description copied from interface: HotSwapCompilerPass
        Process the JS with root node root. This is supposed to be significantly faster compared to corresponding full-compiler passes.
        Specified by:
        hotSwapScript in interface HotSwapCompilerPass
        Parameters:
        scriptRoot - Root node corresponding to the file that is modified, should be of type Token.SCRIPT.
        originalRoot - Root node corresponding to the original version of the file that is modified. Should be of type token.SCRIPT.