Skip to content

[explicit-resource-management] Add remaining tests specific to using statement semantics #4482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions test/language/statements/using/Symbol.dispose-getter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Invokes [Symbol.dispose] getter
info: |
RS: Evaluation
UsingDeclaration : using BindingList ;

1. Perform ? BindingEvaluation of BindingList with argument sync-dispose.
2. Return empty.

RS: BindingEvaluation
LexicalBinding : BindingIdentifier Initializer

...
5. Return ? InitializeReferencedBinding(lhs, value, hint).

InitializeReferencedBinding ( V, W )

...
4. Return ? base.InitializeBinding(V.[[ReferencedName]], W).

InitializeBinding ( N, V, hint )

...
2. If hint is not normal, perform ? AddDisposableResource(envRec.[[DisposeCapability]], V, hint).
...

AddDisposableResource ( disposeCapability, V, hint [, method ] )

1. If method is not present then,
a. If V is either null or undefined and hint is sync-dispose, then
i. Return unused.
b. Let resource be ? CreateDisposableResource(V, hint).
2. Else,
...
3. Append resource to disposeCapability.[[DisposableResourceStack]].
4. Return unused.

CreateDisposableResource ( V, hint [ , method ] )

1. If method is not present, then
a. If V is either null or undefined, then
i. Set V to undefined.
ii. Set method to undefined.
b. Else,
i. If V is not an Object, throw a TypeError exception.
ii. Set method to ? GetDisposeMethod(V, hint).
iii. If method is undefined, throw a TypeError exception.
2. Else,
...
3. Return the DisposableResource Record { [[ResourceValue]]: V, [[Hint]]: hint, [[DisposeMethod]]: method }.

GetDisposeMethod ( V, hint )

1. If hint is async-dispose, then
...
2. Else,
a. Let method be ? GetMethod(V, @@dispose).
3. Return method.

GetMethod ( V, P )

1. Let func be ? GetV(V, P).
2. If func is either undefined or null, return undefined.
3. If IsCallable(func) is false, throw a TypeError exception.
4. Return func.

features: [explicit-resource-management]
---*/

var resource = {
disposed: false,
get [Symbol.dispose]() {
return function() {
this.disposed = true;
};
}
};

{
using _ = resource;
}

assert.sameValue(resource.disposed, true, 'Expected resource to have been disposed');
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-block-runtime-semantics-evaluation
description: Initialized value is disposed with the correct 'this' value
info: |
RS: Evaluation
Block : { StatementList }

...
5. Let blockValue be the result of evaluating StatementList.
6. Set blockValue to DisposeResources(blockEnv.[[DisposeCapability]], blockValue).
...

DisposeResources ( disposeCapability, completion )

1. For each resource of disposeCapability.[[DisposableResourceStack]], in reverse list order, do
a. Let result be Dispose(resource.[[ResourceValue]], resource.[[Hint]], resource.[[DisposeMethod]]).
b. If result.[[Type]] is throw, then
i. If completion.[[Type]] is throw, then
1. Set result to result.[[Value]].
2. Let suppressed be completion.[[Value]].
3. Let error be a newly created SuppressedError object.
4. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "error", result).
5. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "suppressed", suppressed).
6. Set completion to ThrowCompletion(error).
ii. Else,
1. Set completion to result.
2. Return completion.

Dispose ( V, hint, method )

1. If method is undefined, let result be undefined.
2. Else, let result be ? Call(method, V).
...

features: [explicit-resource-management]
---*/

var resource = {
disposed: false,
[Symbol.dispose]() {
assert.sameValue(this, resource);
}
};

