diff --git a/.eslintrc.json b/.eslintrc.json index 4f1db28..d9dea31 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -134,9 +134,9 @@ "message": "Use symbol instead", "fixWith": "symbol" }, - "Function": { - "message": "The `Function` type accepts any function-like value.\nIt provides no type safety when calling the function, which can be a common source of bugs.\nIt also accepts things like class declarations, which will throw at runtime as they will not be called with `new`.\nIf you are expecting the function to accept certain arguments, you should explicitly define the function shape." - }, + // "Function": { + // "message": "The `Function` type accepts any function-like value.\nIt provides no type safety when calling the function, which can be a common source of bugs.\nIt also accepts things like class declarations, which will throw at runtime as they will not be called with `new`.\nIf you are expecting the function to accept certain arguments, you should explicitly define the function shape." + // }, "Object": { "message": "The `Object` type actually means \"any non-nullish value\", so it is marginally better than `unknown`.\n- If you want a type meaning \"any object\", you probably want `Record` instead.\n- If you want a type meaning \"any value\", you probably want `unknown` instead." }, @@ -239,7 +239,15 @@ ], "@typescript-eslint/strict-boolean-expressions": [ "warn", - { "allowNullableBoolean": true, "allowNullableNumber": true, "allowNullableString": true } + { + "allowString": true, + "allowNumber": true, + "allowNullableObject": false, + "allowNullableBoolean": true, + "allowNullableNumber": true, + "allowNullableString": true, + "allowAny": false + } ], "@typescript-eslint/unbound-method": "off" // Too many bugs right now: https://github.com/typescript-eslint/typescript-eslint/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+unbound-method } diff --git a/src/annotations/autolinks.ts b/src/annotations/autolinks.ts index f5c15dc..9e906a8 100644 --- a/src/annotations/autolinks.ts +++ b/src/annotations/autolinks.ts @@ -175,7 +175,7 @@ export class Autolinks implements Disposable { if (ref.title) { title = ` "${ref.title.replace(numRegex, num)}`; - if (issue) { + if (issue != null) { if (issue instanceof Promises.CancellationError) { title += `\n${GlyphChars.Dash.repeat(2)}\nDetails timed out`; } else { diff --git a/src/annotations/lineAnnotationController.ts b/src/annotations/lineAnnotationController.ts index ab0e9a9..a6119da 100644 --- a/src/annotations/lineAnnotationController.ts +++ b/src/annotations/lineAnnotationController.ts @@ -178,7 +178,7 @@ export class LineAnnotationController implements Disposable { const selections = Container.lineTracker.selections; if (editor == null || selections == null || !isTextEditor(editor)) { - if (cc) { + if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because there is no valid editor or no valid selections`; } @@ -195,7 +195,7 @@ export class LineAnnotationController implements Disposable { const cfg = Container.config.currentLine; if (this.suspended) { - if (cc) { + if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the controller is suspended`; } @@ -205,7 +205,7 @@ export class LineAnnotationController implements Disposable { const trackedDocument = await Container.tracker.getOrAdd(editor.document); if (!trackedDocument.isBlameable && this.suspended) { - if (cc) { + if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${ this.suspended ? 'controller is suspended' @@ -219,7 +219,7 @@ export class LineAnnotationController implements Disposable { // Make sure the editor hasn't died since the await above and that we are still on the same line(s) if (editor.document == null || !Container.lineTracker.includes(selections)) { - if (cc) { + if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${ editor.document == null ? 'editor is gone' @@ -231,7 +231,7 @@ export class LineAnnotationController implements Disposable { return; } - if (cc) { + if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} selection(s)=${selections .map(s => `[${s.anchor}-${s.active}]`) .join()}`; diff --git a/src/codelens/codeLensProvider.ts b/src/codelens/codeLensProvider.ts index 65b2446..66648f4 100644 --- a/src/codelens/codeLensProvider.ts +++ b/src/codelens/codeLensProvider.ts @@ -205,7 +205,7 @@ export class GitCodeLensProvider implements CodeLensProvider { !languageScope.symbolScopes.includes('!file') ) { // Check if we have a lens for the whole document -- if not add one - if (!lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0)) { + if (lenses.find(l => l.range.start.line === 0 && l.range.end.line === 0) == null) { const blameRange = documentRangeFn(); let blameForRangeFn: (() => GitBlameLines | undefined) | undefined = undefined; diff --git a/src/commands/closeUnchangedFiles.ts b/src/commands/closeUnchangedFiles.ts index 4b93db9..0452063 100644 --- a/src/commands/closeUnchangedFiles.ts +++ b/src/commands/closeUnchangedFiles.ts @@ -133,7 +133,7 @@ export class CloseUnchangedFilesCommand extends Command { let timer: NodeJS.Timer | undefined; this._onEditorChangedFn = (editor: TextEditor | undefined) => { - if (timer) { + if (timer != null) { clearTimeout(timer); timer = undefined; diff --git a/src/commands/copyMessageToClipboard.ts b/src/commands/copyMessageToClipboard.ts index 3842c28..0cd6651 100644 --- a/src/commands/copyMessageToClipboard.ts +++ b/src/commands/copyMessageToClipboard.ts @@ -47,7 +47,7 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { if (!repoPath) return; const log = await Container.git.getLog(repoPath, { limit: 1 }); - if (!log) return; + if (log == null) return; args.message = Iterables.first(log.commits.values()).message; } else if (args.message == null) { diff --git a/src/commands/copyShaToClipboard.ts b/src/commands/copyShaToClipboard.ts index 163d30f..41442f4 100644 --- a/src/commands/copyShaToClipboard.ts +++ b/src/commands/copyShaToClipboard.ts @@ -45,7 +45,7 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { if (!repoPath) return; const log = await Container.git.getLog(repoPath, { limit: 1 }); - if (!log) return; + if (log == null) return; args.sha = Iterables.first(log.commits.values()).sha; } else if (args.sha == null) { diff --git a/src/commands/git/pull.ts b/src/commands/git/pull.ts index a333508..9d4faae 100644 --- a/src/commands/git/pull.ts +++ b/src/commands/git/pull.ts @@ -195,9 +195,10 @@ export class PullGitCommand extends QuickCommand { ).fromNow()}`; } - const pullDetails = status?.state.behind - ? ` ${Strings.pluralize('commit', status.state.behind)} into $(repo) ${repo.formattedName}` - : ` into $(repo) ${repo.formattedName}`; + const pullDetails = + status?.state.behind != null + ? ` ${Strings.pluralize('commit', status.state.behind)} into $(repo) ${repo.formattedName}` + : ` into $(repo) ${repo.formattedName}`; step = this.createConfirmStep( appendReposToTitle(`Confirm ${context.title}`, state, context, lastFetchedOn), diff --git a/src/commands/git/reset.ts b/src/commands/git/reset.ts index bb218e8..50a9e82 100644 --- a/src/commands/git/reset.ts +++ b/src/commands/git/reset.ts @@ -150,8 +150,7 @@ export class ResetGitCommand extends QuickCommand { return state.counter < 0 ? StepResult.Break : undefined; } - // eslint-disable-next-line @typescript-eslint/require-await - private async *confirmStep(state: ResetStepState, context: Context): StepResultGenerator { + private *confirmStep(state: ResetStepState, context: Context): StepResultGenerator { const step: QuickPickStep> = this.createConfirmStep( appendReposToTitle(`Confirm ${context.title}`, state, context), [ diff --git a/src/commands/git/revert.ts b/src/commands/git/revert.ts index 3265b05..f9a81ad 100644 --- a/src/commands/git/revert.ts +++ b/src/commands/git/revert.ts @@ -150,8 +150,7 @@ export class RevertGitCommand extends QuickCommand { return state.counter < 0 ? StepResult.Break : undefined; } - // eslint-disable-next-line @typescript-eslint/require-await - private async *confirmStep( + private *confirmStep( state: RevertStepState>, context: Context, ): StepResultGenerator { diff --git a/src/commands/git/stash.ts b/src/commands/git/stash.ts index 3583c83..9cf221f 100644 --- a/src/commands/git/stash.ts +++ b/src/commands/git/stash.ts @@ -2,7 +2,7 @@ import { QuickInputButtons, QuickPickItem, Uri, window } from 'vscode'; import { GlyphChars } from '../../constants'; import { Container } from '../../container'; -import { GitReference, GitStashCommit, GitStashReference, Repository } from '../../git/git'; +import { GitReference, GitStashCommit, GitStashReference, Repository, RunError } from '../../git/git'; import { GitUri } from '../../git/gitUri'; import { GitActions, GitCommandsCommand } from '../gitCommands'; import { @@ -287,32 +287,33 @@ export class StashGitCommand extends QuickCommand { } catch (ex) { Logger.error(ex, context.title); - const msg: string = ex?.message ?? ''; - if (msg.includes('Your local changes to the following files would be overwritten by merge')) { - void window.showWarningMessage( - 'Unable to apply stash. Your working tree changes would be overwritten. Please commit or stash your changes before trying again', - ); + if (ex instanceof Error) { + const msg: string = ex.message ?? ''; + if (msg.includes('Your local changes to the following files would be overwritten by merge')) { + void window.showWarningMessage( + 'Unable to apply stash. Your working tree changes would be overwritten. Please commit or stash your changes before trying again', + ); - return; - } + return; + } - if ( - (msg.includes('Auto-merging') && msg.includes('CONFLICT')) || - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - (ex?.stdout?.includes('Auto-merging') && ex?.stdout?.includes('CONFLICT')) || - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - ex?.stdout?.includes('needs merge') - ) { - void window.showInformationMessage('Stash applied with conflicts'); + if ( + (msg.includes('Auto-merging') && msg.includes('CONFLICT')) || + (ex instanceof RunError && + ((ex.stdout.includes('Auto-merging') && ex.stdout.includes('CONFLICT')) || + ex.stdout.includes('needs merge'))) + ) { + void window.showInformationMessage('Stash applied with conflicts'); - return; - } + return; + } - void Messages.showGenericErrorMessage( - `Unable to apply stash \u2014 ${msg.trim().replace(/\n+?/g, '; ')}`, - ); + void Messages.showGenericErrorMessage( + `Unable to apply stash \u2014 ${msg.trim().replace(/\n+?/g, '; ')}`, + ); - return; + return; + } } } } diff --git a/src/commands/gitCommands.actions.ts b/src/commands/gitCommands.actions.ts index 093ac6f..9a7dcdf 100644 --- a/src/commands/gitCommands.actions.ts +++ b/src/commands/gitCommands.actions.ts @@ -576,12 +576,11 @@ export namespace GitActions { ); } - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const { annotationType, line, ...opts } = { + const { annotationType, line, ...opts }: Exclude = { preserveFocus: true, preview: false, ...options, - } as Exclude; + }; if (line != null && line !== 0) { opts.selection = new Range(line, 0, line, 0); diff --git a/src/commands/gitCommands.ts b/src/commands/gitCommands.ts index 6d3264a..eb654de 100644 --- a/src/commands/gitCommands.ts +++ b/src/commands/gitCommands.ts @@ -58,8 +58,9 @@ export type GitCommandsCommandArgs = | SwitchGitCommandArgs | TagGitCommandArgs; -// eslint-disable-next-line @typescript-eslint/no-empty-function -function* nullSteps(): StepGenerator {} +function* nullSteps(): StepGenerator { + /* noop */ +} @command() export class GitCommandsCommand extends Command { diff --git a/src/commands/openBranchOnRemote.ts b/src/commands/openBranchOnRemote.ts index 0e11847..2ca4f84 100644 --- a/src/commands/openBranchOnRemote.ts +++ b/src/commands/openBranchOnRemote.ts @@ -47,7 +47,7 @@ export class OpenBranchOnRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args?: OpenBranchOnRemoteCommandArgs) { uri = getCommandUri(uri, editor); - const gitUri = uri && (await GitUri.fromUri(uri)); + const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined; const repoPath = await getRepoPathOrActiveOrPrompt( gitUri, diff --git a/src/commands/openBranchesOnRemote.ts b/src/commands/openBranchesOnRemote.ts index 617176f..f60a6b1 100644 --- a/src/commands/openBranchesOnRemote.ts +++ b/src/commands/openBranchesOnRemote.ts @@ -41,7 +41,7 @@ export class OpenBranchesOnRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args?: OpenBranchesOnRemoteCommandArgs) { uri = getCommandUri(uri, editor); - const gitUri = uri && (await GitUri.fromUri(uri)); + const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined; const repoPath = await getRepoPathOrActiveOrPrompt( gitUri, diff --git a/src/commands/openRepoOnRemote.ts b/src/commands/openRepoOnRemote.ts index cff148b..d818291 100644 --- a/src/commands/openRepoOnRemote.ts +++ b/src/commands/openRepoOnRemote.ts @@ -41,7 +41,7 @@ export class OpenRepoOnRemoteCommand extends ActiveEditorCommand { async execute(editor?: TextEditor, uri?: Uri, args?: OpenRepoOnRemoteCommandArgs) { uri = getCommandUri(uri, editor); - const gitUri = uri && (await GitUri.fromUri(uri)); + const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined; const repoPath = await getRepoPathOrActiveOrPrompt( gitUri, diff --git a/src/commands/quickCommand.steps.ts b/src/commands/quickCommand.steps.ts index df6b8d1..ba2fbb0 100644 --- a/src/commands/quickCommand.steps.ts +++ b/src/commands/quickCommand.steps.ts @@ -1052,7 +1052,7 @@ export async function* pickRepositoriesStep< options = { placeholder: 'Choose repositories', skipIfPossible: false, ...options }; let actives: Repository[]; - if (state.repos) { + if (state.repos != null) { if (Arrays.isStringArray(state.repos)) { actives = Arrays.filterMap(state.repos, path => context.repos.find(r => r.path === path)); if (options.skipIfPossible && actives.length !== 0 && state.repos.length === actives.length) { @@ -1063,7 +1063,7 @@ export async function* pickRepositoriesStep< } } else { const active = await Container.git.getActiveRepository(); - actives = active ? [active] : []; + actives = active != null ? [active] : []; } const step = QuickCommand.createPickStep({ @@ -1516,8 +1516,7 @@ async function getShowCommitOrStashStepItems< return items; } -// eslint-disable-next-line @typescript-eslint/require-await -export async function* showCommitOrStashFilesStep< +export function* showCommitOrStashFilesStep< State extends PartialStepState & { repo: Repository; reference: GitLogCommit | GitStashCommit; diff --git a/src/commands/showQuickBranchHistory.ts b/src/commands/showQuickBranchHistory.ts index c4630f3..c63fe90 100644 --- a/src/commands/showQuickBranchHistory.ts +++ b/src/commands/showQuickBranchHistory.ts @@ -29,7 +29,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { async execute(editor?: TextEditor, uri?: Uri, args?: ShowQuickBranchHistoryCommandArgs) { uri = getCommandUri(uri, editor); - const gitUri = uri && (await GitUri.fromUri(uri)); + const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined; const repoPath = args?.repoPath ?? gitUri?.repoPath; diff --git a/src/commands/switchMode.ts b/src/commands/switchMode.ts index 7b15eff..2de0a54 100644 --- a/src/commands/switchMode.ts +++ b/src/commands/switchMode.ts @@ -20,7 +20,7 @@ export class SwitchModeCommand extends Command { const pick = await ModePicker.show(); if (pick === undefined) return; - if (cc) { + if (cc != null) { cc.exitDetails = ` \u2014 mode=${pick.key ?? ''}`; } diff --git a/src/configuration.ts b/src/configuration.ts index 087f314..716937a 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -308,7 +308,7 @@ export class Configuration { if (inspection.globalValue !== undefined) { await this.update( to as any, - options.migrationFn ? options.migrationFn(inspection.globalValue) : inspection.globalValue, + options.migrationFn != null ? options.migrationFn(inspection.globalValue) : inspection.globalValue, ConfigurationTarget.Global, ); migrated = true; @@ -324,7 +324,9 @@ export class Configuration { if (inspection.workspaceValue !== undefined) { await this.update( to as any, - options.migrationFn ? options.migrationFn(inspection.workspaceValue) : inspection.workspaceValue, + options.migrationFn != null + ? options.migrationFn(inspection.workspaceValue) + : inspection.workspaceValue, ConfigurationTarget.Workspace, ); migrated = true; @@ -340,7 +342,7 @@ export class Configuration { if (inspection.workspaceFolderValue !== undefined) { await this.update( to as any, - options.migrationFn + options.migrationFn != null ? options.migrationFn(inspection.workspaceFolderValue) : inspection.workspaceFolderValue, ConfigurationTarget.WorkspaceFolder, @@ -427,7 +429,9 @@ export class Configuration { if (toInspection === undefined || toInspection.globalValue === undefined) { await this.update( to as any, - options.migrationFn ? options.migrationFn(fromInspection.globalValue) : fromInspection.globalValue, + options.migrationFn != null + ? options.migrationFn(fromInspection.globalValue) + : fromInspection.globalValue, ConfigurationTarget.Global, ); // Can't delete the old setting currently because it errors with `Unable to write to User Settings because is not a registered configuration` @@ -444,7 +448,7 @@ export class Configuration { if (toInspection === undefined || toInspection.workspaceValue === undefined) { await this.update( to as any, - options.migrationFn + options.migrationFn != null ? options.migrationFn(fromInspection.workspaceValue) : fromInspection.workspaceValue, ConfigurationTarget.Workspace, @@ -463,7 +467,7 @@ export class Configuration { if (toInspection === undefined || toInspection.workspaceFolderValue === undefined) { await this.update( to as any, - options.migrationFn + options.migrationFn != null ? options.migrationFn(fromInspection.workspaceFolderValue) : fromInspection.workspaceFolderValue, ConfigurationTarget.WorkspaceFolder, diff --git a/src/git/formatters/commitFormatter.ts b/src/git/formatters/commitFormatter.ts index b1ab801..9422f62 100644 --- a/src/git/formatters/commitFormatter.ts +++ b/src/git/formatters/commitFormatter.ts @@ -459,10 +459,9 @@ export class CommitFormatter extends Formatter { ): string { if (CommitFormatter.has(template, 'footnotes')) { if (dateFormatOrOptions == null || typeof dateFormatOrOptions === 'string') { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions dateFormatOrOptions = { dateFormat: dateFormatOrOptions, - } as CommitFormatOptions; + }; } if (dateFormatOrOptions.footnotes == null) { diff --git a/src/git/formatters/formatter.ts b/src/git/formatters/formatter.ts index abe1f11..74c066f 100644 --- a/src/git/formatters/formatter.ts +++ b/src/git/formatters/formatter.ts @@ -13,24 +13,24 @@ type Constructor> = new (...args: any[]) => T; const hasTokenRegexMap = new Map(); const spaceReplacementRegex = / /g; -declare type RequiredTokenOptions = TOptions & Required>; +declare type RequiredTokenOptions = Options & Required>; -export abstract class Formatter { - protected _item!: TItem; - protected _options!: RequiredTokenOptions; +export abstract class Formatter { + protected _item!: Item; + protected _options!: RequiredTokenOptions; - constructor(item: TItem, options?: TOptions) { + constructor(item: Item, options?: Options) { this.reset(item, options); } - reset(item: TItem, options?: TOptions) { + reset(item: Item, options?: Options) { this._item = item; - if (options === undefined && this._options !== undefined) return; + if (options == null && this._options != null) return; - if (options === undefined) { + if (options == null) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - options = {} as TOptions; + options = {} as Options; } if (options.dateFormat == null) { @@ -41,7 +41,7 @@ export abstract class Formatter; + this._options = options as RequiredTokenOptions; } private collapsableWhitespace: number = 0; @@ -96,26 +96,22 @@ export abstract class Formatter, - TItem, - TOptions extends FormatOptions - >( + protected static fromTemplateCore, Item, Options extends FormatOptions>( formatter: TFormatter | Constructor, template: string, - item: TItem, - dateFormatOrOptions?: string | null | TOptions, + item: Item, + dateFormatOrOptions?: string | null | Options, ): string { // Preserve spaces template = template.replace(spaceReplacementRegex, '\u00a0'); if (formatter instanceof Formatter) return Strings.interpolate(template, formatter); - let options: TOptions | undefined = undefined; + let options: Options | undefined = undefined; if (dateFormatOrOptions == null || typeof dateFormatOrOptions === 'string') { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions options = { dateFormat: dateFormatOrOptions, - } as TOptions; + } as Options; } else { options = dateFormatOrOptions; } diff --git a/src/git/git.ts b/src/git/git.ts index 22e6eb3..863a758 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -8,7 +8,7 @@ import { Container } from '../container'; import { Logger } from '../logger'; import { Objects, Strings } from '../system'; import { findGitPath, GitLocation } from './locator'; -import { fsExists, run, RunOptions } from './shell'; +import { fsExists, run, RunError, RunOptions } from './shell'; import { GitBranchParser, GitLogParser, GitReflogParser, GitStashParser, GitTagParser } from './parsers/parsers'; import { GitFileStatus, GitRevision } from './models/models'; @@ -17,6 +17,7 @@ export * from './parsers/parsers'; export * from './formatters/formatters'; export * from './remotes/provider'; export * from './search'; +export { RunError } from './shell'; export type GitDiffFilter = Exclude; @@ -566,8 +567,7 @@ export namespace Git { '-', ); } catch (ex) { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (ex.stdout) { + if (ex instanceof RunError && ex.stdout) { return ex.stdout; } @@ -730,7 +730,7 @@ export namespace Git { params.push('--first-parent'); } - if (authors) { + if (authors != null && authors.length !== 0) { params.push('--use-mailmap', ...authors.map(a => `--author=${a}`)); } diff --git a/src/git/gitService.ts b/src/git/gitService.ts index 7ed934d..da6f41d 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -512,6 +512,7 @@ export class GitService implements Disposable { if (result.title === 'Yes') { try { void (await Git.apply(uri.repoPath, patch, { allowConflicts: true })); + return; } catch (e) { // eslint-disable-next-line no-ex-assign diff --git a/src/git/models/logCommit.ts b/src/git/models/logCommit.ts index 6fc8e09..7a15bc1 100644 --- a/src/git/models/logCommit.ts +++ b/src/git/models/logCommit.ts @@ -81,7 +81,7 @@ export class GitLogCommit extends GitCommit { } get isMerge() { - return this.parentShas && this.parentShas.length > 1; + return this.parentShas != null && this.parentShas.length > 1; } get nextUri(): Uri { diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index 7a8ec3f..e4028ca 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -354,9 +354,10 @@ export class Repository implements Disposable { return void (await window.withProgress( { location: ProgressLocation.Notification, - title: opts.branch - ? `Pulling ${opts.branch.name}...` - : `Fetching ${opts.remote ? `${opts.remote} of ` : ''}${this.formattedName}...`, + title: + opts.branch != null + ? `Pulling ${opts.branch.name}...` + : `Fetching ${opts.remote ? `${opts.remote} of ` : ''}${this.formattedName}...`, }, () => this.fetchCore(opts), )); @@ -549,7 +550,7 @@ export class Repository implements Disposable { { location: ProgressLocation.Notification, title: GitReference.isBranch(opts.reference) - ? `${opts.publish ? 'Publishing ' : 'Pushing '}${opts.reference.name}...` + ? `${opts.publish != null ? 'Publishing ' : 'Pushing '}${opts.reference.name}...` : `Pushing ${this.formattedName}...`, }, () => this.pushCore(opts), diff --git a/src/git/remotes/azure-devops.ts b/src/git/remotes/azure-devops.ts index e6ac1f9..33678aa 100644 --- a/src/git/remotes/azure-devops.ts +++ b/src/git/remotes/azure-devops.ts @@ -117,7 +117,7 @@ export class AzureDevOpsRemote extends RemoteProvider { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = `&line=${range.start.line}`; } else { diff --git a/src/git/remotes/bitbucket-server.ts b/src/git/remotes/bitbucket-server.ts index 22add58..82ac56e 100644 --- a/src/git/remotes/bitbucket-server.ts +++ b/src/git/remotes/bitbucket-server.ts @@ -124,7 +124,7 @@ export class BitbucketServerRemote extends RemoteProvider { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = `#${range.start.line}`; } else { diff --git a/src/git/remotes/bitbucket.ts b/src/git/remotes/bitbucket.ts index cccabc8..b292712 100644 --- a/src/git/remotes/bitbucket.ts +++ b/src/git/remotes/bitbucket.ts @@ -117,7 +117,7 @@ export class BitbucketRemote extends RemoteProvider { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = `#${fileName}-${range.start.line}`; } else { diff --git a/src/git/remotes/custom.ts b/src/git/remotes/custom.ts index e86ee6b..2fccd50 100644 --- a/src/git/remotes/custom.ts +++ b/src/git/remotes/custom.ts @@ -42,7 +42,7 @@ export class CustomRemote extends RemoteProvider { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = Strings.interpolate(this.urls.fileLine, { line: range.start.line }); } else { diff --git a/src/git/remotes/github.ts b/src/git/remotes/github.ts index 532d5e9..7ff026e 100644 --- a/src/git/remotes/github.ts +++ b/src/git/remotes/github.ts @@ -140,7 +140,7 @@ export class GitHubRemote extends RemoteProviderWithApi { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = `#L${range.start.line}`; } else { diff --git a/src/git/remotes/gitlab.ts b/src/git/remotes/gitlab.ts index a098408..bc8a5d3 100644 --- a/src/git/remotes/gitlab.ts +++ b/src/git/remotes/gitlab.ts @@ -112,7 +112,7 @@ export class GitLabRemote extends RemoteProvider { protected getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string { let line; - if (range) { + if (range != null) { if (range.start.line === range.end.line) { line = `#L${range.start.line}`; } else { diff --git a/src/git/shell.ts b/src/git/shell.ts index 9a20276..af29f9d 100644 --- a/src/git/shell.ts +++ b/src/git/shell.ts @@ -1,5 +1,5 @@ 'use strict'; -import { execFile } from 'child_process'; +import { ExecException, execFile } from 'child_process'; import * as fs from 'fs'; import * as paths from 'path'; import * as iconv from 'iconv-lite'; @@ -53,10 +53,8 @@ function runDownPath(exe: string): string { function isExecutable(stats: fs.Stats) { if (isWindows) return true; - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - const isGroup = stats.gid ? process.getgid && stats.gid === process.getgid() : true; - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - const isUser = stats.uid ? process.getuid && stats.uid === process.getuid() : true; + const isGroup = stats.gid ? process.getgid != null && stats.gid === process.getgid() : true; + const isUser = stats.uid ? process.getuid != null && stats.uid === process.getuid() : true; return Boolean(stats.mode & 0o0001 || (stats.mode & 0o0010 && isGroup) || (stats.mode & 0o0100 && isUser)); } @@ -143,6 +141,31 @@ export interface RunOptions { const bufferExceededRegex = /stdout maxBuffer( length)? exceeded/; +export class RunError extends Error { + constructor(private readonly original: ExecException, public readonly stdout: string) { + super(original.message); + + stdout = stdout.trim(); + Error.captureStackTrace(this, RunError); + } + + get cmd(): string | undefined { + return this.original.cmd; + } + + get killed(): boolean | undefined { + return this.original.killed; + } + + get code(): number | undefined { + return this.original.code; + } + + get signal(): NodeJS.Signals | undefined { + return this.original.signal; + } +} + export function run( command: string, args: any[], @@ -152,36 +175,34 @@ export function run( const { stdin, stdinEncoding, ...opts }: RunOptions = { maxBuffer: 100 * 1024 * 1024, ...options }; return new Promise((resolve, reject) => { - const proc = execFile( - command, - args, - opts, - (error: (Error & { stdout?: TOut | undefined }) | null, stdout, stderr) => { - if (error != null) { - if (bufferExceededRegex.test(error.message)) { - error.message = `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${opts.maxBuffer} bytes`; - } - - error.stdout = + const proc = execFile(command, args, opts, (error: ExecException | null, stdout, stderr) => { + if (error != null) { + if (bufferExceededRegex.test(error.message)) { + error.message = `Command output exceeded the allocated stdout buffer. Set 'options.maxBuffer' to a larger value than ${opts.maxBuffer} bytes`; + } + + reject( + new RunError( + error, encoding === 'utf8' || encoding === 'binary' || encoding === 'buffer' - ? (stdout as TOut) - : (iconv.decode(Buffer.from(stdout, 'binary'), encoding) as TOut); - reject(error); + ? stdout + : iconv.decode(Buffer.from(stdout, 'binary'), encoding), + ), + ); - return; - } + return; + } - if (stderr) { - Logger.warn(`Warning(${command} ${args.join(' ')}): ${stderr}`); - } + if (stderr) { + Logger.warn(`Warning(${command} ${args.join(' ')}): ${stderr}`); + } - resolve( - encoding === 'utf8' || encoding === 'binary' || encoding === 'buffer' - ? (stdout as TOut) - : (iconv.decode(Buffer.from(stdout, 'binary'), encoding) as TOut), - ); - }, - ); + resolve( + encoding === 'utf8' || encoding === 'binary' || encoding === 'buffer' + ? (stdout as TOut) + : (iconv.decode(Buffer.from(stdout, 'binary'), encoding) as TOut), + ); + }); if (stdin != null) { proc.stdin?.end(stdin, stdinEncoding ?? 'utf8'); diff --git a/src/keyboard.ts b/src/keyboard.ts index 55a0ac1..0152f16 100644 --- a/src/keyboard.ts +++ b/src/keyboard.ts @@ -50,7 +50,7 @@ export class KeyboardScope implements Disposable { const index = mappings.indexOf(this._mapping); const cc = Logger.getCorrelationContext(); - if (cc) { + if (cc != null) { cc.exitDetails = ` \u2022 index=${index}`; } @@ -75,8 +75,8 @@ export class KeyboardScope implements Disposable { const cc = Logger.getCorrelationContext(); const mapping = mappings[mappings.length - 1]; - if (mapping !== this._mapping || !mapping[key]) { - if (cc) { + if (mapping !== this._mapping || mapping[key] == null) { + if (cc != null) { cc.exitDetails = ' \u2022 skipped'; } @@ -127,7 +127,7 @@ export class KeyboardScope implements Disposable { const mapping = mappings[mappings.length - 1]; if (mapping !== this._mapping) { - if (cc) { + if (cc != null) { cc.exitDetails = ' \u2022 skipped'; } @@ -186,7 +186,7 @@ export class Keyboard implements Disposable { const cc = Logger.getCorrelationContext(); if (!mappings.length) { - if (cc) { + if (cc != null) { cc.exitDetails = ' \u2022 skipped, no mappings'; } @@ -201,7 +201,7 @@ export class Keyboard implements Disposable { command = await command(); } if (typeof command?.onDidPressKey !== 'function') { - if (cc) { + if (cc != null) { cc.exitDetails = ' \u2022 skipped, no callback'; } diff --git a/src/logger.ts b/src/logger.ts index 2ba351b..8bb0fc0 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -222,7 +222,6 @@ export class Logger { } } - // eslint-disable-next-line @typescript-eslint/ban-types static toLoggableName(instance: Function | object) { let name: string; if (typeof instance === 'function') { diff --git a/src/messages.ts b/src/messages.ts index fd587af..5ebf9ec 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -181,7 +181,7 @@ export class Messages { Logger.log( `ShowMessage(${type}, '${message}', ${suppressionKey}, ${JSON.stringify(dontShowAgain)}) returned ${ - result ? result.title : result + result != null ? result.title : result }`, ); return result; diff --git a/src/quickpicks/commitPicker.ts b/src/quickpicks/commitPicker.ts index 3f671e9..53d56a7 100644 --- a/src/quickpicks/commitPicker.ts +++ b/src/quickpicks/commitPicker.ts @@ -3,7 +3,7 @@ import { Disposable, QuickPick, window } from 'vscode'; import { configuration } from '../configuration'; import { Container } from '../container'; import { GitLog, GitLogCommit } from '../git/git'; -import { KeyboardScope, KeyCommand, Keys } from '../keyboard'; +import { KeyboardScope, Keys } from '../keyboard'; import { CommitQuickPickItem, Directive, DirectiveQuickPickItem, getQuickPickIgnoreFocusOut } from '../quickpicks'; import { Iterables, Promises } from '../system'; @@ -99,14 +99,13 @@ export namespace CommitPicker { Object.fromEntries( options.keys.map(key => [ key, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions { onDidPressKey: key => { if (quickpick.activeItems.length !== 0) { void options.onDidPressKey!(key, quickpick); } }, - } as KeyCommand, + }, ]), ), ); diff --git a/src/quickpicks/gitQuickPickItems.ts b/src/quickpicks/gitQuickPickItems.ts index 7337349..8ebab91 100644 --- a/src/quickpicks/gitQuickPickItems.ts +++ b/src/quickpicks/gitQuickPickItems.ts @@ -304,11 +304,11 @@ export namespace RepositoryQuickPickItem { } let description = ''; - if (options.branch && repoStatus) { + if (options.branch && repoStatus != null) { description = repoStatus.branch; } - if (options.status && repoStatus) { + if (options.status && repoStatus != null) { let workingStatus = ''; if (repoStatus.files.length !== 0) { workingStatus = repoStatus.getFormattedDiffStatus({ diff --git a/src/quickpicks/referencePicker.ts b/src/quickpicks/referencePicker.ts index 7a1fe9b..54d0cef 100644 --- a/src/quickpicks/referencePicker.ts +++ b/src/quickpicks/referencePicker.ts @@ -3,7 +3,7 @@ import { CancellationTokenSource, Disposable, QuickPick, window } from 'vscode'; import { GlyphChars } from '../constants'; import { Container } from '../container'; import { GitBranch, GitReference, GitTag } from '../git/git'; -import { KeyboardScope, KeyCommand, Keys } from '../keyboard'; +import { KeyboardScope, Keys } from '../keyboard'; import { BranchQuickPickItem, getQuickPickIgnoreFocusOut, RefQuickPickItem, TagQuickPickItem } from '../quickpicks'; import { getBranchesAndOrTags, getValidateGitReferenceFn } from '../commands/quickCommand'; @@ -53,14 +53,13 @@ export namespace ReferencePicker { Object.fromEntries( options.keys.map(key => [ key, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions { onDidPressKey: key => { if (quickpick.activeItems.length !== 0) { void options.onDidPressKey!(key, quickpick); } }, - } as KeyCommand, + }, ]), ), ); diff --git a/src/system/array.ts b/src/system/array.ts index ea8027d..8b63bf7 100644 --- a/src/system/array.ts +++ b/src/system/array.ts @@ -194,7 +194,7 @@ export namespace Arrays { if (uniqueValues[value]) return false; uniqueValues[value] = accessor; - return predicate ? predicate(item) : true; + return predicate?.(item) ?? true; }); } } diff --git a/src/system/decorators/gate.ts b/src/system/decorators/gate.ts index 596606d..4681e62 100644 --- a/src/system/decorators/gate.ts +++ b/src/system/decorators/gate.ts @@ -20,7 +20,6 @@ function defaultResolver(...args: any[]): string { export function gate any>(resolver?: (...args: Parameters) => string) { return (target: any, key: string, descriptor: PropertyDescriptor) => { - // eslint-disable-next-line @typescript-eslint/ban-types let fn: Function | undefined; if (typeof descriptor.value === 'function') { fn = descriptor.value; diff --git a/src/system/decorators/log.ts b/src/system/decorators/log.ts index 4e04f0a..eb94ed5 100644 --- a/src/system/decorators/log.ts +++ b/src/system/decorators/log.ts @@ -44,7 +44,6 @@ export interface LogContext { export const LogInstanceNameFn = Symbol('logInstanceNameFn'); export function logName(fn: (c: T, name: string) => string) { - // eslint-disable-next-line @typescript-eslint/ban-types return (target: Function) => { (target as any)[LogInstanceNameFn] = fn; }; @@ -89,7 +88,6 @@ export function log any>( | typeof Logger.log; return (target: any, key: string, descriptor: PropertyDescriptor & Record) => { - // eslint-disable-next-line @typescript-eslint/ban-types let fn: Function | undefined; let fnKey: string | undefined; if (typeof descriptor.value === 'function') { diff --git a/src/system/decorators/memoize.ts b/src/system/decorators/memoize.ts index ed9777b..93faea6 100644 --- a/src/system/decorators/memoize.ts +++ b/src/system/decorators/memoize.ts @@ -19,7 +19,6 @@ function defaultResolver(...args: any[]): string { export function memoize any>(resolver?: (...args: Parameters) => string) { return (target: any, key: string, descriptor: PropertyDescriptor & Record) => { - // eslint-disable-next-line @typescript-eslint/ban-types let fn: Function | undefined; let fnKey: string | undefined; diff --git a/src/system/decorators/timeout.ts b/src/system/decorators/timeout.ts index e33ffc8..b705430 100644 --- a/src/system/decorators/timeout.ts +++ b/src/system/decorators/timeout.ts @@ -13,7 +13,6 @@ export function timeout(timeoutOrTimeoutFromLastArg: number | boolean, defaultTi } return (target: any, key: string, descriptor: PropertyDescriptor) => { - // eslint-disable-next-line @typescript-eslint/ban-types let fn: Function | undefined; if (typeof descriptor.value === 'function') { fn = descriptor.value; diff --git a/src/system/function.ts b/src/system/function.ts index 0b937cf..d19893d 100644 --- a/src/system/function.ts +++ b/src/system/function.ts @@ -103,7 +103,6 @@ export namespace Functions { const fnBodyStripCommentsRegex = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm; const fnBodyStripParamDefaultValueRegex = /\s?=.*$/; - // eslint-disable-next-line @typescript-eslint/ban-types export function getParameters(fn: Function): string[] { if (typeof fn !== 'function') throw new Error('Not supported'); diff --git a/src/system/string.ts b/src/system/string.ts index d0da8e7..40a4d3d 100644 --- a/src/system/string.ts +++ b/src/system/string.ts @@ -112,7 +112,6 @@ export namespace Strings { return tokens; } - // eslint-disable-next-line @typescript-eslint/ban-types const interpolationMap = new Map(); export function interpolate(template: string, context: object | undefined): string { diff --git a/src/views/branchesView.ts b/src/views/branchesView.ts index f0ebe3f..478f204 100644 --- a/src/views/branchesView.ts +++ b/src/views/branchesView.ts @@ -98,7 +98,7 @@ export class BranchesRepositoryNode extends SubscribeableViewNode @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/commitsView.ts b/src/views/commitsView.ts index 9cb2df8..99ba8ca 100644 --- a/src/views/commitsView.ts +++ b/src/views/commitsView.ts @@ -121,7 +121,7 @@ export class CommitsRepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/contributorsView.ts b/src/views/contributorsView.ts index 56bcabd..76bb7f8 100644 --- a/src/views/contributorsView.ts +++ b/src/views/contributorsView.ts @@ -78,7 +78,7 @@ export class ContributorsRepositoryNode extends SubscribeableViewNode - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/nodes/compareBranchNode.ts b/src/views/nodes/compareBranchNode.ts index 75b233f..3391bf0 100644 --- a/src/views/nodes/compareBranchNode.ts +++ b/src/views/nodes/compareBranchNode.ts @@ -268,7 +268,7 @@ export class CompareBranchNode extends ViewNode comparisons = Object.create(null) as BranchComparisons; } - if (compareWith) { + if (compareWith != null) { comparisons[this.branch.id] = { ...compareWith }; } else { const { [this.branch.id]: _, ...rest } = comparisons; diff --git a/src/views/nodes/helpers.ts b/src/views/nodes/helpers.ts index ccc13aa..d69d408 100644 --- a/src/views/nodes/helpers.ts +++ b/src/views/nodes/helpers.ts @@ -10,7 +10,6 @@ const markers: [number, string][] = [ [90, 'Over 3 months ago'], ]; -// eslint-disable-next-line consistent-return export function* insertDateMarkers( iterable: Iterable, parent: ViewNode, @@ -62,4 +61,6 @@ export function* insertDateMarkers { @debug({ args: { 0: (e: RepositoryFileSystemChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, uris(${e.uris.length}): [${e.uris + `{ repository: ${e.repository?.name ?? ''}, uris(${e.uris.length}): [${e.uris .slice(0, 1) .map(u => u.fsPath) .join(', ')}${e.uris.length > 1 ? ', ...' : ''}] }`, @@ -302,7 +302,7 @@ export class RepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/remotesView.ts b/src/views/remotesView.ts index 65016e9..078039d 100644 --- a/src/views/remotesView.ts +++ b/src/views/remotesView.ts @@ -95,7 +95,7 @@ export class RemotesRepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/stashesView.ts b/src/views/stashesView.ts index b7e0f4a..f859c82 100644 --- a/src/views/stashesView.ts +++ b/src/views/stashesView.ts @@ -83,7 +83,7 @@ export class StashesRepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/tagsView.ts b/src/views/tagsView.ts index 72f9613..621b79a 100644 --- a/src/views/tagsView.ts +++ b/src/views/tagsView.ts @@ -83,7 +83,7 @@ export class TagsRepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: (e: RepositoryChangeEvent) => - `{ repository: ${e.repository ? e.repository.name : ''}, changes: ${e.changes.join()} }`, + `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`, }, }) private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/webviews/apps/rebase/rebase.ts b/src/webviews/apps/rebase/rebase.ts index 937e987..1ea80e0 100644 --- a/src/webviews/apps/rebase/rebase.ts +++ b/src/webviews/apps/rebase/rebase.ts @@ -288,7 +288,7 @@ class RebaseEditor extends App { } const commit = state.commits.find(c => c.ref.startsWith(state.onto)); - if (commit) { + if (commit != null) { const [$el] = this.createEntry( { action: undefined!, @@ -352,7 +352,7 @@ class RebaseEditor extends App { $entry.appendChild($message); const commit = state.commits.find(c => c.ref.startsWith(entry.ref)); - if (commit) { + if (commit != null) { $message.title = commit.message ?? ''; if (commit.author) { diff --git a/src/webviews/apps/settings/settings.ts b/src/webviews/apps/settings/settings.ts index 51126ad..540c5c4 100644 --- a/src/webviews/apps/settings/settings.ts +++ b/src/webviews/apps/settings/settings.ts @@ -220,7 +220,7 @@ export class SettingsApp extends AppWithConfig { private toggleJumpLink(anchor: string, active: boolean) { const el = document.querySelector(`a.sidebar__jump-link[href="#${anchor}"]`); - if (el) { + if (el != null) { el.classList.toggle('active', active); } } diff --git a/src/webviews/apps/shared/events.ts b/src/webviews/apps/shared/events.ts index 9bf7091..da0a146 100644 --- a/src/webviews/apps/shared/events.ts +++ b/src/webviews/apps/shared/events.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/ban-types */ 'use strict'; // Taken from github.com/microsoft/vscode/src/vs/base/common/event.ts @@ -22,8 +21,9 @@ export interface EmitterOptions { } export class Emitter { - // eslint-disable-next-line @typescript-eslint/no-empty-function - private static readonly _noop = function () {}; + private static readonly _noop = function () { + /* noop */ + }; private readonly _options?: EmitterOptions; private _disposed: boolean = false; @@ -40,35 +40,33 @@ export class Emitter { * to events from this Emitter */ get event(): Event { - if (!this._event) { + if (this._event == null) { this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => { - if (!this._listeners) { + if (this._listeners == null) { this._listeners = new LinkedList(); } const firstListener = this._listeners.isEmpty(); - if (firstListener && this._options && this._options.onFirstListenerAdd) { - this._options.onFirstListenerAdd(this); + if (firstListener) { + this._options?.onFirstListenerAdd?.(this); } const remove = this._listeners.push(thisArgs != null ? listener : [listener, thisArgs]); - if (firstListener && this._options && this._options.onFirstListenerDidAdd) { - this._options.onFirstListenerDidAdd(this); + if (firstListener) { + this._options?.onFirstListenerDidAdd?.(this); } - if (this._options?.onListenerDidAdd) { - this._options.onListenerDidAdd(this, listener, thisArgs); - } + this._options?.onListenerDidAdd?.(this, listener, thisArgs); const result = { dispose: () => { result.dispose = Emitter._noop; if (!this._disposed) { remove(); - if (this._options?.onLastListenerRemove) { - const hasListeners = this._listeners && !this._listeners.isEmpty(); + if (this._options?.onLastListenerRemove != null) { + const hasListeners = !(this._listeners?.isEmpty() ?? true); if (!hasListeners) { this._options.onLastListenerRemove(this); } @@ -91,12 +89,12 @@ export class Emitter { * subscribers */ fire(event: T): void { - if (this._listeners) { + if (this._listeners != null) { // put all [listener,event]-pairs into delivery queue // then emit all event. an inner/nested event might be // the driver of this - if (!this._deliveryQueue) { + if (this._deliveryQueue == null) { this._deliveryQueue = new LinkedList(); } @@ -108,8 +106,7 @@ export class Emitter { const [listener, event] = this._deliveryQueue.shift()!; try { if (typeof listener === 'function') { - // eslint-disable-next-line no-useless-call - listener.call(undefined, event); + listener(event); } else { listener[0].call(listener[1], event); } @@ -122,12 +119,8 @@ export class Emitter { } dispose() { - if (this._listeners) { - this._listeners.clear(); - } - if (this._deliveryQueue) { - this._deliveryQueue.clear(); - } + this._listeners?.clear(); + this._deliveryQueue?.clear(); this._disposed = true; } } diff --git a/src/webviews/apps/welcome/snow.ts b/src/webviews/apps/welcome/snow.ts index cbd625a..28a5c5c 100644 --- a/src/webviews/apps/welcome/snow.ts +++ b/src/webviews/apps/welcome/snow.ts @@ -57,7 +57,7 @@ export class Snow { this._ctx = this._canvas.getContext('2d'); const trigger = document.querySelector('.snow__trigger'); - if (trigger) { + if (trigger != null) { trigger.addEventListener('click', () => this.onToggle()); } diff --git a/src/webviews/webviewBase.ts b/src/webviews/webviewBase.ts index 735cc10..3851d84 100644 --- a/src/webviews/webviewBase.ts +++ b/src/webviews/webviewBase.ts @@ -201,15 +201,15 @@ export abstract class WebviewBase implements Disposable { .replace(/#{cspSource}/g, webview.cspSource) .replace(/#{root}/g, webview.asWebviewUri(Container.context.extensionUri).toString()); - if (this.renderHead) { + if (this.renderHead != null) { html = html.replace(/#{head}/i, await this.renderHead()); } - if (this.renderBody) { + if (this.renderBody != null) { html = html.replace(/#{body}/i, await this.renderBody()); } - if (this.renderEndOfBody) { + if (this.renderEndOfBody != null) { html = html.replace(/#{endOfBody}/i, await this.renderEndOfBody()); }