diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 6973b1aef26..e8dffceda4d 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2946,7 +2946,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel); return isIterationStatement(statement, /*lookInLabeledStatements*/ false) ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node) - : factory.restoreEnclosingLabel(Debug.checkDefined(visitNode(statement, visitor, isStatement, factory.liftToBlock)), node, convertedLoopState && resetLabel); + : factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock) ?? setTextRange(factory.createEmptyStatement(), statement), node, convertedLoopState && resetLabel); } function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) { diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index ca8f46cf226..be0cf4bdf85 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -993,7 +993,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile return factory.updateLabeledStatement( node, node.label, - visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock) ?? factory.createExpressionStatement(factory.createIdentifier("")), + visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock) ?? setTextRange(factory.createEmptyStatement(), node.statement), ); } diff --git a/tests/baselines/reference/capturedLetConstInLoop14.errors.txt b/tests/baselines/reference/capturedLetConstInLoop14.errors.txt new file mode 100644 index 00000000000..ab5b98288ac --- /dev/null +++ b/tests/baselines/reference/capturedLetConstInLoop14.errors.txt @@ -0,0 +1,21 @@ +capturedLetConstInLoop14.ts(7,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'v' must be of type 'number', but here has type 'any'. + + +==== capturedLetConstInLoop14.ts (1 errors) ==== + function use(v: number) {} + + function foo(x: number) { + var v = 1; + do { + let x = v; + var v; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'v' must be of type 'number', but here has type 'any'. +!!! related TS6203 capturedLetConstInLoop14.ts:4:7: 'v' was also declared here. + var v = 2; + () => x + v; + } while (false); + + use(v); + } + \ No newline at end of file diff --git a/tests/baselines/reference/capturedLetConstInLoop14.js b/tests/baselines/reference/capturedLetConstInLoop14.js new file mode 100644 index 00000000000..cbf8119def9 --- /dev/null +++ b/tests/baselines/reference/capturedLetConstInLoop14.js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/capturedLetConstInLoop14.ts] //// + +//// [capturedLetConstInLoop14.ts] +function use(v: number) {} + +function foo(x: number) { + var v = 1; + do { + let x = v; + var v; + var v = 2; + () => x + v; + } while (false); + + use(v); +} + + +//// [capturedLetConstInLoop14.js] +"use strict"; +function use(v) { } +function foo(x) { + var v = 1; + var _loop_1 = function () { + var x_1 = v; + v = 2; + (function () { return x_1 + v; }); + }; + var v, v; + do { + _loop_1(); + } while (false); + use(v); +} diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.errors.txt b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.errors.txt new file mode 100644 index 00000000000..35cdc3ccea0 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.errors.txt @@ -0,0 +1,12 @@ +labeledStatementDeclarationListInLoopNoCrash1.ts(3,11): error TS1123: Variable declaration list cannot be empty. + + +==== labeledStatementDeclarationListInLoopNoCrash1.ts (1 errors) ==== + for (let x of []) { + var v0 = x; + foo: var; + +!!! error TS1123: Variable declaration list cannot be empty. + (function() { return x + v0}); + } + \ No newline at end of file diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.js b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.js new file mode 100644 index 00000000000..985b5ea0008 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash1.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash1.ts] //// + +//// [labeledStatementDeclarationListInLoopNoCrash1.ts] +for (let x of []) { + var v0 = x; + foo: var; + (function() { return x + v0}); +} + + +//// [labeledStatementDeclarationListInLoopNoCrash1.js] +"use strict"; +var _loop_1 = function (x) { + v0 = x; + foo: ; + (function () { return x + v0; }); +}; +var v0; +for (var _i = 0, _a = []; _i < _a.length; _i++) { + var x = _a[_i]; + _loop_1(x); +} diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash2.js b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash2.js new file mode 100644 index 00000000000..a95cecfa2f7 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash2.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash2.ts] //// + +//// [labeledStatementDeclarationListInLoopNoCrash2.ts] +for (let x of []) { + var v0 = x; + foo: var y; + (function() { return x + v0}); +} + + +//// [labeledStatementDeclarationListInLoopNoCrash2.js] +"use strict"; +var _loop_1 = function (x) { + v0 = x; + foo: ; + (function () { return x + v0; }); +}; +var v0, y; +for (var _i = 0, _a = []; _i < _a.length; _i++) { + var x = _a[_i]; + _loop_1(x); +} diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.errors.txt b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.errors.txt new file mode 100644 index 00000000000..075f135a3b8 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.errors.txt @@ -0,0 +1,76 @@ +labeledStatementDeclarationListInLoopNoCrash3.ts(9,12): error TS2339: Property 'classFormat' does not exist on type 'ParseThemeData'. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,12): error TS1005: ',' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,12): error TS2304: Cannot find name 'font'. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,21): error TS1005: ',' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,23): error TS1135: Argument expression expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,26): error TS1134: Variable declaration expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,41): error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,42): error TS1005: ')' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,53): error TS2304: Cannot find name 'fontSize'. +labeledStatementDeclarationListInLoopNoCrash3.ts(15,61): error TS1005: ';' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,12): error TS1005: ';' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,23): error TS1134: Variable declaration expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,38): error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,39): error TS1005: ')' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,50): error TS2304: Cannot find name 'height'. +labeledStatementDeclarationListInLoopNoCrash3.ts(16,56): error TS1005: ';' expected. +labeledStatementDeclarationListInLoopNoCrash3.ts(22,1): error TS1160: Unterminated template literal. + + +==== labeledStatementDeclarationListInLoopNoCrash3.ts (17 errors) ==== + // https://github.com/microsoft/TypeScript/issues/59345 + + export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + ~~~~~~~~~~~ +!!! error TS2339: Property 'classFormat' does not exist on type 'ParseThemeData'. + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2304: Cannot find name 'font'. + ~ +!!! error TS1005: ',' expected. + ~~~ +!!! error TS1135: Argument expression expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. + ~ +!!! error TS1005: ')' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'fontSize'. + ~ +!!! error TS1005: ';' expected. + `height: var(--button-size-${fontType}-height)`, + ~~~~~~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. + ~ +!!! error TS1005: ')' expected. + ~~~~~~ +!!! error TS2304: Cannot find name 'height'. + ~ +!!! error TS1005: ';' expected. + ].join(';') + ); + } + } + } + + +!!! error TS1160: Unterminated template literal. \ No newline at end of file diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.js b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.js new file mode 100644 index 00000000000..ee5a48513f0 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash3.js @@ -0,0 +1,63 @@ +//// [tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash3.ts] //// + +//// [labeledStatementDeclarationListInLoopNoCrash3.ts] +// https://github.com/microsoft/TypeScript/issues/59345 + +export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + `height: var(--button-size-${fontType}-height)`, + ].join(';') + ); + } + } +} + + +//// [labeledStatementDeclarationListInLoopNoCrash3.js] +"use strict"; +// https://github.com/microsoft/TypeScript/issues/59345 +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ParseThemeData = void 0; +var ParseThemeData = /** @class */ (function () { + function ParseThemeData() { + } + ParseThemeData.prototype.parseButton = function (button) { + var type = button.type, size = button.size; + var _loop_1 = function (item) { + var fontType = item.type; + var style = function (state) { return "color: var(--button-".concat(fontType, "-").concat(state, "-font-color)"); }; + this_1.classFormat("".concat(style('active'), ");\n }\n for (let item of size) {\n const fontType = item.type;\n this.classFormat(\n [\n "), font - size); + (--button - size - $); + { + fontType; + } + -fontSize; + ",\n "; + height: ; + (--button - size - $); + { + fontType; + } + -height; + ",\n ].join(';')\n );\n }\n }\n}\n"; + }; + var this_1 = this; + for (var _i = 0, type_1 = type; _i < type_1.length; _i++) { + var item = type_1[_i]; + _loop_1(item); + } + }; + return ParseThemeData; +}()); +exports.ParseThemeData = ParseThemeData; diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.errors.txt b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.errors.txt new file mode 100644 index 00000000000..8d20a6b2ac1 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.errors.txt @@ -0,0 +1,72 @@ +labeledStatementDeclarationListInLoopNoCrash4.ts(7,12): error TS2339: Property 'classFormat' does not exist on type 'ParseThemeData'. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,12): error TS1005: ',' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,12): error TS2304: Cannot find name 'font'. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,21): error TS1005: ',' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,23): error TS1135: Argument expression expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,26): error TS1134: Variable declaration expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,41): error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,42): error TS1005: ')' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,53): error TS2304: Cannot find name 'fontSize'. +labeledStatementDeclarationListInLoopNoCrash4.ts(13,61): error TS1005: ';' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(14,12): error TS1005: ';' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(14,27): error TS1005: ',' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(20,1): error TS1005: '}' expected. +labeledStatementDeclarationListInLoopNoCrash4.ts(20,1): error TS1160: Unterminated template literal. + + +==== labeledStatementDeclarationListInLoopNoCrash4.ts (14 errors) ==== + export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + ~~~~~~~~~~~ +!!! error TS2339: Property 'classFormat' does not exist on type 'ParseThemeData'. + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2304: Cannot find name 'font'. + ~ +!!! error TS1005: ',' expected. + ~~~ +!!! error TS1135: Argument expression expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`. + ~ +!!! error TS1005: ')' expected. + ~~~~~~~~ +!!! error TS2304: Cannot find name 'fontSize'. + ~ +!!! error TS1005: ';' expected. + `height: var foo`, + ~~~~~~ +!!! error TS1005: ';' expected. + ~~ + ].join(';') + ~~~~~~~~~~~~~~~~~~~ + ); + ~~~~~~~~ + } + ~~~~~ + } + ~~~ + } + ~ + + +!!! error TS1005: ',' expected. + +!!! error TS1005: '}' expected. +!!! related TS1007 labeledStatementDeclarationListInLoopNoCrash4.ts:4:28: The parser expected to find a '}' to match the '{' token here. + +!!! error TS1160: Unterminated template literal. \ No newline at end of file diff --git a/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.js b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.js new file mode 100644 index 00000000000..0ac3a9e0a34 --- /dev/null +++ b/tests/baselines/reference/labeledStatementDeclarationListInLoopNoCrash4.js @@ -0,0 +1,55 @@ +//// [tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash4.ts] //// + +//// [labeledStatementDeclarationListInLoopNoCrash4.ts] +export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + `height: var foo`, + ].join(';') + ); + } + } +} + + +//// [labeledStatementDeclarationListInLoopNoCrash4.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ParseThemeData = void 0; +var ParseThemeData = /** @class */ (function () { + function ParseThemeData() { + } + ParseThemeData.prototype.parseButton = function (button) { + var type = button.type, size = button.size; + var _loop_1 = function (item) { + var fontType = item.type; + var style = function (state) { return "color: var(--button-".concat(fontType, "-").concat(state, "-font-color)"); }; + this_1.classFormat("".concat(style('active'), ");\n }\n for (let item of size) {\n const fontType = item.type;\n this.classFormat(\n [\n "), font - size); + (--button - size - $); + { + fontType; + } + -fontSize; + ",\n "; + height: ; + ",\n ].join(';')\n );\n }\n }\n}\n"; + }; + var this_1 = this, foo; + for (var _i = 0, type_1 = type; _i < type_1.length; _i++) { + var item = type_1[_i]; + _loop_1(item); + } + }; + return ParseThemeData; +}()); +exports.ParseThemeData = ParseThemeData; diff --git a/tests/cases/compiler/capturedLetConstInLoop14.ts b/tests/cases/compiler/capturedLetConstInLoop14.ts new file mode 100644 index 00000000000..9c4d94def6c --- /dev/null +++ b/tests/cases/compiler/capturedLetConstInLoop14.ts @@ -0,0 +1,17 @@ +// @strict: true +// @target: es5 +// @noTypesAndSymbols: true + +function use(v: number) {} + +function foo(x: number) { + var v = 1; + do { + let x = v; + var v; + var v = 2; + () => x + v; + } while (false); + + use(v); +} diff --git a/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash1.ts b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash1.ts new file mode 100644 index 00000000000..74265116f75 --- /dev/null +++ b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash1.ts @@ -0,0 +1,9 @@ +// @strict: true +// @target: es5 +// @noTypesAndSymbols: true + +for (let x of []) { + var v0 = x; + foo: var; + (function() { return x + v0}); +} diff --git a/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash2.ts b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash2.ts new file mode 100644 index 00000000000..048775ea293 --- /dev/null +++ b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash2.ts @@ -0,0 +1,9 @@ +// @strict: true +// @target: es5 +// @noTypesAndSymbols: true + +for (let x of []) { + var v0 = x; + foo: var y; + (function() { return x + v0}); +} diff --git a/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash3.ts b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash3.ts new file mode 100644 index 00000000000..0fc7d951d2c --- /dev/null +++ b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash3.ts @@ -0,0 +1,25 @@ +// @strict: true +// @target: es5 +// @noTypesAndSymbols: true + +// https://github.com/microsoft/TypeScript/issues/59345 + +export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + `height: var(--button-size-${fontType}-height)`, + ].join(';') + ); + } + } +} diff --git a/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash4.ts b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash4.ts new file mode 100644 index 00000000000..53d7e6d263f --- /dev/null +++ b/tests/cases/conformance/statements/labeledStatements/labeledStatementDeclarationListInLoopNoCrash4.ts @@ -0,0 +1,23 @@ +// @strict: true +// @target: es5 +// @noTypesAndSymbols: true + +export class ParseThemeData { + parseButton(button: any) { + const {type, size} = button; + for (let item of type) { + const fontType = item.type; + const style = (state: string) => `color: var(--button-${fontType}-${state}-font-color)`; + this.classFormat(`${style('active')}); + } + for (let item of size) { + const fontType = item.type; + this.classFormat( + [ + `font-size: var(--button-size-${fontType}-fontSize)`, + `height: var foo`, + ].join(';') + ); + } + } +}