Class Es6ToEs3ClassSideInheritance

  • All Implemented Interfaces:
    CompilerPass

    public final class Es6ToEs3ClassSideInheritance
    extends java.lang.Object
    implements CompilerPass
    Rewrites static inheritance to explicitly copy inherited properties from superclass to subclass so that the optimizer 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 optimizer 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 optimizer knows that Bar also has this property. (ES5 classes don't have class-side inheritance).
       var Bar = function() {};
       Bar.prop;
       $jscomp.inherits(Bar, Foo);
     

    In order to gather the stub 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 JSDoc, which may include optimization-relevant annotations like @nocollapse.

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

    NOTE: currently this pass only exists to prevent property collapsing from breaking some simple class-side inheritance cases when transpiling.

    • 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