Skip to content

Commit 3c6180f

Browse files
authored
[explicit-resource-management] Add remaining tests specific to await using statement semantics (#4480)
* Add remaining tests specific to await-using semantics * Disallow 'using' in 'switch' * Fix 'await using' use-before-init tests * Fix lint errors
1 parent ef784a8 commit 3c6180f

59 files changed

Lines changed: 3583 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
6+
description: Invokes [Symbol.asyncDispose] getter
7+
info: |
8+
RS: Evaluation
9+
AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList ;
10+
11+
1. Perform ? BindingEvaluation of BindingList with argument async-dispose.
12+
2. Return empty.
13+
14+
RS: BindingEvaluation
15+
LexicalBinding : BindingIdentifier Initializer
16+
17+
...
18+
5. Return ? InitializeReferencedBinding(lhs, value, hint).
19+
20+
InitializeReferencedBinding ( V, W )
21+
22+
...
23+
4. Return ? base.InitializeBinding(V.[[ReferencedName]], W).
24+
25+
InitializeBinding ( N, V, hint )
26+
27+
...
28+
2. If hint is not normal, perform ? AddDisposableResource(envRec.[[DisposeCapability]], V, hint).
29+
...
30+
31+
AddDisposableResource ( disposeCapability, V, hint [, method ] )
32+
33+
1. If method is not present then,
34+
a. If V is either null or undefined and hint is sync-dispose, then
35+
i. Return unused.
36+
b. Let resource be ? CreateDisposableResource(V, hint).
37+
2. Else,
38+
...
39+
3. Append resource to disposeCapability.[[DisposableResourceStack]].
40+
4. Return unused.
41+
42+
CreateDisposableResource ( V, hint [ , method ] )
43+
44+
1. If method is not present, then
45+
a. If V is either null or undefined, then
46+
...
47+
b. Else,
48+
i. If V is not an Object, throw a TypeError exception.
49+
ii. Set method to ? GetDisposeMethod(V, hint).
50+
iii. If method is undefined, throw a TypeError exception.
51+
...
52+
53+
GetDisposeMethod ( V, hint )
54+
55+
1. If hint is async-dispose, then
56+
a. Let method be ? GetMethod(V, @@asyncDispose).
57+
b. If method is undefined, then
58+
i. Set method to ? GetMethod(V, @@dispose).
59+
2. Else,
60+
a. Let method be ? GetMethod(V, @@dispose).
61+
3. Return method.
62+
63+
GetMethod ( V, P )
64+
65+
1. Let func be ? GetV(V, P).
66+
2. If func is either undefined or null, return undefined.
67+
3. ...
68+
69+
flags: [async]
70+
includes: [asyncHelpers.js]
71+
features: [explicit-resource-management]
72+
---*/
73+
74+
asyncTest(async function () {
75+
var resource = {
76+
disposed: false,
77+
get [Symbol.asyncDispose]() {
78+
return async function () {
79+
this.disposed = true;
80+
};
81+
}
82+
};
83+
84+
{
85+
await using _ = resource;
86+
}
87+
88+
assert.sameValue(resource.disposed, true, 'Expected resource to have been disposed');
89+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-block-runtime-semantics-evaluation
6+
description: Initialized value is disposed with the correct 'this' value
7+
info: |
8+
RS: Evaluation
9+
Block : { StatementList }
10+
11+
...
12+
5. Let blockValue be the result of evaluating StatementList.
13+
6. Set blockValue to DisposeResources(blockEnv.[[DisposeCapability]], blockValue).
14+
...
15+
16+
DisposeResources ( disposeCapability, completion )
17+
18+
1. For each resource of disposeCapability.[[DisposableResourceStack]], in reverse list order, do
19+
a. Let result be Dispose(resource.[[ResourceValue]], resource.[[Hint]], resource.[[DisposeMethod]]).
20+
b. If result.[[Type]] is throw, then
21+
i. If completion.[[Type]] is throw, then
22+
1. Set result to result.[[Value]].
23+
2. Let suppressed be completion.[[Value]].
24+
3. Let error be a newly created SuppressedError object.
25+
4. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "error", result).
26+
5. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "suppressed", suppressed).
27+
6. Set completion to ThrowCompletion(error).
28+
ii. Else,
29+
1. Set completion to result.
30+
2. Return completion.
31+
32+
Dispose ( V, hint, method )
33+
34+
1. If method is undefined, let result be undefined.
35+
2. Else, let result be ? Call(method, V).
36+
...
37+
38+
flags: [async]
39+
includes: [asyncHelpers.js]
40+
features: [explicit-resource-management]
41+
---*/
42+
43+
asyncTest(async function () {
44+
var resource = {
45+
disposed: false,
46+
async [Symbol.asyncDispose]() {
47+
assert.sameValue(this, resource);
48+
}
49+
};
50+
51+
{
52+
await using _ = resource;
53+
}
54+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-block-runtime-semantics-evaluation
6+
description: Disposal succeeds even if [Symbol.disposeAsync] does not return a Promise.
7+
info: |
8+
RS: Evaluation
9+
Block : { StatementList }
10+
11+
...
12+
5. Let blockValue be the result of evaluating StatementList.
13+
6. Set blockValue to DisposeResources(blockEnv.[[DisposeCapability]], blockValue).
14+
...
15+
16+
DisposeResources ( disposeCapability, completion )
17+
18+
1. For each resource of disposeCapability.[[DisposableResourceStack]], in reverse list order, do
19+
a. Let result be Dispose(resource.[[ResourceValue]], resource.[[Hint]], resource.[[DisposeMethod]]).
20+
b. If result.[[Type]] is throw, then
21+
i. If completion.[[Type]] is throw, then
22+
1. Set result to result.[[Value]].
23+
2. Let suppressed be completion.[[Value]].
24+
3. Let error be a newly created SuppressedError object.
25+
4. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "error", result).
26+
5. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "suppressed", suppressed).
27+
6. Set completion to ThrowCompletion(error).
28+
ii. Else,
29+
1. Set completion to result.
30+
2. Return completion.
31+
32+
Dispose ( V, hint, method )
33+
34+
1. If method is undefined, let result be undefined.
35+
2. Else, let result be ? Call(method, V).
36+
3. If hint is async-dispose, then
37+
a. ...
38+
4. Return undefined.
39+
40+
flags: [async]
41+
includes: [asyncHelpers.js]
42+
features: [explicit-resource-management]
43+
---*/
44+
45+
asyncTest(async function () {
46+
var resource = {
47+
disposed: false,
48+
[Symbol.asyncDispose]() {
49+
this.disposed = true;
50+
}
51+
};
52+
53+
{
54+
await using _ = resource;
55+
}
56+
57+
assert.sameValue(resource.disposed, true, 'Expected resource to have been disposed');
58+
});
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-let-and-const-declarations-runtime-semantics-evaluation
6+
description: Invokes [Symbol.dispose] getter
7+
info: |
8+
RS: Evaluation
9+
AwaitUsingDeclaration : CoverAwaitExpressionAndAwaitUsingDeclarationHead BindingList ;
10+
11+
1. Perform ? BindingEvaluation of BindingList with argument async-dispose.
12+
2. Return empty.
13+
14+
RS: BindingEvaluation
15+
LexicalBinding : BindingIdentifier Initializer
16+
17+
...
18+
5. Return ? InitializeReferencedBinding(lhs, value, hint).
19+
20+
InitializeReferencedBinding ( V, W )
21+
22+
...
23+
4. Return ? base.InitializeBinding(V.[[ReferencedName]], W).
24+
25+
InitializeBinding ( N, V, hint )
26+
27+
...
28+
2. If hint is not normal, perform ? AddDisposableResource(envRec.[[DisposeCapability]], V, hint).
29+
...
30+
31+
AddDisposableResource ( disposeCapability, V, hint [, method ] )
32+
33+
1. If method is not present then,
34+
a. If V is either null or undefined and hint is sync-dispose, then
35+
i. Return unused.
36+
b. Let resource be ? CreateDisposableResource(V, hint).
37+
2. Else,
38+
...
39+
3. Append resource to disposeCapability.[[DisposableResourceStack]].
40+
4. Return unused.
41+
42+
CreateDisposableResource ( V, hint [ , method ] )
43+
44+
1. If method is not present, then
45+
a. If V is either null or undefined, then
46+
...
47+
b. Else,
48+
i. If V is not an Object, throw a TypeError exception.
49+
ii. Set method to ? GetDisposeMethod(V, hint).
50+
iii. If method is undefined, throw a TypeError exception.
51+
...
52+
53+
GetDisposeMethod ( V, hint )
54+
55+
1. If hint is async-dispose, then
56+
a. Let method be ? GetMethod(V, @@asyncDispose).
57+
b. If method is undefined, then
58+
i. Set method to ? GetMethod(V, @@dispose).
59+
2. Else,
60+
a. Let method be ? GetMethod(V, @@dispose).
61+
3. Return method.
62+
63+
GetMethod ( V, P )
64+
65+
1. Let func be ? GetV(V, P).
66+
2. If func is either undefined or null, return undefined.
67+
3. ...
68+
69+
flags: [async]
70+
includes: [asyncHelpers.js]
71+
features: [explicit-resource-management]
72+
---*/
73+
74+
asyncTest(async function () {
75+
var resource = {
76+
disposed: false,
77+
get [Symbol.dispose]() {
78+
return function() {
79+
this.disposed = true;
80+
};
81+
}
82+
};
83+
84+
{
85+
await using _ = resource;
86+
}
87+
88+
assert.sameValue(resource.disposed, true, 'Expected resource to have been disposed');
89+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-block-runtime-semantics-evaluation
6+
description: Initialized value is disposed with the correct 'this' value
7+
info: |
8+
RS: Evaluation
9+
Block : { StatementList }
10+
11+
...
12+
5. Let blockValue be the result of evaluating StatementList.
13+
6. Set blockValue to DisposeResources(blockEnv.[[DisposeCapability]], blockValue).
14+
...
15+
16+
DisposeResources ( disposeCapability, completion )
17+
18+
1. For each resource of disposeCapability.[[DisposableResourceStack]], in reverse list order, do
19+
a. Let result be Dispose(resource.[[ResourceValue]], resource.[[Hint]], resource.[[DisposeMethod]]).
20+
b. If result.[[Type]] is throw, then
21+
i. If completion.[[Type]] is throw, then
22+
1. Set result to result.[[Value]].
23+
2. Let suppressed be completion.[[Value]].
24+
3. Let error be a newly created SuppressedError object.
25+
4. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "error", result).
26+
5. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "suppressed", suppressed).
27+
6. Set completion to ThrowCompletion(error).
28+
ii. Else,
29+
1. Set completion to result.
30+
2. Return completion.
31+
32+
Dispose ( V, hint, method )
33+
34+
1. If method is undefined, let result be undefined.
35+
2. Else, let result be ? Call(method, V).
36+
...
37+
38+
flags: [async]
39+
includes: [asyncHelpers.js]
40+
features: [explicit-resource-management]
41+
---*/
42+
43+
asyncTest(async function() {
44+
var resource = {
45+
disposed: false,
46+
[Symbol.dispose]() {
47+
assert.sameValue(this, resource);
48+
}
49+
};
50+
51+
{
52+
await using _ = resource;
53+
}
54+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-disposeresources
6+
description: >
7+
`await using` allows a non-Promise return value from `[Symbol.asyncDispose]()`
8+
info: |
9+
DisposeResources ( disposeCapability, completion )
10+
11+
1. For each resource of disposeCapability.[[DisposableResourceStack]], in reverse list order, do
12+
a. Let result be Dispose(resource.[[ResourceValue]], resource.[[Hint]], resource.[[DisposeMethod]]).
13+
b. If result.[[Type]] is throw, then
14+
i. If completion.[[Type]] is throw, then
15+
1. Set result to result.[[Value]].
16+
2. Let suppressed be completion.[[Value]].
17+
3. Let error be a newly created SuppressedError object.
18+
4. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "error", result).
19+
5. Perform ! CreateNonEnumerableDataPropertyOrThrow(error, "suppressed", suppressed).
20+
6. Set completion to ThrowCompletion(error).
21+
ii. Else,
22+
1. Set completion to result.
23+
2. Return completion.
24+
25+
Dispose ( V, hint, method )
26+
27+
1. If method is undefined, let result be undefined.
28+
2. Else, let result be ? Call(method, V).
29+
3. If hint is async-dispose, then
30+
a. Perform ? Await(result).
31+
4. Return undefined.
32+
33+
flags: [async]
34+
includes: [asyncHelpers.js]
35+
features: [explicit-resource-management]
36+
---*/
37+
38+
asyncTest(async function () {
39+
var resource = {
40+
[Symbol.asyncDispose]() {
41+
}
42+
};
43+
44+
{
45+
await using _ = resource;
46+
}
47+
});

0 commit comments

Comments
 (0)