v8/test/mjsunit/es6/function-name.js
Timothy Gu 224b659cd4 Install class "name" accessor before methods
https://github.com/tc39/ecma262/pull/1490 changed the spec so that the
"name" property of a class should be installed after "length" but before
"prototype". This CL adapts accordingly.

After this change, there is now no need for the separate code path to
set the "name" accessor at runtime. Delete the relevant runtime code as
well.

Bug: v8:8771
Change-Id: I8f809b45bf209c899cf5df76d0ebf6d9a45a6d4e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2974772
Commit-Queue: Timothy Gu <timothygu@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75340}
2021-06-23 18:05:30 +00:00

453 lines
13 KiB
JavaScript

// Copyright 2015 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.
(function testVariableDeclarationsFunction() {
'use strict';
var a = function(){};
assertEquals('a', a.name);
let b = () => {};
assertEquals('b', b.name);
const c = ((function(){}));
assertEquals('c', c.name);
var x = function(){}, y = () => {}, z = function withName() {};
assertEquals('x', x.name);
assertEquals('y', y.name);
assertEquals('withName', z.name);
})();
(function testVariableDeclarationsClass() {
'use strict';
var a = class {};
assertEquals('a', a.name);
let b = ((class {}));
assertEquals('b', b.name);
// Should not overwrite name property.
const c = class { static name() { } }
assertEquals('function', typeof c.name);
var x = class {}, y = class NamedClass {};
assertEquals('x', x.name);
assertEquals('NamedClass', y.name);
})();
(function testObjectProperties() {
'use strict';
var obj = {
a: function() {},
b: () => {},
c() { },
get d() { },
set d(val) { },
x: function withName() { },
y: class { },
z: class ClassName { },
''() {},
42: function() {},
4.2: function() {},
__proto__: function() {},
};
assertEquals('a', obj.a.name);
assertEquals('b', obj.b.name);
assertEquals('c', obj.c.name);
var dDescriptor = Object.getOwnPropertyDescriptor(obj, 'd');
assertEquals('get d', dDescriptor.get.name);
assertEquals('set d', dDescriptor.set.name);
assertEquals('withName', obj.x.name);
assertEquals('y', obj.y.name);
assertEquals('ClassName', obj.z.name);
assertEquals('', obj[''].name);
assertEquals('42', obj[42].name);
assertEquals('4.2', obj[4.2].name);
assertEquals('', obj.__proto__.name);
})();
(function testClassProperties() {
'use strict';
class C {
a() { }
static b() { }
get c() { }
set c(val) { }
''() { }
static ''() { }
42() { }
static 43() { }
get 44() { }
set 44(val) { }
static get constructor() { }
static set constructor(val) { }
};
assertEquals('a', C.prototype.a.name);
assertEquals('b', C.b.name);
var descriptor = Object.getOwnPropertyDescriptor(C.prototype, 'c');
assertEquals('get c', descriptor.get.name);
assertEquals('set c', descriptor.set.name);
assertEquals('', C.prototype[''].name);
assertEquals('', C[''].name);
assertEquals('42', C.prototype[42].name);
assertEquals('43', C[43].name);
var descriptor = Object.getOwnPropertyDescriptor(C.prototype, '44');
assertEquals('get 44', descriptor.get.name);
assertEquals('set 44', descriptor.set.name);
var descriptor = Object.getOwnPropertyDescriptor(C, 'constructor');
assertEquals('get constructor', descriptor.get.name);
assertEquals('set constructor', descriptor.set.name);
})();
(function testComputedProperties() {
'use strict';
var a = 'a';
var b = 'b';
var sym1 = Symbol('1');
var sym2 = Symbol('2');
var sym3 = Symbol('3');
var symNoDescription = Symbol();
var proto = "__proto__";
var obj = {
['']: function() {},
[a]: function() {},
[sym1]: function() {},
[sym2]: function withName() {},
[symNoDescription]: function() {},
[proto]: function() {},
get [sym3]() {},
set [b](val) {},
};
assertEquals('', obj[''].name);
assertEquals('a', obj[a].name);
assertEquals('[1]', obj[sym1].name);
assertEquals('withName', obj[sym2].name);
assertEquals('', obj[symNoDescription].name);
assertEquals('__proto__', obj[proto].name);
assertEquals('get [3]', Object.getOwnPropertyDescriptor(obj, sym3).get.name);
assertEquals('set b', Object.getOwnPropertyDescriptor(obj, 'b').set.name);
var objMethods = {
['']() {},
[a]() {},
[sym1]() {},
[symNoDescription]() {},
[proto]() {},
};
assertEquals('', objMethods[''].name);
assertEquals('a', objMethods[a].name);
assertEquals('[1]', objMethods[sym1].name);
assertEquals('', objMethods[symNoDescription].name);
assertEquals('__proto__', objMethods[proto].name);
class C {
['']() { }
static ''() {}
[a]() { }
[sym1]() { }
static [sym2]() { }
[symNoDescription]() { }
get [sym3]() { }
static set [b](val) { }
}
assertEquals('', C.prototype[''].name);
assertEquals('', C[''].name);
assertEquals('a', C.prototype[a].name);
assertEquals('[1]', C.prototype[sym1].name);
assertEquals('[2]', C[sym2].name);
assertEquals('', C.prototype[symNoDescription].name);
assertEquals('get [3]', Object.getOwnPropertyDescriptor(C.prototype, sym3).get.name);
assertEquals('set b', Object.getOwnPropertyDescriptor(C, 'b').set.name);
})();
(function testAssignment() {
var basicFn, arrowFn, generatorFn, classLit;
basicFn = function() { return true; };
assertEquals('basicFn', basicFn.name);
var basicFn2 = basicFn;
assertEquals('basicFn', basicFn2.name);
basicFn = function functionWithName() { };
assertEquals("functionWithName", basicFn.name);
arrowFn = x => x;
assertEquals('arrowFn', arrowFn.name);
var arrowFn2 = arrowFn;
assertEquals('arrowFn', arrowFn2.name);
generatorFn = function*() { yield true; };
assertEquals('generatorFn', generatorFn.name);
var generatorFn2 = generatorFn;
assertEquals('generatorFn', generatorFn2.name);
generatorFn = function* generatorWithName() { };
assertEquals("generatorWithName", generatorFn.name);
classLit = class { constructor() {} };
assertEquals('classLit', classLit.name);
var classLit2 = classLit;
assertEquals('classLit', classLit2.name);
classLit = class classWithName { constructor() {} };
assertEquals('classWithName', classLit.name);
classLit = class { constructor() {} static name() {} };
assertEquals('function', typeof classLit.name);
classLit = class { constructor() {} static get name() { return true; } };
assertTrue(classLit.name);
classLit = class { constructor() {} static ['name']() {} };
assertEquals('function', typeof classLit.name);
classLit = class { constructor() {} static get ['name']() { return true; } };
assertTrue(classLit.name);
})();
(function testObjectBindingPattern() {
var {
a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
foo: bar = function() {},
inParens = (() => {}),
inManyParens = ((((() => {})))),
} = {};
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('bar', bar.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})();
(function testArrayBindingPattern() {
var [
a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
inParens = (() => {}),
inManyParens = ((((() => {})))),
] = [];
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})();
(function testObjectAssignmentPattern() {
var a, b, x, y, z, q;
({
a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
foo: bar = function() {},
inParens = (() => {}),
inManyParens = ((((() => {})))),
} = {});
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('bar', bar.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})();
(function testArrayAssignmentPattern() {
var a, b, x, y, z, q;
[
a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
inParens = (() => {}),
inManyParens = ((((() => {})))),
] = [];
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})();
(function testParameterDestructuring() {
(function({ a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
foo: bar = function() {},
inParens = (() => {}),
inManyParens = ((((() => {})))) }) {
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('bar', bar.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})({});
(function([ a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
inParens = (() => {}),
inManyParens = ((((() => {})))) ]) {
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})([]);
})();
(function testDefaultParameters() {
(function(a = function() {},
b = () => {},
x = function withName() { },
y = class { },
z = class ClassName { },
q = class { static name() { return 42 } },
inParens = (() => {}),
inManyParens = ((((() => {}))))) {
assertEquals('a', a.name);
assertEquals('b', b.name);
assertEquals('withName', x.name);
assertEquals('y', y.name);
assertEquals('ClassName', z.name);
assertEquals('function', typeof q.name);
assertEquals('inParens', inParens.name)
assertEquals('inManyParens', inManyParens.name)
})();
})();
(function testComputedNameNotShared() {
function makeClass(propName) {
return class {
static [propName]() {}
}
}
var sym1 = Symbol('1');
var sym2 = Symbol('2');
var class1 = makeClass(sym1);
assertEquals('[1]', class1[sym1].name);
var class2 = makeClass(sym2);
assertEquals('[2]', class2[sym2].name);
assertEquals('[1]', class1[sym1].name);
})();
(function testComputedNamesOnlyAppliedSyntactically() {
function factory() { return () => {}; }
var obj = { ['foo']: factory() };
assertEquals('', obj.foo.name);
})();
(function testNameNotReflectedInToString() {
var f = function () {};
var g = function* () {};
var obj = {
['h']: function () {},
i: () => {}
};
assertEquals('function () {}', f.toString());
assertEquals('function* () {}', g.toString());
assertEquals('function () {}', obj.h.toString());
assertEquals('() => {}', obj.i.toString());
})();
(function testClassNameOrder() {
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(class {}));
var tmp = {'': class {}};
var Tmp = tmp[''];
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(Tmp));
var name = () => '';
var tmp = {[name()]: class {}};
var Tmp = tmp[name()];
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(Tmp));
class A { }
assertEquals(['length', 'name', 'prototype'], Object.getOwnPropertyNames(A));
class B { static foo() { } }
assertEquals(['length', 'name', 'prototype', 'foo'], Object.getOwnPropertyNames(B));
class C { static name() { } static foo() { } }
assertEquals(['length', 'name', 'prototype', 'foo'], Object.getOwnPropertyNames(C));
})();
(function testStaticName() {
class C { static name() { return 42; } }
assertEquals(42, C.name());
assertEquals(undefined, new C().name);
class D { static get name() { return 17; } }
assertEquals(17, D.name);
assertEquals(undefined, new D().name);
var c = class { static name() { return 42; } }
assertEquals(42, c.name());
assertEquals(undefined, new c().name);
var d = class { static get name() { return 17; } }
assertEquals(17, d.name);
assertEquals(undefined, new d().name);
})();
(function testNonStaticName() {
class C { name() { return 42; } }
assertEquals('C', C.name);
assertEquals(42, new C().name());
class D { get name() { return 17; } }
assertEquals('D', D.name);
assertEquals(17, new D().name);
var c = class { name() { return 42; } }
assertEquals('c', c.name);
assertEquals(42, new c().name());
var d = class { get name() { return 17; } }
assertEquals('d', d.name);
assertEquals(17, new d().name);
})();