mirror of
				https://github.com/tc39/test262.git
				synced 2025-11-04 05:33:50 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			1754 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1754 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Copyright 2017 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 assertThrowsAsync(run, errorType, message) {
 | 
						||
  var actual;
 | 
						||
  var hadValue = false;
 | 
						||
  var hadError = false;
 | 
						||
  var promise = run();
 | 
						||
 | 
						||
  if (typeof promise !== "object" || typeof promise.then !== "function") {
 | 
						||
    throw new MjsUnitAssertionError(
 | 
						||
        `Expected ${run.toString()} to return a Promise, but it returned ` +
 | 
						||
        PrettyPrint(promise));
 | 
						||
  }
 | 
						||
 | 
						||
  promise.then(function(value) { hadValue = true; actual = value; },
 | 
						||
               function(error) { hadError = true; actual = error; });
 | 
						||
 | 
						||
  assertFalse(hadValue || hadError);
 | 
						||
 | 
						||
  %RunMicrotasks();
 | 
						||
 | 
						||
  if (!hadError) {
 | 
						||
    throw new MjsUnitAssertionError(
 | 
						||
        "Expected " + run + "() to throw " + errorType.name +
 | 
						||
        ", but did not throw.");
 | 
						||
  }
 | 
						||
  if (!(actual instanceof errorType))
 | 
						||
    throw new MjsUnitAssertionError(
 | 
						||
        "Expected " + run + "() to throw " + errorType.name +
 | 
						||
        ", but threw '" + actual + "'");
 | 
						||
  if (message !== void 0 && actual.message !== message)
 | 
						||
    throw new MjsUnitAssertionError(
 | 
						||
        "Expected " + run + "() to throw '" + message + "', but threw '" +
 | 
						||
        actual.message + "'");
 | 
						||
};
 | 
						||
 | 
						||
function assertEqualsAsync(expected, run, msg) {
 | 
						||
  var actual;
 | 
						||
  var hadValue = false;
 | 
						||
  var hadError = false;
 | 
						||
  var promise = run();
 | 
						||
 | 
						||
  if (typeof promise !== "object" || typeof promise.then !== "function") {
 | 
						||
    throw new MjsUnitAssertionError(
 | 
						||
        `Expected ${run.toString()} to return a Promise, but it returned ` +
 | 
						||
        `${promise}`);
 | 
						||
  }
 | 
						||
 | 
						||
  promise.then(function(value) { hadValue = true; actual = value; },
 | 
						||
               function(error) { hadError = true; actual = error; });
 | 
						||
 | 
						||
  assertFalse(hadValue || hadError);
 | 
						||
 | 
						||
  %RunMicrotasks();
 | 
						||
 | 
						||
  if (hadError) throw actual;
 | 
						||
 | 
						||
  assertTrue(
 | 
						||
      hadValue, "Expected '" + run.toString() + "' to produce a value");
 | 
						||
 | 
						||
  assertEquals(expected, actual, msg);
 | 
						||
};
 | 
						||
 | 
						||
class MyError extends Error {};
 | 
						||
function Thrower(msg) { throw new MyError(msg); }
 | 
						||
function Rejecter(msg) {
 | 
						||
  return new Promise(function(resolve, reject) {
 | 
						||
    Promise.resolve().then(function() {
 | 
						||
      reject(new MyError(msg));
 | 
						||
    });
 | 
						||
  });
 | 
						||
}
 | 
						||
function Resolver(msg) {
 | 
						||
  return new Promise(function(resolve, reject) {
 | 
						||
    Promise.resolve().then(function() {
 | 
						||
      resolve(msg);
 | 
						||
    });
 | 
						||
  });
 | 
						||
}
 | 
						||
 | 
						||
async function ForAwaitOfValues(it) {
 | 
						||
  let array = [];
 | 
						||
  for await (let x of it) array.push(x);
 | 
						||
  return array;
 | 
						||
}
 | 
						||
 | 
						||
let log = [];
 | 
						||
function logIterResult(iter_result) {
 | 
						||
  log.push(iter_result);
 | 
						||
}
 | 
						||
function logError(error) {
 | 
						||
  log.push(error);
 | 
						||
}
 | 
						||
 | 
						||
function AbortUnreachable() {
 | 
						||
  %AbortJS("This code should not be reachable.");
 | 
						||
}
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Do not install `AsyncGeneratorFunction` constructor on global object
 | 
						||
assertEquals(undefined, this.AsyncGeneratorFunction);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
let AsyncGenerator = Object.getPrototypeOf(async function*() {});
 | 
						||
let AsyncGeneratorPrototype = AsyncGenerator.prototype;
 | 
						||
 | 
						||
// %AsyncGenerator% and %AsyncGeneratorPrototype% are both ordinary objects
 | 
						||
assertEquals("object", typeof AsyncGenerator);
 | 
						||
assertEquals("object", typeof AsyncGeneratorPrototype);
 | 
						||
 | 
						||
// %AsyncGenerator% <---> %AsyncGeneratorPrototype% circular reference
 | 
						||
assertEquals(AsyncGenerator, AsyncGeneratorPrototype.constructor);
 | 
						||
assertEquals(AsyncGeneratorPrototype, AsyncGenerator.prototype);
 | 
						||
 | 
						||
let protoDesc = Object.getOwnPropertyDescriptor(AsyncGenerator, 'prototype');
 | 
						||
assertFalse(protoDesc.enumerable);
 | 
						||
