diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5731936e4978e..b12931c9a7684 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8332,6 +8332,10 @@ "category": "Message", "code": 95197 }, + "A '{0}' declaration cannot be placed within a 'case' or 'default' clause.": { + "category": "Error", + "code": 95198 + }, "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 68133ac5f1e40..88b7ad3644653 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7678,12 +7678,20 @@ namespace Parser { break; case SyntaxKind.UsingKeyword: flags |= NodeFlags.Using; + if ((parsingContext & (1 << ParsingContext.SwitchClauseStatements)) && + !(parsingContext & (1 << ParsingContext.BlockStatements))) { + parseErrorAtCurrentToken(Diagnostics.A_0_declaration_cannot_be_placed_within_a_case_or_default_clause, "using"); + } break; case SyntaxKind.AwaitKeyword: if (!isAwaitUsingDeclaration()) { break; } flags |= NodeFlags.AwaitUsing; + if ((parsingContext & (1 << ParsingContext.SwitchClauseStatements)) && + !(parsingContext & (1 << ParsingContext.BlockStatements))) { + parseErrorAtCurrentToken(Diagnostics.A_0_declaration_cannot_be_placed_within_a_case_or_default_clause, "await using"); + } nextToken(); break; default: diff --git a/tests/baselines/reference/awaitUsingDeclarations.1(target=es2015).errors.txt b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2015).errors.txt index 0334a104e0474..b0bb37aaf02e2 100644 --- a/tests/baselines/reference/awaitUsingDeclarations.1(target=es2015).errors.txt +++ b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2015).errors.txt @@ -1,24 +1,10 @@ -awaitUsingDeclarations.1.ts(1,1): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(36,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(41,9): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(45,9): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(52,13): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(57,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(60,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(63,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(67,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(70,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(74,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(79,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(85,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(90,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +awaitUsingDeclarations.1.ts(41,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(45,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(52,13): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. -==== awaitUsingDeclarations.1.ts (15 errors) ==== +==== awaitUsingDeclarations.1.ts (3 errors) ==== await using d1 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. async function af() { await using d3 = { async [Symbol.asyncDispose]() {} }; @@ -54,21 +40,19 @@ awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' stateme { await using d19 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } switch (Math.random()) { case 0: await using d20 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; case 1: await using d21 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; } @@ -77,69 +61,49 @@ awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' stateme case 0: await using d22 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; } try { await using d23 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } catch { await using d24 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } finally { await using d25 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } if (true) { await using d26 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } else { await using d27 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } while (true) { await using d28 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } do { await using d29 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } while (true); for (;;) { await using d30 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } for (const x in {}) { await using d31 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } for (const x of []) { await using d32 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } export {}; \ No newline at end of file diff --git a/tests/baselines/reference/awaitUsingDeclarations.1(target=es2017).errors.txt b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2017).errors.txt new file mode 100644 index 0000000000000..b0bb37aaf02e2 --- /dev/null +++ b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2017).errors.txt @@ -0,0 +1,109 @@ +awaitUsingDeclarations.1.ts(41,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(45,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(52,13): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== awaitUsingDeclarations.1.ts (3 errors) ==== + await using d1 = { async [Symbol.asyncDispose]() {} }; + + async function af() { + await using d3 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async function * ag() { + await using d5 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + + const a = async () => { + await using d6 = { async [Symbol.asyncDispose]() {} }; + }; + + class C1 { + a = async () => { + await using d7 = { async [Symbol.asyncDispose]() {} }; + }; + + async am() { + await using d13 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async * ag() { + await using d15 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + } + + { + await using d19 = { async [Symbol.asyncDispose]() {} }; + } + + switch (Math.random()) { + case 0: + await using d20 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + await using d21 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + await using d22 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + await using d23 = { async [Symbol.asyncDispose]() {} }; + } + catch { + await using d24 = { async [Symbol.asyncDispose]() {} }; + } + finally { + await using d25 = { async [Symbol.asyncDispose]() {} }; + } + + if (true) { + await using d26 = { async [Symbol.asyncDispose]() {} }; + } + else { + await using d27 = { async [Symbol.asyncDispose]() {} }; + } + + while (true) { + await using d28 = { async [Symbol.asyncDispose]() {} }; + break; + } + + do { + await using d29 = { async [Symbol.asyncDispose]() {} }; + break; + } + while (true); + + for (;;) { + await using d30 = { async [Symbol.asyncDispose]() {} }; + break; + } + + for (const x in {}) { + await using d31 = { async [Symbol.asyncDispose]() {} }; + } + + for (const x of []) { + await using d32 = { async [Symbol.asyncDispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/awaitUsingDeclarations.1(target=es2022).errors.txt b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2022).errors.txt new file mode 100644 index 0000000000000..b0bb37aaf02e2 --- /dev/null +++ b/tests/baselines/reference/awaitUsingDeclarations.1(target=es2022).errors.txt @@ -0,0 +1,109 @@ +awaitUsingDeclarations.1.ts(41,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(45,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(52,13): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== awaitUsingDeclarations.1.ts (3 errors) ==== + await using d1 = { async [Symbol.asyncDispose]() {} }; + + async function af() { + await using d3 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async function * ag() { + await using d5 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + + const a = async () => { + await using d6 = { async [Symbol.asyncDispose]() {} }; + }; + + class C1 { + a = async () => { + await using d7 = { async [Symbol.asyncDispose]() {} }; + }; + + async am() { + await using d13 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async * ag() { + await using d15 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + } + + { + await using d19 = { async [Symbol.asyncDispose]() {} }; + } + + switch (Math.random()) { + case 0: + await using d20 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + await using d21 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + await using d22 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + await using d23 = { async [Symbol.asyncDispose]() {} }; + } + catch { + await using d24 = { async [Symbol.asyncDispose]() {} }; + } + finally { + await using d25 = { async [Symbol.asyncDispose]() {} }; + } + + if (true) { + await using d26 = { async [Symbol.asyncDispose]() {} }; + } + else { + await using d27 = { async [Symbol.asyncDispose]() {} }; + } + + while (true) { + await using d28 = { async [Symbol.asyncDispose]() {} }; + break; + } + + do { + await using d29 = { async [Symbol.asyncDispose]() {} }; + break; + } + while (true); + + for (;;) { + await using d30 = { async [Symbol.asyncDispose]() {} }; + break; + } + + for (const x in {}) { + await using d31 = { async [Symbol.asyncDispose]() {} }; + } + + for (const x of []) { + await using d32 = { async [Symbol.asyncDispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/awaitUsingDeclarations.1(target=es5).errors.txt b/tests/baselines/reference/awaitUsingDeclarations.1(target=es5).errors.txt index 0334a104e0474..b0bb37aaf02e2 100644 --- a/tests/baselines/reference/awaitUsingDeclarations.1(target=es5).errors.txt +++ b/tests/baselines/reference/awaitUsingDeclarations.1(target=es5).errors.txt @@ -1,24 +1,10 @@ -awaitUsingDeclarations.1.ts(1,1): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(36,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(41,9): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(45,9): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(52,13): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(57,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(60,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(63,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(67,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(70,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(74,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(79,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(85,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(90,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. -awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +awaitUsingDeclarations.1.ts(41,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(45,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(52,13): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. -==== awaitUsingDeclarations.1.ts (15 errors) ==== +==== awaitUsingDeclarations.1.ts (3 errors) ==== await using d1 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. async function af() { await using d3 = { async [Symbol.asyncDispose]() {} }; @@ -54,21 +40,19 @@ awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' stateme { await using d19 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } switch (Math.random()) { case 0: await using d20 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; case 1: await using d21 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; } @@ -77,69 +61,49 @@ awaitUsingDeclarations.1.ts(94,5): error TS2854: Top-level 'await using' stateme case 0: await using d22 = { async [Symbol.asyncDispose]() {} }; ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. break; } try { await using d23 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } catch { await using d24 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } finally { await using d25 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } if (true) { await using d26 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } else { await using d27 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } while (true) { await using d28 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } do { await using d29 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } while (true); for (;;) { await using d30 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. break; } for (const x in {}) { await using d31 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } for (const x of []) { await using d32 = { async [Symbol.asyncDispose]() {} }; - ~~~~~ -!!! error TS2854: Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. } export {}; \ No newline at end of file diff --git a/tests/baselines/reference/awaitUsingDeclarations.1(target=esnext).errors.txt b/tests/baselines/reference/awaitUsingDeclarations.1(target=esnext).errors.txt new file mode 100644 index 0000000000000..b0bb37aaf02e2 --- /dev/null +++ b/tests/baselines/reference/awaitUsingDeclarations.1(target=esnext).errors.txt @@ -0,0 +1,109 @@ +awaitUsingDeclarations.1.ts(41,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(45,9): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. +awaitUsingDeclarations.1.ts(52,13): error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== awaitUsingDeclarations.1.ts (3 errors) ==== + await using d1 = { async [Symbol.asyncDispose]() {} }; + + async function af() { + await using d3 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async function * ag() { + await using d5 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + + const a = async () => { + await using d6 = { async [Symbol.asyncDispose]() {} }; + }; + + class C1 { + a = async () => { + await using d7 = { async [Symbol.asyncDispose]() {} }; + }; + + async am() { + await using d13 = { async [Symbol.asyncDispose]() {} }; + await null; + } + + async * ag() { + await using d15 = { async [Symbol.asyncDispose]() {} }; + yield; + await null; + } + } + + { + await using d19 = { async [Symbol.asyncDispose]() {} }; + } + + switch (Math.random()) { + case 0: + await using d20 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + await using d21 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + await using d22 = { async [Symbol.asyncDispose]() {} }; + ~~~~~ +!!! error TS95198: A 'await using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + await using d23 = { async [Symbol.asyncDispose]() {} }; + } + catch { + await using d24 = { async [Symbol.asyncDispose]() {} }; + } + finally { + await using d25 = { async [Symbol.asyncDispose]() {} }; + } + + if (true) { + await using d26 = { async [Symbol.asyncDispose]() {} }; + } + else { + await using d27 = { async [Symbol.asyncDispose]() {} }; + } + + while (true) { + await using d28 = { async [Symbol.asyncDispose]() {} }; + break; + } + + do { + await using d29 = { async [Symbol.asyncDispose]() {} }; + break; + } + while (true); + + for (;;) { + await using d30 = { async [Symbol.asyncDispose]() {} }; + break; + } + + for (const x in {}) { + await using d31 = { async [Symbol.asyncDispose]() {} }; + } + + for (const x of []) { + await using d32 = { async [Symbol.asyncDispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.1(target=es2015).errors.txt b/tests/baselines/reference/usingDeclarations.1(target=es2015).errors.txt new file mode 100644 index 0000000000000..784e40be298ff --- /dev/null +++ b/tests/baselines/reference/usingDeclarations.1(target=es2015).errors.txt @@ -0,0 +1,163 @@ +usingDeclarations.1.ts(95,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(99,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(106,13): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarations.1.ts (3 errors) ==== + using d1 = { [Symbol.dispose]() {} }; + + function f() { + using d2 = { [Symbol.dispose]() {} }; + } + + async function af() { + using d3 = { [Symbol.dispose]() {} }; + await null; + } + + function * g() { + using d4 = { [Symbol.dispose]() {} }; + yield; + } + + async function * ag() { + using d5 = { [Symbol.dispose]() {} }; + yield; + await null; + } + + const a = () => { + using d6 = { [Symbol.dispose]() {} }; + } + + class C1 { + a = () => { + using d7 = { [Symbol.dispose]() {} }; + } + + constructor() { + using d8 = { [Symbol.dispose]() {} }; + } + + static { + using d9 = { [Symbol.dispose]() {} }; + } + + m() { + using d10 = { [Symbol.dispose]() {} }; + } + + get x() { + using d11 = { [Symbol.dispose]() {} }; + return 0; + } + + set x(v) { + using d12 = { [Symbol.dispose]() {} }; + } + + async am() { + using d13 = { [Symbol.dispose]() {} }; + await null; + } + + * g() { + using d14 = { [Symbol.dispose]() {} }; + yield; + } + + async * ag() { + using d15 = { [Symbol.dispose]() {} }; + yield; + await null; + } + } + + class C2 extends C1 { + constructor() { + using d16 = { [Symbol.dispose]() {} }; + super(); + } + } + + class C3 extends C1 { + y = 1; + constructor() { + using d17 = { [Symbol.dispose]() {} }; + super(); + } + } + + namespace N { + using d18 = { [Symbol.dispose]() {} }; + } + + { + using d19 = { [Symbol.dispose]() {} }; + } + + switch (Math.random()) { + case 0: + using d20 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + using d21 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + using d22 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + using d23 = { [Symbol.dispose]() {} }; + } + catch { + using d24 = { [Symbol.dispose]() {} }; + } + finally { + using d25 = { [Symbol.dispose]() {} }; + } + + if (true) { + using d26 = { [Symbol.dispose]() {} }; + } + else { + using d27 = { [Symbol.dispose]() {} }; + } + + while (true) { + using d28 = { [Symbol.dispose]() {} }; + break; + } + + do { + using d29 = { [Symbol.dispose]() {} }; + break; + } + while (true); + + for (;;) { + using d30 = { [Symbol.dispose]() {} }; + break; + } + + for (const x in {}) { + using d31 = { [Symbol.dispose]() {} }; + } + + for (const x of []) { + using d32 = { [Symbol.dispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.1(target=es2017).errors.txt b/tests/baselines/reference/usingDeclarations.1(target=es2017).errors.txt new file mode 100644 index 0000000000000..784e40be298ff --- /dev/null +++ b/tests/baselines/reference/usingDeclarations.1(target=es2017).errors.txt @@ -0,0 +1,163 @@ +usingDeclarations.1.ts(95,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(99,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(106,13): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarations.1.ts (3 errors) ==== + using d1 = { [Symbol.dispose]() {} }; + + function f() { + using d2 = { [Symbol.dispose]() {} }; + } + + async function af() { + using d3 = { [Symbol.dispose]() {} }; + await null; + } + + function * g() { + using d4 = { [Symbol.dispose]() {} }; + yield; + } + + async function * ag() { + using d5 = { [Symbol.dispose]() {} }; + yield; + await null; + } + + const a = () => { + using d6 = { [Symbol.dispose]() {} }; + } + + class C1 { + a = () => { + using d7 = { [Symbol.dispose]() {} }; + } + + constructor() { + using d8 = { [Symbol.dispose]() {} }; + } + + static { + using d9 = { [Symbol.dispose]() {} }; + } + + m() { + using d10 = { [Symbol.dispose]() {} }; + } + + get x() { + using d11 = { [Symbol.dispose]() {} }; + return 0; + } + + set x(v) { + using d12 = { [Symbol.dispose]() {} }; + } + + async am() { + using d13 = { [Symbol.dispose]() {} }; + await null; + } + + * g() { + using d14 = { [Symbol.dispose]() {} }; + yield; + } + + async * ag() { + using d15 = { [Symbol.dispose]() {} }; + yield; + await null; + } + } + + class C2 extends C1 { + constructor() { + using d16 = { [Symbol.dispose]() {} }; + super(); + } + } + + class C3 extends C1 { + y = 1; + constructor() { + using d17 = { [Symbol.dispose]() {} }; + super(); + } + } + + namespace N { + using d18 = { [Symbol.dispose]() {} }; + } + + { + using d19 = { [Symbol.dispose]() {} }; + } + + switch (Math.random()) { + case 0: + using d20 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + using d21 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + using d22 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + using d23 = { [Symbol.dispose]() {} }; + } + catch { + using d24 = { [Symbol.dispose]() {} }; + } + finally { + using d25 = { [Symbol.dispose]() {} }; + } + + if (true) { + using d26 = { [Symbol.dispose]() {} }; + } + else { + using d27 = { [Symbol.dispose]() {} }; + } + + while (true) { + using d28 = { [Symbol.dispose]() {} }; + break; + } + + do { + using d29 = { [Symbol.dispose]() {} }; + break; + } + while (true); + + for (;;) { + using d30 = { [Symbol.dispose]() {} }; + break; + } + + for (const x in {}) { + using d31 = { [Symbol.dispose]() {} }; + } + + for (const x of []) { + using d32 = { [Symbol.dispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.1(target=es2022).errors.txt b/tests/baselines/reference/usingDeclarations.1(target=es2022).errors.txt new file mode 100644 index 0000000000000..784e40be298ff --- /dev/null +++ b/tests/baselines/reference/usingDeclarations.1(target=es2022).errors.txt @@ -0,0 +1,163 @@ +usingDeclarations.1.ts(95,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(99,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(106,13): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarations.1.ts (3 errors) ==== + using d1 = { [Symbol.dispose]() {} }; + + function f() { + using d2 = { [Symbol.dispose]() {} }; + } + + async function af() { + using d3 = { [Symbol.dispose]() {} }; + await null; + } + + function * g() { + using d4 = { [Symbol.dispose]() {} }; + yield; + } + + async function * ag() { + using d5 = { [Symbol.dispose]() {} }; + yield; + await null; + } + + const a = () => { + using d6 = { [Symbol.dispose]() {} }; + } + + class C1 { + a = () => { + using d7 = { [Symbol.dispose]() {} }; + } + + constructor() { + using d8 = { [Symbol.dispose]() {} }; + } + + static { + using d9 = { [Symbol.dispose]() {} }; + } + + m() { + using d10 = { [Symbol.dispose]() {} }; + } + + get x() { + using d11 = { [Symbol.dispose]() {} }; + return 0; + } + + set x(v) { + using d12 = { [Symbol.dispose]() {} }; + } + + async am() { + using d13 = { [Symbol.dispose]() {} }; + await null; + } + + * g() { + using d14 = { [Symbol.dispose]() {} }; + yield; + } + + async * ag() { + using d15 = { [Symbol.dispose]() {} }; + yield; + await null; + } + } + + class C2 extends C1 { + constructor() { + using d16 = { [Symbol.dispose]() {} }; + super(); + } + } + + class C3 extends C1 { + y = 1; + constructor() { + using d17 = { [Symbol.dispose]() {} }; + super(); + } + } + + namespace N { + using d18 = { [Symbol.dispose]() {} }; + } + + { + using d19 = { [Symbol.dispose]() {} }; + } + + switch (Math.random()) { + case 0: + using d20 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + using d21 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + using d22 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + using d23 = { [Symbol.dispose]() {} }; + } + catch { + using d24 = { [Symbol.dispose]() {} }; + } + finally { + using d25 = { [Symbol.dispose]() {} }; + } + + if (true) { + using d26 = { [Symbol.dispose]() {} }; + } + else { + using d27 = { [Symbol.dispose]() {} }; + } + + while (true) { + using d28 = { [Symbol.dispose]() {} }; + break; + } + + do { + using d29 = { [Symbol.dispose]() {} }; + break; + } + while (true); + + for (;;) { + using d30 = { [Symbol.dispose]() {} }; + break; + } + + for (const x in {}) { + using d31 = { [Symbol.dispose]() {} }; + } + + for (const x of []) { + using d32 = { [Symbol.dispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.1(target=es5).errors.txt b/tests/baselines/reference/usingDeclarations.1(target=es5).errors.txt new file mode 100644 index 0000000000000..784e40be298ff --- /dev/null +++ b/tests/baselines/reference/usingDeclarations.1(target=es5).errors.txt @@ -0,0 +1,163 @@ +usingDeclarations.1.ts(95,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(99,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(106,13): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarations.1.ts (3 errors) ==== + using d1 = { [Symbol.dispose]() {} }; + + function f() { + using d2 = { [Symbol.dispose]() {} }; + } + + async function af() { + using d3 = { [Symbol.dispose]() {} }; + await null; + } + + function * g() { + using d4 = { [Symbol.dispose]() {} }; + yield; + } + + async function * ag() { + using d5 = { [Symbol.dispose]() {} }; + yield; + await null; + } + + const a = () => { + using d6 = { [Symbol.dispose]() {} }; + } + + class C1 { + a = () => { + using d7 = { [Symbol.dispose]() {} }; + } + + constructor() { + using d8 = { [Symbol.dispose]() {} }; + } + + static { + using d9 = { [Symbol.dispose]() {} }; + } + + m() { + using d10 = { [Symbol.dispose]() {} }; + } + + get x() { + using d11 = { [Symbol.dispose]() {} }; + return 0; + } + + set x(v) { + using d12 = { [Symbol.dispose]() {} }; + } + + async am() { + using d13 = { [Symbol.dispose]() {} }; + await null; + } + + * g() { + using d14 = { [Symbol.dispose]() {} }; + yield; + } + + async * ag() { + using d15 = { [Symbol.dispose]() {} }; + yield; + await null; + } + } + + class C2 extends C1 { + constructor() { + using d16 = { [Symbol.dispose]() {} }; + super(); + } + } + + class C3 extends C1 { + y = 1; + constructor() { + using d17 = { [Symbol.dispose]() {} }; + super(); + } + } + + namespace N { + using d18 = { [Symbol.dispose]() {} }; + } + + { + using d19 = { [Symbol.dispose]() {} }; + } + + switch (Math.random()) { + case 0: + using d20 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + using d21 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + using d22 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + using d23 = { [Symbol.dispose]() {} }; + } + catch { + using d24 = { [Symbol.dispose]() {} }; + } + finally { + using d25 = { [Symbol.dispose]() {} }; + } + + if (true) { + using d26 = { [Symbol.dispose]() {} }; + } + else { + using d27 = { [Symbol.dispose]() {} }; + } + + while (true) { + using d28 = { [Symbol.dispose]() {} }; + break; + } + + do { + using d29 = { [Symbol.dispose]() {} }; + break; + } + while (true); + + for (;;) { + using d30 = { [Symbol.dispose]() {} }; + break; + } + + for (const x in {}) { + using d31 = { [Symbol.dispose]() {} }; + } + + for (const x of []) { + using d32 = { [Symbol.dispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.1(target=esnext).errors.txt b/tests/baselines/reference/usingDeclarations.1(target=esnext).errors.txt new file mode 100644 index 0000000000000..784e40be298ff --- /dev/null +++ b/tests/baselines/reference/usingDeclarations.1(target=esnext).errors.txt @@ -0,0 +1,163 @@ +usingDeclarations.1.ts(95,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(99,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarations.1.ts(106,13): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarations.1.ts (3 errors) ==== + using d1 = { [Symbol.dispose]() {} }; + + function f() { + using d2 = { [Symbol.dispose]() {} }; + } + + async function af() { + using d3 = { [Symbol.dispose]() {} }; + await null; + } + + function * g() { + using d4 = { [Symbol.dispose]() {} }; + yield; + } + + async function * ag() { + using d5 = { [Symbol.dispose]() {} }; + yield; + await null; + } + + const a = () => { + using d6 = { [Symbol.dispose]() {} }; + } + + class C1 { + a = () => { + using d7 = { [Symbol.dispose]() {} }; + } + + constructor() { + using d8 = { [Symbol.dispose]() {} }; + } + + static { + using d9 = { [Symbol.dispose]() {} }; + } + + m() { + using d10 = { [Symbol.dispose]() {} }; + } + + get x() { + using d11 = { [Symbol.dispose]() {} }; + return 0; + } + + set x(v) { + using d12 = { [Symbol.dispose]() {} }; + } + + async am() { + using d13 = { [Symbol.dispose]() {} }; + await null; + } + + * g() { + using d14 = { [Symbol.dispose]() {} }; + yield; + } + + async * ag() { + using d15 = { [Symbol.dispose]() {} }; + yield; + await null; + } + } + + class C2 extends C1 { + constructor() { + using d16 = { [Symbol.dispose]() {} }; + super(); + } + } + + class C3 extends C1 { + y = 1; + constructor() { + using d17 = { [Symbol.dispose]() {} }; + super(); + } + } + + namespace N { + using d18 = { [Symbol.dispose]() {} }; + } + + { + using d19 = { [Symbol.dispose]() {} }; + } + + switch (Math.random()) { + case 0: + using d20 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + + case 1: + using d21 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + if (true) + switch (0) { + case 0: + using d22 = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + try { + using d23 = { [Symbol.dispose]() {} }; + } + catch { + using d24 = { [Symbol.dispose]() {} }; + } + finally { + using d25 = { [Symbol.dispose]() {} }; + } + + if (true) { + using d26 = { [Symbol.dispose]() {} }; + } + else { + using d27 = { [Symbol.dispose]() {} }; + } + + while (true) { + using d28 = { [Symbol.dispose]() {} }; + break; + } + + do { + using d29 = { [Symbol.dispose]() {} }; + break; + } + while (true); + + for (;;) { + using d30 = { [Symbol.dispose]() {} }; + break; + } + + for (const x in {}) { + using d31 = { [Symbol.dispose]() {} }; + } + + for (const x of []) { + using d32 = { [Symbol.dispose]() {} }; + } + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.errors.txt b/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.errors.txt new file mode 100644 index 0000000000000..abb62d124eb6d --- /dev/null +++ b/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.errors.txt @@ -0,0 +1,215 @@ +usingDeclarationsInSwitchEdgeCases.ts(3,10): error TS2678: Type '0' is not comparable to type '1'. +usingDeclarationsInSwitchEdgeCases.ts(16,10): error TS2678: Type '0' is not comparable to type '2'. +usingDeclarationsInSwitchEdgeCases.ts(25,10): error TS2678: Type '0' is not comparable to type '3'. +usingDeclarationsInSwitchEdgeCases.ts(35,10): error TS2678: Type '0' is not comparable to type '4'. +usingDeclarationsInSwitchEdgeCases.ts(45,10): error TS2678: Type '0' is not comparable to type '5'. +usingDeclarationsInSwitchEdgeCases.ts(54,10): error TS2678: Type '0' is not comparable to type '6'. +usingDeclarationsInSwitchEdgeCases.ts(63,10): error TS2678: Type '0' is not comparable to type '7'. +usingDeclarationsInSwitchEdgeCases.ts(72,10): error TS2678: Type '0' is not comparable to type '8'. +usingDeclarationsInSwitchEdgeCases.ts(81,10): error TS2678: Type '0' is not comparable to type '9'. +usingDeclarationsInSwitchEdgeCases.ts(96,10): error TS2678: Type '0' is not comparable to type '10'. +usingDeclarationsInSwitchEdgeCases.ts(107,10): error TS2678: Type '0' is not comparable to type '11'. +usingDeclarationsInSwitchEdgeCases.ts(117,10): error TS2678: Type '0' is not comparable to type '12'. +usingDeclarationsInSwitchEdgeCases.ts(127,10): error TS2678: Type '0' is not comparable to type '13'. +usingDeclarationsInSwitchEdgeCases.ts(137,10): error TS2678: Type '0' is not comparable to type '14'. +usingDeclarationsInSwitchEdgeCases.ts(148,10): error TS2678: Type '0' is not comparable to type '15'. +usingDeclarationsInSwitchEdgeCases.ts(158,10): error TS2678: Type '0' is not comparable to type '16'. + + +==== usingDeclarationsInSwitchEdgeCases.ts (16 errors) ==== + // Valid: Try-catch inside case + switch (1) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '1'. + try { + using inTry = { [Symbol.dispose]() {} }; + } catch { + using inCatch = { [Symbol.dispose]() {} }; + } finally { + using inFinally = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: For loop inside case + switch (2) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '2'. + for (let i = 0; i < 10; i++) { + using inForBody = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: While loop inside case + switch (3) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '3'. + while (true) { + using inWhile = { [Symbol.dispose]() {} }; + break; + } + break; + } + + // Valid: Do-while loop inside case + switch (4) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '4'. + do { + using inDoWhile = { [Symbol.dispose]() {} }; + break; + } while (false); + break; + } + + // Valid: For-in loop inside case + switch (5) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '5'. + for (const key in {}) { + using inForIn = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: For-of loop inside case + switch (6) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '6'. + for (const item of []) { + using inForOf = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: Function declaration inside case + switch (7) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '7'. + function foo() { + using inFunction = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: Arrow function inside case + switch (8) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '8'. + const arrow = () => { + using inArrow = { [Symbol.dispose]() {} }; + }; + break; + } + + // Valid: Class inside case + switch (9) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '9'. + class C { + method() { + using inMethod = { [Symbol.dispose]() {} }; + } + + constructor() { + using inConstructor = { [Symbol.dispose]() {} }; + } + } + break; + } + + // Valid: Nested function expressions + switch (10) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '10'. + const outer = function() { + const inner = function() { + using deeplyNested = { [Symbol.dispose]() {} }; + }; + }; + break; + } + + // Valid: Generator function inside case + switch (11) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '11'. + function* gen() { + using inGenerator = { [Symbol.dispose]() {} }; + yield 1; + } + break; + } + + // Valid: Async function inside case + switch (12) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '12'. + async function asyncFn() { + using inAsync = { [Symbol.dispose]() {} }; + await Promise.resolve(); + } + break; + } + + // Valid: Async arrow function inside case + switch (13) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '13'. + const asyncArrow = async () => { + using inAsyncArrow = { [Symbol.dispose]() {} }; + await Promise.resolve(); + }; + break; + } + + // Valid: Object method inside case + switch (14) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '14'. + const obj = { + method() { + using inObjectMethod = { [Symbol.dispose]() {} }; + } + }; + break; + } + + // Valid: Labeled block inside case + switch (15) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '15'. + label: { + using inLabeledBlock = { [Symbol.dispose]() {} }; + } + break; + } + + // Valid: With statement inside case (if not in strict mode) + // Note: This would normally require @strict: false but including for completeness + switch (16) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '16'. + // with ({}) { using inWith = { [Symbol.dispose]() {} }; } + break; + } + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.js b/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.js new file mode 100644 index 0000000000000..bee7ecea32c2c --- /dev/null +++ b/tests/baselines/reference/usingDeclarationsInSwitchEdgeCases.js @@ -0,0 +1,317 @@ +//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchEdgeCases.ts] //// + +//// [usingDeclarationsInSwitchEdgeCases.ts] +// Valid: Try-catch inside case +switch (1) { + case 0: + try { + using inTry = { [Symbol.dispose]() {} }; + } catch { + using inCatch = { [Symbol.dispose]() {} }; + } finally { + using inFinally = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: For loop inside case +switch (2) { + case 0: + for (let i = 0; i < 10; i++) { + using inForBody = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: While loop inside case +switch (3) { + case 0: + while (true) { + using inWhile = { [Symbol.dispose]() {} }; + break; + } + break; +} + +// Valid: Do-while loop inside case +switch (4) { + case 0: + do { + using inDoWhile = { [Symbol.dispose]() {} }; + break; + } while (false); + break; +} + +// Valid: For-in loop inside case +switch (5) { + case 0: + for (const key in {}) { + using inForIn = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: For-of loop inside case +switch (6) { + case 0: + for (const item of []) { + using inForOf = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: Function declaration inside case +switch (7) { + case 0: + function foo() { + using inFunction = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: Arrow function inside case +switch (8) { + case 0: + const arrow = () => { + using inArrow = { [Symbol.dispose]() {} }; + }; + break; +} + +// Valid: Class inside case +switch (9) { + case 0: + class C { + method() { + using inMethod = { [Symbol.dispose]() {} }; + } + + constructor() { + using inConstructor = { [Symbol.dispose]() {} }; + } + } + break; +} + +// Valid: Nested function expressions +switch (10) { + case 0: + const outer = function() { + const inner = function() { + using deeplyNested = { [Symbol.dispose]() {} }; + }; + }; + break; +} + +// Valid: Generator function inside case +switch (11) { + case 0: + function* gen() { + using inGenerator = { [Symbol.dispose]() {} }; + yield 1; + } + break; +} + +// Valid: Async function inside case +switch (12) { + case 0: + async function asyncFn() { + using inAsync = { [Symbol.dispose]() {} }; + await Promise.resolve(); + } + break; +} + +// Valid: Async arrow function inside case +switch (13) { + case 0: + const asyncArrow = async () => { + using inAsyncArrow = { [Symbol.dispose]() {} }; + await Promise.resolve(); + }; + break; +} + +// Valid: Object method inside case +switch (14) { + case 0: + const obj = { + method() { + using inObjectMethod = { [Symbol.dispose]() {} }; + } + }; + break; +} + +// Valid: Labeled block inside case +switch (15) { + case 0: + label: { + using inLabeledBlock = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: With statement inside case (if not in strict mode) +// Note: This would normally require @strict: false but including for completeness +switch (16) { + case 0: + // with ({}) { using inWith = { [Symbol.dispose]() {} }; } + break; +} + +export {}; + + +//// [usingDeclarationsInSwitchEdgeCases.js] +// Valid: Try-catch inside case +switch (1) { + case 0: + try { + using inTry = { [Symbol.dispose]() { } }; + } + catch { + using inCatch = { [Symbol.dispose]() { } }; + } + finally { + using inFinally = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: For loop inside case +switch (2) { + case 0: + for (let i = 0; i < 10; i++) { + using inForBody = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: While loop inside case +switch (3) { + case 0: + while (true) { + using inWhile = { [Symbol.dispose]() { } }; + break; + } + break; +} +// Valid: Do-while loop inside case +switch (4) { + case 0: + do { + using inDoWhile = { [Symbol.dispose]() { } }; + break; + } while (false); + break; +} +// Valid: For-in loop inside case +switch (5) { + case 0: + for (const key in {}) { + using inForIn = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: For-of loop inside case +switch (6) { + case 0: + for (const item of []) { + using inForOf = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: Function declaration inside case +switch (7) { + case 0: + function foo() { + using inFunction = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: Arrow function inside case +switch (8) { + case 0: + const arrow = () => { + using inArrow = { [Symbol.dispose]() { } }; + }; + break; +} +// Valid: Class inside case +switch (9) { + case 0: + class C { + method() { + using inMethod = { [Symbol.dispose]() { } }; + } + constructor() { + using inConstructor = { [Symbol.dispose]() { } }; + } + } + break; +} +// Valid: Nested function expressions +switch (10) { + case 0: + const outer = function () { + const inner = function () { + using deeplyNested = { [Symbol.dispose]() { } }; + }; + }; + break; +} +// Valid: Generator function inside case +switch (11) { + case 0: + function* gen() { + using inGenerator = { [Symbol.dispose]() { } }; + yield 1; + } + break; +} +// Valid: Async function inside case +switch (12) { + case 0: + async function asyncFn() { + using inAsync = { [Symbol.dispose]() { } }; + await Promise.resolve(); + } + break; +} +// Valid: Async arrow function inside case +switch (13) { + case 0: + const asyncArrow = async () => { + using inAsyncArrow = { [Symbol.dispose]() { } }; + await Promise.resolve(); + }; + break; +} +// Valid: Object method inside case +switch (14) { + case 0: + const obj = { + method() { + using inObjectMethod = { [Symbol.dispose]() { } }; + } + }; + break; +} +// Valid: Labeled block inside case +switch (15) { + case 0: + label: { + using inLabeledBlock = { [Symbol.dispose]() { } }; + } + break; +} +// Valid: With statement inside case (if not in strict mode) +// Note: This would normally require @strict: false but including for completeness +switch (16) { + case 0: + // with ({}) { using inWith = { [Symbol.dispose]() {} }; } + break; +} +export {}; diff --git a/tests/baselines/reference/usingDeclarationsInSwitchError.errors.txt b/tests/baselines/reference/usingDeclarationsInSwitchError.errors.txt new file mode 100644 index 0000000000000..0154a5cb50cdd --- /dev/null +++ b/tests/baselines/reference/usingDeclarationsInSwitchError.errors.txt @@ -0,0 +1,181 @@ +usingDeclarationsInSwitchError.ts(3,10): error TS2678: Type '0' is not comparable to type '1'. +usingDeclarationsInSwitchError.ts(4,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(11,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(22,10): error TS2678: Type '0' is not comparable to type '5'. +usingDeclarationsInSwitchError.ts(23,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(24,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(30,10): error TS2678: Type '0' is not comparable to type '6'. +usingDeclarationsInSwitchError.ts(32,18): error TS2678: Type '1' is not comparable to type '7'. +usingDeclarationsInSwitchError.ts(33,17): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(42,10): error TS2678: Type '0' is not comparable to type '8'. +usingDeclarationsInSwitchError.ts(43,9): error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. +usingDeclarationsInSwitchError.ts(49,10): error TS2678: Type '0' is not comparable to type '9'. +usingDeclarationsInSwitchError.ts(65,10): error TS2678: Type '0' is not comparable to type '11'. +usingDeclarationsInSwitchError.ts(75,10): error TS2678: Type '0' is not comparable to type '12'. +usingDeclarationsInSwitchError.ts(84,10): error TS2678: Type '0' is not comparable to type '13'. +usingDeclarationsInSwitchError.ts(85,10): error TS2678: Type '1' is not comparable to type '13'. +usingDeclarationsInSwitchError.ts(86,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(92,10): error TS2678: Type '0' is not comparable to type '14'. +usingDeclarationsInSwitchError.ts(93,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. +usingDeclarationsInSwitchError.ts(94,10): error TS2678: Type '1' is not comparable to type '14'. +usingDeclarationsInSwitchError.ts(95,9): error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. +usingDeclarationsInSwitchError.ts(101,10): error TS2678: Type '0' is not comparable to type '15'. +usingDeclarationsInSwitchError.ts(104,9): error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + + +==== usingDeclarationsInSwitchError.ts (23 errors) ==== + // Error: using in case clause + switch (1) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '1'. + using x = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + // Error: using in default clause + switch (2) { + default: + using y = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + // Error: await using in case clause (top-level of module would need to be async, so wrap minimally) + { + // Note: await using requires async context, tested separately in async functions + } + + // Error: Multiple using statements in same case + switch (5) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '5'. + using c = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + using d = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + // Error: Nested switch with using + switch (6) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '6'. + switch (7) { + case 1: + ~ +!!! error TS2678: Type '1' is not comparable to type '7'. + using e = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + break; + } + + // Valid: using before switch statement + using beforeSwitch = { [Symbol.dispose]() {} }; + switch (8) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '8'. + console.log("ok"); + ~~~~~~~ +!!! error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. + break; + } + + // Valid: Block-wrapped in case + switch (9) { + case 0: { + ~ +!!! error TS2678: Type '0' is not comparable to type '9'. + using valid1 = { [Symbol.dispose]() {} }; + break; + } + } + + // Valid: Block-wrapped in default + switch (10) { + default: { + using valid2 = { [Symbol.dispose]() {} }; + break; + } + } + + // Valid: Nested block in case + switch (11) { + case 0: { + ~ +!!! error TS2678: Type '0' is not comparable to type '11'. + { + using valid3 = { [Symbol.dispose]() {} }; + } + break; + } + } + + // Valid: If statement inside case with block + switch (12) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '12'. + if (true) { + using valid4 = { [Symbol.dispose]() {} }; + } + break; + } + + // Error: Fall-through cases + switch (13) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '13'. + case 1: + ~ +!!! error TS2678: Type '1' is not comparable to type '13'. + using fallthrough = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + // Error: Case with no break + switch (14) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '14'. + using nobreak = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + case 1: + ~ +!!! error TS2678: Type '1' is not comparable to type '14'. + console.log("fallthrough"); + ~~~~~~~ +!!! error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. + break; + } + + // Error: Empty case before default + switch (15) { + case 0: + ~ +!!! error TS2678: Type '0' is not comparable to type '15'. + // empty + default: + using inDefault = { [Symbol.dispose]() {} }; + ~~~~~ +!!! error TS95198: A 'using' declaration cannot be placed within a 'case' or 'default' clause. + break; + } + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarationsInSwitchError.js b/tests/baselines/reference/usingDeclarationsInSwitchError.js new file mode 100644 index 0000000000000..9ac9df0957540 --- /dev/null +++ b/tests/baselines/reference/usingDeclarationsInSwitchError.js @@ -0,0 +1,209 @@ +//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchError.ts] //// + +//// [usingDeclarationsInSwitchError.ts] +// Error: using in case clause +switch (1) { + case 0: + using x = { [Symbol.dispose]() {} }; + break; +} + +// Error: using in default clause +switch (2) { + default: + using y = { [Symbol.dispose]() {} }; + break; +} + +// Error: await using in case clause (top-level of module would need to be async, so wrap minimally) +{ + // Note: await using requires async context, tested separately in async functions +} + +// Error: Multiple using statements in same case +switch (5) { + case 0: + using c = { [Symbol.dispose]() {} }; + using d = { [Symbol.dispose]() {} }; + break; +} + +// Error: Nested switch with using +switch (6) { + case 0: + switch (7) { + case 1: + using e = { [Symbol.dispose]() {} }; + break; + } + break; +} + +// Valid: using before switch statement +using beforeSwitch = { [Symbol.dispose]() {} }; +switch (8) { + case 0: + console.log("ok"); + break; +} + +// Valid: Block-wrapped in case +switch (9) { + case 0: { + using valid1 = { [Symbol.dispose]() {} }; + break; + } +} + +// Valid: Block-wrapped in default +switch (10) { + default: { + using valid2 = { [Symbol.dispose]() {} }; + break; + } +} + +// Valid: Nested block in case +switch (11) { + case 0: { + { + using valid3 = { [Symbol.dispose]() {} }; + } + break; + } +} + +// Valid: If statement inside case with block +switch (12) { + case 0: + if (true) { + using valid4 = { [Symbol.dispose]() {} }; + } + break; +} + +// Error: Fall-through cases +switch (13) { + case 0: + case 1: + using fallthrough = { [Symbol.dispose]() {} }; + break; +} + +// Error: Case with no break +switch (14) { + case 0: + using nobreak = { [Symbol.dispose]() {} }; + case 1: + console.log("fallthrough"); + break; +} + +// Error: Empty case before default +switch (15) { + case 0: + // empty + default: + using inDefault = { [Symbol.dispose]() {} }; + break; +} + +export {}; + + +//// [usingDeclarationsInSwitchError.js] +// Error: using in case clause +switch (1) { + case 0: + using x = { [Symbol.dispose]() { } }; + break; +} +// Error: using in default clause +switch (2) { + default: + using y = { [Symbol.dispose]() { } }; + break; +} +// Error: await using in case clause (top-level of module would need to be async, so wrap minimally) +{ + // Note: await using requires async context, tested separately in async functions +} +// Error: Multiple using statements in same case +switch (5) { + case 0: + using c = { [Symbol.dispose]() { } }; + using d = { [Symbol.dispose]() { } }; + break; +} +// Error: Nested switch with using +switch (6) { + case 0: + switch (7) { + case 1: + using e = { [Symbol.dispose]() { } }; + break; + } + break; +} +// Valid: using before switch statement +using beforeSwitch = { [Symbol.dispose]() { } }; +switch (8) { + case 0: + console.log("ok"); + break; +} +// Valid: Block-wrapped in case +switch (9) { + case 0: { + using valid1 = { [Symbol.dispose]() { } }; + break; + } +} +// Valid: Block-wrapped in default +switch (10) { + default: { + using valid2 = { [Symbol.dispose]() { } }; + break; + } +} +// Valid: Nested block in case +switch (11) { + case 0: { + { + using valid3 = { [Symbol.dispose]() { } }; + } + break; + } +} +// Valid: If statement inside case with block +switch (12) { + case 0: + if (true) { + using valid4 = { [Symbol.dispose]() { } }; + } + break; +} +// Error: Fall-through cases +switch (13) { + case 0: + case 1: + using fallthrough = { [Symbol.dispose]() { } }; + break; +} +// Error: Case with no break +switch (14) { + case 0: + using nobreak = { [Symbol.dispose]() { } }; + case 1: + console.log("fallthrough"); + break; +} +// Error: Empty case before default +switch (15) { + case 0: + // empty + default: + using inDefault = { [Symbol.dispose]() { } }; + break; +} +export {}; diff --git a/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchEdgeCases.ts b/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchEdgeCases.ts new file mode 100644 index 0000000000000..1761da106a8d0 --- /dev/null +++ b/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchEdgeCases.ts @@ -0,0 +1,168 @@ +// @target: esnext +// @module: esnext +// @lib: esnext +// @noTypesAndSymbols: true + +// Valid: Try-catch inside case +switch (1) { + case 0: + try { + using inTry = { [Symbol.dispose]() {} }; + } catch { + using inCatch = { [Symbol.dispose]() {} }; + } finally { + using inFinally = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: For loop inside case +switch (2) { + case 0: + for (let i = 0; i < 10; i++) { + using inForBody = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: While loop inside case +switch (3) { + case 0: + while (true) { + using inWhile = { [Symbol.dispose]() {} }; + break; + } + break; +} + +// Valid: Do-while loop inside case +switch (4) { + case 0: + do { + using inDoWhile = { [Symbol.dispose]() {} }; + break; + } while (false); + break; +} + +// Valid: For-in loop inside case +switch (5) { + case 0: + for (const key in {}) { + using inForIn = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: For-of loop inside case +switch (6) { + case 0: + for (const item of []) { + using inForOf = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: Function declaration inside case +switch (7) { + case 0: + function foo() { + using inFunction = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: Arrow function inside case +switch (8) { + case 0: + const arrow = () => { + using inArrow = { [Symbol.dispose]() {} }; + }; + break; +} + +// Valid: Class inside case +switch (9) { + case 0: + class C { + method() { + using inMethod = { [Symbol.dispose]() {} }; + } + + constructor() { + using inConstructor = { [Symbol.dispose]() {} }; + } + } + break; +} + +// Valid: Nested function expressions +switch (10) { + case 0: + const outer = function() { + const inner = function() { + using deeplyNested = { [Symbol.dispose]() {} }; + }; + }; + break; +} + +// Valid: Generator function inside case +switch (11) { + case 0: + function* gen() { + using inGenerator = { [Symbol.dispose]() {} }; + yield 1; + } + break; +} + +// Valid: Async function inside case +switch (12) { + case 0: + async function asyncFn() { + using inAsync = { [Symbol.dispose]() {} }; + await Promise.resolve(); + } + break; +} + +// Valid: Async arrow function inside case +switch (13) { + case 0: + const asyncArrow = async () => { + using inAsyncArrow = { [Symbol.dispose]() {} }; + await Promise.resolve(); + }; + break; +} + +// Valid: Object method inside case +switch (14) { + case 0: + const obj = { + method() { + using inObjectMethod = { [Symbol.dispose]() {} }; + } + }; + break; +} + +// Valid: Labeled block inside case +switch (15) { + case 0: + label: { + using inLabeledBlock = { [Symbol.dispose]() {} }; + } + break; +} + +// Valid: With statement inside case (if not in strict mode) +// Note: This would normally require @strict: false but including for completeness +switch (16) { + case 0: + // with ({}) { using inWith = { [Symbol.dispose]() {} }; } + break; +} + +export {}; diff --git a/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchError.ts b/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchError.ts new file mode 100644 index 0000000000000..b0013ba4a10b8 --- /dev/null +++ b/tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsInSwitchError.ts @@ -0,0 +1,113 @@ +// @target: esnext +// @module: esnext +// @lib: esnext +// @noTypesAndSymbols: true + +// Error: using in case clause +switch (1) { + case 0: + using x = { [Symbol.dispose]() {} }; + break; +} + +// Error: using in default clause +switch (2) { + default: + using y = { [Symbol.dispose]() {} }; + break; +} + +// Error: await using in case clause (top-level of module would need to be async, so wrap minimally) +{ + // Note: await using requires async context, tested separately in async functions +} + +// Error: Multiple using statements in same case +switch (5) { + case 0: + using c = { [Symbol.dispose]() {} }; + using d = { [Symbol.dispose]() {} }; + break; +} + +// Error: Nested switch with using +switch (6) { + case 0: + switch (7) { + case 1: + using e = { [Symbol.dispose]() {} }; + break; + } + break; +} + +// Valid: using before switch statement +using beforeSwitch = { [Symbol.dispose]() {} }; +switch (8) { + case 0: + console.log("ok"); + break; +} + +// Valid: Block-wrapped in case +switch (9) { + case 0: { + using valid1 = { [Symbol.dispose]() {} }; + break; + } +} + +// Valid: Block-wrapped in default +switch (10) { + default: { + using valid2 = { [Symbol.dispose]() {} }; + break; + } +} + +// Valid: Nested block in case +switch (11) { + case 0: { + { + using valid3 = { [Symbol.dispose]() {} }; + } + break; + } +} + +// Valid: If statement inside case with block +switch (12) { + case 0: + if (true) { + using valid4 = { [Symbol.dispose]() {} }; + } + break; +} + +// Error: Fall-through cases +switch (13) { + case 0: + case 1: + using fallthrough = { [Symbol.dispose]() {} }; + break; +} + +// Error: Case with no break +switch (14) { + case 0: + using nobreak = { [Symbol.dispose]() {} }; + case 1: + console.log("fallthrough"); + break; +} + +// Error: Empty case before default +switch (15) { + case 0: + // empty + default: + using inDefault = { [Symbol.dispose]() {} }; + break; +} + +export {};