// 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: --allow-natives-syntax function assertMethodDescriptor(object, name) { var descr = Object.getOwnPropertyDescriptor(object, name); assertTrue(descr.configurable); assertFalse(descr.enumerable); assertTrue(descr.writable); assertEquals('function', typeof descr.value); assertFalse('prototype' in descr.value); assertEquals(name, descr.value.name); } function assertAccessorDescriptor(object, name) { var descr = Object.getOwnPropertyDescriptor(object, name); assertTrue(descr.configurable); assertFalse(descr.enumerable); assertEquals('function', typeof descr.get); assertEquals('function', typeof descr.set); assertFalse('prototype' in descr.get); assertFalse('prototype' in descr.set); assertEquals("get " + name, descr.get.name); assertEquals("set " + name, descr.set.name); } (function TestProto() { class C { __proto__() { return 1; } } assertMethodDescriptor(C.prototype, '__proto__'); assertEquals(1, new C().__proto__()); })(); (function TestProtoStatic() { class C { static __proto__() { return 1; } } assertMethodDescriptor(C, '__proto__'); assertEquals(1, C.__proto__()); })(); (function TestProtoAccessor() { class C { get __proto__() { return this._p; } set __proto__(v) { this._p = v; } } assertAccessorDescriptor(C.prototype, '__proto__'); var c = new C(); c._p = 1; assertEquals(1, c.__proto__); c.__proto__ = 2; assertEquals(2, c.__proto__); })(); (function TestStaticProtoAccessor() { class C { static get __proto__() { return this._p; } static set __proto__(v) { this._p = v; } } assertAccessorDescriptor(C, '__proto__'); C._p = 1; assertEquals(1, C.__proto__); C.__proto__ = 2; assertEquals(2, C.__proto__); })(); (function TestSettersOnProto() { function Base() {} Base.prototype = { set constructor(_) { assertUnreachable(); }, set m(_) { assertUnreachable(); } }; Object.defineProperty(Base, 'staticM', { set: function() { assertUnreachable(); } }); class C extends Base { m() { return 1; } static staticM() { return 2; } } assertEquals(1, new C().m()); assertEquals(2, C.staticM()); })(); (function TestConstructableButNoPrototype() { var Base = function() {}.bind(); assertThrows(function() { class C extends Base {} }, TypeError); })(); (function TestPrototypeGetter() { var calls = 0; var Base = function() {}.bind(); Object.defineProperty(Base, 'prototype', { get: function() { calls++; return null; }, configurable: true }); class C extends Base {} assertEquals(1, calls); calls = 0; Object.defineProperty(Base, 'prototype', { get: function() { calls++; return 42; }, configurable: true }); assertThrows(function() { class C extends Base {} }, TypeError); assertEquals(1, calls); })(); (function TestPrototypeSetter() { var Base = function() {}.bind(); Object.defineProperty(Base, 'prototype', { set: function() { assertUnreachable(); } }); assertThrows(function() { class C extends Base {} }, TypeError); })();