assertFalse(protoDesc.writable);
 | 
						||
assertTrue(protoDesc.configurable);
 | 
						||
 | 
						||
let ctorDesc =
 | 
						||
    Object.getOwnPropertyDescriptor(AsyncGeneratorPrototype, 'constructor');
 | 
						||
assertFalse(ctorDesc.enumerable);
 | 
						||
assertFalse(ctorDesc.writable);
 | 
						||
assertTrue(ctorDesc.configurable);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// The AsyncGeneratorFunction Constructor is the %AsyncGeneratorFunction%
 | 
						||
// intrinsic object and is a subclass of Function.
 | 
						||
// (proposal-async-iteration/#sec-asyncgeneratorfunction-constructor)
 | 
						||
let AsyncGeneratorFunction = AsyncGenerator.constructor;
 | 
						||
assertEquals(Object.getPrototypeOf(AsyncGeneratorFunction), Function);
 | 
						||
assertEquals(Object.getPrototypeOf(AsyncGeneratorFunction.prototype),
 | 
						||
             Function.prototype);
 | 
						||
assertTrue(async function*() {} instanceof Function);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Let functionPrototype be the intrinsic object %AsyncGeneratorPrototype%.
 | 
						||
async function* asyncGeneratorForProto() {}
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype,
 | 
						||
             Object.getPrototypeOf(asyncGeneratorForProto));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype,
 | 
						||
             Object.getPrototypeOf(async function*() {}));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype,
 | 
						||
             Object.getPrototypeOf({ async* method() {} }.method));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype,
 | 
						||
             Object.getPrototypeOf(AsyncGeneratorFunction()));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype,
 | 
						||
             Object.getPrototypeOf(new AsyncGeneratorFunction()));
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// AsyncGeneratorFunctionCreate produces a function whose prototype property is
 | 
						||
// derived from %AsyncGeneratorPrototype%
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype.prototype,
 | 
						||
             Object.getPrototypeOf(asyncGeneratorForProto.prototype));
 | 
						||
assertTrue(asyncGeneratorForProto.hasOwnProperty("prototype"));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype.prototype,
 | 
						||
             Object.getPrototypeOf((async function*() {}).prototype));
 | 
						||
assertTrue((async function*() {}).hasOwnProperty("prototype"));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype.prototype,
 | 
						||
             Object.getPrototypeOf(({ async* method() {} }).method.prototype));
 | 
						||
assertTrue(({ async* method() {} }).method.hasOwnProperty("prototype"));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype.prototype,
 | 
						||
             Object.getPrototypeOf(AsyncGeneratorFunction().prototype));
 | 
						||
assertTrue(AsyncGeneratorFunction().hasOwnProperty("prototype"));
 | 
						||
assertEquals(AsyncGeneratorFunction.prototype.prototype,
 | 
						||
             Object.getPrototypeOf(new AsyncGeneratorFunction().prototype));
 | 
						||
assertTrue(new AsyncGeneratorFunction().hasOwnProperty("prototype"));
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Basic Function.prototype.toString()
 | 
						||
async function* asyncGeneratorForToString() {}
 | 
						||
assertEquals("async function* asyncGeneratorForToString() {}",
 | 
						||
             asyncGeneratorForToString.toString());
 | 
						||
 | 
						||
assertEquals("async function*() {}", async function*() {}.toString());
 | 
						||
assertEquals("async function* namedAsyncGeneratorForToString() {}",
 | 
						||
             async function* namedAsyncGeneratorForToString() {}.toString());
 | 
						||
 | 
						||
assertEquals("async *method() { }",
 | 
						||
             ({ async *method() { } }).method.toString());
 | 
						||
assertEquals("async *method() { }",
 | 
						||
             (class { static async *method() { } }).method.toString());
 | 
						||
assertEquals("async *method() { }",
 | 
						||
             (new (class { async *method() { } })).method.toString());
 | 
						||
 | 
						||
assertEquals("async function* anonymous(\n) {\n\n}",
 | 
						||
             AsyncGeneratorFunction().toString());
 | 
						||
assertEquals("async function* anonymous(\n) {\n\n}",
 | 
						||
             (new AsyncGeneratorFunction()).toString());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// AsyncGenerator functions syntactically allow AwaitExpressions
 | 
						||
assertEquals(1, async function*(a) { await 1; }.length);
 | 
						||
assertEquals(2, async function*(a, b) { await 1; }.length);
 | 
						||
assertEquals(1, async function*(a, b = 2) { await 1; }.length);
 | 
						||
assertEquals(2, async function*(a, b, ...c) { await 1; }.length);
 | 
						||
 | 
						||
assertEquals(1, ({ async* f(a) { await 1; } }).f.length);
 | 
						||
assertEquals(2, ({ async* f(a, b) { await 1; } }).f.length);
 | 
						||
assertEquals(1, ({ async* f(a, b = 2) { await 1; } }).f.length);
 | 
						||
assertEquals(2, ({ async* f(a, b, ...c) { await 1; } }).f.length);
 | 
						||
 | 
						||
assertEquals(1, AsyncGeneratorFunction("a", "await 1").length);
 | 
						||
assertEquals(2, AsyncGeneratorFunction("a", "b", "await 1").length);
 | 
						||
assertEquals(1, AsyncGeneratorFunction("a", "b = 2", "await 1").length);
 | 
						||
assertEquals(2, AsyncGeneratorFunction("a", "b", "...c", "await 1").length);
 | 
						||
 | 
						||
