From 702dc59b367d3180be1ba66cecb85ae2b218c405 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Fri, 21 Jun 2019 18:32:22 +0300 Subject: [PATCH] no-fallthrough --- .eslintrc | 2 +- package.json | 6 +++--- src/compiler/binder.ts | 8 ++++---- src/compiler/checker.ts | 20 +++++++++++++------- src/compiler/core.ts | 1 + src/compiler/factory.ts | 3 ++- src/compiler/parser.ts | 6 ++++-- src/compiler/program.ts | 6 ++++-- src/compiler/scanner.ts | 1 + src/compiler/transformers/ts.ts | 7 +++++-- src/compiler/tsbuild.ts | 3 ++- src/compiler/utilities.ts | 15 ++++++++++----- src/services/breakpoints.ts | 2 +- src/services/codefixes/convertToEs6Module.ts | 1 + src/services/codefixes/inferFromUsage.ts | 6 ++++++ src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 3 ++- src/services/formatting/formatting.ts | 3 ++- src/services/formatting/rules.ts | 15 ++++++++++++--- src/services/services.ts | 8 +++++--- src/services/suggestionDiagnostics.ts | 2 +- src/services/utilities.ts | 5 ++++- 22 files changed, 85 insertions(+), 40 deletions(-) diff --git a/.eslintrc b/.eslintrc index c579a908bf4..b6581a2e8f4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -88,7 +88,7 @@ "no-empty": "error", "no-eval": "error", "no-extra-bind": "error", - "no-fallthrough": "off", + "no-fallthrough": "error", "no-invalid-this": "off", "no-multiple-empty-lines": "off", "no-new-func": "error", diff --git a/package.json b/package.json index 9fab8be64e6..6adf4d56360 100644 --- a/package.json +++ b/package.json @@ -54,8 +54,8 @@ "@types/through2": "latest", "@types/travis-fold": "latest", "@types/xml2js": "^0.4.0", - "@typescript-eslint/eslint-plugin": "latest", - "@typescript-eslint/parser": "latest", + "@typescript-eslint/eslint-plugin": "1.10.2", + "@typescript-eslint/parser": "1.10.2", "azure-devops-node-api": "^8.0.0", "browser-resolve": "^1.11.2", "browserify": "latest", @@ -63,7 +63,7 @@ "chalk": "latest", "convert-source-map": "latest", "del": "latest", - "eslint": "latest", + "eslint": "5.16.0", "eslint-formatter-autolinkable-stylish": "latest", "eslint-plugin-microsoft-typescript": "0.1.11", "fancy-log": "latest", diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 660b19a5872..450974e012b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1490,7 +1490,7 @@ namespace ts { if (isObjectLiteralOrClassExpressionMethod(node)) { return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethod; } - // falls through + // falls through case SyntaxKind.Constructor: case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodSignature: @@ -1776,7 +1776,7 @@ namespace ts { declareModuleMember(node, symbolFlags, symbolExcludes); break; } - // falls through + // falls through default: if (!blockScopeContainer.locals) { blockScopeContainer.locals = createSymbolTable(); @@ -2114,7 +2114,7 @@ namespace ts { bindBlockScopedDeclaration(parentNode as Declaration, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); break; } - // falls through + // falls through case SyntaxKind.ThisKeyword: if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) { node.flowNode = currentFlow; @@ -2296,7 +2296,7 @@ namespace ts { if (!isFunctionLike(node.parent)) { return; } - // falls through + // falls through case SyntaxKind.ModuleBlock: return updateStrictModeStatementList((node).statements); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b081e01d315..ead7e333cfe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4796,7 +4796,9 @@ namespace ts { // Type parameters are always visible case SyntaxKind.TypeParameter: + // Source file and namespace export are always visible + // falls through case SyntaxKind.SourceFile: case SyntaxKind.NamespaceExportDeclaration: return true; @@ -24545,7 +24547,7 @@ namespace ts { if ((node).expression.kind === SyntaxKind.ImportKeyword) { return checkImportCallExpression(node); } - /* falls through */ + // falls through case SyntaxKind.NewExpression: return checkCallExpression(node, checkMode); case SyntaxKind.TaggedTemplateExpression: @@ -25673,7 +25675,9 @@ namespace ts { switch (d.kind) { case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: - // A jsdoc typedef and callback are, by definition, type aliases + + // A jsdoc typedef and callback are, by definition, type aliases. + // falls through case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: return DeclarationSpaces.ExportType; @@ -25692,8 +25696,9 @@ namespace ts { return DeclarationSpaces.ExportValue; } d = (d as ExportAssignment).expression; - /* falls through */ - // The below options all declare an Alias, which is allowed to merge with other values within the importing module + + // The below options all declare an Alias, which is allowed to merge with other values within the importing module. + // falls through case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: case SyntaxKind.ImportClause: @@ -29634,9 +29639,10 @@ namespace ts { if (className) { copySymbol(location.symbol, meaning); } - // falls through + // this fall-through is necessary because we would like to handle - // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration + // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration. + // falls through case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: // If we didn't come from static member of class or interface, @@ -31786,7 +31792,7 @@ namespace ts { switch (prop.kind) { case SyntaxKind.ShorthandPropertyAssignment: checkGrammarForInvalidExclamationToken(prop.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); - /* tslint:disable:no-switch-case-fall-through */ + // falls through case SyntaxKind.PropertyAssignment: // Grammar checking for computedPropertyName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index af493fc44d8..4529ce2fd83 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -943,6 +943,7 @@ namespace ts { case true: // relational comparison + // falls through case Comparison.EqualTo: continue; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 5a4bb57f27b..5c626a8ee45 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2773,7 +2773,8 @@ namespace ts { break; case BundleFileSectionKind.Internal: if (stripInternal) break; - // falls through + // falls through + case BundleFileSectionKind.Text: (texts || (texts = [])).push(createUnparsedNode(section, node) as UnparsedTextLike); break; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c38e4f67fe2..1e1474379d4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4646,7 +4646,7 @@ namespace ts { case SyntaxKind.TemplateHead: // foo `...${100}...` // these are the only tokens can legally follow a type argument // list. So we definitely want to treat them as type arg lists. - + // falls through case SyntaxKind.DotToken: // foo. case SyntaxKind.CloseParenToken: // foo) case SyntaxKind.CloseBracketToken: // foo] @@ -4674,7 +4674,7 @@ namespace ts { // We don't want to treat these as type arguments. Otherwise we'll parse this // as an invocation expression. Instead, we want to parse out the expression // in isolation from the type arguments. - + // falls through default: // Anything else treat as an expression. return false; @@ -5309,6 +5309,7 @@ namespace ts { case SyntaxKind.DebuggerKeyword: // 'catch' and 'finally' do not actually indicate that the code is part of a statement, // however, we say they are here so that we may gracefully parse them and error later. + // falls through case SyntaxKind.CatchKeyword: case SyntaxKind.FinallyKeyword: return true; @@ -5394,6 +5395,7 @@ namespace ts { return parseThrowStatement(); case SyntaxKind.TryKeyword: // Include 'catch' and 'finally' for error recovery. + // falls through case SyntaxKind.CatchKeyword: case SyntaxKind.FinallyKeyword: return parseTryStatement(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index faa5a580a97..ebaf5dbfefa 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1747,7 +1747,8 @@ namespace ts { diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_can_only_be_used_in_a_ts_file, "?")); return; } - // falls through + // falls through + case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: @@ -1829,7 +1830,8 @@ namespace ts { diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file)); return; } - // falls through + // falls through + case SyntaxKind.VariableStatement: // Check modifiers if (nodes === (parent).modifiers) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index a0f0f83309c..854bc6c521b 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -468,6 +468,7 @@ namespace ts { case CharacterCodes.space: case CharacterCodes.slash: // starts of normal trivia + // falls through case CharacterCodes.lessThan: case CharacterCodes.bar: case CharacterCodes.equals: diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index af1679bef88..1cb94244ffb 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -369,8 +369,8 @@ namespace ts { case SyntaxKind.ConstKeyword: case SyntaxKind.DeclareKeyword: case SyntaxKind.ReadonlyKeyword: - // TypeScript accessibility and readonly modifiers are elided. - + // TypeScript accessibility and readonly modifiers are elided + // falls through case SyntaxKind.ArrayType: case SyntaxKind.TupleType: case SyntaxKind.OptionalType: @@ -400,12 +400,15 @@ namespace ts { case SyntaxKind.MappedType: case SyntaxKind.LiteralType: // TypeScript type nodes are elided. + // falls through case SyntaxKind.IndexSignature: // TypeScript index signatures are elided. + // falls through case SyntaxKind.Decorator: // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration. + // falls through case SyntaxKind.TypeAliasDeclaration: // TypeScript type-only declarations are elided. diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 94718a1b368..fdb5d5851e2 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -1666,8 +1666,8 @@ namespace ts { } break; } + // falls through - // falls through case UpToDateStatusType.UpToDateWithUpstreamTypes: case UpToDateStatusType.OutOfDateWithPrepend: if (!(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) { @@ -2098,6 +2098,7 @@ namespace ts { ); case UpToDateStatusType.ContainerOnly: // Don't report status on "solution" projects + // falls through case UpToDateStatusType.ComputingUpstream: // Should never leak from getUptoDateStatusWorker break; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a6e6b7910ce..d4c55f0291e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1051,7 +1051,8 @@ namespace ts { // At this point, node is either a qualified name or an identifier Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'."); - // falls through + // falls through + case SyntaxKind.QualifiedName: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ThisKeyword: { @@ -1383,7 +1384,8 @@ namespace ts { if (!includeArrowFunctions) { continue; } - // falls through + // falls through + case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ModuleDeclaration: @@ -1442,7 +1444,8 @@ namespace ts { if (!stopOnFunctions) { continue; } - // falls through + // falls through + case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: case SyntaxKind.MethodDeclaration: @@ -1654,7 +1657,8 @@ namespace ts { if (node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node)) { return true; } - // falls through + // falls through + case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: case SyntaxKind.StringLiteral: @@ -2680,7 +2684,8 @@ namespace ts { if (node.asteriskToken) { flags |= FunctionFlags.Generator; } - // falls through + // falls through + case SyntaxKind.ArrowFunction: if (hasModifier(node, ModifierFlags.Async)) { flags |= FunctionFlags.Async; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 404e75db147..532944d1cf3 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -471,9 +471,9 @@ namespace ts.BreakpointResolver { if (getModuleInstanceState(block.parent as ModuleDeclaration) !== ModuleInstanceState.Instantiated) { return undefined; } - // falls through // Set on parent if on same line otherwise on first statement + // falls through case SyntaxKind.WhileStatement: case SyntaxKind.IfStatement: case SyntaxKind.ForInStatement: diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index fd756430e49..6c0ac8639d8 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -230,6 +230,7 @@ namespace ts.codefix { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`. + // falls through case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.SpreadAssignment: return undefined; diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 53ca335c7a5..d0aed395a0e 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -569,21 +569,25 @@ namespace ts.codefix { case SyntaxKind.AsteriskAsteriskToken: // MultiplicativeOperator + // falls through case SyntaxKind.AsteriskToken: case SyntaxKind.SlashToken: case SyntaxKind.PercentToken: // ShiftOperator + // falls through case SyntaxKind.LessThanLessThanToken: case SyntaxKind.GreaterThanGreaterThanToken: case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: // BitwiseOperator + // falls through case SyntaxKind.AmpersandToken: case SyntaxKind.BarToken: case SyntaxKind.CaretToken: // CompoundAssignmentOperator + // falls through case SyntaxKind.MinusEqualsToken: case SyntaxKind.AsteriskAsteriskEqualsToken: case SyntaxKind.AsteriskEqualsToken: @@ -597,9 +601,11 @@ namespace ts.codefix { case SyntaxKind.GreaterThanGreaterThanEqualsToken: // AdditiveOperator + // falls through case SyntaxKind.MinusToken: // RelationalOperator + // falls through case SyntaxKind.LessThanToken: case SyntaxKind.LessThanEqualsToken: case SyntaxKind.GreaterThanToken: diff --git a/src/services/completions.ts b/src/services/completions.ts index 6d1d48b22b8..96bf8d7a747 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -837,7 +837,7 @@ namespace ts.Completions { if (!binaryExpressionMayBeOpenTag(parent as BinaryExpression)) { break; } - // falls through + // falls through case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxElement: diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 1f11b0f52d5..c94e2b73e9a 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -172,7 +172,8 @@ namespace ts.DocumentHighlights { if (statement.kind === SyntaxKind.ContinueStatement) { return false; } - // falls through + // falls through + case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 01c09a4989c..b0802532c0c 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -514,7 +514,8 @@ namespace ts.formatting { if ((node).asteriskToken) { return SyntaxKind.AsteriskToken; } - // falls through + // falls through + case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: const name = getNameOfDeclaration(node); diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 38792d448e4..7f378d5d1bf 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -427,12 +427,16 @@ namespace ts.formatting { // equals in binding elements: function foo([[x, y] = [1, 2]]) case SyntaxKind.BindingElement: // equals in type X = ... + // falls through case SyntaxKind.TypeAliasDeclaration: // equal in import a = module('a'); + // falls through case SyntaxKind.ImportEqualsDeclaration: - // equal in let a = 0; + // equal in let a = 0 + // falls through case SyntaxKind.VariableDeclaration: - // equal in p = 0; + // equal in p = 0 + // falls through case SyntaxKind.Parameter: case SyntaxKind.EnumMember: case SyntaxKind.PropertyDeclaration: @@ -440,7 +444,8 @@ namespace ts.formatting { return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; // "in" keyword in for (let x in []) { } case SyntaxKind.ForInStatement: - // "in" keyword in [P in keyof T]: T[P] + // "in" keyword in [P in keyof T]: T[P]; + // falls through case SyntaxKind.TypeParameter: return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword || context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; // Technically, "of" is not a binary operator, but format it the same way as "in" @@ -527,9 +532,11 @@ namespace ts.formatting { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: // case SyntaxKind.MemberFunctionDeclaration: + // falls through case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: // case SyntaxKind.MethodSignature: + // falls through case SyntaxKind.CallSignature: case SyntaxKind.FunctionExpression: case SyntaxKind.Constructor: @@ -537,6 +544,7 @@ namespace ts.formatting { // case SyntaxKind.ConstructorDeclaration: // case SyntaxKind.SimpleArrowFunctionExpression: // case SyntaxKind.ParenthesizedArrowFunctionExpression: + // falls through case SyntaxKind.InterfaceDeclaration: // This one is not truly a function, but for formatting purposes, it acts just like one return true; } @@ -607,6 +615,7 @@ namespace ts.formatting { case SyntaxKind.WithStatement: // TODO // case SyntaxKind.ElseClause: + // falls through case SyntaxKind.CatchClause: return true; diff --git a/src/services/services.ts b/src/services/services.ts index fed659cc59f..db48bc7cb5d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -715,7 +715,8 @@ namespace ts { if (!hasModifier(node, ModifierFlags.ParameterPropertyModifier)) { break; } - // falls through + // falls through + case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: { const decl = node; @@ -769,7 +770,7 @@ namespace ts { if (getAssignmentDeclarationKind(node as BinaryExpression) !== AssignmentDeclarationKind.None) { addDeclaration(node as BinaryExpression); } - // falls through + // falls through default: forEachChild(node, visit); @@ -2226,7 +2227,8 @@ namespace ts { if (node.parent.kind === SyntaxKind.ComputedPropertyName) { return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; } - // falls through + // falls through + case SyntaxKind.Identifier: return isObjectLiteralElement(node.parent) && (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) && diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 63691a72c8b..e95406a4635 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -181,7 +181,7 @@ namespace ts { case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: visitedNestedConvertibleFunctions.set(getKeyFromNode(arg as FunctionLikeDeclaration), true); - /* falls through */ + // falls through case SyntaxKind.NullKeyword: case SyntaxKind.Identifier: // identifier includes undefined return true; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a3d0f154ea3..f8a29985e5b 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -507,7 +507,8 @@ namespace ts { if (!(n).arguments) { return true; } - // falls through + // falls through + case SyntaxKind.CallExpression: case SyntaxKind.ParenthesizedExpression: case SyntaxKind.ParenthesizedType: @@ -1028,6 +1029,7 @@ namespace ts { break; case SyntaxKind.EqualsGreaterThanToken: + // falls through case SyntaxKind.Identifier: case SyntaxKind.StringLiteral: @@ -1035,6 +1037,7 @@ namespace ts { case SyntaxKind.BigIntLiteral: case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: + // falls through case SyntaxKind.TypeOfKeyword: case SyntaxKind.ExtendsKeyword: