From 7826b38426ee358ade6aa345af6f3aefcd95bad5 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 6 Mar 2018 07:30:40 -0800 Subject: [PATCH] Apply 'no-unnecessary-initializer' lint rule (#22014) * Apply 'no-unnecessary-initializer' lint rule Forbids `let`/`const` statements to be initialized to `undefined`, since that's the initial value by default anyway. The auto-fixer also happened to remove two unnecessary `as number` casts in `src/harness/parallel/worker.ts`. For historical data: to run with `--fix`, I modified the line in `Jakefile.js` that declared the `cmd` for running TSLint. * Moved worker.ts type assertions to parameters --- src/compiler/checker.ts | 12 ++++++------ src/compiler/core.ts | 4 ++-- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/parser.ts | 6 +++--- src/compiler/transformers/utilities.ts | 2 +- src/harness/fourslash.ts | 6 +++--- src/harness/harness.ts | 6 +++--- src/harness/loggedIO.ts | 6 +++--- src/harness/parallel/worker.ts | 8 ++++---- src/harness/projectsRunner.ts | 6 +++--- src/server/client.ts | 2 +- src/server/session.ts | 4 ++-- src/services/findAllReferences.ts | 4 ++-- src/services/patternMatcher.ts | 6 +++--- src/services/refactors/extractSymbol.ts | 22 +++++++++++----------- src/services/services.ts | 2 +- src/services/utilities.ts | 2 +- tslint.json | 1 - 18 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 24eaf97cab0..7c1d3c02011 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3200,7 +3200,7 @@ namespace ts { } } - let entityName: EntityName = undefined; + let entityName: EntityName; const nameIdentifier = symbolToTypeReferenceName(type.symbol); if (qualifiedName) { Debug.assert(!qualifiedName.right); @@ -5695,7 +5695,7 @@ namespace ts { } return [signature]; } - let result: Signature[] = undefined; + let result: Signature[]; for (let i = 0; i < signatureLists.length; i++) { // Allow matching non-generic signatures to have excess parameters and different return types const match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true); @@ -5713,7 +5713,7 @@ namespace ts { // type is the union of the constituent return types. function getUnionSignatures(types: Type[], kind: SignatureKind): Signature[] { const signatureLists = map(types, t => getSignaturesOfType(t, kind)); - let result: Signature[] = undefined; + let result: Signature[]; for (let i = 0; i < signatureLists.length; i++) { for (const signature of signatureLists[i]) { // Only process signatures with parameter lists that aren't already in the result list @@ -5849,7 +5849,7 @@ namespace ts { else { // Combinations of function, class, enum and module let members = emptySymbols; - let stringIndexInfo: IndexInfo = undefined; + let stringIndexInfo: IndexInfo; if (symbol.exports) { members = getExportsOfSymbol(symbol); } @@ -6401,7 +6401,7 @@ namespace ts { } const propTypes: Type[] = []; const declarations: Declaration[] = []; - let commonType: Type = undefined; + let commonType: Type; for (const prop of props) { if (prop.declarations) { addRange(declarations, prop.declarations); @@ -6682,7 +6682,7 @@ namespace ts { const parameters: Symbol[] = []; let hasLiteralTypes = false; let minArgumentCount = 0; - let thisParameter: Symbol = undefined; + let thisParameter: Symbol; let hasThisParameter: boolean; const iife = getImmediatelyInvokedFunctionExpression(declaration); const isJSConstructSignature = isJSDocConstructSignature(declaration); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c3bfe55b40b..d44cbf4a72d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1590,7 +1590,7 @@ namespace ts { return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]); } - export let localizedDiagnosticMessages: MapLike = undefined; + export let localizedDiagnosticMessages: MapLike; export function getLocaleSpecificMessage(message: DiagnosticMessage) { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; @@ -3049,7 +3049,7 @@ namespace ts { /** Return the object corresponding to the best pattern to match `candidate`. */ export function findBestPatternMatch(values: ReadonlyArray, getPattern: (value: T) => Pattern, candidate: string): T | undefined { - let matchedValue: T | undefined = undefined; + let matchedValue: T | undefined; // use length of prefix as betterness criteria let longestMatchPrefixLength = -1; diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 534f44cfb7a..bd2b98116a1 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -674,7 +674,7 @@ namespace ts { } // string is for exact match - let matchedPattern: Pattern | string | undefined = undefined; + let matchedPattern: Pattern | string | undefined; if (state.compilerOptions.paths) { if (state.traceEnabled) { trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9da566ae793..5619d3db66d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4773,7 +4773,7 @@ namespace ts { const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword); parseExpected(SyntaxKind.OpenParenToken); - let initializer: VariableDeclarationList | Expression = undefined; + let initializer: VariableDeclarationList | Expression; if (token() !== SyntaxKind.SemicolonToken) { if (token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword) { initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); @@ -6235,7 +6235,7 @@ namespace ts { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. let state = JSDocState.SawAsterisk; - let margin: number | undefined = undefined; + let margin: number | undefined; // + 4 for leading '/** ' let indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; function pushComment(text: string) { @@ -7259,7 +7259,7 @@ namespace ts { } function getLastChildWorker(node: Node): Node | undefined { - let last: Node = undefined; + let last: Node; forEachChild(node, child => { if (nodeIsPresent(child)) { last = child; diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index f7d28d6b4fc..c64c1d169b8 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -48,7 +48,7 @@ namespace ts { const uniqueExports = createMap(); let exportedNames: Identifier[]; let hasExportDefault = false; - let exportEquals: ExportAssignment = undefined; + let exportEquals: ExportAssignment; let hasExportStarsToExportValues = false; let hasImportStarOrImportDefault = false; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 401caac3234..e4e30e67cec 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3329,7 +3329,7 @@ ${code} const ranges: Range[] = []; // Stuff related to the subfile we're parsing - let currentFileContent: string = undefined; + let currentFileContent: string; let currentFileName = fileName; let currentFileSymlinks: string[] | undefined; let currentFileOptions: { [s: string]: string } = {}; @@ -3464,7 +3464,7 @@ ${code} } function recordObjectMarker(fileName: string, location: LocationInformation, text: string, markerMap: ts.Map, markers: Marker[]): Marker { - let markerValue: any = undefined; + let markerValue: any; try { // Attempt to parse the marker value as JSON markerValue = JSON.parse("{ " + text + " }"); @@ -3523,7 +3523,7 @@ ${code} let output = ""; /// The current marker (or maybe multi-line comment?) we're parsing, possibly - let openMarker: LocationInformation = undefined; + let openMarker: LocationInformation; /// A stack of the open range markers that are still unclosed const openRanges: RangeLocationInformation[] = []; diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 12ebf4c4baf..424ee932541 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -145,7 +145,7 @@ namespace Utils { path = "tests/" + path; } - let content: string = undefined; + let content: string; try { content = Harness.IO.readFile(Harness.userSpecifiedRoot + path); } @@ -1891,9 +1891,9 @@ namespace Harness { const lines = Utils.splitContentByNewlines(code); // Stuff related to the subfile we're parsing - let currentFileContent: string = undefined; + let currentFileContent: string; let currentFileOptions: any = {}; - let currentFileName: any = undefined; + let currentFileName: any; let refs: string[] = []; for (const line of lines) { diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 949c6e5d947..e87402ea140 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -87,9 +87,9 @@ interface PlaybackControl { } namespace Playback { - let recordLog: IoLog = undefined; - let replayLog: IoLog = undefined; - let replayFilesRead: ts.Map | undefined = undefined; + let recordLog: IoLog; + let replayLog: IoLog; + let replayFilesRead: ts.Map | undefined; let recordLogFileNameBase = ""; interface Memoized { diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 1902ff70b19..e0194815435 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -54,8 +54,8 @@ namespace Harness.Parallel.Worker { const fakeContext: Mocha.ISuiteCallbackContext = { retries() { return this; }, slow() { return this; }, - timeout(n) { - timeout = n as number; + timeout(n: number) { + timeout = n; return this; }, }; @@ -126,8 +126,8 @@ namespace Harness.Parallel.Worker { let timeout: number; const fakeContext: Mocha.ITestCallbackContext = { skip() { return this; }, - timeout(n) { - timeout = n as number; + timeout(n: number) { + timeout = n; const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } }; process.send(timeoutMsg); return this; diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index f8d4d171f01..7dbfe0c5a75 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -163,7 +163,7 @@ class ProjectRunner extends RunnerBase { } function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile { - let sourceFile: ts.SourceFile = undefined; + let sourceFile: ts.SourceFile; if (fileName === Harness.Compiler.defaultLibFileName) { sourceFile = Harness.Compiler.getDefaultLibrarySourceFile(Harness.Compiler.getDefaultLibFileName(compilerOptions)); } @@ -294,7 +294,7 @@ class ProjectRunner extends RunnerBase { } function getSourceFileText(fileName: string): string { - let text: string = undefined; + let text: string; try { text = Harness.IO.readFile(getFileNameInTheProjectTest(fileName)); } @@ -370,7 +370,7 @@ class ProjectRunner extends RunnerBase { allInputFiles.unshift({ emittedFileName: sourceFile.fileName, code: sourceFile.text }); } else if (!(compilerOptions.outFile || compilerOptions.out)) { - let emitOutputFilePathWithoutExtension: string = undefined; + let emitOutputFilePathWithoutExtension: string; if (compilerOptions.outDir) { let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory()); sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), ""); diff --git a/src/server/client.ts b/src/server/client.ts index f4e70cae59e..542f89d50fc 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -607,7 +607,7 @@ namespace ts.server { const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); const renameFilename: string | undefined = response.body.renameFilename; - let renameLocation: number | undefined = undefined; + let renameLocation: number | undefined; if (renameFilename !== undefined) { renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation); } diff --git a/src/server/session.ts b/src/server/session.ts index 92b0c2ad02b..8e5770a4f66 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1560,7 +1560,7 @@ namespace ts.server { } private extractPositionAndRange(args: protocol.FileLocationOrRangeRequestArgs, scriptInfo: ScriptInfo): { position: number, textRange: TextRange } { - let position: number = undefined; + let position: number; let textRange: TextRange; if (this.isLocation(args)) { position = getPosition(args); @@ -1676,7 +1676,7 @@ namespace ts.server { } private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) { - let startPosition: number = undefined, endPosition: number = undefined; + let startPosition: number, endPosition: number; if (args.startPosition !== undefined) { startPosition = args.startPosition; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 7faf4e2b7f9..3c34bce4526 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -509,7 +509,7 @@ namespace ts.FindAllReferences.Core { // here appears to be intentional). const { text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), - allSearchSymbols = undefined, + allSearchSymbols, } = searchOptions; const escapedText = escapeLeadingUnderscores(text); const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker); @@ -1146,7 +1146,7 @@ namespace ts.FindAllReferences.Core { } function getContainingTypeReference(node: Node): Node { - let topLevelTypeReference: Node = undefined; + let topLevelTypeReference: Node; while (node) { if (isTypeNode(node)) { diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts index db957816146..14a9a73a9e1 100644 --- a/src/services/patternMatcher.ts +++ b/src/services/patternMatcher.ts @@ -336,7 +336,7 @@ namespace ts { // Only if all words have some sort of match is the pattern considered matched. const subWordTextChunks = segment.subWordTextChunks; - let matches: PatternMatch[] = undefined; + let matches: PatternMatch[]; for (const subWordTextChunk of subWordTextChunks) { // Try to match the candidate with this word @@ -393,8 +393,8 @@ namespace ts { let currentCandidate = 0; let currentChunkSpan = 0; - let firstMatch: number = undefined; - let contiguous: boolean = undefined; + let firstMatch: number; + let contiguous: boolean; while (true) { // Let's consider our termination cases diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 1bec23a15d6..2d76ce1843c 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -274,7 +274,7 @@ namespace ts.refactor.extractSymbol { } else if (isVariableStatement(node)) { let numInitializers = 0; - let lastInitializer: Expression | undefined = undefined; + let lastInitializer: Expression | undefined; for (const declaration of node.declarationList.declarations) { if (declaration.initializer) { numInitializers++; @@ -730,12 +730,12 @@ namespace ts.refactor.extractSymbol { const functionName = createIdentifier(functionNameText); - let returnType: TypeNode = undefined; + let returnType: TypeNode; const parameters: ParameterDeclaration[] = []; const callArguments: Identifier[] = []; let writes: UsageEntry[]; usagesInScope.forEach((usage, name) => { - let typeNode: TypeNode = undefined; + let typeNode: TypeNode; if (!isJS) { let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" @@ -1114,7 +1114,7 @@ namespace ts.refactor.extractSymbol { } function getContainingVariableDeclarationIfInList(node: Node, scope: Scope) { - let prevNode = undefined; + let prevNode; while (node !== undefined && node !== scope) { if (isVariableDeclaration(node) && node.initializer === prevNode && @@ -1161,7 +1161,7 @@ namespace ts.refactor.extractSymbol { } function getFirstDeclaration(type: Type): Declaration | undefined { - let firstDeclaration = undefined; + let firstDeclaration; const symbol = type.symbol; if (symbol && symbol.declarations) { @@ -1297,7 +1297,7 @@ namespace ts.refactor.extractSymbol { const members = scope.members; Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one. - let prevMember: ClassElement | undefined = undefined; + let prevMember: ClassElement | undefined; let allProperties = true; for (const member of members) { if (member.pos > maxPos) { @@ -1322,7 +1322,7 @@ namespace ts.refactor.extractSymbol { function getNodeToInsertConstantBefore(node: Node, scope: Scope): Statement { Debug.assert(!isClassLike(scope)); - let prevScope: Scope | undefined = undefined; + let prevScope: Scope | undefined; for (let curr = node; curr !== scope; curr = curr.parent) { if (isScope(curr)) { prevScope = curr; @@ -1331,7 +1331,7 @@ namespace ts.refactor.extractSymbol { for (let curr = (prevScope || node).parent; ; curr = curr.parent) { if (isBlockLike(curr)) { - let prevStatement = undefined; + let prevStatement; for (const statement of curr.statements) { if (statement.pos > node.pos) { break; @@ -1432,7 +1432,7 @@ namespace ts.refactor.extractSymbol { const visibleDeclarationsInExtractedRange: NamedDeclaration[] = []; const exposedVariableSymbolSet = createMap(); // Key is symbol ID const exposedVariableDeclarations: VariableDeclaration[] = []; - let firstExposedNonVariableDeclaration: NamedDeclaration | undefined = undefined; + let firstExposedNonVariableDeclaration: NamedDeclaration | undefined; const expression = !isReadonlyArray(targetRange.range) ? targetRange.range @@ -1440,7 +1440,7 @@ namespace ts.refactor.extractSymbol { ? (targetRange.range[0] as ExpressionStatement).expression : undefined; - let expressionDiagnostic: Diagnostic | undefined = undefined; + let expressionDiagnostic: Diagnostic | undefined; if (expression === undefined) { const statements = targetRange.range as ReadonlyArray; const start = first(statements).getStart(); @@ -1542,7 +1542,7 @@ namespace ts.refactor.extractSymbol { } let hasWrite = false; - let readonlyClassPropertyWrite: Declaration | undefined = undefined; + let readonlyClassPropertyWrite: Declaration | undefined; usagesPerScope[i].usages.forEach(value => { if (value.usage === Usage.Write) { hasWrite = true; diff --git a/src/services/services.ts b/src/services/services.ts index c3f25f3b98b..ed8e79a9069 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1971,7 +1971,7 @@ namespace ts { continue; } - let descriptor: TodoCommentDescriptor = undefined; + let descriptor: TodoCommentDescriptor; for (let i = 0; i < descriptors.length; i++) { if (matchArray[i + firstDescriptorCaptureIndex]) { descriptor = descriptors[i]; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 589b030d686..0b664641220 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1403,7 +1403,7 @@ namespace ts { function suppressTrailing(node: Node) { addEmitFlags(node, EmitFlags.NoTrailingComments); - let lastChild: Node = undefined; + let lastChild: Node; forEachChild( node, child => (lastChild = child, undefined), diff --git a/tslint.json b/tslint.json index eaf76b52155..a0756e63a2d 100644 --- a/tslint.json +++ b/tslint.json @@ -104,7 +104,6 @@ "no-object-literal-type-assertion": false, "no-shadowed-variable": false, "no-submodule-imports": false, - "no-unnecessary-initializer": false, "no-var-requires": false, "ordered-imports": false, "prefer-conditional-expression": false,