Desugar 'super(..)' into 'super.constructor(...)'
authordslomov@chromium.org <dslomov@chromium.org>
Tue, 30 Sep 2014 18:12:22 +0000 (18:12 +0000)
committerdslomov@chromium.org <dslomov@chromium.org>
Tue, 30 Sep 2014 18:12:22 +0000 (18:12 +0000)
R=arv@chromium.org, marja@chromium.org
BUG=v8:3330
LOG=N

Review URL: https://codereview.chromium.org/615043002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24340 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ast.h
test/mjsunit/harmony/super.js

index 80be158..f695e12 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -3390,7 +3390,16 @@ class AstNodeFactory FINAL BASE_EMBEDDED {
   Call* NewCall(Expression* expression,
                 ZoneList<Expression*>* arguments,
                 int pos) {
-    Call* call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
+    SuperReference* super_ref = expression->AsSuperReference();
+    Call* call;
+    if (super_ref != NULL) {
+      Literal* constructor =
+          NewStringLiteral(ast_value_factory_->constructor_string(), pos);
+      Property* superConstructor = NewProperty(super_ref, constructor, pos);
+      call = new (zone_) Call(zone_, superConstructor, arguments, pos, id_gen_);
+    } else {
+      call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
+    }
     VISIT_AND_RETURN(Call, call)
   }
 
index e23328b..35f6469 100644 (file)
 }());
 
 
+(function TestSuperCall() {
+  function Subclass(base, constructor) {
+    var homeObject = { __proto__ : base.prototype };
+    var result = constructor.toMethod(homeObject);
+    homeObject.constructor = result;
+    result.prototype = homeObject;
+    return result;
+  }
+
+  var baseCalled = 0;
+  var derivedCalled = 0;
+  var derivedDerivedCalled = 0;
+
+  function Base() {
+    baseCalled++;
+  }
+
+  var Derived = Subclass(Base, function () {
+    super();
+    derivedCalled++;
+  });
+
+  assertEquals(Base, Base.prototype.constructor);
+  assertEquals(Base.prototype, Derived.prototype.__proto__);
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  new Derived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+
+  var DerivedDerived = Subclass(Derived, function () {
+    super();
+    derivedDerivedCalled++;
+  });
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  derivedDerivedCalled = 0;
+  new DerivedDerived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+  assertEquals(1, derivedDerivedCalled);
+
+  function Base2(v) {
+    this.fromBase = v;
+  }
+  var Derived2 = Subclass(Base2, function (v1, v2) {
+    super(v1);
+    this.fromDerived = v2;
+  });
+
+  var d = new Derived2("base", "derived");
+  assertEquals("base", d.fromBase);
+  assertEquals("derived", d.fromDerived);
+}());
+
+
 (function TestUnsupportedCases() {
   function f1(x) { return super[x]; }
   function f2(x) { super[x] = 5; }