From 166d5ac589a78e9291044b93a8df5a650d79b247 Mon Sep 17 00:00:00 2001 From: Caio Lima Date: Wed, 26 Jun 2019 13:03:36 -0300 Subject: [PATCH] Adding tests to validate HomeObject setup on private methods and accessors (#2214) --- .../super-access-inside-a-private-getter.js | 50 +++++++++++++++++++ .../super-access-inside-a-private-method.js | 50 +++++++++++++++++++ .../super-access-inside-a-private-setter.js | 50 +++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 test/language/statements/class/elements/super-access-inside-a-private-getter.js create mode 100644 test/language/statements/class/elements/super-access-inside-a-private-method.js create mode 100644 test/language/statements/class/elements/super-access-inside-a-private-setter.js diff --git a/test/language/statements/class/elements/super-access-inside-a-private-getter.js b/test/language/statements/class/elements/super-access-inside-a-private-getter.js new file mode 100644 index 0000000000..dbb39b1f2a --- /dev/null +++ b/test/language/statements/class/elements/super-access-inside-a-private-getter.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Private getter contains proper HomeObject +esid: sec-method-definitions-runtime-semantics-classelementevaluation +info: | + MethodDefinition : get ClassElementName () { FunctionBody } + 1. Let key be the result of evaluating ClassElementName. + 2. ReturnIfAbrupt(key). + 3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false. + 4. Let scope be the running execution context's LexicalEnvironment. + 5. Let formalParameterList be an instance of the production FormalParameters:[empty] . + 6. Let closure be FunctionCreate(Method, formalParameterList, FunctionBody, scope, strict). + 7. Perform MakeMethod(closure, homeObject). + 8. Perform SetFunctionName(closure, key, "get"). + 9. If key is a Private Name, + a. If key has a [[Kind]] field, + i. Assert: key.[[Kind]] is "accessor". + ii. Assert: key.[[Brand]] is homeObject. + iii. Assert: key does not have a [[Get]] field. + iv. Set key.[[Get]] to closure. + b. Otherwise, + i. Set key.[[Kind]] to "accessor". + ii. Set key.[[Brand]] to homeObject. + iii. Set key.[[Get]] to closure. + 10. Else, + a. Let desc be the PropertyDescriptor{[[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}. + b. Perform ? DefinePropertyOrThrow(homeObject, key, desc). +features: [class-methods-private, class] +---*/ + +class A { + method() { + return "Test262"; + } +} + +class C extends A { + get #m() { + return super.method(); + } + + access() { + return this.#m; + } +} + +let c = new C(); +assert.sameValue(c.access(), "Test262"); diff --git a/test/language/statements/class/elements/super-access-inside-a-private-method.js b/test/language/statements/class/elements/super-access-inside-a-private-method.js new file mode 100644 index 0000000000..f20a1fb94e --- /dev/null +++ b/test/language/statements/class/elements/super-access-inside-a-private-method.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Private method contains proper HomeObject +esid: sec-method-definitions-runtime-semantics-classelementevaluation +info: | + MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } + 1. Let methodDef be DefineMethod of MethodDefinition with argument homeObject. + 2. ReturnIfAbrupt(methodDef). + 3. Perform ? DefineOrdinaryMethod(methodDef.[[Key]], homeObject, methodDef.[[Closure]], _enumerable). + + MethodDefinition : PropertyName ( UniqueFormalParameters ) { FunctionBody } + 1. Let propKey be the result of evaluating PropertyName. + 2. ReturnIfAbrupt(propKey). + 3. Let scope be the running execution context's LexicalEnvironment. + 4. If functionPrototype is present as a parameter, then + a. Let kind be Normal. + b. Let prototype be functionPrototype. + 5. Else, + a. Let kind be Method. + b. Let prototype be the intrinsic object %FunctionPrototype%. + 6. Let closure be FunctionCreate(kind, UniqueFormalParameters, FunctionBody, scope, prototype). + 7. Perform MakeMethod(closure, object). + 8. Set closure.[[SourceText]] to the source text matched by MethodDefinition. + 9. Return the Record { [[Key]]: propKey, [[Closure]]: closure }. +features: [class-methods-private, class] +---*/ + +class A { + method() { + return "Test262"; + } +} + +class C extends A { + #m() { + return super.method(); + } + + access(o) { + return this.#m.call(o); + } +} + +let c = new C(); +assert.sameValue(c.access(c), "Test262"); + +let o = {}; +assert.sameValue(c.access(o), "Test262"); diff --git a/test/language/statements/class/elements/super-access-inside-a-private-setter.js b/test/language/statements/class/elements/super-access-inside-a-private-setter.js new file mode 100644 index 0000000000..ce0d317aeb --- /dev/null +++ b/test/language/statements/class/elements/super-access-inside-a-private-setter.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Caio Lima (Igalia SL). All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Private setter contains proper HomeObject +esid: sec-method-definitions-runtime-semantics-classelementevaluation +info: | + MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody } + 1. Let key be the result of evaluating ClassElementName. + 2. ReturnIfAbrupt(key). + 3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false. + 4. Let scope be the running execution context's LexicalEnvironment. + 5. Let closure be FunctionCreate(Method, PropertySetParameterList, FunctionBody, scope, strict). + 6. Perform MakeMethod(closure, homeObject). + 7. Perform SetFunctionName(closure, key, "set"). + 8. If key is a Private Name, + a. If key has a [[Kind]] field, + i. Assert: key.[[Kind]] is "accessor". + ii. Assert: key.[[Brand]] is homeObject. + iii. Assert: key does not have a [[Set]] field. + iv. Set key.[[Set]] to closure. + b. Otherwise, + i. Set key.[[Kind]] to "accessor". + ii. Set key.[[Brand]] to homeObject. + iii. Set key.[[Set]] to closure. + 9. Else, + a. Let desc be the PropertyDescriptor{[[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}. + b. Perform ? DefinePropertyOrThrow(homeObject, key, desc). +features: [class-methods-private, class] +---*/ + +class A { + method(v) { + return v; + } +} + +class C extends A { + set #m(v) { + this._v = super.method(v); + } + + access() { + return this.#m = "Test262"; + } +} + +let c = new C(); +c.access(); +assert.sameValue(c._v, "Test262");