From 9fcaa19ab03423581f27ac8ce93264befe00e994 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Thu, 20 Jun 2019 13:32:34 +0300 Subject: [PATCH] microsoft-typescript/no-in-operator --- .eslintrc | 2 +- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 4 ++-- src/compiler/debug.ts | 2 +- src/compiler/factory.ts | 1 + src/harness/fourslash.ts | 12 ++++++------ src/server/project.ts | 1 + src/services/codefixes/convertToAsyncFunction.ts | 1 + src/services/findAllReferences.ts | 2 +- src/services/shims.ts | 4 ++-- src/testRunner/parallel/host.ts | 4 ++-- src/testRunner/unittests/services/extract/helpers.ts | 4 ++-- src/testRunner/unittests/tsserver/helpers.ts | 2 +- 13 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.eslintrc b/.eslintrc index 877092ee2f5..c579a908bf4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -59,7 +59,7 @@ }], "microsoft-typescript/no-double-space": "error", "microsoft-typescript/boolean-trivia": "error", - "microsoft-typescript/no-in-operator": "off", + "microsoft-typescript/no-in-operator": "error", "microsoft-typescript/debug-assert": "error", "microsoft-typescript/no-keywords": "error", diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ed08f6c3f4..b081e01d315 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -835,7 +835,7 @@ namespace ts { } } function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { - addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(location, message)); + addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line microsoft-typescript/no-in-operator } function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 063cfb10144..af493fc44d8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -114,7 +114,7 @@ namespace ts { // The global Map object. This may not be available, so we must test for it. declare const Map: (new () => Map) | undefined; // Internet Explorer's Map doesn't support iteration, so don't use it. - // tslint:disable-next-line no-in-operator variable-name + // eslint-disable-next-line microsoft-typescript/no-in-operator export const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. @@ -221,7 +221,7 @@ namespace ts { } has(key: string): boolean { - // tslint:disable-next-line:no-in-operator + // eslint-disable-next-line microsoft-typescript/no-in-operator return key in this.data; } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index c8c693399e9..ac7fbedf50e 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -66,7 +66,7 @@ namespace ts { } export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never { - const detail = typeof member === "object" && "kind" in member && "pos" in member && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member); + const detail = typeof member === "object" && hasProperty(member, "kind") && hasProperty(member, "pos") && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member); return fail(`${message} ${detail}`, stackCrawlMark || assertNever); } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 845de5941b7..5a4bb57f27b 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -75,6 +75,7 @@ namespace ts { if (typeof value === "number") { return createNumericLiteral(value + ""); } + // eslint-disable-next-line microsoft-typescript/no-in-operator if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt return createBigIntLiteral(pseudoBigIntToString(value) + "n"); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d7676176541..bdb725ea369 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -746,7 +746,7 @@ namespace FourSlash { private verifyCompletionsWorker(options: FourSlashInterface.VerifyCompletionsOptions): void { const actualCompletions = this.getCompletionListAtCaret({ ...options.preferences, triggerCharacter: options.triggerCharacter })!; if (!actualCompletions) { - if ("exact" in options && options.exact === undefined) return; + if (ts.hasProperty(options, "exact") && options.exact === undefined) return; this.raiseError(`No completions at position '${this.currentCaretPosition}'.`); } @@ -754,7 +754,7 @@ namespace FourSlash { this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options.isNewIdentifierLocation || false}, got ${actualCompletions.isNewIdentifierLocation}`); } - if ("isGlobalCompletion" in options && actualCompletions.isGlobalCompletion !== options.isGlobalCompletion) { + if (ts.hasProperty(options, "isGlobalCompletion") && actualCompletions.isGlobalCompletion !== options.isGlobalCompletion) { this.raiseError(`Expected 'isGlobalCompletion to be ${options.isGlobalCompletion}, got ${actualCompletions.isGlobalCompletion}`); } @@ -772,8 +772,8 @@ namespace FourSlash { } } - if ("exact" in options) { - ts.Debug.assert(!("includes" in options) && !("excludes" in options)); + if (ts.hasProperty(options, "exact")) { + ts.Debug.assert(!ts.hasProperty(options, "includes") && !ts.hasProperty(options, "excludes")); if (options.exact === undefined) throw this.raiseError("Expected no completions"); this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.exact), options.marker); } @@ -1192,7 +1192,7 @@ Actual: ${stringify(fullActual)}`); const sort = (locations: ReadonlyArray | undefined) => locations && ts.sort(locations, (r1, r2) => ts.compareStringsCaseSensitive(r1.fileName, r2.fileName) || r1.textSpan.start - r2.textSpan.start); assert.deepEqual(sort(references), sort(ranges.map((rangeOrOptions): ts.RenameLocation => { - const { range, ...prefixSuffixText } = "range" in rangeOrOptions ? rangeOrOptions : { range: rangeOrOptions }; + const { range, ...prefixSuffixText } = "range" in rangeOrOptions ? rangeOrOptions : { range: rangeOrOptions }; // eslint-disable-line microsoft-typescript/no-in-operator const { contextRangeIndex } = (range.marker && range.marker.data || {}) as { contextRangeIndex?: number; }; return { fileName: range.fileName, @@ -3129,7 +3129,7 @@ Actual: ${stringify(fullActual)}`); return this.getApplicableRefactorsWorker(this.getSelection(), this.activeFile.fileName); } private getApplicableRefactors(rangeOrMarker: Range | Marker, preferences = ts.emptyOptions): ReadonlyArray { - return this.getApplicableRefactorsWorker("position" in rangeOrMarker ? rangeOrMarker.position : rangeOrMarker, rangeOrMarker.fileName, preferences); + return this.getApplicableRefactorsWorker("position" in rangeOrMarker ? rangeOrMarker.position : rangeOrMarker, rangeOrMarker.fileName, preferences); // eslint-disable-line microsoft-typescript/no-in-operator } private getApplicableRefactorsWorker(positionOrRange: number | ts.TextRange, fileName: string, preferences = ts.emptyOptions): ReadonlyArray { return this.languageService.getApplicableRefactors(fileName, positionOrRange, preferences) || ts.emptyArray; diff --git a/src/server/project.ts b/src/server/project.ts index a1a43a430f1..72104e68911 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1190,6 +1190,7 @@ namespace ts.server { const pluginModule = pluginModuleFactory({ typescript: ts }); const newLS = pluginModule.create(info); for (const k of Object.keys(this.languageService)) { + // eslint-disable-next-line microsoft-typescript/no-in-operator if (!(k in newLS)) { this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); (newLS as any)[k] = (this.languageService as any)[k]; diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 3842c30d6aa..a537c0c40d3 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -607,6 +607,7 @@ namespace ts.codefix { } // return undefined argName when arg is null or undefined + // eslint-disable-next-line microsoft-typescript/no-in-operator if (!name || "identifier" in name && name.identifier.text === "undefined") { return undefined; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index fbe33df92a5..c77e6f497ac 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1440,7 +1440,7 @@ namespace ts.FindAllReferences.Core { } function addReference(referenceLocation: Node, relatedSymbol: Symbol | RelatedSymbol, state: State): void { - const { kind, symbol } = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol }; + const { kind, symbol } = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol }; // eslint-disable-line microsoft-typescript/no-in-operator const addRef = state.referenceAdder(symbol); if (state.options.implementations) { addImplementationReferences(referenceLocation, addRef, state); diff --git a/src/services/shims.ts b/src/services/shims.ts index 17de5f12e3e..5b6ef390e57 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -18,7 +18,7 @@ let debugObjectHost: { CollectGarbage(): void } = (function (this: any) { return // We need to use 'null' to interface with the managed side. /* tslint:disable:no-null-keyword */ -/* tslint:disable:no-in-operator */ +/* eslint-disable microsoft-typescript/no-in-operator */ /* @internal */ namespace ts { @@ -1271,7 +1271,7 @@ namespace ts { } } -/* tslint:enable:no-in-operator */ +/* eslint-enable microsoft-typescript/no-in-operator */ /* tslint:enable:no-null */ diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 1f0205e2b5b..9fa1135b20c 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -51,7 +51,7 @@ namespace Harness.Parallel.Host { constructor(info: ErrorInfo | TestInfo) { super(info.name[info.name.length - 1]); this.info = info; - this.state = "error" in info ? "failed" : "passed"; + this.state = "error" in info ? "failed" : "passed"; // eslint-disable-line microsoft-typescript/no-in-operator this.pending = false; } } @@ -518,7 +518,7 @@ namespace Harness.Parallel.Host { function replayTest(runner: Mocha.Runner, test: RemoteTest) { runner.emit("test", test); if (test.isFailed()) { - runner.emit("fail", test, "error" in test.info ? rebuildError(test.info) : new Error("Unknown error")); + runner.emit("fail", test, "error" in test.info ? rebuildError(test.info) : new Error("Unknown error")); // eslint-disable-line microsoft-typescript/no-in-operator } else { runner.emit("pass", test); diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index cc3ba9f372e..a998bf6f510 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -43,7 +43,7 @@ namespace ts { text += source.substring(lastPos, pos); activeRanges[activeRanges.length - 1].end = text.length; const range = activeRanges.pop()!; - if (range.name in ranges) { + if (hasProperty(ranges, range.name)) { throw new Error(`Duplicate name of range ${range.name}`); } ranges.set(range.name, range); @@ -173,4 +173,4 @@ namespace ts { assert.isUndefined(find(infos, info => info.description === description.message)); }); } -} \ No newline at end of file +} diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 1c2383ab004..bef4691cbe3 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -662,7 +662,7 @@ namespace ts.projectSystem { export function openFilesForSession(files: ReadonlyArray, session: server.Session): void { for (const file of files) { session.executeCommand(makeSessionRequest(CommandNames.Open, - "projectRootPath" in file ? { file: typeof file.file === "string" ? file.file : file.file.path, projectRootPath: file.projectRootPath } : { file: file.path })); + "projectRootPath" in file ? { file: typeof file.file === "string" ? file.file : file.file.path, projectRootPath: file.projectRootPath } : { file: file.path })); // eslint-disable-line microsoft-typescript/no-in-operator } }