diff --git a/test/language/statements/class/subclass/class-definition-null-proto-contains-return-override.js b/test/language/statements/class/subclass/class-definition-null-proto-contains-return-override.js index 0ea3d0c221..bfc962a401 100644 --- a/test/language/statements/class/subclass/class-definition-null-proto-contains-return-override.js +++ b/test/language/statements/class/subclass/class-definition-null-proto-contains-return-override.js @@ -1,6 +1,7 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: sec-runtime-semantics-classdefinitionevaluation es6id: 14.5.14 description: > Runtime Semantics: ClassDefinitionEvaluation @@ -8,8 +9,6 @@ description: > If superclass is null, then Let protoParent be null. Let constructorParent be the intrinsic object %FunctionPrototype%. - - `extends null` requires return override in the constructor ---*/ class Foo extends null { constructor() { diff --git a/test/language/statements/class/subclass/class-definition-null-proto-missing-return-override.js b/test/language/statements/class/subclass/class-definition-null-proto-missing-return-override.js index 9a32025987..b9562e2eb8 100644 --- a/test/language/statements/class/subclass/class-definition-null-proto-missing-return-override.js +++ b/test/language/statements/class/subclass/class-definition-null-proto-missing-return-override.js @@ -1,21 +1,43 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 14.5.14 +esid: sec-runtime-semantics-classdefinitionevaluation description: > - Runtime Semantics: ClassDefinitionEvaluation + The `this` value of a null-extending class is automatically initialized, + obviating the need for an explicit return value in the constructor. +info: | + The behavior under test was introduced in the "ES2017" revision of the + specification and conflicts with prior editions. - If superclass is null, then - Let protoParent be null. - Let constructorParent be the intrinsic object %FunctionPrototype%. + Runtime Semantics: ClassDefinitionEvaluation - `extends null` requires return override in the constructor + [...] + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + [...] + e. If superclass is null, then + i. Let protoParent be null. + ii. Let constructorParent be the intrinsic object %FunctionPrototype%. + [...] + 15. If ClassHeritageopt is present and protoParent is not null, then set F's + [[ConstructorKind]] internal slot to "derived". + [...] + + 9.2.2 [[Construct]] + + [...] + 5. If kind is "base", then + a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, + "%ObjectPrototype%"). + [...] + 15. Return ? envRec.GetThisBinding(). ---*/ + class Foo extends null { constructor() {} } -assert.throws(ReferenceError, function() { - new Foo(); -}); +var foo = new Foo(); +assert.sameValue(Object.getPrototypeOf(foo), Foo); diff --git a/test/language/statements/class/subclass/class-definition-null-proto-super.js b/test/language/statements/class/subclass/class-definition-null-proto-super.js new file mode 100644 index 0000000000..d93be7ef90 --- /dev/null +++ b/test/language/statements/class/subclass/class-definition-null-proto-super.js @@ -0,0 +1,67 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The `this` value of a null-extending class is automatically initialized, + preventing the use of `super` from within the constructor. +info: | + Runtime Semantics: ClassDefinitionEvaluation + + [...] + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + [...] + e. If superclass is null, then + i. Let protoParent be null. + ii. Let constructorParent be the intrinsic object %FunctionPrototype%. + [...] + 15. If ClassHeritageopt is present and protoParent is not null, then set F's + [[ConstructorKind]] internal slot to "derived". + [...] + + 9.2.2 [[Construct]] + + [...] + 5. If kind is "base", then + a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, + "%ObjectPrototype%"). + [...] + + 12.3.5.1 Runtime Semantics: Evaluation + + SuperCall : super Arguments + + [...] + 6. Let result be ? Construct(func, argList, newTarget). + 7. Let thisER be GetThisEnvironment( ). + 8. Return ? thisER.BindThisValue(result). + + 8.1.1.3.1 BindThisValue + + [...] + 3. If envRec.[[ThisBindingStatus]] is "initialized", throw a ReferenceError + exception. + 4. Set envRec.[[ThisValue]] to V. + 5. Set envRec.[[ThisBindingStatus]] to "initialized". + [...] +---*/ + +var unreachable = 0; +var reachable = 0; + +class C extends null { + constructor() { + reachable += 1; + super(); + unreachable += 1; + } +} + +assert.throws(TypeError, function() { + new C(); +}); + +assert.sameValue(reachable, 1); +assert.sameValue(unreachable, 0); diff --git a/test/language/statements/class/subclass/class-definition-null-proto-this.js b/test/language/statements/class/subclass/class-definition-null-proto-this.js new file mode 100644 index 0000000000..097553123a --- /dev/null +++ b/test/language/statements/class/subclass/class-definition-null-proto-this.js @@ -0,0 +1,46 @@ +// Copyright (C) 2014 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The `this` value of a null-extending class is automatically initialized +info: | + The behavior under test was introduced in the "ES2017" revision of the + specification and conflicts with prior editions. + + Runtime Semantics: ClassDefinitionEvaluation + + [...] + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + [...] + e. If superclass is null, then + i. Let protoParent be null. + ii. Let constructorParent be the intrinsic object %FunctionPrototype%. + [...] + 15. If ClassHeritageopt is present and protoParent is not null, then set F's + [[ConstructorKind]] internal slot to "derived". + [...] + + 9.2.2 [[Construct]] + + [...] + 5. If kind is "base", then + a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, + "%ObjectPrototype%"). + [...] +---*/ + +var thisVal, instance; + +class C extends null { + constructor() { + thisVal = this; + } +} + +instance = new C(); + +assert.sameValue(instance instanceof C, true); +assert.sameValue(instance, thisVal); diff --git a/test/language/statements/class/subclass/class-definition-null-proto.js b/test/language/statements/class/subclass/class-definition-null-proto.js index 9c3ec337c3..4ea67b03c5 100644 --- a/test/language/statements/class/subclass/class-definition-null-proto.js +++ b/test/language/statements/class/subclass/class-definition-null-proto.js @@ -1,19 +1,41 @@ -// Copyright (C) 2014 the V8 project authors. All rights reserved. +// Copyright (C) 2016 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 14.5.14_S6.e +esid: sec-runtime-semantics-classdefinitionevaluation +es6id: 14.5.14 description: > - Runtime Semantics: ClassDefinitionEvaluation + When a null-extending class does not specify a `constructor` method + definition, a method with zero parameters and an empty body is used +info: | + The behavior under test was introduced in the "ES2017" revision of the + specification and conflicts with prior editions. - If superclass is null, then - Let protoParent be null. - Let constructorParent be the intrinsic object %FunctionPrototype%. + Runtime Semantics: ClassDefinitionEvaluation + + 5. If ClassHeritageopt is not present, then + [...] + 6. Else, + [...] + e. If superclass is null, then + i. Let protoParent be null. + ii. Let constructorParent be the intrinsic object %FunctionPrototype%. + [...] + 7. Let proto be ObjectCreate(protoParent). + 8. If ClassBodyopt is not present, let constructor be empty. + 9. Else, let constructor be ConstructorMethod of ClassBody. + 10. If constructor is empty, then + a. If ClassHeritageopt is present and protoParent is not null, then + [...] + b. Else, + i. Let constructor be the result of parsing the source text + + constructor( ){ } + + using the syntactic grammar with the goal symbol MethodDefinition. + [...] ---*/ -class Foo extends null { - constructor() { - return {}; - } -} + +class Foo extends null {} assert.sameValue(Object.getPrototypeOf(Foo.prototype), null); assert.sameValue(Object.getPrototypeOf(Foo.prototype.constructor), Function.prototype);