From 6d6c620cc2e047047f8aba4eb7fe6acea81d77b4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 15:30:45 -0700 Subject: [PATCH] Report grammatic and type-based unreachable code errors in the same way --- src/compiler/binder.ts | 3 +++ src/compiler/checker.ts | 10 +++++----- src/compiler/types.ts | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5006e841dc7..cf93ee17ebd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -672,6 +672,9 @@ namespace ts { bindJSDoc(node); return; } + if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement) { + node.flowNode = currentFlow; + } switch (node.kind) { case SyntaxKind.WhileStatement: bindWhileStatement(node); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba06e08a301..501e6c4d92e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17057,11 +17057,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType) { - error(reference, Diagnostics.Unreachable_code_detected); - return declaredType; - } - if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType|| reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -30533,6 +30529,10 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); } } + if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && + !compilerOptions.allowUnreachableCode && node.flowNode && !isReachableFlowNode(node.flowNode)) { + errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected); + } switch (kind) { case SyntaxKind.TypeParameter: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f80126b64c5..afb53aea7a3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -363,8 +363,8 @@ namespace ts { SemicolonClassElement, // Element Block, - VariableStatement, EmptyStatement, + VariableStatement, ExpressionStatement, IfStatement, DoStatement, @@ -514,6 +514,8 @@ namespace ts { LastTemplateToken = TemplateTail, FirstBinaryOperator = LessThanToken, LastBinaryOperator = CaretEqualsToken, + FirstStatement = VariableStatement, + LastStatement = DebuggerStatement, FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, LastJSDocNode = JSDocPropertyTag,