mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-16 07:13:45 -05:00
Fix early call to return/throw on generator (#51294)
This commit is contained in:
@@ -705,6 +705,8 @@ namespace ts {
|
||||
// - The verb (`next`, `throw`, or `return` method) to delegate to the expression
|
||||
// of a `yield*`.
|
||||
// - The result of evaluating the verb delegated to the expression of a `yield*`.
|
||||
// g A temporary variable that holds onto the generator object until the generator
|
||||
// is started, allowing it to also act as the `suspendedStart` state.
|
||||
//
|
||||
// functions:
|
||||
// verb(n) Creates a bound callback to the `step` function for opcode `n`.
|
||||
@@ -750,7 +752,7 @@ namespace ts {
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
"unittests/evaluation/externalModules.ts",
|
||||
"unittests/evaluation/forAwaitOf.ts",
|
||||
"unittests/evaluation/forOf.ts",
|
||||
"unittests/evaluation/generator.ts",
|
||||
"unittests/evaluation/optionalCall.ts",
|
||||
"unittests/evaluation/objectRest.ts",
|
||||
"unittests/evaluation/superInStaticInitializer.ts",
|
||||
|
||||
33
src/testRunner/unittests/evaluation/generator.ts
Normal file
33
src/testRunner/unittests/evaluation/generator.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
describe("unittests:: evaluation:: generatorEvaluation", () => {
|
||||
it("throw before start (es5)", () => {
|
||||
const { gen, output } = evaluator.evaluateTypeScript(`
|
||||
export const output: string[] = [];
|
||||
export function * gen() {
|
||||
output.push("start");
|
||||
yield 1;
|
||||
output.push("end");
|
||||
}
|
||||
`, { target: ts.ScriptTarget.ES5 });
|
||||
|
||||
const g = gen();
|
||||
const e = new Error();
|
||||
assert.throws(() => g.throw(e), e);
|
||||
assert.deepEqual(g.next(), { value: undefined, done: true });
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
it("return before start (es5)", () => {
|
||||
const { gen, output } = evaluator.evaluateTypeScript(`
|
||||
export const output: string[] = [];
|
||||
export function * gen() {
|
||||
output.push("start");
|
||||
yield 1;
|
||||
output.push("end");
|
||||
}
|
||||
`, { target: ts.ScriptTarget.ES5 });
|
||||
|
||||
const g = gen();
|
||||
assert.deepEqual(g.return(2), { value: 2, done: true });
|
||||
assert.deepEqual(g.next(), { value: undefined, done: true });
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user