assertEquals(1, (new AsyncGeneratorFunction("a", "await 1")).length);
 | 
						||
assertEquals(2, (new AsyncGeneratorFunction("a", "b", "await 1")).length);
 | 
						||
assertEquals(1, (new AsyncGeneratorFunction("a", "b = 2", "await 1")).length);
 | 
						||
assertEquals(2,
 | 
						||
             (new AsyncGeneratorFunction("a", "b", "...c", "await 1")).length);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// AsyncGenerator functions syntactically allow YieldExpressions
 | 
						||
assertEquals(1, async function*(a) { yield 1; }.length);
 | 
						||
assertEquals(2, async function*(a, b) { yield 1; }.length);
 | 
						||
assertEquals(1, async function*(a, b = 2) { yield 1; }.length);
 | 
						||
assertEquals(2, async function*(a, b, ...c) { yield 1; }.length);
 | 
						||
 | 
						||
assertEquals(1, ({ async* f(a) { yield 1; } }).f.length);
 | 
						||
assertEquals(2, ({ async* f(a, b) { yield 1; } }).f.length);
 | 
						||
assertEquals(1, ({ async* f(a, b = 2) { yield 1; } }).f.length);
 | 
						||
assertEquals(2, ({ async* f(a, b, ...c) { yield 1; } }).f.length);
 | 
						||
 | 
						||
assertEquals(1, AsyncGeneratorFunction("a", "yield 1").length);
 | 
						||
assertEquals(2, AsyncGeneratorFunction("a", "b", "yield 1").length);
 | 
						||
assertEquals(1, AsyncGeneratorFunction("a", "b = 2", "yield 1").length);
 | 
						||
assertEquals(2, AsyncGeneratorFunction("a", "b", "...c", "yield 1").length);
 | 
						||
 | 
						||
assertEquals(1, (new AsyncGeneratorFunction("a", "yield 1")).length);
 | 
						||
assertEquals(2, (new AsyncGeneratorFunction("a", "b", "yield 1")).length);
 | 
						||
assertEquals(1, (new AsyncGeneratorFunction("a", "b = 2", "yield 1")).length);
 | 
						||
assertEquals(2,
 | 
						||
             (new AsyncGeneratorFunction("a", "b", "...c", "yield 1")).length);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// AsyncGeneratorFunction.prototype[ @@toStringTag ]
 | 
						||
var descriptor =
 | 
						||
    Object.getOwnPropertyDescriptor(AsyncGeneratorFunction.prototype,
 | 
						||
                                    Symbol.toStringTag);
 | 
						||
assertEquals("AsyncGeneratorFunction", descriptor.value);
 | 
						||
assertEquals(false, descriptor.enumerable);
 | 
						||
assertEquals(false, descriptor.writable);
 | 
						||
assertEquals(true, descriptor.configurable);
 | 
						||
 | 
						||
assertEquals(1, AsyncGeneratorFunction.length);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor")
 | 
						||
async function* asyncNonConstructorDecl() {}
 | 
						||
assertThrows(() => new asyncNonConstructorDecl(), TypeError);
 | 
						||
assertThrows(() => asyncNonConstructorDecl.caller, TypeError);
 | 
						||
assertThrows(() => asyncNonConstructorDecl.arguments, TypeError);
 | 
						||
 | 
						||
assertThrows(() => new (async function*() {}), TypeError);
 | 
						||
assertThrows(() => (async function*() {}).caller, TypeError);
 | 
						||
assertThrows(() => (async function*() {}).arguments, TypeError);
 | 
						||
 | 
						||
assertThrows(
 | 
						||
    () => new ({ async* nonConstructor() {} }).nonConstructor(), TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => ({ async* nonConstructor() {} }).nonConstructor.caller, TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => ({ async* nonConstructor() {} }).nonConstructor.arguments, TypeError);
 | 
						||
 | 
						||
assertThrows(
 | 
						||
    () => new (AsyncGeneratorFunction("nonconstructor"))(), TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => AsyncGeneratorFunction("nonconstructor").caller, TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => AsyncGeneratorFunction("nonconstructor").arguments, TypeError);
 | 
						||
 | 
						||
assertThrows(
 | 
						||
    () => new (new AsyncGeneratorFunction("nonconstructor"))(), TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => (new AsyncGeneratorFunction("nonconstructor")).caller, TypeError);
 | 
						||
assertThrows(
 | 
						||
    () => (new AsyncGeneratorFunction("nonconstructor")).arguments, TypeError);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Empty functions
 | 
						||
async function* emptyAsyncGenerator() {}
 | 
						||
let it = emptyAsyncGenerator();
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function* emptyAsyncGeneratorExpr() { })();
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({ async* method() { } }).method();
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(``)();
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(``))();
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level ReturnStatement
 | 
						||
async function* asyncGeneratorForReturn() {
 | 
						||
  return "boop1";
 | 
						||
  throw "(unreachble)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturn();
 | 
						||
assertEqualsAsync({ value: "boop1", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  return "boop2";
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "boop2", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({ async* method() { return "boop3"; throw "(unreachable)"; } }).method();
 | 
						||
assertEqualsAsync({ value: "boop3", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(`
 | 
						||
  return "boop4";
 | 
						||
  throw "(unreachable)";`)();
 | 
						||
assertEqualsAsync({ value: "boop4", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  return "boop5";
 | 
						||
  throw "(unreachable)";`))();
 | 
						||
assertEqualsAsync({ value: "boop5", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level ReturnStatement after await
 | 
						||
async function* asyncGeneratorForReturnAfterAwait() {
 | 
						||
  await 1;
 | 
						||
  return "boop6";
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnAfterAwait();
 | 
						||
assertEqualsAsync({ value: "boop6", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() { await 1; return "boop7"; throw "(unreachable)"; })();
 | 
						||
assertEqualsAsync({ value: "boop7", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    await 1;
 | 
						||
    return "boop8";
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "boop8", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(`
 | 
						||
  await 1;
 | 
						||
  return "boop9";
 | 
						||
  throw "(unreachable)"`)();
 | 
						||
assertEqualsAsync({ value: "boop9", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  await 1;
 | 
						||
  return "boop10";
 | 
						||
  throw "(unreachable)"`))();
 | 
						||
assertEqualsAsync({ value: "boop10", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level Yields
 | 
						||
 | 
						||
async function* asyncGeneratorForYields() {
 | 
						||
  yield 1;
 | 
						||
  yield await Resolver(2);
 | 
						||
  yield Resolver(3);
 | 
						||
  return 4;
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
 | 
						||
it = asyncGeneratorForYields();
 | 
						||
assertEqualsAsync([1, 2, 3], () => ForAwaitOfValues(it));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  yield "cow";
 | 
						||
  yield await Resolver("bird");
 | 
						||
  yield await "dog";
 | 
						||
  yield Resolver("donkey");
 | 
						||
  return "badger";
 | 
						||
  throw "(unreachable)"; })();
 | 
						||
assertEqualsAsync(["cow", "bird", "dog", "donkey"], () => ForAwaitOfValues(it));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    yield "A";
 | 
						||
    yield await Resolver("B");
 | 
						||
    yield await "C";
 | 
						||
    yield Resolver("CC");
 | 
						||
    return "D";
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync(["A", "B", "C", "CC"], () => ForAwaitOfValues(it));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(`
 | 
						||
  yield "alpha";
 | 
						||
  yield await Resolver("beta");
 | 
						||
  yield await "gamma";
 | 
						||
  yield Resolver("delta");
 | 
						||
  return "epsilon";
 | 
						||
  throw "(unreachable)"`)();
 | 
						||
assertEqualsAsync(["alpha", "beta", "gamma", "delta"],
 | 
						||
                  () => ForAwaitOfValues(it));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  yield "α";
 | 
						||
  yield await Resolver("β");
 | 
						||
  yield await "γ";
 | 
						||
  yield Resolver("δ");
 | 
						||
  return "ε";
 | 
						||
  throw "(unreachable)"`))();
 | 
						||
assertEqualsAsync(["α", "β", "γ", "δ"], () => ForAwaitOfValues(it));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Nested Resume via [AsyncGenerator].next()
 | 
						||
log = [];
 | 
						||
async function* asyncGeneratorForNestedResumeNext() {
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  yield "rootbeer";
 | 
						||
  yield await Resolver("float");
 | 
						||
}
 | 
						||
it = asyncGeneratorForNestedResumeNext();
 | 
						||
it.next().then(logIterResult, AbortUnreachable);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "rootbeer", done: false },
 | 
						||
  { value: "float", done: false },
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorExprForNestedResumeNext = async function*() {
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  yield "first";
 | 
						||
  yield await Resolver("second");
 | 
						||
};
 | 
						||
it = asyncGeneratorExprForNestedResumeNext();
 | 
						||
it.next().then(logIterResult, AbortUnreachable);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "first", done: false },
 | 
						||
  { value: "second", done: false },
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorMethodForNestedResumeNext = ({
 | 
						||
  async* method() {
 | 
						||
    it.next().then(logIterResult, logError);
 | 
						||
    it.next().then(logIterResult, logError);
 | 
						||
    yield "remember";
 | 
						||
    yield await Resolver("the cant!");
 | 
						||
  }
 | 
						||
}).method;
 | 
						||
it = asyncGeneratorMethodForNestedResumeNext();
 | 
						||
it.next().then(logIterResult, AbortUnreachable);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "remember", done: false },
 | 
						||
  { value: "the cant!", done: false },
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorCallEvalForNestedResumeNext =
 | 
						||
    AsyncGeneratorFunction(`
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      yield "reading";
 | 
						||
      yield await Resolver("rainbow!");`);
 | 
						||
it = asyncGeneratorCallEvalForNestedResumeNext();
 | 
						||
it.next().then(logIterResult, AbortUnreachable);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "reading", done: false },
 | 
						||
  { value: "rainbow!", done: false },
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorNewEvalForNestedResumeNext =
 | 
						||
    new AsyncGeneratorFunction(`
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      yield 731;
 | 
						||
      yield await Resolver("BB!");`);
 | 
						||
it = asyncGeneratorNewEvalForNestedResumeNext();
 | 
						||
it.next().then(logIterResult, AbortUnreachable);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: 731, done: false },
 | 
						||
  { value: "BB!", done: false },
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Nested Resume via [AsyncGenerator].throw()
 | 
						||
log = [];
 | 
						||
async function* asyncGeneratorForNestedResumeThrow() {
 | 
						||
  try {
 | 
						||
    it.throw(await Rejecter("...")).then(logIterResult, logError);
 | 
						||
  } catch (e) {
 | 
						||
    it.throw("throw2").then(logIterResult, logError);
 | 
						||
    it.next().then(logIterResult, logError);
 | 
						||
    throw "throw1";
 | 
						||
  }
 | 
						||
  AbortUnreachable();
 | 
						||
}
 | 
						||
it = asyncGeneratorForNestedResumeThrow();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  "throw1",
 | 
						||
  "throw2",
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorExprForNestedResumeThrow = async function*() {
 | 
						||
  try {
 | 
						||
    it.throw(await Rejecter("...")).then(logIterResult, logError);
 | 
						||
  } catch (e) {
 | 
						||
    it.throw("throw4").then(logIterResult, logError);
 | 
						||
    it.next().then(logIterResult, logError);
 | 
						||
    throw "throw3";
 | 
						||
  }
 | 
						||
  AbortUnreachable();
 | 
						||
};
 | 
						||
it = asyncGeneratorExprForNestedResumeThrow();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  "throw3",
 | 
						||
  "throw4",
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorMethodForNestedResumeThrow = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      it.throw(await Rejecter("...")).then(logIterResult, logError);
 | 
						||
    } catch (e) {
 | 
						||
      it.throw("throw6").then(logIterResult, logError);
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      throw "throw5";
 | 
						||
    }
 | 
						||
    AbortUnreachable();
 | 
						||
  }
 | 
						||
}).method;
 | 
						||
it = asyncGeneratorMethodForNestedResumeThrow();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  "throw5",
 | 
						||
  "throw6",
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorCallEvalForNestedResumeThrow =
 | 
						||
    AsyncGeneratorFunction(`
 | 
						||
      try {
 | 
						||
        it.throw(await Rejecter("...")).then(logIterResult, logError);
 | 
						||
      } catch (e) {
 | 
						||
        it.throw("throw8").then(logIterResult, logError);
 | 
						||
        it.next().then(logIterResult, logError);
 | 
						||
        throw "throw7";
 | 
						||
      }
 | 
						||
      AbortUnreachable();`);
 | 
						||
it = asyncGeneratorCallEvalForNestedResumeThrow();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  "throw7",
 | 
						||
  "throw8",
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorNewEvalForNestedResumeThrow =
 | 
						||
    new AsyncGeneratorFunction(`
 | 
						||
      try {
 | 
						||
        it.throw(await Rejecter("...")).then(logIterResult, logError);
 | 
						||
      } catch (e) {
 | 
						||
        it.throw("throw10").then(logIterResult, logError);
 | 
						||
        it.next().then(logIterResult, logError);
 | 
						||
        throw "throw9";
 | 
						||
      }
 | 
						||
      AbortUnreachable();`);
 | 
						||
it = asyncGeneratorNewEvalForNestedResumeThrow();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  "throw9",
 | 
						||
  "throw10",
 | 
						||
  { value: undefined, done: true }
 | 
						||
], log);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Nested Resume via [AsyncGenerator].return()
 | 
						||
log = [];
 | 
						||
async function* asyncGeneratorForNestedResumeReturn() {
 | 
						||
  it.return("step2").then(logIterResult, logError);
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  yield "step1";
 | 
						||
  AbortUnreachable();
 | 
						||
}
 | 
						||
it = asyncGeneratorForNestedResumeReturn();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "step1", done: false },
 | 
						||
  { value: "step2", done: true },
 | 
						||
  { value: undefined, done: true },
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorExprForNestedResumeReturn = async function*() {
 | 
						||
  it.return("step4").then(logIterResult, logError);
 | 
						||
  it.next().then(logIterResult, logError);
 | 
						||
  yield "step3";
 | 
						||
};
 | 
						||
it = asyncGeneratorExprForNestedResumeReturn();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "step3", done: false },
 | 
						||
  { value: "step4", done: true },
 | 
						||
  { value: undefined, done: true },
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorMethodForNestedResumeReturn = ({
 | 
						||
  async* method() {
 | 
						||
    it.return("step6").then(logIterResult, logError);
 | 
						||
    it.next().then(logIterResult, logError);
 | 
						||
    yield "step5";
 | 
						||
  }
 | 
						||
}).method;
 | 
						||
it = asyncGeneratorMethodForNestedResumeReturn();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "step5", done: false },
 | 
						||
  { value: "step6", done: true },
 | 
						||
  { value: undefined, done: true },
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorCallEvalForNestedResumeReturn =
 | 
						||
    AsyncGeneratorFunction(`
 | 
						||
      it.return("step8").then(logIterResult, logError);
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      yield "step7";`);
 | 
						||
it = asyncGeneratorCallEvalForNestedResumeReturn();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "step7", done: false },
 | 
						||
  { value: "step8", done: true },
 | 
						||
  { value: undefined, done: true },
 | 
						||
], log);
 | 
						||
 | 
						||
log = [];
 | 
						||
let asyncGeneratorNewEvalForNestedResumeReturn =
 | 
						||
    new AsyncGeneratorFunction(`
 | 
						||
      it.return("step10").then(logIterResult, logError);
 | 
						||
      it.next().then(logIterResult, logError);
 | 
						||
      yield "step9";`);
 | 
						||
it = asyncGeneratorNewEvalForNestedResumeReturn();
 | 
						||
it.next().then(logIterResult, logError);
 | 
						||
%RunMicrotasks();
 | 
						||
assertEquals([
 | 
						||
  { value: "step9", done: false },
 | 
						||
  { value: "step10", done: true },
 | 
						||
  { value: undefined, done: true },
 | 
						||
], log);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level Yield ThrowStatement
 | 
						||
 | 
						||
async function* asyncGeneratorForYieldThrow() {
 | 
						||
  yield await Thrower("OOPS1");
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForYieldThrow();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() { yield Thrower("OOPS2"); throw "(unreachable)"; })();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    yield Thrower("OOPS3");
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(`
 | 
						||
  yield Thrower("OOPS4");
 | 
						||
  throw "(unreachable)"`)();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  yield Thrower("OOPS5");
 | 
						||
  throw "(unreachable)"`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level Yield Awaited Rejection
 | 
						||
async function* asyncGeneratorForYieldAwaitedRejection() {
 | 
						||
  yield await Rejecter("OOPS1");
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForYieldAwaitedRejection();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  yield await Rejecter("OOPS2");
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    yield await Rejecter("OOPS3");
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = AsyncGeneratorFunction(`
 | 
						||
  yield await Rejecter("OOPS4");
 | 
						||
  throw "(unreachable)"`)();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  yield await Rejecter("OOPS5");
 | 
						||
  throw "(unreachable)"`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "OOPS5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level ThrowStatement
 | 
						||
async function* asyncGeneratorForThrow() {
 | 
						||
  throw new MyError("BOOM1");
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrow();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  throw new MyError("BOOM2");
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    throw new MyError("BOOM3");
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  throw new MyError("BOOM4");
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  throw new MyError("BOOM5");
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level ThrowStatement after Await
 | 
						||
async function* asyncGeneratorForThrowAfterAwait() {
 | 
						||
  await 1;
 | 
						||
  throw new MyError("BOOM6");
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrowAfterAwait();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM6");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  await 1;
 | 
						||
  throw new MyError("BOOM7");
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM7");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    await 1;
 | 
						||
    throw new MyError("BOOM8");
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM8");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  await 1;
 | 
						||
  throw new MyError("BOOM9");
 | 
						||
  throw "(unreachable)";`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM9");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  await 1;
 | 
						||
  throw new MyError("BOOM10");
 | 
						||
  throw "(unreachable)";`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM10");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Top-level Awaited rejection
 | 
						||
async function* asyncGeneratorForAwaitedRejection() {
 | 
						||
  await Rejecter("BOOM11");
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForAwaitedRejection();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM11");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  await Rejecter("BOOM12");
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM12");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    await Rejecter("BOOM13");
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM13");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  await Rejecter("BOOM14");
 | 
						||
  throw "(unreachable)";`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM14");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (new AsyncGeneratorFunction(`
 | 
						||
  await Rejecter("BOOM15");
 | 
						||
  throw "(unreachable)";`))();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM15");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Caught ThrowStatement
 | 
						||
async function* asyncGeneratorForCaughtThrow() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  } catch (e) {
 | 
						||
    return "caught1";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForCaughtThrow();
 | 
						||
assertEqualsAsync({ value: "caught1", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  } catch (e) {
 | 
						||
    return "caught2";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "caught2", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    } catch (e) {
 | 
						||
      return "caught3";
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "caught3", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  } catch (e) {
 | 
						||
    return "caught4";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "caught4", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  } catch (e) {
 | 
						||
    return "caught5";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "caught5", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Caught ThrowStatement and rethrow
 | 
						||
async function* asyncGeneratorForCaughtRethrow() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  } catch (e) {
 | 
						||
    throw new MyError("RETHROW1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForCaughtRethrow();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "RETHROW1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  } catch (e) {
 | 
						||
    throw new MyError("RETHROW2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "RETHROW2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    } catch (e) {
 | 
						||
      throw new MyError("RETHROW3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "RETHROW3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  } catch (e) {
 | 
						||
    throw new MyError("RETHROW4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "RETHROW4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  } catch (e) {
 | 
						||
    throw new MyError("RETHROW5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "RETHROW5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ReturnStatement in Try, ReturnStatement in Finally
 | 
						||
async function* asyncGeneratorForReturnInTryReturnInFinally() {
 | 
						||
  try {
 | 
						||
    return "early1"
 | 
						||
  } finally {
 | 
						||
    return "later1";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnInTryReturnInFinally();
 | 
						||
assertEqualsAsync({ value: "later1", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    return "early2";
 | 
						||
  } finally {
 | 
						||
    return "later2";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "later2", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      return "early3";
 | 
						||
    } finally {
 | 
						||
      return "later3";
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "later3", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early4";
 | 
						||
  } finally {
 | 
						||
    return "later4";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later4", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early5";
 | 
						||
  } finally {
 | 
						||
    return "later5";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later5", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ThrowStatement in Try, ReturnStatement in Finally
 | 
						||
async function* asyncGeneratorForThrowInTryReturnInFinally() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  } finally {
 | 
						||
    return "later1";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrowInTryReturnInFinally();
 | 
						||
assertEqualsAsync({ value: "later1", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  } finally {
 | 
						||
    return "later2";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "later2", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    } finally {
 | 
						||
      return "later3";
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "later3", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  } finally {
 | 
						||
    return "later4";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later4", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  } finally {
 | 
						||
    return "later5";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later5", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Awaited Rejection in Try, ReturnStatement in Finally
 | 
						||
async function* asyncGeneratorForAwaitRejectionInTryReturnInFinally() {
 | 
						||
  try {
 | 
						||
    await Rejecter("BOOM1");
 | 
						||
  } finally {
 | 
						||
    return "later1";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrowInTryReturnInFinally();
 | 
						||
assertEqualsAsync({ value: "later1", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    await Rejecter("BOOM2");
 | 
						||
  } finally {
 | 
						||
    return "later2";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "later2", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      await Rejecter("BOOM3");
 | 
						||
    } finally {
 | 
						||
      return "later3";
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "later3", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("BOOM4");
 | 
						||
  } finally {
 | 
						||
    return "later4";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later4", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("BOOM5");
 | 
						||
  } finally {
 | 
						||
    return "later5";
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertEqualsAsync({ value: "later5", done: true }, () => it.next());
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ReturnStatement in Try, ThrowStatement in Finally
 | 
						||
async function* asyncGeneratorForReturnInTryThrowInFinally() {
 | 
						||
  try {
 | 
						||
    return "early1"
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnInTryThrowInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    return "early2";
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      return "early3";
 | 
						||
    } finally {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early4";
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early5";
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ThrowStatement in Try, ThrowStatement in Finally
 | 
						||
 | 
						||
async function* asyncGeneratorForThrowInTryThrowInFinally() {
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY1");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrowInTryThrowInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY2");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      throw new MyError("EARLY3");
 | 
						||
    } finally {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY4");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY5");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Awaited Rejection in Try, ThrowStatement in Finally
 | 
						||
 | 
						||
async function* asyncGeneratorForAwaitedRejectInTryThrowInFinally() {
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY1");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForAwaitedRejectInTryThrowInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY2");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      await Rejecter("EARLY3");
 | 
						||
    } finally {
 | 
						||
      throw new MyError("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY4");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY5");
 | 
						||
  } finally {
 | 
						||
    throw new MyError("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ReturnStatement in Try, Awaited Rejection in Finally
 | 
						||
async function* asyncGeneratorForReturnInTryAwaitedRejectionInFinally() {
 | 
						||
  try {
 | 
						||
    return "early1"
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnInTryAwaitedRejectionInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    return "early2";
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      return "early3";
 | 
						||
    } finally {
 | 
						||
      await Rejecter("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early4";
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    return "early5";
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// ThrowStatement in Try, Awaited Rejection in Finally
 | 
						||
 | 
						||
async function* asyncGeneratorForThrowInTryAwaitedRejectionInFinally() {
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY1");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForThrowInTryAwaitedRejectionInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY2");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      throw new MyError("EARLY3");
 | 
						||
    } finally {
 | 
						||
      await Rejecter("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY4");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    throw new MyError("EARLY5");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Awaited Rejection in Try, Awaited Rejection in Finally
 | 
						||
 | 
						||
async function* asyncGeneratorForAwaitedRejectInTryAwaitedRejectionInFinally() {
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY1");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM1");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
}
 | 
						||
it = asyncGeneratorForAwaitedRejectInTryAwaitedRejectionInFinally();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY2");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM2");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    try {
 | 
						||
      await Rejecter("EARLY3");
 | 
						||
    } finally {
 | 
						||
      await Rejecter("BOOM3");
 | 
						||
    }
 | 
						||
    throw "(unreachable)";
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY4");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM4");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`
 | 
						||
  try {
 | 
						||
    await Rejecter("EARLY5");
 | 
						||
  } finally {
 | 
						||
    await Rejecter("BOOM5");
 | 
						||
  }
 | 
						||
  throw "(unreachable)";`))()
 | 
						||
assertThrowsAsync(() => it.next(), MyError, "BOOM5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Early errors during parameter initialization
 | 
						||
 | 
						||
async function* asyncGeneratorForParameterInitializationErrors(
 | 
						||
    [...a], b = c, d) {
 | 
						||
  AbortUnreachable();
 | 
						||
}
 | 
						||
assertThrows(() => asyncGeneratorForParameterInitializationErrors(null),
 | 
						||
             TypeError);
 | 
						||
assertThrows(() => asyncGeneratorForParameterInitializationErrors([]),
 | 
						||
             ReferenceError);
 | 
						||
 | 
						||
let asyncGeneratorExprForParameterInitializationErrors =
 | 
						||
    async function*([...a], b = c, d) {
 | 
						||
      AbortUnreachable();
 | 
						||
    };
 | 
						||
assertThrows(() => asyncGeneratorExprForParameterInitializationErrors(null),
 | 
						||
             TypeError);
 | 
						||
assertThrows(() => asyncGeneratorExprForParameterInitializationErrors([]),
 | 
						||
             ReferenceError);
 | 
						||
 | 
						||
let asyncGeneratorMethodForParameterInitializationErrors = ({
 | 
						||
  async* method([...a], b = c, d) {
 | 
						||
    AbortUnreachable();
 | 
						||
  }
 | 
						||
}).method;
 | 
						||
assertThrows(() => asyncGeneratorMethodForParameterInitializationErrors(null),
 | 
						||
             TypeError);
 | 
						||
assertThrows(() => asyncGeneratorMethodForParameterInitializationErrors([]),
 | 
						||
             ReferenceError);
 | 
						||
 | 
						||
let asyncGeneratorCallEvalForParameterInitializationErrors =
 | 
						||
    AsyncGeneratorFunction("[...a], b = c, d", `AbortUnreachable();`);
 | 
						||
assertThrows(() => asyncGeneratorCallEvalForParameterInitializationErrors(null),
 | 
						||
             TypeError);
 | 
						||
assertThrows(() => asyncGeneratorCallEvalForParameterInitializationErrors([]),
 | 
						||
             ReferenceError);
 | 
						||
 | 
						||
let asyncGeneratorNewEvalForParameterInitializationErrors =
 | 
						||
    new AsyncGeneratorFunction("[...a], b = c, d",
 | 
						||
                               `AbortUnreachable();`);
 | 
						||
assertThrows(() => asyncGeneratorNewEvalForParameterInitializationErrors(null),
 | 
						||
             TypeError);
 | 
						||
assertThrows(() => asyncGeneratorNewEvalForParameterInitializationErrors([]),
 | 
						||
             ReferenceError);
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Invoke [AsyncGenerator].return() when generator is in state suspendedStart
 | 
						||
 | 
						||
async function* asyncGeneratorForReturnSuspendedStart() {
 | 
						||
  AbortUnreachable();
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnSuspendedStart();
 | 
						||
assertEqualsAsync({ value: "ret1", done: true }, () => it.return("ret1"));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  AbortUnreachable();
 | 
						||
})();
 | 
						||
assertEqualsAsync({ value: "ret2", done: true }, () => it.return("ret2"));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    AbortUnreachable();
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertEqualsAsync({ value: "ret3", done: true }, () => it.return("ret3"));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`AbortUnreachable();`))();
 | 
						||
assertEqualsAsync({ value: "ret4", done: true }, () => it.return("ret4"));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`AbortUnreachable();`))();
 | 
						||
assertEqualsAsync({ value: "ret5", done: true }, () => it.return("ret5"));
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Invoke [AsyncGenerator].throw() when generator is in state suspendedStart
 | 
						||
 | 
						||
async function* asyncGeneratorForThrowSuspendedStart() {
 | 
						||
  AbortUnreachable();
 | 
						||
}
 | 
						||
it = asyncGeneratorForReturnSuspendedStart();
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("throw1")), MyError, "throw1");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (async function*() {
 | 
						||
  AbortUnreachable();
 | 
						||
})();
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("throw2")), MyError, "throw2");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = ({
 | 
						||
  async* method() {
 | 
						||
    AbortUnreachable();
 | 
						||
  }
 | 
						||
}).method();
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("throw3")), MyError, "throw3");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`AbortUnreachable()`))();
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("throw4")), MyError, "throw4");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
it = (AsyncGeneratorFunction(`AbortUnreachable();`))();
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("throw5")), MyError, "throw5");
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next("x"));
 | 
						||
assertEqualsAsync({ value: "nores", done: true },
 | 
						||
                  () => it.return("nores"));
 | 
						||
assertThrowsAsync(() => it.throw(new MyError("nores")), MyError, "nores");
 | 
						||
 | 
						||
// ----------------------------------------------------------------------------
 | 
						||
// Simple yield*:
 | 
						||
 | 
						||
log = [];
 | 
						||
async function* asyncGeneratorYieldStar1() {
 | 
						||
  yield* {
 | 
						||
    get [Symbol.asyncIterator]() {
 | 
						||
      log.push({ name: "get @@asyncIterator" });
 | 
						||
      return (...args) => {
 | 
						||
        log.push({ name: "call @@asyncIterator", args });
 | 
						||
        return this;
 | 
						||
      };
 | 
						||
    },
 | 
						||
    get [Symbol.iterator]() {
 | 
						||
      log.push({ name: "get @@iterator" });
 | 
						||
      return (...args) => {
 | 
						||
        log.push({ name: "call @@iterator", args });
 | 
						||
        return this;
 | 
						||
      }
 | 
						||
    },
 | 
						||
    get next() {
 | 
						||
      log.push({ name: "get next" });
 | 
						||
      return (...args) => {
 | 
						||
        log.push({ name: "call next", args });
 | 
						||
        return {
 | 
						||
          get then() {
 | 
						||
            log.push({ name: "get then" });
 | 
						||
            return null;
 | 
						||
          },
 | 
						||
          get value() {
 | 
						||
            log.push({ name: "get value" });
 | 
						||
            throw (exception = new MyError("AbruptValue!"));
 | 
						||
          },
 | 
						||
          get done() {
 | 
						||
            log.push({ name: "get done" });
 | 
						||
            return false;
 | 
						||
          }
 | 
						||
        };
 | 
						||
      }
 | 
						||
    },
 | 
						||
    get return() {
 | 
						||
      log.push({ name: "get return" });
 | 
						||
      return (...args) => {
 | 
						||
        log.push({ name: "call return", args });
 | 
						||
        return { value: args[0], done: true };
 | 
						||
      }
 | 
						||
    },
 | 
						||
    get throw() {
 | 
						||
      log.push({ name: "get throw" });
 | 
						||
      return (...args) => {
 | 
						||
        log.push({ name: "call throw", args });
 | 
						||
        throw args[0];
 | 
						||
      };
 | 
						||
    },
 | 
						||
  };
 | 
						||
}
 | 
						||
 | 
						||
it = asyncGeneratorYieldStar1();
 | 
						||
assertThrowsAsync(() => it.next(), MyError);
 | 
						||
assertEquals([
 | 
						||
  { name: "get @@asyncIterator" },
 | 
						||
  { name: "call @@asyncIterator", args: [] },
 | 
						||
  { name: "get next" },
 | 
						||
  { name: "call next", args: [undefined] },
 | 
						||
  { name: "get then" },
 | 
						||
  { name: "get done" },
 | 
						||
  { name: "get value" },
 | 
						||
], log);
 | 
						||
assertEqualsAsync({ value: undefined, done: true }, () => it.next());
 |