Lint for fallthrough in switch

This commit is contained in:
Andy Hanson 2017-03-27 15:09:00 -07:00
parent 5e4b8d66ff
commit 1cf765d664
20 changed files with 64 additions and 38 deletions

View File

@ -1413,6 +1413,7 @@ namespace ts {
if (isObjectLiteralOrClassExpressionMethod(node)) {
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsObjectLiteralOrClassExpressionMethod;
}
// falls through
case SyntaxKind.Constructor:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodSignature:
@ -1714,7 +1715,7 @@ namespace ts {
declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
// fall through.
// falls through
default:
if (!blockScopeContainer.locals) {
blockScopeContainer.locals = createMap<Symbol>();
@ -2006,6 +2007,7 @@ namespace ts {
bindBlockScopedDeclaration(<Declaration>parentNode, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
break;
}
// falls through
case SyntaxKind.ThisKeyword:
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
node.flowNode = currentFlow;
@ -2183,7 +2185,7 @@ namespace ts {
if (!isFunctionLike(node.parent)) {
return;
}
// Fall through
// falls through
case SyntaxKind.ModuleBlock:
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
}

View File

@ -872,6 +872,7 @@ namespace ts {
case SyntaxKind.SourceFile:
if (!isExternalOrCommonJsModule(<SourceFile>location)) break;
isInExternalModule = true;
// falls through
case SyntaxKind.ModuleDeclaration:
const moduleExports = getSymbolOfNode(location).exports;
if (location.kind === SyntaxKind.SourceFile || isAmbientModule(location)) {
@ -1872,6 +1873,7 @@ namespace ts {
if (!isExternalOrCommonJsModule(<SourceFile>location)) {
break;
}
// falls through
case SyntaxKind.ModuleDeclaration:
if (result = callback(getSymbolOfNode(location).exports)) {
return result;
@ -3592,7 +3594,7 @@ namespace ts {
// If the binding pattern is empty, this variable declaration is not visible
return false;
}
// Otherwise fall through
// falls through
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
@ -3623,7 +3625,8 @@ namespace ts {
// Private/protected properties/methods are not visible
return false;
}
// Public properties/methods are visible if its parents are visible, so const it fall into next case statement
// Public properties/methods are visible if its parents are visible, so
// falls through
case SyntaxKind.Constructor:
case SyntaxKind.ConstructSignature:
@ -20863,7 +20866,7 @@ namespace ts {
}
break;
}
// fallthrough
// falls through
case SyntaxKind.ClassDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.FunctionDeclaration:
@ -21498,6 +21501,7 @@ namespace ts {
if (!isExternalOrCommonJsModule(<SourceFile>location)) {
break;
}
// falls through
case SyntaxKind.ModuleDeclaration:
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember);
break;
@ -21509,7 +21513,8 @@ namespace ts {
if (className) {
copySymbol(location.symbol, meaning);
}
// fall through; this fall-through is necessary because we would like to handle
// 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
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
@ -21795,7 +21800,7 @@ namespace ts {
return sig.thisParameter;
}
}
// fallthrough
// falls through
case SyntaxKind.SuperKeyword:
const type = isPartOfExpression(node) ? getTypeOfExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
@ -21823,7 +21828,7 @@ namespace ts {
if (isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
return resolveExternalModuleName(node, <LiteralExpression>node);
}
// Fall through
// falls through
case SyntaxKind.NumericLiteral:
// index access

View File

@ -3576,6 +3576,7 @@ namespace ts {
if (isAwaitExpression()) {
return parseAwaitExpression();
}
// falls through
default:
return parseIncrementExpression();
}
@ -3609,8 +3610,8 @@ namespace ts {
if (sourceFile.languageVariant !== LanguageVariant.JSX) {
return false;
}
// We are in JSX context and the token is part of JSXElement.
// Fall through
// We are in JSX context and the token is part of JSXElement.
// falls through
default:
return true;
}
@ -6557,7 +6558,8 @@ namespace ts {
indent += scanner.getTokenText().length;
break;
}
// FALLTHROUGH otherwise to record the * as a comment
// record the * as a comment
// falls through
default:
state = JSDocState.SavingComments; // leading identifiers start recording as well
pushComment(scanner.getTokenText());
@ -6783,6 +6785,7 @@ namespace ts {
break;
case SyntaxKind.Identifier:
canParseTag = false;
break;
case SyntaxKind.EndOfFileToken:
break;
}

View File

@ -941,8 +941,7 @@ namespace ts {
diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
return;
}
// Pass through
// falls through
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.Constructor:
@ -1022,7 +1021,7 @@ namespace ts {
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
return;
}
// pass through
// falls through
case SyntaxKind.VariableStatement:
// Check modifiers
if (nodes === (<ClassDeclaration | FunctionLikeDeclaration | VariableStatement>parent).modifiers) {
@ -1070,7 +1069,8 @@ namespace ts {
if (isConstValid) {
continue;
}
// Fallthrough to report error
// to report error,
// falls through
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:

View File

@ -306,6 +306,7 @@ namespace ts {
if (text.charCodeAt(pos) === CharacterCodes.lineFeed) {
pos++;
}
// falls through
case CharacterCodes.lineFeed:
result.push(lineStart);
lineStart = pos;
@ -452,6 +453,7 @@ namespace ts {
if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) {
pos++;
}
// falls through
case CharacterCodes.lineFeed:
pos++;
if (stopAfterLineBreak) {
@ -623,6 +625,7 @@ namespace ts {
if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) {
pos++;
}
// falls through
case CharacterCodes.lineFeed:
pos++;
if (trailing) {
@ -1067,7 +1070,7 @@ namespace ts {
if (pos < end && text.charCodeAt(pos) === CharacterCodes.lineFeed) {
pos++;
}
// fall through
// falls through
case CharacterCodes.lineFeed:
case CharacterCodes.lineSeparator:
case CharacterCodes.paragraphSeparator:
@ -1449,6 +1452,7 @@ namespace ts {
// This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
// can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
// permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
// falls through
case CharacterCodes._1:
case CharacterCodes._2:
case CharacterCodes._3:

View File

@ -477,8 +477,8 @@ namespace ts {
// module is imported only for side-effects, no emit required
break;
}
// falls through
// fall-through
case SyntaxKind.ImportEqualsDeclaration:
Debug.assert(importVariableName !== undefined);
// save import into the local

View File

@ -733,6 +733,7 @@ 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
case SyntaxKind.QualifiedName:
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.ThisKeyword:
@ -842,6 +843,7 @@ namespace ts {
if (operand) {
traverse(operand);
}
return;
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.ModuleDeclaration:
@ -1059,7 +1061,7 @@ namespace ts {
if (!includeArrowFunctions) {
continue;
}
// Fall through
// falls through
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ModuleDeclaration:
@ -1118,6 +1120,7 @@ namespace ts {
if (!stopOnFunctions) {
continue;
}
// falls through
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.MethodDeclaration:
@ -1317,7 +1320,7 @@ namespace ts {
if (node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node)) {
return true;
}
// fall through
// falls through
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
case SyntaxKind.ThisKeyword:
@ -1995,7 +1998,7 @@ namespace ts {
if (node.asteriskToken) {
flags |= FunctionFlags.Generator;
}
// fall through
// falls through
case SyntaxKind.ArrowFunction:
if (hasModifier(node, ModifierFlags.Async)) {
flags |= FunctionFlags.Async;

View File

@ -322,7 +322,7 @@ namespace ts {
nodesVisitor((<UnionOrIntersectionTypeNode>node).types, visitor, isTypeNode));
case SyntaxKind.ParenthesizedType:
Debug.fail("not implemented.");
throw Debug.fail("not implemented.");
case SyntaxKind.TypeOperator:
return updateTypeOperatorNode(<TypeOperatorNode>node, visitNode((<TypeOperatorNode>node).type, visitor, isTypeNode));
@ -1289,6 +1289,7 @@ namespace ts {
case SyntaxKind.JsxAttributes:
result = reduceNodes((<JsxAttributes>node).properties, cbNodes, result);
break;
case SyntaxKind.JsxClosingElement:
result = reduceNode((<JsxClosingElement>node).tagName, cbNode, result);
@ -1310,7 +1311,7 @@ namespace ts {
// Clauses
case SyntaxKind.CaseClause:
result = reduceNode((<CaseClause>node).expression, cbNode, result);
// fall-through
// falls through
case SyntaxKind.DefaultClause:
result = reduceNodes((<CaseClause | DefaultClause>node).statements, cbNodes, result);
@ -1344,6 +1345,7 @@ namespace ts {
case SyntaxKind.EnumMember:
result = reduceNode((<EnumMember>node).name, cbNode, result);
result = reduceNode((<EnumMember>node).initializer, cbNode, result);
break;
// Top-level nodes
case SyntaxKind.SourceFile:

View File

@ -97,7 +97,7 @@ namespace ts.BreakpointResolver {
if (isFunctionBlock(node)) {
return spanInFunctionBlock(<Block>node);
}
// Fall through
// falls through
case SyntaxKind.ModuleBlock:
return spanInBlock(<Block>node);
@ -186,6 +186,7 @@ namespace ts.BreakpointResolver {
if (getModuleInstanceState(node) !== ModuleInstanceState.Instantiated) {
return undefined;
}
// falls through
case SyntaxKind.ClassDeclaration:
case SyntaxKind.EnumDeclaration:
@ -473,6 +474,7 @@ namespace ts.BreakpointResolver {
if (getModuleInstanceState(block.parent) !== ModuleInstanceState.Instantiated) {
return undefined;
}
// falls through
// Set on parent if on same line otherwise on first statement
case SyntaxKind.WhileStatement:
@ -582,6 +584,7 @@ namespace ts.BreakpointResolver {
if (getModuleInstanceState(node.parent.parent) !== ModuleInstanceState.Instantiated) {
return undefined;
}
// falls through
case SyntaxKind.EnumDeclaration:
case SyntaxKind.ClassDeclaration:
@ -593,7 +596,7 @@ namespace ts.BreakpointResolver {
// Span on close brace token
return textSpan(node);
}
// fall through
// falls through
case SyntaxKind.CatchClause:
return spanInNode(lastOrUndefined((<Block>node.parent).statements));

View File

@ -160,7 +160,7 @@ namespace ts {
case EndOfLineState.InTemplateMiddleOrTail:
text = "}\n" + text;
offset = 2;
// fallthrough
// falls through
case EndOfLineState.InTemplateSubstitutionPosition:
templateStack.push(SyntaxKind.TemplateHead);
break;

View File

@ -42,12 +42,13 @@ namespace ts.codefix {
switch (this.compareModuleSpecifiers(existingAction.moduleSpecifier, newAction.moduleSpecifier)) {
case ModuleSpecifierComparison.Better:
// the new one is not worth considering if it is a new improt.
// the new one is not worth considering if it is a new import.
// However if it is instead a insertion into existing import, the user might want to use
// the module specifier even it is worse by our standards. So keep it.
if (newAction.kind === "NewImport") {
return;
}
// falls through
case ModuleSpecifierComparison.Equal:
// the current one is safe. But it is still possible that the new one is worse
// than another existing one. For example, you may have new imports from "./foo/bar"

View File

@ -58,6 +58,8 @@ namespace ts.codefix {
return deleteNodeInList(token.parent);
}
}
// TODO: #14885
// falls through
case SyntaxKind.TypeParameter:
const typeParameters = (<DeclarationWithTypeParameters>token.parent.parent).typeParameters;

View File

@ -485,7 +485,7 @@ namespace ts.Completions {
// It has a left-hand side, so we're not in an opening JSX tag.
break;
}
// fall through
// falls through
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxElement:

View File

@ -245,7 +245,7 @@ namespace ts.DocumentHighlights {
if (statement.kind === SyntaxKind.ContinueStatement) {
continue;
}
// Fall through.
// falls through
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:

View File

@ -956,7 +956,7 @@ namespace ts.FindAllReferences {
if (isObjectLiteralMethod(searchSpaceNode)) {
break;
}
// fall through
// falls through
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.Constructor:
@ -969,7 +969,7 @@ namespace ts.FindAllReferences {
if (isExternalModule(<SourceFile>searchSpaceNode)) {
return undefined;
}
// Fall through
// falls through
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
break;

View File

@ -483,9 +483,8 @@ namespace ts.formatting {
case SyntaxKind.MethodDeclaration:
if ((<MethodDeclaration>node).asteriskToken) {
return SyntaxKind.AsteriskToken;
}/*
fall-through
*/
}
// falls through
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.Parameter:
return (<Declaration>node).name.kind;

View File

@ -144,7 +144,7 @@ namespace ts.OutliningElementsCollector {
});
break;
}
// Fallthrough.
// falls through
case SyntaxKind.ModuleBlock: {
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);

View File

@ -635,7 +635,7 @@ namespace ts {
if (!hasModifier(node, ModifierFlags.ParameterPropertyModifier)) {
break;
}
// fall through
// falls through
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement: {
const decl = <VariableDeclaration>node;
@ -646,6 +646,7 @@ namespace ts {
if (decl.initializer)
visit(decl.initializer);
}
// falls through
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
@ -2028,7 +2029,7 @@ namespace ts {
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// intentionally fall through
// falls through
case SyntaxKind.Identifier:
return isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) &&

View File

@ -450,7 +450,7 @@ namespace ts {
if (!(<NewExpression>n).arguments) {
return true;
}
// fall through
// falls through
case SyntaxKind.CallExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.ParenthesizedType:

View File

@ -49,6 +49,7 @@
"no-increment-decrement": true,
"object-literal-surrounding-space": true,
"no-type-assertion-whitespace": true,
"no-in-operator": true
"no-in-operator": true,
"no-switch-case-fall-through": true
}
}