Commit 9acfd4fe authored by arv's avatar arv Committed by Commit bot

super is only allowed in methods, accessors and constructor

super() is only allowed in a class constructor.
super.p is allowed in methods, accessors and constructors.

The parser now checks the FunctionState to see what kind of function
we are currently inside.

BUG=v8:3330
LOG=N
R=dslomov@chromium.org, marja@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26557}
parent 5cd84502
......@@ -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<Traits>::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<Traits>::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<Traits>::ParseMemberExpression(bool* ok) {
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::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 <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
......
......@@ -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));
}
......
......@@ -874,10 +874,4 @@ function assertAccessorDescriptor(object, name) {
}
};
new C3();
class C4 extends Object {
constructor() {
super(new super());
}
}; new C4();
}());
......@@ -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);
})();
// 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 Base() { }
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 Base() { }
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);
assertEquals(5, super.x = 5);
assertEquals(1, getCalled);
assertEquals(1, 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 {
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(6, super.x += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
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);
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);
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; }
assertTrue(ex instanceof TypeError);
}
};
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);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, 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 {
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(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
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);
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);
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; }
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);
assertEquals(5, super[x] = 5);
assertEquals(1, getCalled);
assertEquals(1, 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 {
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(6, super[x] += 5);
assertEquals(2, getCalled);
assertEquals(2, setCalled);
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.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);
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);
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.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);
......@@ -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_);
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_);
}
};
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);
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.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);
}.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);
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);
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 = 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.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);
}.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);
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);
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] = 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.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);
}.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);
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);
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] = 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);
}());
(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();
}());
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment