mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Merge pull request #10883 from Microsoft/fix10876
Fix missing final label
This commit is contained in:
commit
7e33955fe7
@ -2629,7 +2629,7 @@ namespace ts {
|
||||
* Flush the final label of the generator function body.
|
||||
*/
|
||||
function flushFinalLabel(operationIndex: number): void {
|
||||
if (!lastOperationWasCompletion) {
|
||||
if (isFinalLabelReachable(operationIndex)) {
|
||||
tryEnterLabel(operationIndex);
|
||||
withBlockStack = undefined;
|
||||
writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
|
||||
@ -2642,6 +2642,34 @@ namespace ts {
|
||||
updateLabelExpressions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the final label of the generator function body
|
||||
* is reachable by user code.
|
||||
*/
|
||||
function isFinalLabelReachable(operationIndex: number) {
|
||||
// if the last operation was *not* a completion (return/throw) then
|
||||
// the final label is reachable.
|
||||
if (!lastOperationWasCompletion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if there are no labels defined or referenced, then the final label is
|
||||
// not reachable.
|
||||
if (!labelOffsets || !labelExpressions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the label for this offset is referenced, then the final label
|
||||
// is reachable.
|
||||
for (let label = 0; label < labelOffsets.length; label++) {
|
||||
if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a case clause for the last label and sets the new label.
|
||||
*
|
||||
|
||||
28
tests/baselines/reference/generatorTransformFinalLabel.js
Normal file
28
tests/baselines/reference/generatorTransformFinalLabel.js
Normal file
@ -0,0 +1,28 @@
|
||||
//// [generatorTransformFinalLabel.ts]
|
||||
async function test(skip: boolean) {
|
||||
if (!skip) {
|
||||
await 1
|
||||
}
|
||||
else {
|
||||
throw Error('test')
|
||||
}
|
||||
}
|
||||
|
||||
//// [generatorTransformFinalLabel.js]
|
||||
function test(skip) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!!skip)
|
||||
return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, 1];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 3];
|
||||
case 2: throw Error('test');
|
||||
case 3: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
=== tests/cases/compiler/generatorTransformFinalLabel.ts ===
|
||||
async function test(skip: boolean) {
|
||||
>test : Symbol(test, Decl(generatorTransformFinalLabel.ts, 0, 0))
|
||||
>skip : Symbol(skip, Decl(generatorTransformFinalLabel.ts, 0, 20))
|
||||
|
||||
if (!skip) {
|
||||
>skip : Symbol(skip, Decl(generatorTransformFinalLabel.ts, 0, 20))
|
||||
|
||||
await 1
|
||||
}
|
||||
else {
|
||||
throw Error('test')
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
20
tests/baselines/reference/generatorTransformFinalLabel.types
Normal file
20
tests/baselines/reference/generatorTransformFinalLabel.types
Normal file
@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/generatorTransformFinalLabel.ts ===
|
||||
async function test(skip: boolean) {
|
||||
>test : (skip: boolean) => Promise<void>
|
||||
>skip : boolean
|
||||
|
||||
if (!skip) {
|
||||
>!skip : boolean
|
||||
>skip : boolean
|
||||
|
||||
await 1
|
||||
>await 1 : 1
|
||||
>1 : 1
|
||||
}
|
||||
else {
|
||||
throw Error('test')
|
||||
>Error('test') : Error
|
||||
>Error : ErrorConstructor
|
||||
>'test' : "test"
|
||||
}
|
||||
}
|
||||
11
tests/cases/compiler/generatorTransformFinalLabel.ts
Normal file
11
tests/cases/compiler/generatorTransformFinalLabel.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// @target: es5
|
||||
// @lib: es5,es6
|
||||
// @noEmitHelpers: true
|
||||
async function test(skip: boolean) {
|
||||
if (!skip) {
|
||||
await 1
|
||||
}
|
||||
else {
|
||||
throw Error('test')
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user