{
using _ = resource;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-declarative-environment-records-getbindingvalue-n-s
description: >
using: block local closure [[Get]] before initialization.
(TDZ, Temporal Dead Zone)
features: [explicit-resource-management]
---*/
{
function f() { return x + 1; }

assert.throws(ReferenceError, function() {
f();
});

using x = null;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-declarative-environment-records-getbindingvalue-n-s
description: >
using: block local use before initialization in declaration statement.
(TDZ, Temporal Dead Zone)
features: [explicit-resource-management]
---*/

assert.throws(ReferenceError, function() {
{
using x = x + 1;
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-declarative-environment-records-getbindingvalue-n-s
description: >
using: block local use before initialization in prior statement.
(TDZ, Temporal Dead Zone)
features: [explicit-resource-management]
---*/

assert.throws(ReferenceError, function() {
{
x; using x = null;
}
});
26 changes: 26 additions & 0 deletions test/language/statements/using/cptn-value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Returns an empty completion
info: |
UsingDeclaration : using BindingList ;

1. Perform ? BindingEvaluation of BindingList with argument sync-dispose.
2. Return empty.

features: [explicit-resource-management]
---*/

assert.sameValue(
eval('{using test262id1 = null;}'), undefined, 'Single declaration'
);
assert.sameValue(
eval('{using test262id2 = null, test262id3 = null;}'),
undefined,
'Multiple declarations'
);

assert.sameValue(eval('4; {using test262id5 = null;}'), 4);
assert.sameValue(eval('6; {using test262id7 = null, test262id8 = null;}'), 6);
26 changes: 26 additions & 0 deletions test/language/statements/using/fn-name-arrow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Assignment of function `name` attribute (ArrowFunction)
info: |
LexicalBinding : BindingIdentifier Initializer

...
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
a. Let value be NamedEvaluation of Initializer with argument bindingId
includes: [propertyHelper.js]
features: [explicit-resource-management]
---*/

// NOTE: only way to verify is to patch `Function.prototype` so as not to trigger a TypeError from AddDisposableResource
Function.prototype[Symbol.dispose] = function () {}
{
using arrow = () => {};

assert.sameValue(arrow.name, 'arrow');
verifyNotEnumerable(arrow, 'name');
verifyNotWritable(arrow, 'name');
verifyConfigurable(arrow, 'name');
}
28 changes: 28 additions & 0 deletions test/language/statements/using/fn-name-class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Assignment of function `name` attribute (ClassExpression)
info: |
LexicalBinding : BindingIdentifier Initializer

...
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
a. Let value be NamedEvaluation of Initializer with argument bindingId
includes: [propertyHelper.js]
features: [class, explicit-resource-management]
---*/
{
using xCls = class x { static [Symbol.dispose]() {} };
using cls = class { static [Symbol.dispose]() {} };
using xCls2 = class { static name() {} static [Symbol.dispose]() {} };

assert.notSameValue(xCls.name, 'xCls');
assert.notSameValue(xCls2.name, 'xCls2');

assert.sameValue(cls.name, 'cls');
verifyNotEnumerable(cls, 'name');
verifyNotWritable(cls, 'name');
verifyConfigurable(cls, 'name');
}
30 changes: 30 additions & 0 deletions test/language/statements/using/fn-name-cover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: >
Assignment of function `name` attribute (CoverParenthesizedExpression)
info: |
LexicalBinding : BindingIdentifier Initializer

...
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
a. Let value be NamedEvaluation of Initializer with argument bindingId
includes: [propertyHelper.js]
features: [explicit-resource-management]
---*/

// NOTE: only way to verify is to patch `Function.prototype` so as not to trigger a TypeError from AddDisposableResource
Function.prototype[Symbol.dispose] = function () {}
{
using xCover = (0, function() {});
using cover = (function() {});

assert(xCover.name !== 'xCover');

assert.sameValue(cover.name, 'cover');
verifyNotEnumerable(cover, 'name');
verifyNotWritable(cover, 'name');
verifyConfigurable(cover, 'name');
}
29 changes: 29 additions & 0 deletions test/language/statements/using/fn-name-fn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Assignment of function `name` attribute (FunctionExpression)
info: |
LexicalBinding : BindingIdentifier Initializer

...
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
a. Let value be NamedEvaluation of Initializer with argument bindingId
includes: [propertyHelper.js]
features: [explicit-resource-management]
---*/

// NOTE: only way to verify is to patch `Function.prototype` so as not to trigger a TypeError from AddDisposableResource
Function.prototype[Symbol.dispose] = function () {}
{
using xFn = function x() {};
using fn = function() {};

assert(xFn.name !== 'xFn');

assert.sameValue(fn.name, 'fn');
verifyNotEnumerable(fn, 'name');
verifyNotWritable(fn, 'name');
verifyConfigurable(fn, 'name');
}
29 changes: 29 additions & 0 deletions test/language/statements/using/fn-name-gen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
description: Assignment of function `name` attribute (GeneratorExpression)
info: |
LexicalBinding : BindingIdentifier Initializer

...
3. If IsAnonymousFunctionDefinition(Initializer) is true, then
a. Let value be NamedEvaluation of Initializer with argument bindingId
includes: [propertyHelper.js]
features: [generators,explicit-resource-management]
---*/

// NOTE: only way to verify is to patch `Function.prototype` so as not to trigger a TypeError from AddDisposableResource
Function.prototype[Symbol.dispose] = function () {}
{
using xGen = function* x() {};
using gen = function*() {};

assert(xGen.name !== 'xGen');

assert.sameValue(gen.name, 'gen');
verifyNotEnumerable(gen, 'name');
verifyNotWritable(gen, 'name');
verifyConfigurable(gen, 'name');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2023 Ron Buckton. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-declarative-environment-records-getbindingvalue-n-s
description: >
using: function local closure [[Get]] before initialization.
(TDZ, Temporal Dead Zone)
features: [explicit-resource-management]
---*/

(function() {
function f() { return x + 1; }

assert.throws(ReferenceError, function() {
f();
});

using x = null;
}());
Loading