From 8bc45541e391d737491cd43168c42ae66ce61613 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 2 Jul 2018 18:39:45 -0700 Subject: [PATCH 1/3] Increase span of unreachable code error --- src/compiler/binder.ts | 17 +++++++--- .../reference/reachabilityChecks1.errors.txt | 33 ++++++++++++------- .../reference/reachabilityChecks2.errors.txt | 9 +++-- .../reference/reachabilityChecks5.errors.txt | 6 ++-- .../reference/reachabilityChecks6.errors.txt | 6 ++-- .../unreachableJavascriptChecked.errors.txt | 7 ++-- .../reference/unreachableJavascriptChecked.js | 5 ++- .../unreachableJavascriptChecked.symbols | 2 ++ .../unreachableJavascriptChecked.types | 6 +++- .../compiler/unreachableJavascriptChecked.ts | 3 +- .../cases/fourslash/codeFixUnreachableCode.ts | 4 +-- 11 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b571530c5d9d7..efbce0f249257 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1211,7 +1211,7 @@ namespace ts { bind(node.statement); popActiveLabel(); if (!activeLabel.referenced && !options.allowUnusedLabels) { - errorOrSuggestionOnFirstToken(unusedLabelIsError(options), node, Diagnostics.Unused_label); + errorOrSuggestionOnNode(unusedLabelIsError(options), node.label, Diagnostics.Unused_label); } if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) { // do statement sets current flow inside bindDoStatement @@ -1918,9 +1918,16 @@ namespace ts { file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); } - function errorOrSuggestionOnFirstToken(isError: boolean, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { - const span = getSpanOfTokenAtPosition(file, node.pos); - const diag = createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2); + function errorOrSuggestionOnNode(isError: boolean, node: Node, message: DiagnosticMessage): void { + errorOrSuggestionOnRange(isError, node, node, message); + } + + function errorOrSuggestionOnRange(isError: boolean, startNode: Node, endNode: Node, message: DiagnosticMessage): void { + addErrorOrSuggestionDiagnostic(isError, { pos: getTokenPosOfNode(startNode, file), end: endNode.end }, message); + } + + function addErrorOrSuggestionDiagnostic(isError: boolean, range: TextRange, message: DiagnosticMessage): void { + const diag = createFileDiagnostic(file, range.pos, range.end - range.pos, message); if (isError) { file.bindDiagnostics.push(diag); } @@ -2792,7 +2799,7 @@ namespace ts { node.declarationList.declarations.some(d => !!d.initializer) ); - errorOrSuggestionOnFirstToken(isError, node, Diagnostics.Unreachable_code_detected); + errorOrSuggestionOnRange(isError, node, isBlock(node.parent) ? last(node.parent.statements) : node, Diagnostics.Unreachable_code_detected); } } } diff --git a/tests/baselines/reference/reachabilityChecks1.errors.txt b/tests/baselines/reference/reachabilityChecks1.errors.txt index 0f1a9b7bb1eeb..041d10bfecd5b 100644 --- a/tests/baselines/reference/reachabilityChecks1.errors.txt +++ b/tests/baselines/reference/reachabilityChecks1.errors.txt @@ -10,13 +10,13 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod ==== tests/cases/compiler/reachabilityChecks1.ts (7 errors) ==== while (true); var x = 1; - ~~~ + ~~~~~~~~~~ !!! error TS7027: Unreachable code detected. module A { while (true); let x; - ~~~ + ~~~~~~ !!! error TS7027: Unreachable code detected. } @@ -30,10 +30,12 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod module A2 { while (true); module A { - ~~~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~~~ var x = 1; + ~~~~~~~~~~~~~~~~~~ } + ~~~~~ +!!! error TS7027: Unreachable code detected. } module A3 { @@ -44,10 +46,12 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod module A4 { while (true); module A { - ~~~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~~~ const enum E { X } + ~~~~~~~~~~~~~~~~~~~~~~~~~~ } + ~~~~~ +!!! error TS7027: Unreachable code detected. } function f1(x) { @@ -63,9 +67,10 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod function f2() { return; class A { - ~~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~~ } + ~~~~~ +!!! error TS7027: Unreachable code detected. } module B { @@ -78,10 +83,12 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod do { } while (true); enum E { - ~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~ X = 1 + ~~~~~~~~~~~~~ } + ~~~~~ +!!! error TS7027: Unreachable code detected. } function f4() { @@ -89,10 +96,12 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod throw new Error(); } const enum E { - ~~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~~~~~~~ X = 1 + ~~~~~~~~~~~~~ } + ~~~~~ +!!! error TS7027: Unreachable code detected. } \ No newline at end of file diff --git a/tests/baselines/reference/reachabilityChecks2.errors.txt b/tests/baselines/reference/reachabilityChecks2.errors.txt index 9061effeb667f..922f888fad374 100644 --- a/tests/baselines/reference/reachabilityChecks2.errors.txt +++ b/tests/baselines/reference/reachabilityChecks2.errors.txt @@ -6,12 +6,17 @@ tests/cases/compiler/reachabilityChecks2.ts(4,1): error TS7027: Unreachable code const enum E { X } module A4 { - ~~~~~~ -!!! error TS7027: Unreachable code detected. + ~~~~~~~~~~~ while (true); + ~~~~~~~~~~~~~~~~~ module A { + ~~~~~~~~~~~~~~ const enum E { X } + ~~~~~~~~~~~~~~~~~~~~~~~~~~ } + ~~~~~ } + ~ +!!! error TS7027: Unreachable code detected. \ No newline at end of file diff --git a/tests/baselines/reference/reachabilityChecks5.errors.txt b/tests/baselines/reference/reachabilityChecks5.errors.txt index 4dc7c1705f1c8..f8c7e6f4dbc1a 100644 --- a/tests/baselines/reference/reachabilityChecks5.errors.txt +++ b/tests/baselines/reference/reachabilityChecks5.errors.txt @@ -109,7 +109,7 @@ tests/cases/compiler/reachabilityChecks5.ts(122,13): error TS7027: Unreachable c } else { return 1; - ~~~~~~ + ~~~~~~~~~ !!! error TS7027: Unreachable code detected. } } @@ -124,7 +124,7 @@ tests/cases/compiler/reachabilityChecks5.ts(122,13): error TS7027: Unreachable c try { while (false) { return 1; - ~~~~~~ + ~~~~~~~~~ !!! error TS7027: Unreachable code detected. } } @@ -154,7 +154,7 @@ tests/cases/compiler/reachabilityChecks5.ts(122,13): error TS7027: Unreachable c break test; } while (true); x++; - ~ + ~~~~ !!! error TS7027: Unreachable code detected. } while (true); } diff --git a/tests/baselines/reference/reachabilityChecks6.errors.txt b/tests/baselines/reference/reachabilityChecks6.errors.txt index 9dadf3b2d6f51..66744af3e033b 100644 --- a/tests/baselines/reference/reachabilityChecks6.errors.txt +++ b/tests/baselines/reference/reachabilityChecks6.errors.txt @@ -106,7 +106,7 @@ tests/cases/compiler/reachabilityChecks6.ts(122,13): error TS7027: Unreachable c } else { return 1; - ~~~~~~ + ~~~~~~~~~ !!! error TS7027: Unreachable code detected. } } @@ -121,7 +121,7 @@ tests/cases/compiler/reachabilityChecks6.ts(122,13): error TS7027: Unreachable c try { while (false) { return 1; - ~~~~~~ + ~~~~~~~~~ !!! error TS7027: Unreachable code detected. } } @@ -151,7 +151,7 @@ tests/cases/compiler/reachabilityChecks6.ts(122,13): error TS7027: Unreachable c break test; } while (true); x++; - ~ + ~~~~ !!! error TS7027: Unreachable code detected. } while (true); } diff --git a/tests/baselines/reference/unreachableJavascriptChecked.errors.txt b/tests/baselines/reference/unreachableJavascriptChecked.errors.txt index c66b342177fcd..50aca71943e80 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.errors.txt +++ b/tests/baselines/reference/unreachableJavascriptChecked.errors.txt @@ -5,6 +5,9 @@ tests/cases/compiler/unreachable.js(3,5): error TS7027: Unreachable code detecte function unreachable() { return 1; return 2; - ~~~~~~ + ~~~~~~~~~ + return 3; + ~~~~~~~~~~~~~ !!! error TS7027: Unreachable code detected. - } \ No newline at end of file + } + \ No newline at end of file diff --git a/tests/baselines/reference/unreachableJavascriptChecked.js b/tests/baselines/reference/unreachableJavascriptChecked.js index 6bf264bf3d22c..00a3d8de64567 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.js +++ b/tests/baselines/reference/unreachableJavascriptChecked.js @@ -2,10 +2,13 @@ function unreachable() { return 1; return 2; -} + return 3; +} + //// [unreachable.js] function unreachable() { return 1; return 2; + return 3; } diff --git a/tests/baselines/reference/unreachableJavascriptChecked.symbols b/tests/baselines/reference/unreachableJavascriptChecked.symbols index f2db6a6a3477f..d844d61b00533 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.symbols +++ b/tests/baselines/reference/unreachableJavascriptChecked.symbols @@ -4,4 +4,6 @@ function unreachable() { return 1; return 2; + return 3; } + diff --git a/tests/baselines/reference/unreachableJavascriptChecked.types b/tests/baselines/reference/unreachableJavascriptChecked.types index 266a9038875cb..adc64c9ae3fdd 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.types +++ b/tests/baselines/reference/unreachableJavascriptChecked.types @@ -1,10 +1,14 @@ === tests/cases/compiler/unreachable.js === function unreachable() { ->unreachable : () => 1 | 2 +>unreachable : () => 1 | 2 | 3 return 1; >1 : 1 return 2; >2 : 2 + + return 3; +>3 : 3 } + diff --git a/tests/cases/compiler/unreachableJavascriptChecked.ts b/tests/cases/compiler/unreachableJavascriptChecked.ts index afddcba6a23b1..ba0cc1dee1408 100644 --- a/tests/cases/compiler/unreachableJavascriptChecked.ts +++ b/tests/cases/compiler/unreachableJavascriptChecked.ts @@ -6,4 +6,5 @@ function unreachable() { return 1; return 2; -} \ No newline at end of file + return 3; +} diff --git a/tests/cases/fourslash/codeFixUnreachableCode.ts b/tests/cases/fourslash/codeFixUnreachableCode.ts index 5f70d51c1ee10..506db9dd5ea3c 100644 --- a/tests/cases/fourslash/codeFixUnreachableCode.ts +++ b/tests/cases/fourslash/codeFixUnreachableCode.ts @@ -2,7 +2,7 @@ ////function f() { //// return f(); -//// [|return|] 1; +//// [|return 1; //// function f() {} //// return 2; //// type T = number; @@ -13,7 +13,7 @@ //// namespace N { export const x: T = 0; } //// var x: I; //// var y: T = 0; -//// E; N; x; y; +//// E; N; x; y;|] ////} verify.getSuggestionDiagnostics([{ From 96db135849b401f5e8b9d08e7574287a7d56e819 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 3 Jul 2018 15:46:22 -0700 Subject: [PATCH 2/3] Add a new diagnostic for each range of unreachable statements --- src/compiler/binder.ts | 34 +++++++++++++- src/compiler/utilities.ts | 6 +++ src/services/codefixes/fixUnreachableCode.ts | 45 +++++-------------- ...mpilationBindReachabilityErrors.errors.txt | 2 +- .../unreachableJavascriptChecked.errors.txt | 9 +++- .../reference/unreachableJavascriptChecked.js | 8 +++- .../unreachableJavascriptChecked.symbols | 8 +++- .../unreachableJavascriptChecked.types | 13 ++++-- .../compiler/unreachableJavascriptChecked.ts | 4 +- .../cases/fourslash/codeFixUnreachableCode.ts | 21 ++++----- 10 files changed, 96 insertions(+), 54 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index efbce0f249257..20183785dfd10 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2799,7 +2799,7 @@ namespace ts { node.declarationList.declarations.some(d => !!d.initializer) ); - errorOrSuggestionOnRange(isError, node, isBlock(node.parent) ? last(node.parent.statements) : node, Diagnostics.Unreachable_code_detected); + eachUnreachableRange(node, (start, end) => errorOrSuggestionOnRange(isError, start, end, Diagnostics.Unreachable_code_detected)); } } } @@ -2807,6 +2807,38 @@ namespace ts { } } + function eachUnreachableRange(node: Node, cb: (start: Node, last: Node) => void): void { + if (isStatement(node) && isExecutableStatement(node) && isBlock(node.parent)) { + const { statements } = node.parent; + const slice = sliceAfter(statements, node); + getRangesWhere(slice, isExecutableStatement, (start, afterEnd) => cb(slice[start], slice[afterEnd - 1])); + } + else { + cb(node, node); + } + } + // As opposed to a pure declaration like an `interface` + function isExecutableStatement(s: Statement): boolean { + // Don't remove statements that can validly be used before they appear. + return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && + // `var x;` may declare a variable used above + !(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer)); + } + + function isPurelyTypeDeclaration(s: Statement): boolean { + switch (s.kind) { + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.TypeAliasDeclaration: + return true; + case SyntaxKind.ModuleDeclaration: + return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated; + case SyntaxKind.EnumDeclaration: + return hasModifier(s, ModifierFlags.Const); + default: + return false; + } + } + /* @internal */ export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean { return isExportsIdentifier(node) || diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a1c6d5137b27d..0c99290d74b7d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -8105,4 +8105,10 @@ namespace ts { return findBestPatternMatch(patterns, _ => _, candidate); } + + export function sliceAfter(arr: ReadonlyArray, value: T): ReadonlyArray { + const index = arr.indexOf(value); + Debug.assert(index !== -1); + return arr.slice(index); + } } diff --git a/src/services/codefixes/fixUnreachableCode.ts b/src/services/codefixes/fixUnreachableCode.ts index 1c6c53efe8e60..4fdb2c2016fd5 100644 --- a/src/services/codefixes/fixUnreachableCode.ts +++ b/src/services/codefixes/fixUnreachableCode.ts @@ -5,14 +5,14 @@ namespace ts.codefix { registerCodeFix({ errorCodes, getCodeActions(context) { - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start)); + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.span.length)); return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unreachable_code, fixId, Diagnostics.Remove_all_unreachable_code)]; }, fixIds: [fixId], - getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start)), + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start, diag.length)), }); - function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number): void { + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number, length: number): void { const token = getTokenAtPosition(sourceFile, start); const statement = findAncestor(token, isStatement)!; Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile)); @@ -36,7 +36,9 @@ namespace ts.codefix { break; default: if (isBlock(statement.parent)) { - split(sliceAfter(statement.parent.statements, statement), shouldRemove, (start, end) => changes.deleteNodeRange(sourceFile, start, end)); + const end = start + length; + const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end)); + changes.deleteNodeRange(sourceFile, statement, lastStatement); } else { changes.delete(sourceFile, statement); @@ -44,35 +46,12 @@ namespace ts.codefix { } } - function shouldRemove(s: Statement): boolean { - // Don't remove statements that can validly be used before they appear. - return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && - // `var x;` may declare a variable used above - !(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer)); - } - - function isPurelyTypeDeclaration(s: Statement): boolean { - switch (s.kind) { - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return true; - case SyntaxKind.ModuleDeclaration: - return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated; - case SyntaxKind.EnumDeclaration: - return hasModifier(s, ModifierFlags.Const); - default: - return false; + function lastWhere(a: ReadonlyArray, pred: (value: T) => boolean): T | undefined { + let last: T | undefined; + for (const value of a) { + if (!pred(value)) break; + last = value; } - } - - function sliceAfter(arr: ReadonlyArray, value: T): ReadonlyArray { - const index = arr.indexOf(value); - Debug.assert(index !== -1); - return arr.slice(index); - } - - // Calls 'cb' with the start and end of each range where 'pred' is true. - function split(arr: ReadonlyArray, pred: (t: T) => boolean, cb: (start: T, end: T) => void): void { - getRangesWhere(arr, pred, (start, afterEnd) => cb(arr[start], arr[afterEnd - 1])); + return last; } } diff --git a/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt b/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt index a883e66e6072f..c2c572aa3042b 100644 --- a/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt +++ b/tests/baselines/reference/jsFileCompilationBindReachabilityErrors.errors.txt @@ -22,7 +22,7 @@ tests/cases/compiler/a.js(19,1): error TS7028: Unused label. function bar2() { } var x = 10; // error - ~~~ + ~~~~~~~~~~~ !!! error TS7027: Unreachable code detected. } diff --git a/tests/baselines/reference/unreachableJavascriptChecked.errors.txt b/tests/baselines/reference/unreachableJavascriptChecked.errors.txt index 50aca71943e80..a4aee3b7805dd 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.errors.txt +++ b/tests/baselines/reference/unreachableJavascriptChecked.errors.txt @@ -1,13 +1,18 @@ tests/cases/compiler/unreachable.js(3,5): error TS7027: Unreachable code detected. +tests/cases/compiler/unreachable.js(6,5): error TS7027: Unreachable code detected. -==== tests/cases/compiler/unreachable.js (1 errors) ==== +==== tests/cases/compiler/unreachable.js (2 errors) ==== function unreachable() { - return 1; + return f(); return 2; ~~~~~~~~~ return 3; ~~~~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + function f() {} + return 4; + ~~~~~~~~~ !!! error TS7027: Unreachable code detected. } \ No newline at end of file diff --git a/tests/baselines/reference/unreachableJavascriptChecked.js b/tests/baselines/reference/unreachableJavascriptChecked.js index 00a3d8de64567..d12d4af675348 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.js +++ b/tests/baselines/reference/unreachableJavascriptChecked.js @@ -1,14 +1,18 @@ //// [unreachable.js] function unreachable() { - return 1; + return f(); return 2; return 3; + function f() {} + return 4; } //// [unreachable.js] function unreachable() { - return 1; + return f(); return 2; return 3; + function f() { } + return 4; } diff --git a/tests/baselines/reference/unreachableJavascriptChecked.symbols b/tests/baselines/reference/unreachableJavascriptChecked.symbols index d844d61b00533..11610239f5939 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.symbols +++ b/tests/baselines/reference/unreachableJavascriptChecked.symbols @@ -2,8 +2,14 @@ function unreachable() { >unreachable : Symbol(unreachable, Decl(unreachable.js, 0, 0)) - return 1; + return f(); +>f : Symbol(f, Decl(unreachable.js, 3, 13)) + return 2; return 3; + function f() {} +>f : Symbol(f, Decl(unreachable.js, 3, 13)) + + return 4; } diff --git a/tests/baselines/reference/unreachableJavascriptChecked.types b/tests/baselines/reference/unreachableJavascriptChecked.types index adc64c9ae3fdd..d27af1d33d88d 100644 --- a/tests/baselines/reference/unreachableJavascriptChecked.types +++ b/tests/baselines/reference/unreachableJavascriptChecked.types @@ -1,14 +1,21 @@ === tests/cases/compiler/unreachable.js === function unreachable() { ->unreachable : () => 1 | 2 | 3 +>unreachable : () => void | 2 | 3 | 4 - return 1; ->1 : 1 + return f(); +>f() : void +>f : () => void return 2; >2 : 2 return 3; >3 : 3 + + function f() {} +>f : () => void + + return 4; +>4 : 4 } diff --git a/tests/cases/compiler/unreachableJavascriptChecked.ts b/tests/cases/compiler/unreachableJavascriptChecked.ts index ba0cc1dee1408..3d9c906dc05e2 100644 --- a/tests/cases/compiler/unreachableJavascriptChecked.ts +++ b/tests/cases/compiler/unreachableJavascriptChecked.ts @@ -4,7 +4,9 @@ // @outDir: out // @allowUnreachableCode: false function unreachable() { - return 1; + return f(); return 2; return 3; + function f() {} + return 4; } diff --git a/tests/cases/fourslash/codeFixUnreachableCode.ts b/tests/cases/fourslash/codeFixUnreachableCode.ts index 506db9dd5ea3c..9c9eea6dae40c 100644 --- a/tests/cases/fourslash/codeFixUnreachableCode.ts +++ b/tests/cases/fourslash/codeFixUnreachableCode.ts @@ -2,29 +2,30 @@ ////function f() { //// return f(); -//// [|return 1; +//// [|return 1;|] //// function f() {} -//// return 2; +//// [|return 2;|] //// type T = number; //// interface I {} //// const enum E {} -//// enum E {} +//// [|enum E {}|] //// namespace N { export type T = number; } -//// namespace N { export const x: T = 0; } +//// [|namespace N { export const x: T = 0; }|] //// var x: I; -//// var y: T = 0; +//// [|var y: T = 0; //// E; N; x; y;|] ////} -verify.getSuggestionDiagnostics([{ +verify.getSuggestionDiagnostics(test.ranges().map((range): FourSlashInterface.Diagnostic => ({ message: "Unreachable code detected.", code: 7027, reportsUnnecessary: true, -}]); + range, +}))); -verify.codeFix({ - description: "Remove unreachable code", - index: 0, +verify.codeFixAll({ + fixId: "fixUnreachableCode", + fixAllDescription: "Remove all unreachable code", newFileContent: `function f() { return f(); From 03de0dbfa62d05d1af5e3bdecb446b3e47011932 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 5 Jul 2018 17:19:33 -0700 Subject: [PATCH 3/3] Update baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/cf.errors.txt | 8 ++++---- .../reference/jsFileCompilationBindErrors.errors.txt | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index bb441132862ac..dd6aaf2708ead 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7390,6 +7390,7 @@ declare namespace ts { type Mutable = { -readonly [K in keyof T]: T[K]; }; + function sliceAfter(arr: ReadonlyArray, value: T): ReadonlyArray; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; diff --git a/tests/baselines/reference/cf.errors.txt b/tests/baselines/reference/cf.errors.txt index 8f5f82f816962..910ffe5d88d37 100644 --- a/tests/baselines/reference/cf.errors.txt +++ b/tests/baselines/reference/cf.errors.txt @@ -14,7 +14,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected. if (y==7) { continue L1; x=11; - ~ + ~~~~~ !!! error TS7027: Unreachable code detected. } if (y==3) { @@ -28,7 +28,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected. if (y==20) { break; x=12; - ~ + ~~~~~ !!! error TS7027: Unreachable code detected. } } while (y<41); @@ -41,13 +41,13 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected. L3: if (x