Commit 1dcce1c8 authored by Erik Arvidsson's avatar Erik Arvidsson

Make super() a syntax error in base class constructor

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

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

Cr-Commit-Position: refs/heads/master@{#26633}
parent fd5a0de2
......@@ -2752,8 +2752,8 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) {
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)) {
// super() is only allowed in derived constructor
if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
scope_->RecordSuperConstructorCallUsage();
return this->SuperReference(scope_, factory());
}
......
......@@ -960,12 +960,10 @@ TEST(ScopeUsesArgumentsSuperThis) {
NONE = 0,
ARGUMENTS = 1,
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
THIS = 1 << 2,
INNER_ARGUMENTS = 1 << 3,
INNER_SUPER_PROPERTY = 1 << 4,
INNER_THIS = 1 << 5
};
static const struct {
......@@ -975,14 +973,13 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"", 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},
{"return x => super.f() + x", INNER_SUPER_PROPERTY},
{"this.foo = 42;", THIS},
{"this.foo();", THIS},
{"if (foo()) { this.f() }", THIS},
......@@ -993,8 +990,8 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"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},
{"while (true) { while (true) { while (true) return super.f() } }",
SUPER_PROPERTY},
{"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.
......@@ -1009,8 +1006,8 @@ TEST(ScopeUsesArgumentsSuperThis) {
// 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\"; while (true) { let x; this, super.f(), arguments; }",
INNER_ARGUMENTS | INNER_SUPER_PROPERTY | INNER_THIS},
{"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS},
{"\"use strict\"; if (foo()) { let x; super.f() }",
INNER_SUPER_PROPERTY},
......@@ -1032,11 +1029,8 @@ 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) ||
if (((source_data[i].expected & SUPER_PROPERTY) ||
(source_data[i].expected & INNER_SUPER_PROPERTY) ||
(source_data[i].expected == NONE)) && j != 2) {
continue;
......@@ -1079,15 +1073,11 @@ TEST(ScopeUsesArgumentsSuperThis) {
scope->uses_arguments());
CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
scope->uses_super_property());
CHECK_EQ((source_data[i].expected & SUPER_CONSTRUCTOR_CALL) != 0,
scope->uses_super_constructor_call());
CHECK_EQ((source_data[i].expected & THIS) != 0, scope->uses_this());
CHECK_EQ((source_data[i].expected & INNER_ARGUMENTS) != 0,
scope->inner_uses_arguments());
CHECK_EQ((source_data[i].expected & INNER_SUPER_PROPERTY) != 0,
scope->inner_uses_super_property());
CHECK_EQ((source_data[i].expected & INNER_SUPER_CONSTRUCTOR_CALL) != 0,
scope->inner_uses_super_constructor_call());
CHECK_EQ((source_data[i].expected & INNER_THIS) != 0,
scope->inner_uses_this());
}
......@@ -3713,7 +3703,6 @@ TEST(SuperCall) {
{NULL, NULL}};
const char* success_data[] = {
"class C { constructor() { super(); } }",
"class C extends B { constructor() { super(); } }",
"class C extends B { constructor() { () => super(); } }",
NULL
......@@ -3729,6 +3718,7 @@ TEST(SuperCall) {
always_flags, arraysize(always_flags));
const char* error_data[] = {
"class C { constructor() { super(); } }",
"class C { method() { super(); } }",
"class C { method() { () => super(); } }",
"class C { *method() { super(); } }",
......
......@@ -2,9 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
*%(basename)s:11: ReferenceError: Unsupported reference to 'super'
*%(basename)s:11: SyntaxError: 'super' keyword unexpected here
super(x);
^
ReferenceError: Unsupported reference to 'super'
at new C (*%(basename)s:11:5)
at *%(basename)s:15:9
^^^^^
SyntaxError: 'super' keyword unexpected here
# 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.
*%(basename)s:10: ReferenceError: Unsupported reference to 'super'
*%(basename)s:10: SyntaxError: 'super' keyword unexpected here
super(this.x);
^
ReferenceError: Unsupported reference to 'super'
at new C (*%(basename)s:10:5)
at *%(basename)s:14:9
^^^^^
SyntaxError: 'super' keyword unexpected here
......@@ -164,23 +164,6 @@
}());
(function TestSuperInBaseConstructors() {
class Base {
constructor() {
let exn = null;
try {
super();
} catch (e) {
exn = e;
}
assertTrue(exn instanceof ReferenceError);
}
}
new Base();
}());
(function TestPrototypeWiring() {
class Base {
constructor(x) {
......
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