bublejs / buble

https://buble.surge.sh
MIT License
871 stars 64 forks source link

class extends expression not transpiled #251

Closed ClassicOldSong closed 4 years ago

ClassicOldSong commented 4 years ago

Reproduce

On output line 12, it keeps the {ccc} unchanged, which should be {ccc: ccc}.

This should be considered as a serious bug.

kzc commented 4 years ago

I'm surprised this wasn't noticed before.

A more accurate issue title would be "class extends expression not transpiled".

Here's a likely fix:

--- a/src/program/types/ClassDeclaration.js
+++ b/src/program/types/ClassDeclaration.js
@@ -40,6 +40,7 @@ export default class ClassDeclaration extends Node {
                        }

                        if (this.superClass) {
+                               this.superClass.transpile(code, transforms);
                                if (this.superClass.end === this.body.start) {
                                        code.remove(c, this.superClass.start);
                                        code.appendLeft(c, ` = /*@__PURE__*/(function (${superName}) {\n${i1}`);
diff --git a/src/program/types/ClassExpression.js b/src/program/types/ClassExpression.js
index 911003a..ded0bb3 100644
--- a/src/program/types/ClassExpression.js
+++ b/src/program/types/ClassExpression.js
@@ -28,6 +28,7 @@ export default class ClassExpression extends Node {
                        const i1 = i0 + code.getIndentString();

                        if (this.superClass) {
+                               this.superClass.transpile(code, transforms);
                                code.remove(this.start, this.superClass.start);
                                code.remove(this.superClass.end, this.body.start);
                                code.appendRight(this.start, `/*@__PURE__*/(function (${superName}) {\n${i1}`);

Without patch:

$ echo 'class A extends class B extends class C{c(){}}{b(){}}{a(){}}' | buble
var A = /*@__PURE__*/(function (B) {
    function A () {
        B.apply(this, arguments);
    }

    if ( B ) A.__proto__ = B;
    A.prototype = Object.create( B && B.prototype );
    A.prototype.constructor = A;

    A.prototype.a = function a (){};

    return A;
}(class B extends class C{c(){}}{b(){}}));

With patch:

$ echo 'class A extends class B extends class C{c(){}}{b(){}}{a(){}}' | bin/buble
var A = /*@__PURE__*/(function (B) {
    function A () {
        B.apply(this, arguments);
    }

    if ( B ) A.__proto__ = B;
    A.prototype = Object.create( B && B.prototype );
    A.prototype.constructor = A;

    A.prototype.a = function a (){};

    return A;
}(/*@__PURE__*/(function (C) {
    function B () {
        C.apply(this, arguments);
    }

    if ( C ) B.__proto__ = C;
    B.prototype = Object.create( C && C.prototype );
    B.prototype.constructor = B;

    B.prototype.b = function b (){};

    return B;
}(/*@__PURE__*/(function () {
    function C () {}

    C.prototype.c = function c (){};

    return C;
}())))));

Please submit a PR with this test exercising extends transpilation of class declaration and class expression.

Here's an example of a test: https://github.com/bublejs/buble/commit/5195f3f7cef5e7cf91b9da46cba8672d7e2e203c