mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-10 00:20:22 -06:00
Move unreachable checks to checker (#62751)
This commit is contained in:
parent
ea48dedd7d
commit
09e31cf04a
@ -46,7 +46,6 @@ import {
|
||||
DeleteExpression,
|
||||
DestructuringAssignment,
|
||||
DiagnosticArguments,
|
||||
DiagnosticCategory,
|
||||
DiagnosticMessage,
|
||||
DiagnosticRelatedInformation,
|
||||
Diagnostics,
|
||||
@ -87,7 +86,6 @@ import {
|
||||
getAssignmentDeclarationKind,
|
||||
getAssignmentDeclarationPropertyAccessKind,
|
||||
getCombinedModifierFlags,
|
||||
getCombinedNodeFlags,
|
||||
getContainingClass,
|
||||
getEffectiveContainerForJSDocTemplateTag,
|
||||
getElementOrPropertyAccessName,
|
||||
@ -106,7 +104,6 @@ import {
|
||||
getNameOfDeclaration,
|
||||
getNameOrArgument,
|
||||
getNodeId,
|
||||
getRangesWhere,
|
||||
getRightMostAssignedExpression,
|
||||
getSourceFileOfNode,
|
||||
getSourceTextOfNodeFromSourceFile,
|
||||
@ -115,10 +112,8 @@ import {
|
||||
getSymbolNameForPrivateIdentifier,
|
||||
getTextOfIdentifierOrLiteral,
|
||||
getThisContainer,
|
||||
getTokenPosOfNode,
|
||||
HasContainerFlags,
|
||||
hasDynamicName,
|
||||
HasFlowNode,
|
||||
hasJSDocNodes,
|
||||
HasLocals,
|
||||
hasSyntacticModifier,
|
||||
@ -164,7 +159,6 @@ import {
|
||||
isExternalModule,
|
||||
isExternalOrCommonJsModule,
|
||||
isForInOrOfStatement,
|
||||
isFunctionDeclaration,
|
||||
isFunctionLike,
|
||||
isFunctionLikeDeclaration,
|
||||
isFunctionLikeOrClassStaticBlockDeclaration,
|
||||
@ -204,6 +198,7 @@ import {
|
||||
isParenthesizedExpression,
|
||||
isPartOfParameterDeclaration,
|
||||
isPartOfTypeQuery,
|
||||
isPotentiallyExecutableNode,
|
||||
isPrefixUnaryExpression,
|
||||
isPrivateIdentifier,
|
||||
isPrologueDirective,
|
||||
@ -217,8 +212,6 @@ import {
|
||||
isSignedNumericLiteral,
|
||||
isSourceFile,
|
||||
isSpecialPropertyDeclaration,
|
||||
isStatement,
|
||||
isStatementButNotDeclaration,
|
||||
isStatic,
|
||||
isString,
|
||||
isStringLiteralLike,
|
||||
@ -286,10 +279,8 @@ import {
|
||||
setParentRecursive,
|
||||
setValueDeclaration,
|
||||
ShorthandPropertyAssignment,
|
||||
shouldPreserveConstEnums,
|
||||
SignatureDeclaration,
|
||||
skipParentheses,
|
||||
sliceAfter,
|
||||
some,
|
||||
SourceFile,
|
||||
SpreadElement,
|
||||
@ -302,7 +293,6 @@ import {
|
||||
symbolName,
|
||||
SymbolTable,
|
||||
SyntaxKind,
|
||||
TextRange,
|
||||
ThisExpression,
|
||||
ThrowStatement,
|
||||
tokenToString,
|
||||
@ -315,8 +305,6 @@ import {
|
||||
TypeOfExpression,
|
||||
TypeParameterDeclaration,
|
||||
unescapeLeadingUnderscores,
|
||||
unreachableCodeIsError,
|
||||
unusedLabelIsError,
|
||||
VariableDeclaration,
|
||||
WhileStatement,
|
||||
WithStatement,
|
||||
@ -565,7 +553,6 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
var classifiableNames: Set<__String>;
|
||||
|
||||
var unreachableFlow = createFlowNode(FlowFlags.Unreachable, /*node*/ undefined, /*antecedent*/ undefined);
|
||||
var reportedUnreachableFlow = createFlowNode(FlowFlags.Unreachable, /*node*/ undefined, /*antecedent*/ undefined);
|
||||
var bindBinaryExpressionFlow = createBindBinaryExpressionFlow();
|
||||
/* eslint-enable no-var */
|
||||
|
||||
@ -592,7 +579,6 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
|
||||
// Attach debugging information if necessary
|
||||
Debug.attachFlowNodeDebugInfo(unreachableFlow);
|
||||
Debug.attachFlowNodeDebugInfo(reportedUnreachableFlow);
|
||||
|
||||
if (!file.locals) {
|
||||
tracing?.push(tracing.Phase.Bind, "bindSourceFile", { path: file.path }, /*separateBeginAndEnd*/ true);
|
||||
@ -1104,18 +1090,24 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
// Most nodes aren't valid in an assignment pattern, so we clear the value here
|
||||
// and set it before we descend into nodes that could actually be part of an assignment pattern.
|
||||
inAssignmentPattern = false;
|
||||
if (checkUnreachable(node)) {
|
||||
if (canHaveFlowNode(node) && node.flowNode) {
|
||||
|
||||
if (currentFlow === unreachableFlow) {
|
||||
if (canHaveFlowNode(node)) {
|
||||
node.flowNode = undefined;
|
||||
}
|
||||
if (isPotentiallyExecutableNode(node)) {
|
||||
(node as Mutable<Node>).flags |= NodeFlags.Unreachable;
|
||||
}
|
||||
bindEachChild(node);
|
||||
bindJSDoc(node);
|
||||
inAssignmentPattern = saveInAssignmentPattern;
|
||||
return;
|
||||
}
|
||||
if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement && (!options.allowUnreachableCode || node.kind === SyntaxKind.ReturnStatement)) {
|
||||
(node as HasFlowNode).flowNode = currentFlow;
|
||||
|
||||
if (SyntaxKind.FirstStatement <= node.kind && node.kind <= SyntaxKind.LastStatement && canHaveFlowNode(node)) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.WhileStatement:
|
||||
bindWhileStatement(node as WhileStatement);
|
||||
@ -1793,8 +1785,8 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
};
|
||||
bind(node.label);
|
||||
bind(node.statement);
|
||||
if (!activeLabelList.referenced && !options.allowUnusedLabels) {
|
||||
errorOrSuggestionOnNode(unusedLabelIsError(options), node.label, Diagnostics.Unused_label);
|
||||
if (!activeLabelList.referenced) {
|
||||
(node.label as Mutable<Node>).flags |= NodeFlags.Unreachable;
|
||||
}
|
||||
activeLabelList = activeLabelList.next;
|
||||
addAntecedent(postStatementLabel, currentFlow);
|
||||
@ -2743,24 +2735,6 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, ...args));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
file.bindSuggestionDiagnostics = append(file.bindSuggestionDiagnostics, { ...diag, category: DiagnosticCategory.Suggestion });
|
||||
}
|
||||
}
|
||||
|
||||
function bind(node: Node | undefined): void {
|
||||
if (!node) {
|
||||
return;
|
||||
@ -3793,93 +3767,6 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
// reachability checks
|
||||
|
||||
function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean {
|
||||
const instanceState = getModuleInstanceState(node);
|
||||
return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && shouldPreserveConstEnums(options));
|
||||
}
|
||||
|
||||
function checkUnreachable(node: Node): boolean {
|
||||
if (!(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
return false;
|
||||
}
|
||||
if (currentFlow === unreachableFlow) {
|
||||
const reportError =
|
||||
// report error on all statements except empty ones
|
||||
(isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) ||
|
||||
// report error on class declarations
|
||||
node.kind === SyntaxKind.ClassDeclaration ||
|
||||
// report errors on enums with preserved emit
|
||||
isEnumDeclarationWithPreservedEmit(node, options) ||
|
||||
// report error on instantiated modules
|
||||
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node as ModuleDeclaration));
|
||||
|
||||
if (reportError) {
|
||||
currentFlow = reportedUnreachableFlow;
|
||||
|
||||
if (!options.allowUnreachableCode) {
|
||||
// unreachable code is reported if
|
||||
// - user has explicitly asked about it AND
|
||||
// - statement is in not ambient context (statements in ambient context is already an error
|
||||
// so we should not report extras) AND
|
||||
// - node is not variable statement OR
|
||||
// - node is block scoped variable statement OR
|
||||
// - node is not block scoped variable statement and at least one variable declaration has initializer
|
||||
// Rationale: we don't want to report errors on non-initialized var's since they are hoisted
|
||||
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
|
||||
const isError = unreachableCodeIsError(options) &&
|
||||
!(node.flags & NodeFlags.Ambient) &&
|
||||
(
|
||||
!isVariableStatement(node) ||
|
||||
!!(getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) ||
|
||||
node.declarationList.declarations.some(d => !!d.initializer)
|
||||
);
|
||||
|
||||
eachUnreachableRange(node, options, (start, end) => errorOrSuggestionOnRange(isError, start, end, Diagnostics.Unreachable_code_detected));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function isEnumDeclarationWithPreservedEmit(node: Node, options: CompilerOptions): boolean {
|
||||
return node.kind === SyntaxKind.EnumDeclaration && (!isEnumConst(node as EnumDeclaration) || shouldPreserveConstEnums(options));
|
||||
}
|
||||
|
||||
function eachUnreachableRange(node: Node, options: CompilerOptions, 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.BlockScoped)) && 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 !isEnumDeclarationWithPreservedEmit(s, options);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@ -62,6 +62,7 @@ import {
|
||||
canHaveLocals,
|
||||
canHaveModifiers,
|
||||
canHaveModuleSpecifier,
|
||||
canHaveStatements,
|
||||
canHaveSymbol,
|
||||
canIncludeBindAndCheckDiagnostics,
|
||||
canUsePropertyAccess,
|
||||
@ -708,6 +709,7 @@ import {
|
||||
isPartOfTypeOnlyImportOrExportDeclaration,
|
||||
isPartOfTypeQuery,
|
||||
isPlainJsFile,
|
||||
isPotentiallyExecutableNode,
|
||||
isPrefixUnaryExpression,
|
||||
isPrivateIdentifier,
|
||||
isPrivateIdentifierClassElementDeclaration,
|
||||
@ -1512,6 +1514,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
var currentNode: Node | undefined;
|
||||
var varianceTypeParameter: TypeParameter | undefined;
|
||||
var isInferencePartiallyBlocked = false;
|
||||
var withinUnreachableCode = false;
|
||||
var reportedUnreachableNodes: Set<Node> | undefined;
|
||||
|
||||
var emptySymbols = createSymbolTable();
|
||||
var arrayVariances = [VarianceFlags.Covariant];
|
||||
@ -46603,6 +46607,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
});
|
||||
}
|
||||
|
||||
if (node.label.flags & NodeFlags.Unreachable && compilerOptions.allowUnusedLabels !== true) {
|
||||
errorOrSuggestion(compilerOptions.allowUnusedLabels === false, node.label, Diagnostics.Unused_label);
|
||||
}
|
||||
|
||||
// ensure that label is unique
|
||||
checkSourceElement(node.statement);
|
||||
}
|
||||
@ -48967,10 +48975,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function checkSourceElement(node: Node | undefined): void {
|
||||
if (node) {
|
||||
const saveCurrentNode = currentNode;
|
||||
const saveWithinUnreachableCode = withinUnreachableCode;
|
||||
currentNode = node;
|
||||
instantiationCount = 0;
|
||||
checkSourceElementWorker(node);
|
||||
currentNode = saveCurrentNode;
|
||||
withinUnreachableCode = saveWithinUnreachableCode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49003,8 +49013,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && canHaveFlowNode(node) && node.flowNode && !isReachableFlowNode(node.flowNode)) {
|
||||
errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected);
|
||||
|
||||
if (compilerOptions.allowUnreachableCode !== true && !withinUnreachableCode) {
|
||||
if (checkSourceElementUnreachable(node)) {
|
||||
withinUnreachableCode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If editing this, keep `isSourceElement` in utilities up to date.
|
||||
@ -49185,6 +49198,86 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function checkSourceElementUnreachable(node: Node): boolean {
|
||||
if (!isPotentiallyExecutableNode(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reportedUnreachableNodes?.has(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isSourceElementUnreachable(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(reportedUnreachableNodes ??= new Set()).add(node);
|
||||
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
|
||||
let start = node.pos;
|
||||
let end = node.end;
|
||||
|
||||
const parent = node.parent;
|
||||
if (canHaveStatements(parent)) {
|
||||
const statements = parent.statements;
|
||||
const offset = statements.indexOf(node as Statement);
|
||||
if (offset >= 0) {
|
||||
// Scan backwards to find the first unreachable unreported node;
|
||||
// this may happen when producing region diagnostics where not all nodes
|
||||
// will have been visited.
|
||||
let first = offset;
|
||||
for (let i = offset - 1; i >= 0; i--) {
|
||||
const prevNode = statements[i];
|
||||
if (!isPotentiallyExecutableNode(prevNode) || reportedUnreachableNodes.has(prevNode) || !isSourceElementUnreachable(prevNode)) {
|
||||
break;
|
||||
}
|
||||
first = i;
|
||||
reportedUnreachableNodes.add(prevNode);
|
||||
}
|
||||
|
||||
let last = offset;
|
||||
for (let i = offset + 1; i < statements.length; i++) {
|
||||
const nextNode = statements[i];
|
||||
if (!isPotentiallyExecutableNode(nextNode) || !isSourceElementUnreachable(nextNode)) {
|
||||
break;
|
||||
}
|
||||
last = i;
|
||||
reportedUnreachableNodes.add(nextNode);
|
||||
}
|
||||
|
||||
start = statements[first].pos;
|
||||
end = statements[last].end;
|
||||
}
|
||||
}
|
||||
|
||||
start = skipTrivia(sourceFile.text, start);
|
||||
addErrorOrSuggestion(compilerOptions.allowUnreachableCode === false, createFileDiagnostic(sourceFile, start, end - start, Diagnostics.Unreachable_code_detected));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isSourceElementUnreachable(node: Node): boolean {
|
||||
// Precondition: isPotentiallyExecutableNode is true
|
||||
if (node.flags & NodeFlags.Unreachable) {
|
||||
// The binder has determined that this code is unreachable.
|
||||
// Ignore const enums unless preserveConstEnums is set.
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return !isEnumConst(node as EnumDeclaration) || shouldPreserveConstEnums(compilerOptions);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return isInstantiatedModule(node as ModuleDeclaration, shouldPreserveConstEnums(compilerOptions));
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (canHaveFlowNode(node) && node.flowNode) {
|
||||
// For code the binder doesn't know is unreachable, use control flow / types.
|
||||
return !isReachableFlowNode(node.flowNode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkJSDocCommentWorker(node: string | readonly JSDocComment[] | undefined) {
|
||||
if (isArray(node)) {
|
||||
forEach(node, tag => {
|
||||
@ -49383,6 +49476,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
performance.mark(afterMark);
|
||||
performance.measure("Check", beforeMark, afterMark);
|
||||
tracing?.pop();
|
||||
reportedUnreachableNodes = undefined;
|
||||
}
|
||||
|
||||
function unusedIsError(kind: UnusedKind, isAmbient: boolean): boolean {
|
||||
|
||||
@ -823,6 +823,7 @@ export const enum NodeFlags {
|
||||
JsonFile = 1 << 27, // If node was parsed in a Json
|
||||
/** @internal */ TypeCached = 1 << 28, // If a type was cached for node at any point
|
||||
/** @internal */ Deprecated = 1 << 29, // If has '@deprecated' JSDoc tag
|
||||
/** @internal */ Unreachable = 1 << 30, // If node is unreachable according to the binder
|
||||
|
||||
BlockScoped = Let | Const | Using,
|
||||
Constant = Const | Using,
|
||||
|
||||
@ -261,7 +261,9 @@ import {
|
||||
isBinaryExpression,
|
||||
isBindingElement,
|
||||
isBindingPattern,
|
||||
isBlock,
|
||||
isCallExpression,
|
||||
isCaseClause,
|
||||
isClassDeclaration,
|
||||
isClassElement,
|
||||
isClassExpression,
|
||||
@ -274,6 +276,7 @@ import {
|
||||
isDeclaration,
|
||||
isDeclarationFileName,
|
||||
isDecorator,
|
||||
isDefaultClause,
|
||||
isElementAccessExpression,
|
||||
isEnumDeclaration,
|
||||
isEnumMember,
|
||||
@ -332,6 +335,7 @@ import {
|
||||
isMethodDeclaration,
|
||||
isMethodOrAccessor,
|
||||
isModifierLike,
|
||||
isModuleBlock,
|
||||
isModuleDeclaration,
|
||||
isModuleOrEnumDeclaration,
|
||||
isNamedDeclaration,
|
||||
@ -9273,16 +9277,6 @@ export function hasJsonModuleEmitEnabled(options: CompilerOptions): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function unreachableCodeIsError(options: CompilerOptions): boolean {
|
||||
return options.allowUnreachableCode === false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function unusedLabelIsError(options: CompilerOptions): boolean {
|
||||
return options.allowUnusedLabels === false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution: ModuleResolutionKind): boolean {
|
||||
return moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext
|
||||
@ -12372,3 +12366,22 @@ function addEmitFlagsRecursively(node: Node, flag: EmitFlags, getChild: (n: Node
|
||||
function getFirstChild(node: Node): Node | undefined {
|
||||
return forEachChild(node, child => child);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function canHaveStatements(node: Node): node is Block | ModuleBlock | SourceFile | CaseClause | DefaultClause {
|
||||
return isBlock(node) || isModuleBlock(node) || isSourceFile(node) || isCaseClause(node) || isDefaultClause(node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isPotentiallyExecutableNode(node: Node): boolean {
|
||||
if (SyntaxKind.FirstStatement <= node.kind && node.kind <= SyntaxKind.LastStatement) {
|
||||
if (isVariableStatement(node)) {
|
||||
if (getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) {
|
||||
return true;
|
||||
}
|
||||
return some(node.declarationList.declarations, d => d.initializer !== undefined);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return isClassDeclaration(node) || isEnumDeclaration(node) || isModuleDeclaration(node);
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ neverReturningFunctions1.ts(101,13): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(103,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(105,5): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(111,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(112,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(122,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(127,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(129,5): error TS7027: Unreachable code detected.
|
||||
@ -23,7 +22,7 @@ neverReturningFunctions1.ts(148,9): error TS7027: Unreachable code detected.
|
||||
neverReturningFunctions1.ts(153,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== neverReturningFunctions1.ts (23 errors) ====
|
||||
==== neverReturningFunctions1.ts (22 errors) ====
|
||||
function fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
@ -163,10 +162,9 @@ neverReturningFunctions1.ts(153,5): error TS7027: Unreachable code detected.
|
||||
if (typeof x.a === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
x.a; // Unreachable
|
||||
~~~~
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // { a: string | number }
|
||||
|
||||
@ -1,58 +1,77 @@
|
||||
reachabilityChecks1.ts(2,1): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(6,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(18,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(30,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(47,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(51,1): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(60,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks1.ts(69,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== reachabilityChecks1.ts (7 errors) ====
|
||||
==== reachabilityChecks1.ts (5 errors) ====
|
||||
while (true);
|
||||
var x = 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
namespace A {
|
||||
~~~~~~~~~~~~~
|
||||
while (true);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
let x;
|
||||
~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
~~~~~~~~~~
|
||||
}
|
||||
~
|
||||
|
||||
|
||||
namespace A1 {
|
||||
~~~~~~~~~~~~~~
|
||||
do {} while(true);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
namespace A {
|
||||
~~~~~~~~~~~~~~~~~
|
||||
interface F {}
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
}
|
||||
~
|
||||
|
||||
|
||||
namespace A2 {
|
||||
~~~~~~~~~~~~~~
|
||||
while (true);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
namespace A {
|
||||
~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~
|
||||
var x = 1;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
~
|
||||
|
||||
|
||||
namespace A3 {
|
||||
~~~~~~~~~~~~~~
|
||||
while (true);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
type T = string;
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~
|
||||
|
||||
|
||||
namespace A4 {
|
||||
~~~~~~~~~~~~~~
|
||||
while (true);
|
||||
~~~~~~~~~~~~~~~~~
|
||||
namespace A {
|
||||
~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~
|
||||
const enum E { X }
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
|
||||
function f1(x) {
|
||||
if (x) {
|
||||
@ -74,10 +93,16 @@ reachabilityChecks1.ts(69,5): error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
namespace B {
|
||||
~~~~~~~~~~~~~
|
||||
for (; ;);
|
||||
~~~~~~~~~~~~~~
|
||||
namespace C {
|
||||
~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
}
|
||||
~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
|
||||
function f3() {
|
||||
do {
|
||||
|
||||
11
tests/baselines/reference/reachabilityChecks10.errors.txt
Normal file
11
tests/baselines/reference/reachabilityChecks10.errors.txt
Normal file
@ -0,0 +1,11 @@
|
||||
reachabilityChecks10.ts(2,1): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== reachabilityChecks10.ts (1 errors) ====
|
||||
throw new Error("")
|
||||
console.log("1")
|
||||
~~~~~~~~~~~~~~~~
|
||||
console.log("2")
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
|
||||
16
tests/baselines/reference/reachabilityChecks10.symbols
Normal file
16
tests/baselines/reference/reachabilityChecks10.symbols
Normal file
@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks10.ts] ////
|
||||
|
||||
=== reachabilityChecks10.ts ===
|
||||
throw new Error("")
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
console.log("1")
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
console.log("2")
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
35
tests/baselines/reference/reachabilityChecks10.types
Normal file
35
tests/baselines/reference/reachabilityChecks10.types
Normal file
@ -0,0 +1,35 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks10.ts] ////
|
||||
|
||||
=== reachabilityChecks10.ts ===
|
||||
throw new Error("")
|
||||
>new Error("") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
|
||||
console.log("1")
|
||||
>console.log("1") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"1" : "1"
|
||||
> : ^^^
|
||||
|
||||
console.log("2")
|
||||
>console.log("2") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"2" : "2"
|
||||
> : ^^^
|
||||
|
||||
104
tests/baselines/reference/reachabilityChecks11.errors.txt
Normal file
104
tests/baselines/reference/reachabilityChecks11.errors.txt
Normal file
@ -0,0 +1,104 @@
|
||||
reachabilityChecks11.ts(6,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks11.ts(18,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks11.ts(30,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks11.ts(47,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks11.ts(60,5): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks11.ts(69,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== reachabilityChecks11.ts (6 errors) ====
|
||||
// while (true);
|
||||
var x = 1;
|
||||
|
||||
module A {
|
||||
while (true);
|
||||
let x;
|
||||
~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
module A1 {
|
||||
do {} while(true);
|
||||
module A {
|
||||
interface F {}
|
||||
}
|
||||
}
|
||||
|
||||
module A2 {
|
||||
while (true);
|
||||
module A {
|
||||
~~~~~~~~~~
|
||||
var x = 1;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
module A3 {
|
||||
while (true);
|
||||
type T = string;
|
||||
}
|
||||
|
||||
module A4 {
|
||||
while (true);
|
||||
module A {
|
||||
~~~~~~~~~~
|
||||
const enum E { X }
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f1(x) {
|
||||
if (x) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
}
|
||||
var x;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
return;
|
||||
class A {
|
||||
~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
module B {
|
||||
for (; ;);
|
||||
module C {
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
do {
|
||||
} while (true);
|
||||
enum E {
|
||||
~~~~~~~~
|
||||
X = 1
|
||||
~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
throw new Error();
|
||||
}
|
||||
const enum E {
|
||||
~~~~~~~~~~~~~~
|
||||
X = 1
|
||||
~~~~~~~~~~~~~
|
||||
}
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
|
||||
156
tests/baselines/reference/reachabilityChecks11.js
Normal file
156
tests/baselines/reference/reachabilityChecks11.js
Normal file
@ -0,0 +1,156 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks11.ts] ////
|
||||
|
||||
//// [reachabilityChecks11.ts]
|
||||
// while (true);
|
||||
var x = 1;
|
||||
|
||||
module A {
|
||||
while (true);
|
||||
let x;
|
||||
}
|
||||
|
||||
module A1 {
|
||||
do {} while(true);
|
||||
module A {
|
||||
interface F {}
|
||||
}
|
||||
}
|
||||
|
||||
module A2 {
|
||||
while (true);
|
||||
module A {
|
||||
var x = 1;
|
||||
}
|
||||
}
|
||||
|
||||
module A3 {
|
||||
while (true);
|
||||
type T = string;
|
||||
}
|
||||
|
||||
module A4 {
|
||||
while (true);
|
||||
module A {
|
||||
const enum E { X }
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x) {
|
||||
if (x) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
}
|
||||
var x;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
return;
|
||||
class A {
|
||||
}
|
||||
}
|
||||
|
||||
module B {
|
||||
for (; ;);
|
||||
module C {
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
do {
|
||||
} while (true);
|
||||
enum E {
|
||||
X = 1
|
||||
}
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
throw new Error();
|
||||
}
|
||||
const enum E {
|
||||
X = 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// [reachabilityChecks11.js]
|
||||
// while (true);
|
||||
var x = 1;
|
||||
var A;
|
||||
(function (A) {
|
||||
while (true)
|
||||
;
|
||||
var x;
|
||||
})(A || (A = {}));
|
||||
var A1;
|
||||
(function (A1) {
|
||||
do { } while (true);
|
||||
})(A1 || (A1 = {}));
|
||||
var A2;
|
||||
(function (A2) {
|
||||
while (true)
|
||||
;
|
||||
var A;
|
||||
(function (A) {
|
||||
var x = 1;
|
||||
})(A || (A = {}));
|
||||
})(A2 || (A2 = {}));
|
||||
var A3;
|
||||
(function (A3) {
|
||||
while (true)
|
||||
;
|
||||
})(A3 || (A3 = {}));
|
||||
var A4;
|
||||
(function (A4) {
|
||||
while (true)
|
||||
;
|
||||
var A;
|
||||
(function (A) {
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["X"] = 0] = "X";
|
||||
})(E || (E = {}));
|
||||
})(A || (A = {}));
|
||||
})(A4 || (A4 = {}));
|
||||
function f1(x) {
|
||||
if (x) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
}
|
||||
var x;
|
||||
}
|
||||
function f2() {
|
||||
return;
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
}
|
||||
var B;
|
||||
(function (B) {
|
||||
for (;;)
|
||||
;
|
||||
})(B || (B = {}));
|
||||
function f3() {
|
||||
do {
|
||||
} while (true);
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["X"] = 1] = "X";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
function f4() {
|
||||
if (true) {
|
||||
throw new Error();
|
||||
}
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["X"] = 1] = "X";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
124
tests/baselines/reference/reachabilityChecks11.symbols
Normal file
124
tests/baselines/reference/reachabilityChecks11.symbols
Normal file
@ -0,0 +1,124 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks11.ts] ////
|
||||
|
||||
=== reachabilityChecks11.ts ===
|
||||
// while (true);
|
||||
var x = 1;
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 1, 3))
|
||||
|
||||
module A {
|
||||
>A : Symbol(A, Decl(reachabilityChecks11.ts, 1, 10))
|
||||
|
||||
while (true);
|
||||
let x;
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 5, 7))
|
||||
}
|
||||
|
||||
module A1 {
|
||||
>A1 : Symbol(A1, Decl(reachabilityChecks11.ts, 6, 1))
|
||||
|
||||
do {} while(true);
|
||||
module A {
|
||||
>A : Symbol(A, Decl(reachabilityChecks11.ts, 9, 22))
|
||||
|
||||
interface F {}
|
||||
>F : Symbol(F, Decl(reachabilityChecks11.ts, 10, 14))
|
||||
}
|
||||
}
|
||||
|
||||
module A2 {
|
||||
>A2 : Symbol(A2, Decl(reachabilityChecks11.ts, 13, 1))
|
||||
|
||||
while (true);
|
||||
module A {
|
||||
>A : Symbol(A, Decl(reachabilityChecks11.ts, 16, 17))
|
||||
|
||||
var x = 1;
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 18, 11))
|
||||
}
|
||||
}
|
||||
|
||||
module A3 {
|
||||
>A3 : Symbol(A3, Decl(reachabilityChecks11.ts, 20, 1))
|
||||
|
||||
while (true);
|
||||
type T = string;
|
||||
>T : Symbol(T, Decl(reachabilityChecks11.ts, 23, 17))
|
||||
}
|
||||
|
||||
module A4 {
|
||||
>A4 : Symbol(A4, Decl(reachabilityChecks11.ts, 25, 1))
|
||||
|
||||
while (true);
|
||||
module A {
|
||||
>A : Symbol(A, Decl(reachabilityChecks11.ts, 28, 17))
|
||||
|
||||
const enum E { X }
|
||||
>E : Symbol(E, Decl(reachabilityChecks11.ts, 29, 14))
|
||||
>X : Symbol(E.X, Decl(reachabilityChecks11.ts, 30, 22))
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x) {
|
||||
>f1 : Symbol(f1, Decl(reachabilityChecks11.ts, 32, 1))
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 34, 12), Decl(reachabilityChecks11.ts, 41, 7))
|
||||
|
||||
if (x) {
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 34, 12), Decl(reachabilityChecks11.ts, 41, 7))
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
var x;
|
||||
>x : Symbol(x, Decl(reachabilityChecks11.ts, 34, 12), Decl(reachabilityChecks11.ts, 41, 7))
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(reachabilityChecks11.ts, 42, 1))
|
||||
|
||||
return;
|
||||
class A {
|
||||
>A : Symbol(A, Decl(reachabilityChecks11.ts, 45, 11))
|
||||
}
|
||||
}
|
||||
|
||||
module B {
|
||||
>B : Symbol(B, Decl(reachabilityChecks11.ts, 48, 1))
|
||||
|
||||
for (; ;);
|
||||
module C {
|
||||
>C : Symbol(C, Decl(reachabilityChecks11.ts, 51, 14))
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(reachabilityChecks11.ts, 54, 1))
|
||||
|
||||
do {
|
||||
} while (true);
|
||||
enum E {
|
||||
>E : Symbol(E, Decl(reachabilityChecks11.ts, 58, 19))
|
||||
|
||||
X = 1
|
||||
>X : Symbol(E.X, Decl(reachabilityChecks11.ts, 59, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : Symbol(f4, Decl(reachabilityChecks11.ts, 62, 1))
|
||||
|
||||
if (true) {
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
const enum E {
|
||||
>E : Symbol(E, Decl(reachabilityChecks11.ts, 67, 5))
|
||||
|
||||
X = 1
|
||||
>X : Symbol(E.X, Decl(reachabilityChecks11.ts, 68, 18))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
180
tests/baselines/reference/reachabilityChecks11.types
Normal file
180
tests/baselines/reference/reachabilityChecks11.types
Normal file
@ -0,0 +1,180 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks11.ts] ////
|
||||
|
||||
=== reachabilityChecks11.ts ===
|
||||
// while (true);
|
||||
var x = 1;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
|
||||
module A {
|
||||
>A : typeof A
|
||||
> : ^^^^^^^^
|
||||
|
||||
while (true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
let x;
|
||||
>x : any
|
||||
> : ^^^
|
||||
}
|
||||
|
||||
module A1 {
|
||||
>A1 : typeof A1
|
||||
> : ^^^^^^^^^
|
||||
|
||||
do {} while(true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
module A {
|
||||
interface F {}
|
||||
}
|
||||
}
|
||||
|
||||
module A2 {
|
||||
>A2 : typeof A2
|
||||
> : ^^^^^^^^^
|
||||
|
||||
while (true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
module A {
|
||||
>A : typeof A
|
||||
> : ^^^^^^^^
|
||||
|
||||
var x = 1;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
}
|
||||
}
|
||||
|
||||
module A3 {
|
||||
>A3 : typeof A3
|
||||
> : ^^^^^^^^^
|
||||
|
||||
while (true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
type T = string;
|
||||
>T : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
module A4 {
|
||||
>A4 : typeof A4
|
||||
> : ^^^^^^^^^
|
||||
|
||||
while (true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
module A {
|
||||
const enum E { X }
|
||||
>E : E
|
||||
> : ^
|
||||
>X : E.X
|
||||
> : ^^^
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x) {
|
||||
>f1 : (x: any) => void
|
||||
> : ^ ^^^^^^^^^^^^^^
|
||||
>x : any
|
||||
> : ^^^
|
||||
|
||||
if (x) {
|
||||
>x : any
|
||||
> : ^^^
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
>new Error("123") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"123" : "123"
|
||||
> : ^^^^^
|
||||
}
|
||||
var x;
|
||||
>x : any
|
||||
> : ^^^
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
return;
|
||||
class A {
|
||||
>A : A
|
||||
> : ^
|
||||
}
|
||||
}
|
||||
|
||||
module B {
|
||||
>B : typeof B
|
||||
> : ^^^^^^^^
|
||||
|
||||
for (; ;);
|
||||
module C {
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
do {
|
||||
} while (true);
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
enum E {
|
||||
>E : E
|
||||
> : ^
|
||||
|
||||
X = 1
|
||||
>X : E.X
|
||||
> : ^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
}
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
if (true) {
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
}
|
||||
const enum E {
|
||||
>E : E
|
||||
> : ^
|
||||
|
||||
X = 1
|
||||
>X : E.X
|
||||
> : ^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
tests/baselines/reference/reachabilityChecks9.errors.txt
Normal file
37
tests/baselines/reference/reachabilityChecks9.errors.txt
Normal file
@ -0,0 +1,37 @@
|
||||
reachabilityChecks9.ts(7,7): error TS7027: Unreachable code detected.
|
||||
reachabilityChecks9.ts(20,7): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== reachabilityChecks9.ts (2 errors) ====
|
||||
// https://github.com/microsoft/TypeScript/issues/55562
|
||||
|
||||
function g(str: string) {
|
||||
switch (str) {
|
||||
case "a":
|
||||
return;
|
||||
console.log("1");
|
||||
~~~~~~~~~~~~~~~~~
|
||||
console.log("2");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
case "b":
|
||||
console.log("3");
|
||||
}
|
||||
}
|
||||
|
||||
function h(str: string) {
|
||||
switch (str) {
|
||||
case "a":
|
||||
console.log("1");
|
||||
default:
|
||||
return;
|
||||
console.log("2");
|
||||
~~~~~~~~~~~~~~~~~
|
||||
console.log("3");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
case "b":
|
||||
console.log("4");
|
||||
}
|
||||
}
|
||||
|
||||
65
tests/baselines/reference/reachabilityChecks9.symbols
Normal file
65
tests/baselines/reference/reachabilityChecks9.symbols
Normal file
@ -0,0 +1,65 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks9.ts] ////
|
||||
|
||||
=== reachabilityChecks9.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55562
|
||||
|
||||
function g(str: string) {
|
||||
>g : Symbol(g, Decl(reachabilityChecks9.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(reachabilityChecks9.ts, 2, 11))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(reachabilityChecks9.ts, 2, 11))
|
||||
|
||||
case "a":
|
||||
return;
|
||||
console.log("1");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
console.log("2");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
case "b":
|
||||
console.log("3");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
function h(str: string) {
|
||||
>h : Symbol(h, Decl(reachabilityChecks9.ts, 11, 1))
|
||||
>str : Symbol(str, Decl(reachabilityChecks9.ts, 13, 11))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(reachabilityChecks9.ts, 13, 11))
|
||||
|
||||
case "a":
|
||||
console.log("1");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
default:
|
||||
return;
|
||||
console.log("2");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
console.log("3");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
case "b":
|
||||
console.log("4");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
132
tests/baselines/reference/reachabilityChecks9.types
Normal file
132
tests/baselines/reference/reachabilityChecks9.types
Normal file
@ -0,0 +1,132 @@
|
||||
//// [tests/cases/compiler/reachabilityChecks9.ts] ////
|
||||
|
||||
=== reachabilityChecks9.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55562
|
||||
|
||||
function g(str: string) {
|
||||
>g : (str: string) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>str : string
|
||||
> : ^^^^^^
|
||||
|
||||
switch (str) {
|
||||
>str : string
|
||||
> : ^^^^^^
|
||||
|
||||
case "a":
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
return;
|
||||
console.log("1");
|
||||
>console.log("1") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"1" : "1"
|
||||
> : ^^^
|
||||
|
||||
console.log("2");
|
||||
>console.log("2") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"2" : "2"
|
||||
> : ^^^
|
||||
|
||||
case "b":
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
|
||||
console.log("3");
|
||||
>console.log("3") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"3" : "3"
|
||||
> : ^^^
|
||||
}
|
||||
}
|
||||
|
||||
function h(str: string) {
|
||||
>h : (str: string) => void
|
||||
> : ^ ^^ ^^^^^^^^^
|
||||
>str : string
|
||||
> : ^^^^^^
|
||||
|
||||
switch (str) {
|
||||
>str : string
|
||||
> : ^^^^^^
|
||||
|
||||
case "a":
|
||||
>"a" : "a"
|
||||
> : ^^^
|
||||
|
||||
console.log("1");
|
||||
>console.log("1") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"1" : "1"
|
||||
> : ^^^
|
||||
|
||||
default:
|
||||
return;
|
||||
console.log("2");
|
||||
>console.log("2") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"2" : "2"
|
||||
> : ^^^
|
||||
|
||||
console.log("3");
|
||||
>console.log("3") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"3" : "3"
|
||||
> : ^^^
|
||||
|
||||
case "b":
|
||||
>"b" : "b"
|
||||
> : ^^^
|
||||
|
||||
console.log("4");
|
||||
>console.log("4") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"4" : "4"
|
||||
> : ^^^
|
||||
}
|
||||
}
|
||||
|
||||
28
tests/baselines/reference/reachabilityChecksIgnored.js
Normal file
28
tests/baselines/reference/reachabilityChecksIgnored.js
Normal file
@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/reachabilityChecksIgnored.ts] ////
|
||||
|
||||
//// [reachabilityChecksIgnored.ts]
|
||||
function a() {
|
||||
throw new Error("");
|
||||
|
||||
// @ts-ignore
|
||||
console.log("unreachable");
|
||||
}
|
||||
|
||||
function b() {
|
||||
throw new Error("");
|
||||
|
||||
// @ts-expect-error
|
||||
console.log("unreachable");
|
||||
}
|
||||
|
||||
//// [reachabilityChecksIgnored.js]
|
||||
function a() {
|
||||
throw new Error("");
|
||||
// @ts-ignore
|
||||
console.log("unreachable");
|
||||
}
|
||||
function b() {
|
||||
throw new Error("");
|
||||
// @ts-expect-error
|
||||
console.log("unreachable");
|
||||
}
|
||||
28
tests/baselines/reference/reachabilityChecksIgnored.symbols
Normal file
28
tests/baselines/reference/reachabilityChecksIgnored.symbols
Normal file
@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/reachabilityChecksIgnored.ts] ////
|
||||
|
||||
=== reachabilityChecksIgnored.ts ===
|
||||
function a() {
|
||||
>a : Symbol(a, Decl(reachabilityChecksIgnored.ts, 0, 0))
|
||||
|
||||
throw new Error("");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
// @ts-ignore
|
||||
console.log("unreachable");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
|
||||
function b() {
|
||||
>b : Symbol(b, Decl(reachabilityChecksIgnored.ts, 5, 1))
|
||||
|
||||
throw new Error("");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
// @ts-expect-error
|
||||
console.log("unreachable");
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
54
tests/baselines/reference/reachabilityChecksIgnored.types
Normal file
54
tests/baselines/reference/reachabilityChecksIgnored.types
Normal file
@ -0,0 +1,54 @@
|
||||
//// [tests/cases/compiler/reachabilityChecksIgnored.ts] ////
|
||||
|
||||
=== reachabilityChecksIgnored.ts ===
|
||||
function a() {
|
||||
>a : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
throw new Error("");
|
||||
>new Error("") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
|
||||
// @ts-ignore
|
||||
console.log("unreachable");
|
||||
>console.log("unreachable") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"unreachable" : "unreachable"
|
||||
> : ^^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
function b() {
|
||||
>b : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
throw new Error("");
|
||||
>new Error("") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
|
||||
// @ts-expect-error
|
||||
console.log("unreachable");
|
||||
>console.log("unreachable") : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"unreachable" : "unreachable"
|
||||
> : ^^^^^^^^^^^^^
|
||||
}
|
||||
7
tests/cases/compiler/reachabilityChecks10.ts
Normal file
7
tests/cases/compiler/reachabilityChecks10.ts
Normal file
@ -0,0 +1,7 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
// @allowUnreachableCode: false
|
||||
|
||||
throw new Error("")
|
||||
console.log("1")
|
||||
console.log("2")
|
||||
76
tests/cases/compiler/reachabilityChecks11.ts
Normal file
76
tests/cases/compiler/reachabilityChecks11.ts
Normal file
@ -0,0 +1,76 @@
|
||||
// @allowUnreachableCode: false
|
||||
// @preserveConstEnums: true
|
||||
|
||||
// while (true);
|
||||
var x = 1;
|
||||
|
||||
module A {
|
||||
while (true);
|
||||
let x;
|
||||
}
|
||||
|
||||
module A1 {
|
||||
do {} while(true);
|
||||
module A {
|
||||
interface F {}
|
||||
}
|
||||
}
|
||||
|
||||
module A2 {
|
||||
while (true);
|
||||
module A {
|
||||
var x = 1;
|
||||
}
|
||||
}
|
||||
|
||||
module A3 {
|
||||
while (true);
|
||||
type T = string;
|
||||
}
|
||||
|
||||
module A4 {
|
||||
while (true);
|
||||
module A {
|
||||
const enum E { X }
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x) {
|
||||
if (x) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Error("123");
|
||||
}
|
||||
var x;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
return;
|
||||
class A {
|
||||
}
|
||||
}
|
||||
|
||||
module B {
|
||||
for (; ;);
|
||||
module C {
|
||||
}
|
||||
}
|
||||
|
||||
function f3() {
|
||||
do {
|
||||
} while (true);
|
||||
enum E {
|
||||
X = 1
|
||||
}
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
throw new Error();
|
||||
}
|
||||
const enum E {
|
||||
X = 1
|
||||
}
|
||||
}
|
||||
|
||||
29
tests/cases/compiler/reachabilityChecks9.ts
Normal file
29
tests/cases/compiler/reachabilityChecks9.ts
Normal file
@ -0,0 +1,29 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
// @allowUnreachableCode: false
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/55562
|
||||
|
||||
function g(str: string) {
|
||||
switch (str) {
|
||||
case "a":
|
||||
return;
|
||||
console.log("1");
|
||||
console.log("2");
|
||||
case "b":
|
||||
console.log("3");
|
||||
}
|
||||
}
|
||||
|
||||
function h(str: string) {
|
||||
switch (str) {
|
||||
case "a":
|
||||
console.log("1");
|
||||
default:
|
||||
return;
|
||||
console.log("2");
|
||||
console.log("3");
|
||||
case "b":
|
||||
console.log("4");
|
||||
}
|
||||
}
|
||||
17
tests/cases/compiler/reachabilityChecksIgnored.ts
Normal file
17
tests/cases/compiler/reachabilityChecksIgnored.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// @allowUnreachableCode: false
|
||||
// @preserveConstEnums: true
|
||||
|
||||
|
||||
function a() {
|
||||
throw new Error("");
|
||||
|
||||
// @ts-ignore
|
||||
console.log("unreachable");
|
||||
}
|
||||
|
||||
function b() {
|
||||
throw new Error("");
|
||||
|
||||
// @ts-expect-error
|
||||
console.log("unreachable");
|
||||
}
|
||||
@ -2,6 +2,6 @@
|
||||
|
||||
// @allowUnreachableCode: true
|
||||
|
||||
////if (false) 0;
|
||||
////if (false) [|0;|]
|
||||
|
||||
verify.getSuggestionDiagnostics([]);
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
|
||||
// @allowUnusedLabels: true
|
||||
|
||||
////foo: while (true) {}
|
||||
////[|foo|]: while (true) {}
|
||||
|
||||
verify.getSuggestionDiagnostics([]);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user