bublejs / buble

https://buble.surge.sh
MIT License
870 stars 67 forks source link

super relies on name of base class #259

Open kumavis opened 4 years ago

kumavis commented 4 years ago
class Base { xyz () {} }
const Enhanced = enhance(Base)
const inst = new Enhanced()

inst.xyz()

function enhance (Klass) {
  Klass = class extends Klass {
    xyz () {
      super.xyz()
    }
  }
  return Klass
}
$ cat abc.js | node

$ npx buble abc.js | node
[stdin]:20
    Klass.prototype.xyz = function xyz () {
                                       ^

RangeError: Maximum call stack size exceeded
    at Klass.xyz ([stdin]:20:40)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
    at Klass.xyz ([stdin]:21:27)
kumavis commented 4 years ago

this pattern can be found in this acorn plugin

which is run under buble in acorn-node. it has a manual workaround for this case.

kumavis commented 4 years ago

transpiled output

var Base = function Base () {};

Base.prototype.xyz = function xyz () {};
var Enhanced = enhance(Base)
var inst = new Enhanced()

inst.xyz()

function enhance (Klass) {
  Klass = /*@__PURE__*/(function (Klass$1) {
    function Klass () {
      Klass$1.apply(this, arguments);
    }

    if ( Klass$1 ) Klass.__proto__ = Klass$1;
    Klass.prototype = Object.create( Klass$1 && Klass$1.prototype );
    Klass.prototype.constructor = Klass;

    Klass.prototype.xyz = function xyz () {
      Klass.prototype.xyz.call(this)
    };

    return Klass;
  }(Klass))
  return Klass
}

the super.xyz() call is rendered as

Klass.prototype.xyz.call(this)

but it should be

Klass$1.prototype.xyz.call(this)
goto-bus-stop commented 4 years ago

I believe https://github.com/bublejs/buble/commit/0c06cae4779d4b9e6d929248de6036d066c5bbc2 attempted to fix this—we didn't upgrade to the latest Bublé yet in acorn-node. Not sure if it's still an issue in 0.20.0

kumavis commented 4 years ago

I verified it's an issue on 0.20.0, the transpired output above is from that version

goto-bus-stop commented 4 years ago

Ohh I see, this is about super.xyz(), but the earlier fix was for super() in the constructor call only