diff --git a/src/preparser.h b/src/preparser.h index bb7b40d2c9..4b526f5f1f 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -217,6 +217,7 @@ class ParserBase : public Traits { bool is_generator() const { return IsGeneratorFunction(kind_); } FunctionKind kind() const { return kind_; } + FunctionState* outer() const { return outer_function_state_; } void set_generator_object_variable( typename Traits::Type::GeneratorVariable* variable) { @@ -249,7 +250,6 @@ class ParserBase : public Traits { // for generator functions to have this variable set. Variable* generator_object_variable_; - FunctionState** function_state_stack_; FunctionState* outer_function_state_; Scope** scope_stack_; @@ -569,6 +569,7 @@ class ParserBase : public Traits { bool* ok); ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); void AddTemplateExpression(ExpressionT); + ExpressionT ParseSuperExpression(bool is_new, bool* ok); // Checks if the expression is a valid reference expression (e.g., on the // left-hand side of assignments). Although ruled out by ECMA as early errors, @@ -2666,8 +2667,9 @@ ParserBase::ParseMemberWithNewPrefixesExpression(bool* ok) { Consume(Token::NEW); int new_pos = position(); ExpressionT result = this->EmptyExpression(); - if (Check(Token::SUPER)) { - result = this->SuperReference(scope_, factory()); + if (peek() == Token::SUPER) { + const bool is_new = true; + result = ParseSuperExpression(is_new, CHECK_OK); } else { result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); } @@ -2724,21 +2726,8 @@ ParserBase::ParseMemberExpression(bool* ok) { function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, CHECK_OK); } else if (peek() == Token::SUPER) { - int beg_pos = position(); - Consume(Token::SUPER); - Token::Value next = peek(); - if (next == Token::PERIOD || next == Token::LBRACK) { - scope_->RecordSuperPropertyUsage(); - result = this->SuperReference(scope_, factory()); - } else if (next == Token::LPAREN) { - scope_->RecordSuperConstructorCallUsage(); - result = this->SuperReference(scope_, factory()); - } else { - ReportMessageAt(Scanner::Location(beg_pos, position()), - "unexpected_super"); - *ok = false; - return this->EmptyExpression(); - } + const bool is_new = false; + result = ParseSuperExpression(is_new, CHECK_OK); } else { result = ParsePrimaryExpression(CHECK_OK); } @@ -2748,6 +2737,39 @@ ParserBase::ParseMemberExpression(bool* ok) { } +template +typename ParserBase::ExpressionT +ParserBase::ParseSuperExpression(bool is_new, bool* ok) { + int beg_pos = position(); + Expect(Token::SUPER, CHECK_OK); + + FunctionState* function_state = function_state_; + while (IsArrowFunction(function_state->kind())) { + function_state = function_state->outer(); + } + // TODO(arv): Handle eval scopes similarly. + + FunctionKind kind = function_state->kind(); + if (IsConciseMethod(kind) || IsAccessorFunction(kind) || + i::IsConstructor(kind)) { + if (peek() == Token::PERIOD || peek() == Token::LBRACK) { + scope_->RecordSuperPropertyUsage(); + return this->SuperReference(scope_, factory()); + } + // new super() is never allowed. + // super() is only allowed in constructor + if (!is_new && peek() == Token::LPAREN && i::IsConstructor(kind)) { + scope_->RecordSuperConstructorCallUsage(); + return this->SuperReference(scope_, factory()); + } + } + + ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super"); + *ok = false; + return this->EmptyExpression(); +} + + template typename ParserBase::ExpressionT ParserBase::ParseMemberExpressionContinuation(ExpressionT expression, diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index ba2fa975fd..a59566bd80 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -954,74 +954,73 @@ TEST(ScopeUsesArgumentsSuperThis) { const char* suffix; } surroundings[] = { { "function f() {", "}" }, - { "var f = () => {", "}" }, + { "var f = () => {", "};" }, + { "class C { constructor() {", "} }" }, }; enum Expected { NONE = 0, ARGUMENTS = 1, - SUPER_PROPERTY = 2, - SUPER_CONSTRUCTOR_CALL = 4, - THIS = 8, - INNER_ARGUMENTS = 16, - INNER_SUPER_PROPERTY = 32, - INNER_SUPER_CONSTRUCTOR_CALL = 64, - INNER_THIS = 128 + SUPER_PROPERTY = 1 << 1, + SUPER_CONSTRUCTOR_CALL = 1 << 2, + THIS = 1 << 3, + INNER_ARGUMENTS = 1 << 4, + INNER_SUPER_PROPERTY = 1 << 5, + INNER_SUPER_CONSTRUCTOR_CALL = 1 << 6, + INNER_THIS = 1 << 7 }; static const struct { const char* body; int expected; } source_data[] = { - {"", NONE}, - {"return this", THIS}, - {"return arguments", ARGUMENTS}, - {"return super()", SUPER_CONSTRUCTOR_CALL}, - {"return super.x", SUPER_PROPERTY}, - {"return arguments[0]", ARGUMENTS}, - {"return this + arguments[0]", ARGUMENTS | THIS}, - {"return this + arguments[0] + super.x", - ARGUMENTS | SUPER_PROPERTY | THIS}, - {"return x => this + x", INNER_THIS}, - {"return x => super() + x", INNER_SUPER_CONSTRUCTOR_CALL}, - {"this.foo = 42;", THIS}, - {"this.foo();", THIS}, - {"if (foo()) { this.f() }", THIS}, - {"if (foo()) { super.f() }", SUPER_PROPERTY}, - {"if (arguments.length) { this.f() }", ARGUMENTS | THIS}, - {"while (true) { this.f() }", THIS}, - {"while (true) { super.f() }", SUPER_PROPERTY}, - {"if (true) { while (true) this.foo(arguments) }", ARGUMENTS | THIS}, - // Multiple nesting levels must work as well. - {"while (true) { while (true) { while (true) return this } }", THIS}, - {"while (true) { while (true) { while (true) return super() } }", - SUPER_CONSTRUCTOR_CALL}, - {"if (1) { return () => { while (true) new this() } }", INNER_THIS}, - {"if (1) { return () => { while (true) new super() } }", NONE}, - {"if (1) { return () => { while (true) new new super() } }", NONE}, - // Note that propagation of the inner_uses_this() value does not - // cross boundaries of normal functions onto parent scopes. - {"return function (x) { return this + x }", NONE}, - {"return function (x) { return super() + x }", NONE}, - {"var x = function () { this.foo = 42 };", NONE}, - {"var x = function () { super.foo = 42 };", NONE}, - {"if (1) { return function () { while (true) new this() } }", NONE}, - {"if (1) { return function () { while (true) new super() } }", NONE}, - {"return function (x) { return () => this }", NONE}, - {"return function (x) { return () => super() }", NONE}, - // Flags must be correctly set when using block scoping. - {"\"use strict\"; while (true) { let x; this, arguments; }", - INNER_ARGUMENTS | INNER_THIS}, - {"\"use strict\"; while (true) { let x; this, super(), arguments; }", - INNER_ARGUMENTS | INNER_SUPER_CONSTRUCTOR_CALL | INNER_THIS}, - {"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS}, - {"\"use strict\"; if (foo()) { let x; super.f() }", - INNER_SUPER_PROPERTY}, - {"\"use strict\"; if (1) {" - " let x; return function () { return this + super() + arguments }" - "}", - NONE}, - }; + {"", NONE}, + {"return this", THIS}, + {"return arguments", ARGUMENTS}, + {"return super()", SUPER_CONSTRUCTOR_CALL}, + {"return super.x", SUPER_PROPERTY}, + {"return arguments[0]", ARGUMENTS}, + {"return this + arguments[0]", ARGUMENTS | THIS}, + {"return this + arguments[0] + super.x", + ARGUMENTS | SUPER_PROPERTY | THIS}, + {"return x => this + x", INNER_THIS}, + {"return x => super() + x", INNER_SUPER_CONSTRUCTOR_CALL}, + {"this.foo = 42;", THIS}, + {"this.foo();", THIS}, + {"if (foo()) { this.f() }", THIS}, + {"if (foo()) { super.f() }", SUPER_PROPERTY}, + {"if (arguments.length) { this.f() }", ARGUMENTS | THIS}, + {"while (true) { this.f() }", THIS}, + {"while (true) { super.f() }", SUPER_PROPERTY}, + {"if (true) { while (true) this.foo(arguments) }", ARGUMENTS | THIS}, + // Multiple nesting levels must work as well. + {"while (true) { while (true) { while (true) return this } }", THIS}, + {"while (true) { while (true) { while (true) return super() } }", + SUPER_CONSTRUCTOR_CALL}, + {"if (1) { return () => { while (true) new this() } }", INNER_THIS}, + // Note that propagation of the inner_uses_this() value does not + // cross boundaries of normal functions onto parent scopes. + {"return function (x) { return this + x }", NONE}, + {"return { m(x) { return super.m() + x } }", NONE}, + {"var x = function () { this.foo = 42 };", NONE}, + {"var x = { m() { super.foo = 42 } };", NONE}, + {"if (1) { return function () { while (true) new this() } }", NONE}, + {"if (1) { return { m() { while (true) super.m() } } }", NONE}, + {"return function (x) { return () => this }", NONE}, + {"return { m(x) { return () => super.m() } }", NONE}, + // Flags must be correctly set when using block scoping. + {"\"use strict\"; while (true) { let x; this, arguments; }", + INNER_ARGUMENTS | INNER_THIS}, + {"\"use strict\"; while (true) { let x; this, super(), arguments; }", + INNER_ARGUMENTS | INNER_SUPER_CONSTRUCTOR_CALL | INNER_THIS}, + {"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS}, + {"\"use strict\"; if (foo()) { let x; super.f() }", + INNER_SUPER_PROPERTY}, + {"\"use strict\"; if (1) {" + " let x; return { m() { return this + super.m() + arguments } }" + "}", + NONE}, + }; i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); @@ -1035,6 +1034,15 @@ TEST(ScopeUsesArgumentsSuperThis) { for (unsigned j = 0; j < arraysize(surroundings); ++j) { for (unsigned i = 0; i < arraysize(source_data); ++i) { + // Super constructor call is only allowed in constructor. + // Super property is only allowed in constructor and method. + if (((source_data[i].expected & SUPER_CONSTRUCTOR_CALL) || + (source_data[i].expected & SUPER_PROPERTY) || + (source_data[i].expected & INNER_SUPER_CONSTRUCTOR_CALL) || + (source_data[i].expected & INNER_SUPER_PROPERTY) || + (source_data[i].expected == NONE)) && j != 2) { + continue; + } int kProgramByteSize = i::StrLength(surroundings[j].prefix) + i::StrLength(surroundings[j].suffix) + i::StrLength(source_data[i].body); @@ -1052,9 +1060,11 @@ TEST(ScopeUsesArgumentsSuperThis) { i::Parser parser(&info, &parse_info); parser.set_allow_harmony_arrow_functions(true); parser.set_allow_harmony_classes(true); + parser.set_allow_harmony_object_literals(true); parser.set_allow_harmony_scoping(true); + parser.set_allow_harmony_sloppy(true); info.MarkAsGlobal(); - parser.Parse(); + CHECK(parser.Parse()); CHECK(i::Rewriter::Rewrite(&info)); CHECK(i::Scope::Analyze(&info)); CHECK(info.function() != NULL); @@ -1064,6 +1074,11 @@ TEST(ScopeUsesArgumentsSuperThis) { CHECK_EQ(1, script_scope->inner_scopes()->length()); i::Scope* scope = script_scope->inner_scopes()->at(0); + // Adjust for constructor scope. + if (j == 2) { + CHECK_EQ(1, scope->inner_scopes()->length()); + scope = scope->inner_scopes()->at(0); + } CHECK_EQ((source_data[i].expected & ARGUMENTS) != 0, scope->uses_arguments()); CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0, @@ -3637,45 +3652,224 @@ TEST(NoErrorsArrowFunctions) { } -TEST(NoErrorsSuper) { +TEST(SuperNoErrors) { // Tests that parser and preparser accept 'super' keyword in right places. - const char* context_data[][2] = {{"", ";"}, - {"k = ", ";"}, - {"foo(", ");"}, - {NULL, NULL}}; + const char* context_data[][2] = { + {"class C { m() { ", "; } }"}, + {"class C { m() { k = ", "; } }"}, + {"class C { m() { foo(", "); } }"}, + {"class C { m() { () => ", "; } }"}, + {NULL, NULL} + }; const char* statement_data[] = { "super.x", "super[27]", + "new super.x", + "new super.x()", + "new super[27]", + "new super[27]()", + "z.super", // Ok, property lookup. + NULL + }; + + static const ParserFlag always_flags[] = { + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; + RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(SuperErrors) { + const char* context_data[][2] = { + {"class C { m() { ", "; } }"}, + {"class C { m() { k = ", "; } }"}, + {"class C { m() { foo(", "); } }"}, + {"class C { m() { () => ", "; } }"}, + {NULL, NULL} + }; + + const char* expression_data[] = { + "super", + "super = x", + "y = super", + "f(super)", "new super", "new super()", "new super(12, 45)", "new new super", "new new super()", "new new super()()", - "z.super", // Ok, property lookup. - NULL}; + NULL + }; - static const ParserFlag always_flags[] = {kAllowHarmonyClasses}; - RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, + static const ParserFlag always_flags[] = { + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; + RunParserSyncTest(context_data, expression_data, kError, NULL, 0, always_flags, arraysize(always_flags)); } -TEST(ErrorsSuper) { - // Tests that parser and preparser generate same errors for 'super'. - const char* context_data[][2] = {{"", ";"}, - {"k = ", ";"}, - {"foo(", ");"}, +TEST(SuperCall) { + const char* context_data[][2] = {{"", ""}, {NULL, NULL}}; + const char* success_data[] = { + "class C { constructor() { super(); } }", + "class C extends B { constructor() { super(); } }", + "class C extends B { constructor() { () => super(); } }", + NULL + }; + + static const ParserFlag always_flags[] = { + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; + RunParserSyncTest(context_data, success_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); + + const char* error_data[] = { + "class C { method() { super(); } }", + "class C { method() { () => super(); } }", + "class C { *method() { super(); } }", + "class C { get x() { super(); } }", + "class C { set x(_) { super(); } }", + "({ method() { super(); } })", + "({ *method() { super(); } })", + "({ get x() { super(); } })", + "({ set x(_) { super(); } })", + "({ f: function() { super(); } })", + "(function() { super(); })", + "var f = function() { super(); }", + "({ f: function*() { super(); } })", + "(function*() { super(); })", + "var f = function*() { super(); }", + NULL + }; + + RunParserSyncTest(context_data, error_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(SuperNewNoErrors) { + const char* context_data[][2] = { + {"class C { constructor() { ", " } }"}, + {"class C { *method() { ", " } }"}, + {"class C { get x() { ", " } }"}, + {"class C { set x(_) { ", " } }"}, + {"({ method() { ", " } })"}, + {"({ *method() { ", " } })"}, + {"({ get x() { ", " } })"}, + {"({ set x(_) { ", " } })"}, + {NULL, NULL} + }; + + const char* expression_data[] = { + "new super.x;", + "new super.x();", + "() => new super.x;", + "() => new super.x();", + NULL + }; + + static const ParserFlag always_flags[] = { + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; + RunParserSyncTest(context_data, expression_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(SuperNewErrors) { + const char* context_data[][2] = { + {"class C { method() { ", " } }"}, + {"class C { *method() { ", " } }"}, + {"class C { get x() { ", " } }"}, + {"class C { set x(_) { ", " } }"}, + {"({ method() { ", " } })"}, + {"({ *method() { ", " } })"}, + {"({ get x() { ", " } })"}, + {"({ set x(_) { ", " } })"}, + {"({ f: function() { ", " } })"}, + {"(function() { ", " })"}, + {"var f = function() { ", " }"}, + {"({ f: function*() { ", " } })"}, + {"(function*() { ", " })"}, + {"var f = function*() { ", " }"}, + {NULL, NULL} + }; + const char* statement_data[] = { + "new super;", + "new super();", + "() => new super;", + "() => new super();", + NULL + }; + + static const ParserFlag always_flags[] = { + kAllowHarmonyArrowFunctions, + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; + RunParserSyncTest(context_data, statement_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(SuperErrorsNonMethods) { + // super is only allowed in methods, accessors and constructors. + const char* context_data[][2] = { + {"", ";"}, + {"k = ", ";"}, + {"foo(", ");"}, + {"if (", ") {}"}, + {"if (true) {", "}"}, + {"if (false) {} else {", "}"}, + {"while (true) {", "}"}, + {"function f() {", "}"}, + {"class C extends (", ") {}"}, + {"class C { m() { function f() {", "} } }"}, + {"({ m() { function f() {", "} } })"}, + {NULL, NULL} + }; + + const char* statement_data[] = { + "super", "super = x", "y = super", "f(super)", - NULL}; + "super.x", + "super[27]", + "super.x()", + "super[27]()", + "super()", + "new super.x", + "new super.x()", + "new super[27]", + "new super[27]()", + NULL + }; - static const ParserFlag always_flags[] = {kAllowHarmonyClasses}; + static const ParserFlag always_flags[] = { + kAllowHarmonyClasses, + kAllowHarmonyObjectLiterals, + kAllowHarmonySloppy + }; RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, arraysize(always_flags)); } diff --git a/test/mjsunit/harmony/classes.js b/test/mjsunit/harmony/classes.js index a28cddf4dc..31871bf814 100644 --- a/test/mjsunit/harmony/classes.js +++ b/test/mjsunit/harmony/classes.js @@ -874,10 +874,4 @@ function assertAccessorDescriptor(object, name) { } }; new C3(); - - class C4 extends Object { - constructor() { - super(new super()); - } - }; new C4(); }()); diff --git a/test/mjsunit/harmony/object-literals-super.js b/test/mjsunit/harmony/object-literals-super.js index ec22b8a8a3..c2d456c877 100644 --- a/test/mjsunit/harmony/object-literals-super.js +++ b/test/mjsunit/harmony/object-literals-super.js @@ -22,15 +22,6 @@ set accessor(v) { super.accessor = v; }, - property: function() { - super.property(); - }, - propertyWithParen: (function() { - super.property(); - }), - propertyWithParens: ((function() { - super.property(); - })), methodNoSuper() {}, get getterNoSuper() {}, @@ -50,9 +41,6 @@ desc = Object.getOwnPropertyDescriptor(object, 'accessor'); assertEquals(object, desc.get[%HomeObjectSymbol()]); assertEquals(object, desc.set[%HomeObjectSymbol()]); - assertEquals(object, object.property[%HomeObjectSymbol()]); - assertEquals(object, object.propertyWithParen[%HomeObjectSymbol()]); - assertEquals(object, object.propertyWithParens[%HomeObjectSymbol()]); assertEquals(undefined, object.methodNoSuper[%HomeObjectSymbol()]); desc = Object.getOwnPropertyDescriptor(object, 'getterNoSuper'); @@ -118,21 +106,6 @@ })(); -(function TestMethodAsProperty() { - var object = { - __proto__: { - method: function(x) { - return 'proto' + x; - } - }, - method: function(x) { - return super.method(x); - } - }; - assertEquals('proto42', object.method(42)); -})(); - - (function TestOptimized() { // Object literals without any accessors get optimized. var object = { @@ -154,15 +127,7 @@ *g() { yield super.m(); }, - g2: function*() { - yield super.m() + 1; - }, - g3: (function*() { - yield super.m() + 2; - }) }; assertEquals(42, o.g().next().value); - assertEquals(43, o.g2().next().value); - assertEquals(44, o.g3().next().value); })(); diff --git a/test/mjsunit/harmony/super.js b/test/mjsunit/harmony/super.js index 6dcc393cce..bf805a4304 100644 --- a/test/mjsunit/harmony/super.js +++ b/test/mjsunit/harmony/super.js @@ -1,36 +1,38 @@ // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -// Flags: --harmony-classes +// Flags: --harmony-classes (function TestSuperNamedLoads() { function Base() { } + function fBase() { } + Base.prototype = { + f() { + return "Base " + this.toString(); + }, + x: 15, + toString() { + return "this is Base"; + } + }; + function Derived() { this.derivedDataProperty = "xxx"; } - Derived.prototype = Object.create(Base.prototype); - - function fBase() { return "Base " + this.toString(); } - - Base.prototype.f = fBase.toMethod(Base.prototype); - - function fDerived() { - assertEquals("Base this is Derived", super.f()); - var a = super.x; - assertEquals(15, a); - assertEquals(15, super.x); - assertEquals(27, this.x); - - return "Derived" - } - - Base.prototype.x = 15; - Base.prototype.toString = function() { return "this is Base"; }; - Derived.prototype.toString = function() { return "this is Derived"; }; - Derived.prototype.x = 27; - Derived.prototype.f = fDerived.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + toString() { return "this is Derived"; }, + x: 27, + f() { + assertEquals("Base this is Derived", super.f()); + var a = super.x; + assertEquals(15, a); + assertEquals(15, super.x); + assertEquals(27, this.x); + return "Derived"; + } + }; assertEquals("Base this is Base", new Base().f()); assertEquals("Derived", new Derived().f()); @@ -41,31 +43,29 @@ var x = 'x'; var derivedDataProperty = 'derivedDataProperty'; var f = 'f'; + function Base() { } - function Derived() { - this[derivedDataProperty] = 'xxx'; - } - Derived.prototype = Object.create(Base.prototype); - function fBase() { return "Base " + this.toString(); } - Base.prototype[f] = fBase.toMethod(Base.prototype); - - function fDerived() { - assertEquals("Base this is Derived", super[f]()); - var a = super[x]; - assertEquals(15, a); - assertEquals(15, super[x]); - assertEquals(27, this[x]); - - return "Derived" - } - Base.prototype[x] = 15; Base.prototype.toString = function() { return "this is Base"; }; - Derived.prototype.toString = function() { return "this is Derived"; }; - Derived.prototype[x] = 27; - Derived.prototype[f] = fDerived.toMethod(Derived.prototype); + + function Derived() { + this[derivedDataProperty] = "xxx"; + } + Derived.prototype = { + __proto__: Base.prototype, + toString() { return "this is Derived"; }, + x: 27, + f() { + assertEquals("Base this is Derived", super[f]()); + var a = super[x]; + assertEquals(15, a); + assertEquals(15, super[x]); + assertEquals(27, this[x]); + return "Derived"; + } + }; assertEquals("Base this is Base", new Base().f()); assertEquals("Derived", new Derived().f()); @@ -76,31 +76,29 @@ var x = 1; var derivedDataProperty = 2; var f = 3; + function Base() { } - function Derived() { - this[derivedDataProperty] = 'xxx'; - } - Derived.prototype = Object.create(Base.prototype); - function fBase() { return "Base " + this.toString(); } - Base.prototype[f] = fBase.toMethod(Base.prototype); - - function fDerived() { - assertEquals("Base this is Derived", super[f]()); - var a = super[x]; - assertEquals(15, a); - assertEquals(15, super[x]); - assertEquals(27, this[x]); - - return "Derived" - } - Base.prototype[x] = 15; Base.prototype.toString = function() { return "this is Base"; }; - Derived.prototype.toString = function() { return "this is Derived"; }; - Derived.prototype[x] = 27; - Derived.prototype[f] = fDerived.toMethod(Derived.prototype); + + function Derived() { + this[derivedDataProperty] = "xxx"; + } + Derived.prototype = { + __proto__: Base.prototype, + toString() { return "this is Derived"; }, + 1: 27, + 3() { + assertEquals("Base this is Derived", super[f]()); + var a = super[x]; + assertEquals(15, a); + assertEquals(15, super[x]); + assertEquals(27, this[x]); + return "Derived"; + } + }; assertEquals("Base this is Base", new Base()[f]()); assertEquals("Derived", new Derived()[f]()); @@ -108,11 +106,17 @@ (function TestSuperKeywordNonMethod() { - function f() { - super.unknown(); + 'use strict'; + + class C { + f() { + super.unknown(); + } } - assertThrows(f, ReferenceError); + assertThrows(function() { + new C().f(); + }, TypeError); }()); @@ -133,15 +137,16 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testGetter() { + return super.x; + }, + testGetterStrict() { + 'use strict'; + return super.x; + } }; - Derived.prototype.testGetter = function() { - return super.x; - }.toMethod(Derived.prototype); - Derived.prototype.testGetterStrict = function() { - 'use strict'; - return super.x; - }.toMethod(Derived.prototype); + derived = new Derived(); assertEquals('derived', derived.testGetter()); derived = new Derived(); @@ -167,44 +172,45 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testGetter() { + return super[x]; + }, + testGetterStrict() { + 'use strict'; + return super[x]; + }, + testGetterWithToString() { + var toStringCalled; + var o = { toString: function() { + toStringCalled++; + return 'x'; + } }; + + toStringCalled = 0; + assertEquals('derived', super[o]); + assertEquals(1, toStringCalled); + + var eToThrow = new Error(); + var oThrowsInToString = { toString: function() { + throw eToThrow; + } }; + + var ex = null; + try { + super[oThrowsInToString]; + } catch(e) { ex = e } + assertEquals(eToThrow, ex); + + var oReturnsNumericString = { toString: function() { + return "1"; + } }; + + assertEquals(undefined, super[oReturnsNumericString]); + assertEquals(undefined, super[1]); + } }; - Derived.prototype.testGetter = function() { - return super[x]; - }.toMethod(Derived.prototype); - Derived.prototype.testGetterStrict = function() { - 'use strict'; - return super[x]; - }.toMethod(Derived.prototype); - Derived.prototype.testGetterWithToString = function() { - var toStringCalled; - var o = { toString: function() { - toStringCalled++; - return 'x'; - } }; - toStringCalled = 0; - assertEquals('derived', super[o]); - assertEquals(1, toStringCalled); - - var eToThrow = new Error(); - var oThrowsInToString = { toString: function() { - throw eToThrow; - } }; - - var ex = null; - try { - super[oThrowsInToString]; - } catch(e) { ex = e } - assertEquals(eToThrow, ex); - - var oReturnsNumericString = { toString: function() { - return "1"; - } }; - - assertEquals(undefined, super[oReturnsNumericString]); - assertEquals(undefined, super[1]); - }.toMethod(Derived.prototype); derived = new Derived(); assertEquals('derived', derived.testGetter()); derived = new Derived(); @@ -233,45 +239,51 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testGetter() { + return super[x]; + }, + testGetterStrict() { + 'use strict'; + return super[x]; + }, + testGetterWithToString() { + var toStringCalled; + var o = { + toString: function() { + toStringCalled++; + return '42'; + } + }; + + toStringCalled = 0; + assertEquals('derived', super[o]); + assertEquals(1, toStringCalled); + + var eToThrow = new Error(); + var oThrowsInToString = { + toString: function() { + throw eToThrow; + } + }; + + var ex = null; + try { + super[oThrowsInToString]; + } catch(e) { ex = e } + assertEquals(eToThrow, ex); + + var oReturnsNumericString = { + toString: function() { + return "42"; + } + }; + + assertEquals('derived', super[oReturnsNumericString]); + assertEquals('derived', super[42]); + } }; - Derived.prototype.testGetter = function() { - return super[x]; - }.toMethod(Derived.prototype); - Derived.prototype.testGetterStrict = function() { - 'use strict'; - return super[x]; - }.toMethod(Derived.prototype); - Derived.prototype.testGetterWithToString = function() { - var toStringCalled; - var o = { toString: function() { - toStringCalled++; - return '42'; - } }; - - toStringCalled = 0; - assertEquals('derived', super[o]); - assertEquals(1, toStringCalled); - - var eToThrow = new Error(); - var oThrowsInToString = { toString: function() { - throw eToThrow; - } }; - - var ex = null; - try { - super[oThrowsInToString]; - } catch(e) { ex = e } - assertEquals(eToThrow, ex); - - var oReturnsNumericString = { toString: function() { - return "42"; - } }; - - assertEquals('derived', super[oReturnsNumericString]); - assertEquals('derived', super[42]); - }.toMethod(Derived.prototype); derived = new Derived(); assertEquals('derived', derived.testGetter()); derived = new Derived(); @@ -299,22 +311,24 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testSetter() { + assertEquals('foobar', super.x = 'foobar'); + assertEquals('foobarabc', super.x += 'abc'); + }, + testSetterStrict() { + 'use strict'; + assertEquals('foobar', super.x = 'foobar'); + assertEquals('foobarabc', super.x += 'abc'); + } }; - Derived.prototype.testSetter = function() { - assertEquals('foobar', super.x = 'foobar'); - assertEquals('foobarabc', super.x += 'abc'); - }.toMethod(Derived.prototype); + var d = new Derived(); d.testSetter(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); d._x = ''; - Derived.prototype.testSetterStrict = function() { - 'use strict'; - assertEquals('foobar', super.x = 'foobar'); - assertEquals('foobarabc', super.x += 'abc'); - }.toMethod(Derived.prototype); + d.testSetterStrict(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); @@ -339,51 +353,56 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testSetter() { + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }, + testSetterStrict() { + 'use strict'; + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }, + testSetterWithToString() { + var toStringCalled; + var o = { + toString: function() { + toStringCalled++; + return x; + } + }; + + toStringCalled = 0; + super[o] = 'set'; + assertEquals(1, toStringCalled); + assertEquals('set', this._x); + + var eToThrow = new Error(); + var oThrowsInToString = { + toString: function() { + throw eToThrow; + } + }; + + var ex = null; + try { + super[oThrowsInToString] = 'xyz'; + } catch(e) { ex = e } + assertEquals(eToThrow, ex); + assertEquals('set', this._x); + } }; - Derived.prototype.testSetter = function() { - assertEquals('foobar', super[x] = 'foobar'); - assertEquals('foobarabc', super[x] += 'abc'); - }.toMethod(Derived.prototype); + var d = new Derived(); d.testSetter(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); d._x = ''; - Derived.prototype.testSetterStrict = function() { - 'use strict'; - assertEquals('foobar', super[x] = 'foobar'); - assertEquals('foobarabc', super[x] += 'abc'); - }.toMethod(Derived.prototype); + d.testSetterStrict(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); - - Derived.prototype.testSetterWithToString = function() { - var toStringCalled; - var o = { toString: function() { - toStringCalled++; - return x; - } }; - - toStringCalled = 0; - super[o] = 'set'; - assertEquals(1, toStringCalled); - assertEquals('set', this._x); - - var eToThrow = new Error(); - var oThrowsInToString = { toString: function() { - throw eToThrow; - } }; - - var ex = null; - try { - super[oThrowsInToString] = 'xyz'; - } catch(e) { ex = e } - assertEquals(eToThrow, ex); - assertEquals('set', this._x); - }.toMethod(Derived.prototype); d = new Derived(); d.testSetterWithToString(); }()); @@ -408,61 +427,67 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 'derived' + _x: 'derived', + testSetter() { + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }, + testSetterStrict() { + 'use strict'; + assertEquals('foobar', super[x] = 'foobar'); + assertEquals('foobarabc', super[x] += 'abc'); + }, + testSetterWithToString() { + var toStringCalled; + var o = { + toString: function() { + toStringCalled++; + return 'x'; + } + }; + + toStringCalled = 0; + super[o] = 'set'; + assertEquals(1, toStringCalled); + assertEquals('set', this._x); + + var eToThrow = new Error(); + var oThrowsInToString = { + toString: function() { + throw eToThrow; + } + }; + + var ex = null; + try { + super[oThrowsInToString] = 'xyz'; + } catch(e) { ex = e } + assertEquals(eToThrow, ex); + assertEquals('set', this._x); + + var oReturnsNumericString = { + toString: function() { + return "1"; + } + }; + + assertEquals('abc', super[oReturnsNumericString] = 'abc'); + + assertEquals('set', this._x); + + assertEquals(10, super[1] = 10); + } }; - Derived.prototype.testSetter = function() { - assertEquals('foobar', super[x] = 'foobar'); - assertEquals('foobarabc', super[x] += 'abc'); - }.toMethod(Derived.prototype); + var d = new Derived(); d.testSetter(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); d._x = ''; - Derived.prototype.testSetterStrict = function() { - 'use strict'; - assertEquals('foobar', super[x] = 'foobar'); - assertEquals('foobarabc', super[x] += 'abc'); - }.toMethod(Derived.prototype); d.testSetterStrict(); assertEquals('base', Base.prototype._x); assertEquals('foobarabc', d._x); - - Derived.prototype.testSetterWithToString = function() { - var toStringCalled; - var o = { toString: function() { - toStringCalled++; - return 'x'; - } }; - - toStringCalled = 0; - super[o] = 'set'; - assertEquals(1, toStringCalled); - assertEquals('set', this._x); - - var eToThrow = new Error(); - var oThrowsInToString = { toString: function() { - throw eToThrow; - } }; - - var ex = null; - try { - super[oThrowsInToString] = 'xyz'; - } catch(e) { ex = e } - assertEquals(eToThrow, ex); - assertEquals('set', this._x); - - var oReturnsNumericString = { toString: function() { - return "1"; - } }; - - assertEquals('abc', super[oReturnsNumericString] = 'abc'); - - assertEquals('set', this._x); - - assertEquals(10, super[1] = 10); - }.toMethod(Derived.prototype); d = new Derived(); d.testSetterWithToString(); }()); @@ -479,15 +504,14 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, + testSetter() { + assertEquals('x from Base', super.x); + super.x = 'data property'; + assertEquals('x from Base', super.x); + assertEquals('data property', this.x); + } }; - Derived.prototype.testSetter = function() { - assertEquals('x from Base', super.x); - super.x = 'data property'; - assertEquals('x from Base', super.x); - assertEquals('data property', this.x); - }.toMethod(Derived.prototype); - new Derived().testSetter(); }()); @@ -504,15 +528,14 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, + testSetter() { + assertEquals('x from Base', super[x]); + super[x] = 'data property'; + assertEquals('x from Base', super[x]); + assertEquals('data property', this[x]); + } }; - Derived.prototype.testSetter = function() { - assertEquals('x from Base', super[x]); - super[x] = 'data property'; - assertEquals('x from Base', super[x]); - assertEquals('data property', this[x]); - }.toMethod(Derived.prototype); - new Derived().testSetter(); }()); @@ -529,15 +552,14 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, + testSetter() { + assertEquals('x from Base', super[x]); + super[x] = 'data property'; + assertEquals('x from Base', super[x]); + assertEquals('data property', this[x]); + } }; - Derived.prototype.testSetter = function() { - assertEquals('x from Base', super[x]); - super[x] = 'data property'; - assertEquals('x from Base', super[x]); - assertEquals('data property', this[x]); - }.toMethod(Derived.prototype); - new Derived().testSetter(); }()); @@ -562,73 +584,74 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - }; - Derived.prototype.testSetter = function() { - setCalled = 0; - getCalled = 0; - assertEquals('object', typeof this); - assertTrue(this instanceof Number) - assertEquals(42, this.valueOf()); - assertEquals(1, super.x); - assertEquals(1, getCalled); - assertEquals(0, setCalled); + testSetter() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof Number) + assertEquals(42, this.valueOf()); + assertEquals(1, super.x); + assertEquals(1, getCalled); + assertEquals(0, setCalled); - assertEquals(5, super.x = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); + assertEquals(5, super.x = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); - assertEquals(6, super.x += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); + assertEquals(6, super.x += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); - super.newProperty = 15; - assertEquals(15, this.newProperty); - assertEquals(undefined, super.newProperty); - }.toMethod(Derived.prototype); - - Derived.prototype.testSetterStrict = function() { - 'use strict'; - getCalled = 0; - setCalled = 0; - assertTrue(42 === this); - - assertEquals(1, super.x); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - assertEquals(5, super.x = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); - - assertEquals(6, super.x += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); - - var ex; - try { super.newProperty = 15; - } catch (e) { ex = e; } - assertTrue(ex instanceof TypeError); - }.toMethod(Derived.prototype); + assertEquals(15, this.newProperty); + assertEquals(undefined, super.newProperty); + }, + testSetterStrict() { + 'use strict'; + getCalled = 0; + setCalled = 0; + assertTrue(42 === this); + + assertEquals(1, super.x); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + assertEquals(5, super.x = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); + + assertEquals(6, super.x += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); + + var ex; + try { + super.newProperty = 15; + } catch (e) { ex = e; } + assertTrue(ex instanceof TypeError); + } + } Derived.prototype.testSetter.call(42); Derived.prototype.testSetterStrict.call(42); function DerivedFromString() {} - DerivedFromString.prototype = Object.create(String.prototype); + DerivedFromString.prototype = { + __proto__: String.prototype, + f() { + 'use strict'; + assertTrue(42 === this); + assertEquals(String.prototype.toString, super.toString); + var ex; + try { + super.toString(); + } catch(e) { ex = e; } - function f() { - 'use strict'; - assertTrue(42 === this); - assertEquals(String.prototype.toString, super.toString); - var ex; - try { - super.toString(); - } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + } + }; - assertTrue(ex instanceof TypeError); - } - f.toMethod(DerivedFromString.prototype).call(42); + DerivedFromString.prototype.f.call(42); }()); @@ -655,73 +678,73 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - }; - Derived.prototype.testSetter = function() { - setCalled = 0; - getCalled = 0; - assertEquals('object', typeof this); - assertTrue(this instanceof Number) - assertEquals(42, this.valueOf()); - assertEquals(1, super[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); + testSetter() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof Number) + assertEquals(42, this.valueOf()); + assertEquals(1, super[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); - assertEquals(5, super[x] = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); + assertEquals(5, super[x] = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); - assertEquals(6, super[x] += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); + assertEquals(6, super[x] += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); - super[newProperty] = 15; - assertEquals(15, this[newProperty]); - assertEquals(undefined, super[newProperty]); - }.toMethod(Derived.prototype); - - Derived.prototype.testSetterStrict = function() { - 'use strict'; - getCalled = 0; - setCalled = 0; - assertTrue(42 === this); - - assertEquals(1, super[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - assertEquals(5, super[x] = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); - - assertEquals(6, super[x] += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); - - var ex; - try { super[newProperty] = 15; - } catch (e) { ex = e; } - assertTrue(ex instanceof TypeError); - }.toMethod(Derived.prototype); + assertEquals(15, this[newProperty]); + assertEquals(undefined, super[newProperty]); + }, + testSetterStrict() { + 'use strict'; + getCalled = 0; + setCalled = 0; + assertTrue(42 === this); + + assertEquals(1, super[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + assertEquals(5, super[x] = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); + + assertEquals(6, super[x] += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); + + var ex; + try { + super[newProperty] = 15; + } catch (e) { ex = e; } + assertTrue(ex instanceof TypeError); + } + }; Derived.prototype.testSetter.call(42); Derived.prototype.testSetterStrict.call(42); function DerivedFromString() {} - DerivedFromString.prototype = Object.create(String.prototype); + DerivedFromString.prototype = { + __proto__: String.prototype, + f() { + 'use strict'; + assertTrue(42 === this); + assertEquals(String.prototype.toString, super[toString]); + var ex; + try { + super[toString](); + } catch(e) { ex = e; } - function f() { - 'use strict'; - assertTrue(42 === this); - assertEquals(String.prototype.toString, super[toString]); - var ex; - try { - super[toString](); - } catch(e) { ex = e; } - - assertTrue(ex instanceof TypeError); - } - f.toMethod(DerivedFromString.prototype).call(42); + assertTrue(ex instanceof TypeError); + } + }; + DerivedFromString.prototype.f.call(42); }()); @@ -750,54 +773,53 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - }; - Derived.prototype.testSetter = function() { - setCalled = 0; - getCalled = 0; - assertEquals('object', typeof this); - assertTrue(this instanceof Number) - assertEquals(42, this.valueOf()); - assertEquals(1, super[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); + testSetter() { + setCalled = 0; + getCalled = 0; + assertEquals('object', typeof this); + assertTrue(this instanceof Number) + assertEquals(42, this.valueOf()); + assertEquals(1, super[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); - assertEquals(5, super[x] = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); + assertEquals(5, super[x] = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); - assertEquals(6, super[x] += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); + assertEquals(6, super[x] += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); - super[newProperty] = 15; - assertEquals(15, this[newProperty]); - assertEquals(undefined, super[newProperty]); - }.toMethod(Derived.prototype); - - Derived.prototype.testSetterStrict = function() { - 'use strict'; - getCalled = 0; - setCalled = 0; - assertTrue(42 === this); - - assertEquals(1, super[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - assertEquals(5, super[x] = 5); - assertEquals(1, getCalled); - assertEquals(1, setCalled); - - assertEquals(6, super[x] += 5); - assertEquals(2, getCalled); - assertEquals(2, setCalled); - - var ex; - try { super[newProperty] = 15; - } catch (e) { ex = e; } - assertTrue(ex instanceof TypeError); - }.toMethod(Derived.prototype); + assertEquals(15, this[newProperty]); + assertEquals(undefined, super[newProperty]); + }, + testSetterStrict() { + 'use strict'; + getCalled = 0; + setCalled = 0; + assertTrue(42 === this); + + assertEquals(1, super[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + assertEquals(5, super[x] = 5); + assertEquals(1, getCalled); + assertEquals(1, setCalled); + + assertEquals(6, super[x] += 5); + assertEquals(2, getCalled); + assertEquals(2, setCalled); + + var ex; + try { + super[newProperty] = 15; + } catch (e) { ex = e; } + assertTrue(ex instanceof TypeError); + } + }; Derived.prototype.testSetter.call(42); Derived.prototype.testSetterStrict.call(42); @@ -807,28 +829,28 @@ (function TestKeyedNumericSetterOnExotics() { function Base() {} function Derived() {} - Derived.prototype = { __proto__: Base.prototype }; + Derived.prototype = { + __proto__: Base.prototype, + callSetterOnArray() { + super[42] = 1; + }, + callStrictSetterOnString() { + 'use strict'; + assertEquals('string', typeof this); + assertTrue('abcdef' === this); + var ex = null; + try { + super[5] = 'q'; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); - Derived.prototype.callSetterOnArray = function() { - super[42] = 1; - }.toMethod(Derived.prototype); - - Derived.prototype.callStrictSetterOnString = function() { - 'use strict'; - assertEquals('string', typeof this); - assertTrue('abcdef' === this); - var ex = null; - try { - super[5] = 'q'; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - - ex = null; - try { - super[1024] = 'q'; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - }.toMethod(Derived.prototype); + ex = null; + try { + super[1024] = 'q'; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + } + }; var x = []; assertEquals(0, x.length); @@ -844,23 +866,25 @@ (function TestSetterUndefinedProperties() { function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - Derived.prototype.mSloppy = function () { - assertEquals(undefined, super.x); - assertEquals(undefined, this.x); - super.x = 10; - assertEquals(10, this.x); - assertEquals(undefined, super.x); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(undefined, super.x); + assertEquals(undefined, this.x); + super.x = 10; + assertEquals(10, this.x); + assertEquals(undefined, super.x); + }, + mStrict() { + 'use strict'; + assertEquals(undefined, super.x); + assertEquals(undefined, this.x); + super.x = 10; + assertEquals(10, this.x); + assertEquals(undefined, super.x); + } + }; - Derived.prototype.mStrict = function () { - 'use strict'; - assertEquals(undefined, super.x); - assertEquals(undefined, this.x); - super.x = 10; - assertEquals(10, this.x); - assertEquals(undefined, super.x); - }.toMethod(Derived.prototype); var d = new Derived(); d.mSloppy(); assertEquals(10, d.x); @@ -874,23 +898,24 @@ var x = 'x'; function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - Derived.prototype.mSloppy = function () { - assertEquals(undefined, super[x]); - assertEquals(undefined, this[x]); - super[x] = 10; - assertEquals(10, this[x]); - assertEquals(undefined, super[x]); - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function () { - 'use strict'; - assertEquals(undefined, super[x]); - assertEquals(undefined, this[x]); - super[x] = 10; - assertEquals(10, this[x]); - assertEquals(undefined, super[x]); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }, + mStrict() { + 'use strict'; + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + } + }; var d = new Derived(); d.mSloppy(); assertEquals(10, d.x); @@ -904,23 +929,24 @@ var x = 42; function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - Derived.prototype.mSloppy = function () { - assertEquals(undefined, super[x]); - assertEquals(undefined, this[x]); - super[x] = 10; - assertEquals(10, this[x]); - assertEquals(undefined, super[x]); - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function () { - 'use strict'; - assertEquals(undefined, super[x]); - assertEquals(undefined, this[x]); - super[x] = 10; - assertEquals(10, this[x]); - assertEquals(undefined, super[x]); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + }, + mStrict() { + 'use strict'; + assertEquals(undefined, super[x]); + assertEquals(undefined, this[x]); + super[x] = 10; + assertEquals(10, this[x]); + assertEquals(undefined, super[x]); + } + }; var d = new Derived(); d.mSloppy(); assertEquals(10, d[x]); @@ -931,47 +957,47 @@ (function TestSetterCreatingOwnProperties() { + var setterCalled; function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - var setterCalled; - - Derived.prototype.mSloppy = function() { - assertEquals(42, this.ownReadOnly); - super.ownReadOnly = 55; - assertEquals(42, this.ownReadOnly); - - assertEquals(15, this.ownReadonlyAccessor); - super.ownReadonlyAccessor = 55; - assertEquals(15, this.ownReadonlyAccessor); - - setterCalled = 0; - super.ownSetter = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(42, this.ownReadOnly); - var ex; - try { + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(42, this.ownReadOnly); super.ownReadOnly = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(42, this.ownReadOnly); + assertEquals(42, this.ownReadOnly); - assertEquals(15, this.ownReadonlyAccessor); - ex = null; - try { + assertEquals(15, this.ownReadonlyAccessor); super.ownReadonlyAccessor = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(15, this.ownReadonlyAccessor); + assertEquals(15, this.ownReadonlyAccessor); - setterCalled = 0; - super.ownSetter = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); + setterCalled = 0; + super.ownSetter = 42; + assertEquals(1, setterCalled); + }, + mStrict() { + 'use strict'; + assertEquals(42, this.ownReadOnly); + var ex; + try { + super.ownReadOnly = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this.ownReadOnly); + + assertEquals(15, this.ownReadonlyAccessor); + ex = null; + try { + super.ownReadonlyAccessor = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this.ownReadonlyAccessor); + + setterCalled = 0; + super.ownSetter = 42; + assertEquals(1, setterCalled); + } + }; var d = new Derived(); Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); @@ -1006,39 +1032,38 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - }; + testIter() { + setCalled = 0; + getCalled = 0; + for (super.x in [1,2,3]) {} + assertEquals(0, getCalled); + assertEquals(3, setCalled); + assertEquals(["0", "1", "2"], this.x_); + }, + testIterKeyed() { + setCalled = 0; + getCalled = 0; + for (super[x] in [1,2,3]) {} + assertEquals(0, getCalled); + assertEquals(3, setCalled); + assertEquals(["0","1","2"], this.x_); - Derived.prototype.testIter = function() { - setCalled = 0; - getCalled = 0; - for (super.x in [1,2,3]) {} - assertEquals(0, getCalled); - assertEquals(3, setCalled); - assertEquals(["0","1","2"], this.x_); - }.toMethod(Derived.prototype); + this.x_ = []; + setCalled = 0; + getCalled = 0; + var toStringCalled = 0; + var o = {toString: function () { toStringCalled++; return x }}; + for (super[o] in [1,2,3]) {} + assertEquals(0, getCalled); + assertEquals(3, setCalled); + assertEquals(3, toStringCalled); + assertEquals(["0","1","2"], this.x_); + } + }; new Derived().testIter(); var x = 'x'; - Derived.prototype.testIterKeyed = function() { - setCalled = 0; - getCalled = 0; - for (super[x] in [1,2,3]) {} - assertEquals(0, getCalled); - assertEquals(3, setCalled); - assertEquals(["0","1","2"], this.x_); - - this.x_ = []; - setCalled = 0; - getCalled = 0; - var toStringCalled = 0; - var o = {toString: function () { toStringCalled++; return x }}; - for (super[o] in [1,2,3]) {} - assertEquals(0, getCalled); - assertEquals(3, setCalled); - assertEquals(3, toStringCalled); - assertEquals(["0","1","2"], this.x_); - }.toMethod(Derived.prototype); new Derived().testIterKeyed(); }()); @@ -1048,47 +1073,47 @@ var ownReadOnly = 'ownReadOnly'; var ownReadonlyAccessor = 'ownReadonlyAccessor'; var ownSetter = 'ownSetter'; + var setterCalled; function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - var setterCalled; - - Derived.prototype.mSloppy = function() { - assertEquals(42, this[ownReadOnly]); - super[ownReadOnly] = 55; - assertEquals(42, this[ownReadOnly]); - - assertEquals(15, this[ownReadonlyAccessor]); - super[ownReadonlyAccessor] = 55; - assertEquals(15, this[ownReadonlyAccessor]); - - setterCalled = 0; - super[ownSetter] = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(42, this[ownReadOnly]); - var ex; - try { + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(42, this[ownReadOnly]); super[ownReadOnly] = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(42, this[ownReadOnly]); + assertEquals(42, this[ownReadOnly]); - assertEquals(15, this[ownReadonlyAccessor]); - ex = null; - try { + assertEquals(15, this[ownReadonlyAccessor]); super[ownReadonlyAccessor] = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(15, this[ownReadonlyAccessor]); + assertEquals(15, this[ownReadonlyAccessor]); - setterCalled = 0; - super[ownSetter] = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }, + mStrict() { + 'use strict'; + assertEquals(42, this[ownReadOnly]); + var ex; + try { + super[ownReadOnly] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + ex = null; + try { + super[ownReadonlyAccessor] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + } + }; var d = new Derived(); Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false }); @@ -1105,47 +1130,47 @@ var ownReadOnly = 42; var ownReadonlyAccessor = 43; var ownSetter = 44; + var setterCalled; function Base() {} function Derived() {} - Derived.prototype = { __proto__ : Base.prototype }; - var setterCalled; - - Derived.prototype.mSloppy = function() { - assertEquals(42, this[ownReadOnly]); - super[ownReadOnly] = 55; - assertEquals(42, this[ownReadOnly]); - - assertEquals(15, this[ownReadonlyAccessor]); - super[ownReadonlyAccessor] = 55; - assertEquals(15, this[ownReadonlyAccessor]); - - setterCalled = 0; - super[ownSetter] = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(42, this[ownReadOnly]); - var ex; - try { + Derived.prototype = { + __proto__: Base.prototype, + mSloppy() { + assertEquals(42, this[ownReadOnly]); super[ownReadOnly] = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(42, this[ownReadOnly]); + assertEquals(42, this[ownReadOnly]); - assertEquals(15, this[ownReadonlyAccessor]); - ex = null; - try { + assertEquals(15, this[ownReadonlyAccessor]); super[ownReadonlyAccessor] = 55; - } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(15, this[ownReadonlyAccessor]); + assertEquals(15, this[ownReadonlyAccessor]); - setterCalled = 0; - super[ownSetter] = 42; - assertEquals(1, setterCalled); - }.toMethod(Derived.prototype); + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + }, + mStrict() { + 'use strict'; + assertEquals(42, this[ownReadOnly]); + var ex; + try { + super[ownReadOnly] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(42, this[ownReadOnly]); + + assertEquals(15, this[ownReadonlyAccessor]); + ex = null; + try { + super[ownReadonlyAccessor] = 55; + } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(15, this[ownReadonlyAccessor]); + + setterCalled = 0; + super[ownSetter] = 42; + assertEquals(1, setterCalled); + } + } var d = new Derived(); Object.defineProperty(d, ownReadOnly, { value : 42, writable : false }); @@ -1164,62 +1189,58 @@ var getCalled; var setCalled; Derived.prototype = { - __proto__ : Base.prototype, + __proto__: Base.prototype, get x() { getCalled++; return 42; }, - set x(v) { setCalled++; } + set x(v) { setCalled++; }, + mSloppy() { + setCalled = 0; + getCalled = 0; + assertEquals(42, this.x); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this.x = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super.x = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this.x); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + }, + mStrict() { + 'use strict'; + setCalled = 0; + getCalled = 0; + assertEquals(42, this.x); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this.x = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super.x = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this.x); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + } }; - Derived.prototype.mSloppy = function() { - setCalled = 0; - getCalled = 0; - assertEquals(42, this.x); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this.x = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super.x = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this.x); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - setCalled = 0; - getCalled = 0; - assertEquals(42, this.x); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this.x = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super.x = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this.x); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - new Derived().mSloppy(); new Derived().mStrict(); }()); @@ -1232,62 +1253,58 @@ var getCalled; var setCalled; Derived.prototype = { - __proto__ : Base.prototype, + __proto__: Base.prototype, get x() { getCalled++; return 42; }, - set x(v) { setCalled++; } + set x(v) { setCalled++; }, + mSloppy() { + setCalled = 0; + getCalled = 0; + assertEquals(42, this[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this[x] = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super[x] = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this[x]); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + }, + mStrict() { + 'use strict'; + setCalled = 0; + getCalled = 0; + assertEquals(42, this[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this[x] = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super[x] = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this[x]); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + } }; - Derived.prototype.mSloppy = function() { - setCalled = 0; - getCalled = 0; - assertEquals(42, this[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this[x] = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super[x] = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this[x]); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - setCalled = 0; - getCalled = 0; - assertEquals(42, this[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this[x] = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super[x] = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this[x]); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - new Derived().mSloppy(); new Derived().mStrict(); }()); @@ -1300,7 +1317,54 @@ var getCalled; var setCalled; Derived.prototype = { - __proto__ : Base.prototype, + __proto__: Base.prototype, + mSloppy() { + setCalled = 0; + getCalled = 0; + assertEquals(42, this[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this[x] = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super[x] = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this[x]); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + }, + mStrict() { + 'use strict'; + setCalled = 0; + getCalled = 0; + assertEquals(42, this[x]); + assertEquals(1, getCalled); + assertEquals(0, setCalled); + + getCalled = 0; + setCalled = 0; + this[x] = 43; + assertEquals(0, getCalled); + assertEquals(1, setCalled); + + getCalled = 0; + setCalled = 0; + super[x] = 15; + assertEquals(0, setCalled); + assertEquals(0, getCalled); + + assertEquals(15, this[x]); + assertEquals(0, getCalled); + assertEquals(0, setCalled); + } }; Object.defineProperty(Derived.prototype, x, { @@ -1308,57 +1372,6 @@ set: function(v) { setCalled++; } }); - Derived.prototype.mSloppy = function() { - setCalled = 0; - getCalled = 0; - assertEquals(42, this[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this[x] = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super[x] = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this[x]); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - - Derived.prototype.mStrict = function() { - 'use strict'; - setCalled = 0; - getCalled = 0; - assertEquals(42, this[x]); - assertEquals(1, getCalled); - assertEquals(0, setCalled); - - getCalled = 0; - setCalled = 0; - this[x] = 43; - assertEquals(0, getCalled); - assertEquals(1, setCalled); - - getCalled = 0; - setCalled = 0; - super[x] = 15; - assertEquals(0, setCalled); - assertEquals(0, getCalled); - - assertEquals(15, this[x]); - assertEquals(0, getCalled); - assertEquals(0, setCalled); - - }.toMethod(Derived.prototype); - new Derived().mSloppy(); new Derived().mStrict(); }()); @@ -1367,35 +1380,36 @@ (function TestSetterDoesNotReconfigure() { function Base() {} function Derived() {} + Derived.prototype = { + __proto__: Derived.prototype, + mStrict(){ + 'use strict'; + super.nonEnumConfig = 5; + var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); + assertEquals(5, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - Derived.prototype.mStrict = function (){ - 'use strict'; - super.nonEnumConfig = 5; - var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); - assertEquals(5, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); + super.nonEnumNonConfig = 5; + var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); + assertEquals(5, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + }, + mSloppy(){ + super.nonEnumConfig = 42; + var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); + assertEquals(42, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - super.nonEnumNonConfig = 5; - var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); - assertEquals(5, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); - - Derived.prototype.mSloppy = function (){ - super.nonEnumConfig = 42; - var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig'); - assertEquals(42, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); - - super.nonEnumNonConfig = 42; - var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); - assertEquals(42, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); + super.nonEnumNonConfig = 42; + var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig'); + assertEquals(42, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + } + }; var d = new Derived(); Object.defineProperty(d, 'nonEnumConfig', @@ -1413,36 +1427,36 @@ function Base() {} function Derived() {} - Derived.prototype = { __proto__: Base.prototype }; + Derived.prototype = { + __proto__: Base.prototype, + mStrict(){ + 'use strict'; + super[nonEnumConfig] = 5; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); + assertEquals(5, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - Derived.prototype.mStrict = function (){ - 'use strict'; - super[nonEnumConfig] = 5; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); - assertEquals(5, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); + super[nonEnumNonConfig] = 5; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); + assertEquals(5, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + }, + mSloppy(){ + super[nonEnumConfig] = 42; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); + assertEquals(42, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - super[nonEnumNonConfig] = 5; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); - assertEquals(5, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); - - Derived.prototype.mSloppy = function (){ - super[nonEnumConfig] = 42; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); - assertEquals(42, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); - - super[nonEnumNonConfig] = 42; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); - assertEquals(42, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); + super[nonEnumNonConfig] = 42; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); + assertEquals(42, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + } + }; var d = new Derived(); Object.defineProperty(d, nonEnumConfig, @@ -1460,36 +1474,36 @@ function Base() {} function Derived() {} - Derived.prototype = { __proto__: Base.prototype }; + Derived.prototype = { + __proto__: Base.prototype, + mStrict(){ + 'use strict'; + super[nonEnumConfig] = 5; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); + assertEquals(5, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - Derived.prototype.mStrict = function (){ - 'use strict'; - super[nonEnumConfig] = 5; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); - assertEquals(5, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); + super[nonEnumNonConfig] = 5; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); + assertEquals(5, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + }, + mSloppy(){ + super[nonEnumConfig] = 42; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); + assertEquals(42, d1.value); + assertTrue(d1.configurable); + assertFalse(d1.enumerable); - super[nonEnumNonConfig] = 5; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); - assertEquals(5, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); - - Derived.prototype.mSloppy = function (){ - super[nonEnumConfig] = 42; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig); - assertEquals(42, d1.value); - assertTrue(d1.configurable); - assertFalse(d1.enumerable); - - super[nonEnumNonConfig] = 42; - var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); - assertEquals(42, d1.value); - assertFalse(d1.configurable); - assertFalse(d1.enumerable); - }.toMethod(Derived.prototype); + super[nonEnumNonConfig] = 42; + var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig); + assertEquals(42, d1.value); + assertFalse(d1.configurable); + assertFalse(d1.enumerable); + } + }; var d = new Derived(); Object.defineProperty(d, nonEnumConfig, @@ -1519,32 +1533,31 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 2 + _x: 2, + testCounts() { + assertEquals(2, this._x); + assertEquals(2, super.x); + super.x++; + assertEquals(3, super.x); + ++super.x; + assertEquals(4, super.x); + assertEquals(4, super.x++); + assertEquals(5, super.x); + assertEquals(6, ++super.x); + assertEquals(6, super.x); + assertEquals(6, this._x); + + super.x--; + assertEquals(5, super.x); + --super.x; + assertEquals(4, super.x); + assertEquals(4, super.x--); + assertEquals(3, super.x); + assertEquals(2, --super.x); + assertEquals(2, super.x); + assertEquals(2, this._x); + } }; - - Derived.prototype.testCounts = function() { - assertEquals(2, this._x); - assertEquals(2, super.x); - super.x++; - assertEquals(3, super.x); - ++super.x; - assertEquals(4, super.x); - assertEquals(4, super.x++); - assertEquals(5, super.x); - assertEquals(6, ++super.x); - assertEquals(6, super.x); - assertEquals(6, this._x); - - super.x--; - assertEquals(5, super.x); - --super.x; - assertEquals(4, super.x); - assertEquals(4, super.x--); - assertEquals(3, super.x); - assertEquals(2, --super.x); - assertEquals(2, super.x); - assertEquals(2, this._x); - }.toMethod(Derived.prototype); new Derived().testCounts(); }()); @@ -1568,32 +1581,31 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 2 + _x: 2, + testCounts() { + assertEquals(2, this._x); + assertEquals(2, super[x]); + super[x]++; + assertEquals(3, super[x]); + ++super[x]; + assertEquals(4, super[x]); + assertEquals(4, super[x]++); + assertEquals(5, super[x]); + assertEquals(6, ++super[x]); + assertEquals(6, super[x]); + assertEquals(6, this._x); + + super[x]--; + assertEquals(5, super[x]); + --super[x]; + assertEquals(4, super[x]); + assertEquals(4, super[x]--); + assertEquals(3, super[x]); + assertEquals(2, --super[x]); + assertEquals(2, super[x]); + assertEquals(2, this._x); + } }; - - Derived.prototype.testCounts = function() { - assertEquals(2, this._x); - assertEquals(2, super[x]); - super[x]++; - assertEquals(3, super[x]); - ++super[x]; - assertEquals(4, super[x]); - assertEquals(4, super[x]++); - assertEquals(5, super[x]); - assertEquals(6, ++super[x]); - assertEquals(6, super[x]); - assertEquals(6, this._x); - - super[x]--; - assertEquals(5, super[x]); - --super[x]; - assertEquals(4, super[x]); - assertEquals(4, super[x]--); - assertEquals(3, super[x]); - assertEquals(2, --super[x]); - assertEquals(2, super[x]); - assertEquals(2, this._x); - }.toMethod(Derived.prototype); new Derived().testCounts(); }()); @@ -1616,32 +1628,31 @@ Derived.prototype = { __proto__: Base.prototype, constructor: Derived, - _x: 2 + _x: 2, + testCounts() { + assertEquals(2, this._x); + assertEquals(2, super[x]); + super[x]++; + assertEquals(3, super[x]); + ++super[x]; + assertEquals(4, super[x]); + assertEquals(4, super[x]++); + assertEquals(5, super[x]); + assertEquals(6, ++super[x]); + assertEquals(6, super[x]); + assertEquals(6, this._x); + + super[x]--; + assertEquals(5, super[x]); + --super[x]; + assertEquals(4, super[x]); + assertEquals(4, super[x]--); + assertEquals(3, super[x]); + assertEquals(2, --super[x]); + assertEquals(2, super[x]); + assertEquals(2, this._x); + } }; - - Derived.prototype.testCounts = function() { - assertEquals(2, this._x); - assertEquals(2, super[x]); - super[x]++; - assertEquals(3, super[x]); - ++super[x]; - assertEquals(4, super[x]); - assertEquals(4, super[x]++); - assertEquals(5, super[x]); - assertEquals(6, ++super[x]); - assertEquals(6, super[x]); - assertEquals(6, this._x); - - super[x]--; - assertEquals(5, super[x]); - --super[x]; - assertEquals(4, super[x]); - assertEquals(4, super[x]--); - assertEquals(3, super[x]); - assertEquals(2, --super[x]); - assertEquals(2, super[x]); - assertEquals(2, this._x); - }.toMethod(Derived.prototype); new Derived().testCounts(); }()); @@ -1650,26 +1661,27 @@ function Base() {} Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false }); function Derived() {} - - Derived.prototype = { __proto__: Base.prototype, constructor: Derived }; - - Derived.prototype.mSloppy = function() { - assertEquals(27, super.x); - assertEquals(27, this.x); - super.x = 10; - assertEquals(27, super.x); - assertEquals(27, this.x); - }.toMethod(Derived.prototype); - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(27, super.x); - assertEquals(27, this.x); - var ex = null; - try { super.x = 10; } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(27, super.x); - assertEquals(27, this.x); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + constructor: Derived, + mSloppy() { + assertEquals(27, super.x); + assertEquals(27, this.x); + super.x = 10; + assertEquals(27, super.x); + assertEquals(27, this.x); + }, + mStrict() { + 'use strict'; + assertEquals(27, super.x); + assertEquals(27, this.x); + var ex = null; + try { super.x = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super.x); + assertEquals(27, this.x); + } + }; new Derived().mSloppy(); new Derived().mStrict(); }()); @@ -1681,25 +1693,27 @@ Object.defineProperty(Base.prototype, x, { value : 27, writable: false }); function Derived() {} - Derived.prototype = { __proto__: Base.prototype, constructor: Derived }; - - Derived.prototype.mSloppy = function() { - assertEquals(27, super[x]); - assertEquals(27, this[x]); - super[x] = 10; - assertEquals(27, super[x]); - assertEquals(27, this[x]); - }.toMethod(Derived.prototype); - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(27, super[x]); - assertEquals(27, this[x]); - var ex = null; - try { super[x] = 10; } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(27, super[x]); - assertEquals(27, this[x]); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + constructor: Derived, + mSloppy() { + assertEquals(27, super[x]); + assertEquals(27, this[x]); + super[x] = 10; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }, + mStrict() { + 'use strict'; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + var ex = null; + try { super[x] = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super[x]); + assertEquals(27, this[x]); + } + }; new Derived().mSloppy(); new Derived().mStrict(); }()); @@ -1711,55 +1725,51 @@ Object.defineProperty(Base.prototype, x, { value : 27, writable: false }); function Derived() {} - Derived.prototype = { __proto__: Base.prototype, constructor: Derived }; - - Derived.prototype.mSloppy = function() { - assertEquals(27, super[x]); - assertEquals(27, this[x]); - super[x] = 10; - assertEquals(27, super[x]); - assertEquals(27, this[x]); - }.toMethod(Derived.prototype); - Derived.prototype.mStrict = function() { - 'use strict'; - assertEquals(27, super[x]); - assertEquals(27, this[x]); - var ex = null; - try { super[x] = 10; } catch(e) { ex = e; } - assertTrue(ex instanceof TypeError); - assertEquals(27, super[x]); - assertEquals(27, this[x]); - }.toMethod(Derived.prototype); + Derived.prototype = { + __proto__: Base.prototype, + constructor: Derived, + mSloppy() { + assertEquals(27, super[x]); + assertEquals(27, this[x]); + super[x] = 10; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + }, + mStrict() { + 'use strict'; + assertEquals(27, super[x]); + assertEquals(27, this[x]); + var ex = null; + try { super[x] = 10; } catch(e) { ex = e; } + assertTrue(ex instanceof TypeError); + assertEquals(27, super[x]); + assertEquals(27, this[x]); + } + }; new Derived().mSloppy(); new Derived().mStrict(); }()); -function Subclass(base, constructor) { - var homeObject = { - __proto__: base.prototype, - constructor: constructor - }; - constructor.__proto__ = base; - constructor.prototype = homeObject; - // not doing toMethod: home object is not required for - // super constructor calls. - return constructor; -} - (function TestSuperCall() { + 'use strict'; + var baseCalled = 0; var derivedCalled = 0; var derivedDerivedCalled = 0; - function Base() { - baseCalled++; + class Base { + constructor() { + baseCalled++; + } } - var Derived = Subclass(Base, function () { - super(); - derivedCalled++; - }); + class Derived extends Base { + constructor() { + super(); + derivedCalled++; + } + } assertEquals(Base, Base.prototype.constructor); assertEquals(Base.prototype, Derived.prototype.__proto__); @@ -1770,10 +1780,12 @@ function Subclass(base, constructor) { assertEquals(1, baseCalled); assertEquals(1, derivedCalled); - var DerivedDerived = Subclass(Derived, function () { - super(); - derivedDerivedCalled++; - }); + class DerivedDerived extends Derived { + constructor() { + super(); + derivedDerivedCalled++; + } + } baseCalled = 0; derivedCalled = 0; @@ -1783,32 +1795,42 @@ function Subclass(base, constructor) { assertEquals(1, derivedCalled); assertEquals(1, derivedDerivedCalled); - function Base2(v) { - this.fromBase = v; + class Base2 { + constructor(v) { + this.fromBase = v; + } + } + class Derived2 extends Base2 { + constructor(v1, v2) { + super(v1); + this.fromDerived = v2; + } } - 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 ImplicitSubclassOfFunction() { - super(); - this.x = 123; + class ImplicitSubclassOfFunction { + constructor() { + super(); + this.x = 123; + } } var o = new ImplicitSubclassOfFunction(); assertEquals(123, o.x); var calls = 0; - function G() { - calls++; + class G { + constructor() { + calls++; + } } - function F() { - super(); + class F { + constructor() { + super(); + } } F.__proto__ = G; new F(); @@ -1819,103 +1841,84 @@ function Subclass(base, constructor) { }()); -(function TestNewSuper() { - var baseCalled = 0; - var derivedCalled = 0; - - function Base() { - baseCalled++; - this.x = 15; - } - - - var Derived = Subclass(Base, function() { - baseCalled = 0; - var b = new super(); - assertEquals(1, baseCalled) - assertEquals(Base.prototype, b.__proto__); - assertEquals(15, b.x); - assertEquals(undefined, this.x); - derivedCalled++; - }); - - derivedCalled = 0; - new Derived(); - assertEquals(1, derivedCalled); -}()); - - (function TestSuperCallErrorCases() { - function T() { - super(); + 'use strict'; + class T { + constructor() { + super(); + } } - T.__proto__ = null; - // Spec says ReferenceError here, but for other IsCallable failures - // we throw TypeError. - // Filed https://bugs.ecmascript.org/show_bug.cgi?id=3282 - assertThrows(function() { new T(); }, TypeError); - function T1() { - var b = new super(); - } - T1.__proto = null; - assertThrows(function() { new T1(); }, TypeError); + T.__proto__ = null; + assertThrows(function() { new T(); }, TypeError); }()); (function TestSuperCallSyntacticRestriction() { + 'use strict'; assertThrows(function() { - function C() { - var y; - super(); + class C { + constructor() { + super(this.x); + } } new C(); }, TypeError); assertThrows(function() { - function C() { - super(this.x); + class C { + constructor() { + super(this); + } } new C(); }, TypeError); assertThrows(function() { - function C() { - super(this); + class C { + constructor() { + super(1, 2, Object.getPrototypeOf(this)); + } } new C(); }, TypeError); assertThrows(function() { - function C() { - super(1, 2, Object.getPrototypeOf(this)); + class C { + constructor() { + { super(1, 2); } + } } new C(); }, TypeError); assertThrows(function() { - function C() { - { super(1, 2); } - }; new C(); - }, TypeError); - assertThrows(function() { - function C() { - if (1) super(); - }; new C(); + class C { + constructor() { + if (1) super(); + } + } + new C(); }, TypeError); - function C1() { - 'use strict'; - super(); - }; + class C1 { + constructor() { + 'use strict'; + super(); + } + } new C1(); - function C2() { - ; 'use strict';;;;; - super(); - }; + class C2 { + constructor() { + ; 'use strict';;;;; + super(); + } + } new C2(); - function C3() { - ; 'use strict';;;;; - // This is a comment. - super(); + class C3 { + constructor() { + ; 'use strict';;;;; + // This is a comment. + super(); + } } new C3(); }()); diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index a003d30483..423ff17468 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -117,6 +117,7 @@ # TODO(arv): TurboFan does not yet add [[HomeObject]] as needed. 'harmony/object-literals-super': [PASS, NO_VARIANTS], + 'harmony/super': [PASS, NO_VARIANTS], ############################################################################## # Too slow in debug mode with --stress-opt mode.