mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-13 11:46:08 -05:00
Disallow [await] using statements under case/default clauses (#62709)
This commit is contained in:
@@ -504,6 +504,7 @@ import {
|
||||
isCallLikeOrFunctionLikeExpression,
|
||||
isCallOrNewExpression,
|
||||
isCallSignatureDeclaration,
|
||||
isCaseOrDefaultClause,
|
||||
isCatchClause,
|
||||
isCatchClauseVariableDeclaration,
|
||||
isCatchClauseVariableDeclarationOrBindingElement,
|
||||
@@ -53175,6 +53176,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_an_await_using_declaration,
|
||||
);
|
||||
}
|
||||
else if (isVariableStatement(declarationList.parent) && isCaseOrDefaultClause(declarationList.parent.parent)) {
|
||||
return grammarErrorOnNode(
|
||||
declarationList,
|
||||
blockScopeFlags === NodeFlags.Using ?
|
||||
Diagnostics.using_declarations_are_not_allowed_in_case_or_default_clauses_unless_contained_within_a_block :
|
||||
Diagnostics.await_using_declarations_are_not_allowed_in_case_or_default_clauses_unless_contained_within_a_block,
|
||||
);
|
||||
}
|
||||
|
||||
if (declarationList.flags & NodeFlags.Ambient) {
|
||||
return grammarErrorOnNode(
|
||||
|
||||
@@ -1849,6 +1849,14 @@
|
||||
"category": "Error",
|
||||
"code": 1546
|
||||
},
|
||||
"'using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": {
|
||||
"category": "Error",
|
||||
"code": 1547
|
||||
},
|
||||
"'await using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": {
|
||||
"category": "Error",
|
||||
"code": 1548
|
||||
},
|
||||
|
||||
"The types of '{0}' are incompatible between these types.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
BindingElement,
|
||||
Block,
|
||||
Bundle,
|
||||
CaseOrDefaultClause,
|
||||
chainBundle,
|
||||
ClassDeclaration,
|
||||
Debug,
|
||||
@@ -25,7 +24,6 @@ import {
|
||||
isArray,
|
||||
isBindingPattern,
|
||||
isBlock,
|
||||
isCaseClause,
|
||||
isCustomPrologue,
|
||||
isExpression,
|
||||
isGeneratedIdentifier,
|
||||
@@ -49,7 +47,6 @@ import {
|
||||
skipOuterExpressions,
|
||||
SourceFile,
|
||||
Statement,
|
||||
SwitchStatement,
|
||||
SyntaxKind,
|
||||
TransformationContext,
|
||||
TransformFlags,
|
||||
@@ -123,9 +120,6 @@ export function transformESNext(context: TransformationContext): (x: SourceFile
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(node as ForOfStatement);
|
||||
|
||||
case SyntaxKind.SwitchStatement:
|
||||
return visitSwitchStatement(node as SwitchStatement);
|
||||
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
@@ -339,72 +333,6 @@ export function transformESNext(context: TransformationContext): (x: SourceFile
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitCaseOrDefaultClause(node: CaseOrDefaultClause, envBinding: Identifier) {
|
||||
if (getUsingKindOfStatements(node.statements) !== UsingKind.None) {
|
||||
if (isCaseClause(node)) {
|
||||
return factory.updateCaseClause(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
transformUsingDeclarations(node.statements, /*start*/ 0, node.statements.length, envBinding, /*topLevelStatements*/ undefined),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return factory.updateDefaultClause(
|
||||
node,
|
||||
transformUsingDeclarations(node.statements, /*start*/ 0, node.statements.length, envBinding, /*topLevelStatements*/ undefined),
|
||||
);
|
||||
}
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitSwitchStatement(node: SwitchStatement) {
|
||||
// given:
|
||||
//
|
||||
// switch (expr) {
|
||||
// case expr:
|
||||
// using res = expr;
|
||||
// }
|
||||
//
|
||||
// produces:
|
||||
//
|
||||
// const env_1 = { stack: [], error: void 0, hasError: false };
|
||||
// try {
|
||||
// switch(expr) {
|
||||
// case expr:
|
||||
// const res = __addDisposableResource(env_1, expr, false);
|
||||
// }
|
||||
// }
|
||||
// catch (e_1) {
|
||||
// env_1.error = e_1;
|
||||
// env_1.hasError = true;
|
||||
// }
|
||||
// finally {
|
||||
// __disposeResources(env_1);
|
||||
// }
|
||||
//
|
||||
const usingKind = getUsingKindOfCaseOrDefaultClauses(node.caseBlock.clauses);
|
||||
if (usingKind) {
|
||||
const envBinding = createEnvBinding();
|
||||
return createDownlevelUsingStatements(
|
||||
[
|
||||
factory.updateSwitchStatement(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
factory.updateCaseBlock(
|
||||
node.caseBlock,
|
||||
node.caseBlock.clauses.map(clause => visitCaseOrDefaultClause(clause, envBinding)),
|
||||
),
|
||||
),
|
||||
],
|
||||
envBinding,
|
||||
usingKind === UsingKind.Async,
|
||||
);
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform `using` declarations in a statement list.
|
||||
*/
|
||||
@@ -870,13 +798,3 @@ function getUsingKindOfStatements(statements: readonly Statement[]): UsingKind {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getUsingKindOfCaseOrDefaultClauses(clauses: readonly CaseOrDefaultClause[]): UsingKind {
|
||||
let result = UsingKind.None;
|
||||
for (const clause of clauses) {
|
||||
const usingKind = getUsingKindOfStatements(clause.statements);
|
||||
if (usingKind === UsingKind.Async) return UsingKind.Async;
|
||||
if (usingKind > result) result = usingKind;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user