diff --git a/.github/prompts/no-any.prompt.md b/.github/prompts/no-any.prompt.md new file mode 100644 index 00000000000..8abaee77660 --- /dev/null +++ b/.github/prompts/no-any.prompt.md @@ -0,0 +1,10 @@ +--- +mode: agent +description: 'Remove any usage of the any type in TypeScript files' +--- + +I am trying to minimize the usage of `any` types in our TypeScript codebase. +Find usages of the TypeScript `any` type in this file and replace it with the right type based on usages in the file. + +You are NOT allowed to disable ESLint rules or add `// @ts-ignore` comments to the code. +You are NOT allowed to add more `any` types to the code. diff --git a/eslint.config.js b/eslint.config.js index 1caf79fa44a..7790d8f5464 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -187,6 +187,7 @@ export default tseslint.config( 'src/vs/base/browser/ui/scrollbar/**', 'src/vs/base/browser/ui/widget.ts', 'src/vs/base/common/extpath.ts', + 'src/vs/base/common/fuzzyScorer.ts', 'src/vs/base/common/glob.ts', 'src/vs/base/common/path.ts', 'src/vs/base/common/stream.ts', @@ -201,30 +202,32 @@ export default tseslint.config( 'src/vs/base/common/uriTransformer.ts', 'src/vs/base/common/worker/webWorker.ts', 'src/vs/base/node/pfs.ts', + 'src/vs/base/node/unc.ts', 'src/vs/base/parts/contextmenu/**', 'src/vs/editor/browser/**', 'src/vs/editor/common/**', // 'src/vs/base/parts/ipc/**', - // 'src/vs/base/parts/sandbox/**', + 'src/vs/base/parts/sandbox/**', 'src/vs/base/parts/storage/**', 'src/vs/platform/auxiliaryWindow/**', - // 'src/vs/platform/backup/**', - // 'src/vs/platform/editor/**', - // 'src/vs/platform/environment/**', - // 'src/vs/platform/files/**', - // 'src/vs/platform/ipc/**', - // 'src/vs/platform/launch/**', - // 'src/vs/platform/lifecycle/**', - // 'src/vs/platform/menubar/**', - // 'src/vs/platform/native/**', - // 'src/vs/platform/sharedProcess/**', - // 'src/vs/platform/state/**', - // 'src/vs/platform/storage/**', - // 'src/vs/platform/utilityProcess/**', - // 'src/vs/platform/window/**', - // 'src/vs/platform/windows/**', - // 'src/vs/platform/workspace/**', - // 'src/vs/platform/workspaces/**', + 'src/vs/platform/backup/**', + 'src/vs/platform/editor/**', + 'src/vs/platform/environment/**', + 'src/vs/platform/dialogs/**', + 'src/vs/platform/files/**', + 'src/vs/platform/ipc/**', + 'src/vs/platform/launch/**', + 'src/vs/platform/lifecycle/**', + 'src/vs/platform/menubar/**', + 'src/vs/platform/native/**', + 'src/vs/platform/sharedProcess/**', + 'src/vs/platform/state/**', + 'src/vs/platform/storage/**', + 'src/vs/platform/utilityProcess/**', + 'src/vs/platform/window/**', + 'src/vs/platform/windows/**', + 'src/vs/platform/workspace/**', + 'src/vs/platform/workspaces/**', 'src/bootstrap-cli.ts', 'src/bootstrap-esm.ts', 'src/bootstrap-fork.ts', @@ -243,7 +246,7 @@ export default tseslint.config( 'src/vs/workbench/services/contextmenu/**', 'src/vs/workbench/services/dialogs/**', 'src/vs/workbench/services/editor/**', - // 'src/vs/workbench/services/environment/**', + 'src/vs/workbench/services/environment/**', 'src/vs/workbench/services/files/**', 'src/vs/workbench/services/filesConfiguration/**', 'src/vs/workbench/services/history/**', @@ -254,19 +257,22 @@ export default tseslint.config( 'src/vs/workbench/services/notification/**', 'src/vs/workbench/services/path/**', 'src/vs/workbench/services/progress/**', - // 'src/vs/workbench/services/storage/**', - // 'src/vs/workbench/services/textfile/**', - // 'src/vs/workbench/services/textmodelResolver/**', - // 'src/vs/workbench/services/untitled/**', - // 'src/vs/workbench/services/utilityProcess/**', - // 'src/vs/workbench/services/views/**', - // 'src/vs/workbench/services/workingCopy/**', - // 'src/vs/workbench/services/workspaces/**', - // 'src/vs/workbench/common/**', + 'src/vs/workbench/services/storage/**', + 'src/vs/workbench/services/textfile/**', + 'src/vs/workbench/services/textmodelResolver/**', + 'src/vs/workbench/services/untitled/**', + 'src/vs/workbench/services/utilityProcess/**', + 'src/vs/workbench/services/views/**', + 'src/vs/workbench/services/workingCopy/**', + 'src/vs/workbench/services/workspaces/**', + 'src/vs/workbench/common/**', // 'src/vs/workbench/browser/**', - // 'src/vs/workbench/electron-browser/**', - // 'src/vs/workbench/contrib/files/**', + 'src/vs/workbench/electron-browser/**', + 'src/vs/workbench/contrib/files/**', + 'src/vs/workbench/contrib/chat/browser/chatSetup.ts', + 'src/vs/workbench/contrib/chat/browser/chatStatus.ts', ], + ignores: ['**/*.test.ts', '**/*.integrationTest.ts'], languageOptions: { parser: tseslint.parser, }, diff --git a/src/bootstrap-fork.ts b/src/bootstrap-fork.ts index a92290a213d..ba08fb3c47d 100644 --- a/src/bootstrap-fork.ts +++ b/src/bootstrap-fork.ts @@ -184,9 +184,9 @@ function configureCrashReporter(): void { const crashReporterProcessType = process.env['VSCODE_CRASH_REPORTER_PROCESS_TYPE']; if (crashReporterProcessType) { try { - //@ts-ignore + //@ts-expect-error if (process['crashReporter'] && typeof process['crashReporter'].addExtraParameter === 'function' /* Electron only */) { - //@ts-ignore + //@ts-expect-error process['crashReporter'].addExtraParameter('processType', crashReporterProcessType); } } catch (error) { diff --git a/src/main.ts b/src/main.ts index 3954cd352b8..7b7e1da509e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -88,7 +88,7 @@ perf.mark('code/didStartCrashReporter'); // to ensure that no 'logs' folder is created on disk at a // location outside of the portable directory // (https://github.com/microsoft/vscode/issues/56651) -if (portable && portable.isPortable) { +if (portable.isPortable) { app.setAppLogsPath(path.join(userDataPath, 'logs')); } diff --git a/src/server-main.ts b/src/server-main.ts index 6c192ab8997..a589510cfc8 100644 --- a/src/server-main.ts +++ b/src/server-main.ts @@ -99,7 +99,7 @@ if (shouldSpawnCli) { perf.mark('code/server/firstWebSocket'); } const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer(); - // @ts-ignore + // @ts-expect-error return remoteExtensionHostAgentServer.handleUpgrade(req, socket); }); server.on('error', async (err) => { diff --git a/src/vs/base/common/extpath.ts b/src/vs/base/common/extpath.ts index bf8b0905ae6..2e48d19de23 100644 --- a/src/vs/base/common/extpath.ts +++ b/src/vs/base/common/extpath.ts @@ -359,14 +359,14 @@ export interface IPathWithLineAndColumn { export function parseLineAndColumnAware(rawPath: string): IPathWithLineAndColumn { const segments = rawPath.split(':'); // C:\file.txt:: - let path: string | undefined = undefined; - let line: number | undefined = undefined; - let column: number | undefined = undefined; + let path: string | undefined; + let line: number | undefined; + let column: number | undefined; for (const segment of segments) { const segmentAsNumber = Number(segment); if (!isNumber(segmentAsNumber)) { - path = !!path ? [path, segment].join(':') : segment; // a colon can well be part of a path (e.g. C:\...) + path = path ? [path, segment].join(':') : segment; // a colon can well be part of a path (e.g. C:\...) } else if (line === undefined) { line = segmentAsNumber; } else if (column === undefined) { diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts index 276f076788d..9914ab91e43 100644 --- a/src/vs/base/common/glob.ts +++ b/src/vs/base/common/glob.ts @@ -508,7 +508,7 @@ function toRegExp(pattern: string): ParsedStringPattern { return typeof path === 'string' && regExp.test(path) ? pattern : null; }; - } catch (error) { + } catch { return NULL; } } diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 3a0839940f8..e13b27372fc 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -72,7 +72,7 @@ async function rimrafMove(path: string, moveToPath = randomPath(tmpdir())): Prom } // Delete but do not return as promise - rimrafUnlink(moveToPath).catch(error => {/* ignore */ }); + rimrafUnlink(moveToPath).catch(() => {/* ignore */ }); } catch (error) { if (error.code !== 'ENOENT') { throw error; @@ -113,7 +113,7 @@ async function readdir(path: string, options?: { withFileTypes: true }): Promise if (error.code === 'ENOENT' && isWindows && isRootOrDriveLetter(path)) { try { return await doReaddir(`${path}.`, options); - } catch (e) { + } catch { // ignore } } @@ -268,7 +268,7 @@ export namespace SymlinkSupport { if (!lstats.isSymbolicLink()) { return { stat: lstats }; } - } catch (error) { + } catch { /* ignore - use stat() instead */ } @@ -324,7 +324,7 @@ export namespace SymlinkSupport { const { stat, symbolicLink } = await SymlinkSupport.stat(path); return stat.isFile() && symbolicLink?.dangling !== true; - } catch (error) { + } catch { // Ignore, path might not exist } @@ -346,7 +346,7 @@ export namespace SymlinkSupport { const { stat, symbolicLink } = await SymlinkSupport.stat(path); return stat.isDirectory() && symbolicLink?.dangling !== true; - } catch (error) { + } catch { // Ignore, path might not exist } @@ -542,7 +542,7 @@ async function renameWithRetry(source: string, target: string, startTime: number if (!stat.isFile()) { abortRetry = true; // if target is not a file, EPERM error may be raised and we should not attempt to retry } - } catch (error) { + } catch { // Ignore } @@ -601,7 +601,7 @@ async function doCopy(source: string, target: string, payload: ICopyPayload): Pr if (payload.options.preserveSymlinks) { try { return await doCopySymlink(source, target, payload); - } catch (error) { + } catch { // in any case of an error fallback to normal copy via dereferencing } } @@ -713,7 +713,7 @@ export async function realcase(path: string, token?: CancellationToken): Promise } } } - } catch (error) { + } catch { // silently ignore error } @@ -727,7 +727,7 @@ async function realpath(path: string): Promise { // drives to be resolved to their target on Windows // https://github.com/microsoft/vscode/issues/118562 return await promisify(fs.realpath)(path); - } catch (error) { + } catch { // We hit an error calling fs.realpath(). Since fs.realpath() is doing some path normalization // we now do a similar normalization and then try again if we can access the path with read @@ -748,7 +748,7 @@ async function realpath(path: string): Promise { export function realpathSync(path: string): string { try { return fs.realpathSync(path); - } catch (error) { + } catch { // We hit an error calling fs.realpathSync(). Since fs.realpathSync() is doing some path normalization // we now do a similar normalization and then try again if we can access the path with read diff --git a/src/vs/base/node/unc.ts b/src/vs/base/node/unc.ts index 5267af07345..4076e601262 100644 --- a/src/vs/base/node/unc.ts +++ b/src/vs/base/node/unc.ts @@ -12,13 +12,12 @@ export function getUNCHostAllowlist(): string[] { return []; } -function processUNCHostAllowlist(): Set { +function processUNCHostAllowlist(): Set | undefined { // The property `process.uncHostAllowlist` is not available in official node.js // releases, only in our own builds, so we have to probe for availability - // eslint-disable-next-line local/code-no-any-casts - return (process as any).uncHostAllowlist; + return (process as unknown as { uncHostAllowlist?: Set }).uncHostAllowlist; } export function addUNCHostToAllowlist(allowedHost: string | string[]): void { @@ -91,8 +90,7 @@ export function disableUNCAccessRestrictions(): void { return; } - // eslint-disable-next-line local/code-no-any-casts - (process as any).restrictUNCAccess = false; + (process as unknown as { restrictUNCAccess?: boolean }).restrictUNCAccess = false; } export function isUNCAccessRestrictionsDisabled(): boolean { @@ -100,6 +98,5 @@ export function isUNCAccessRestrictionsDisabled(): boolean { return true; } - // eslint-disable-next-line local/code-no-any-casts - return (process as any).restrictUNCAccess === false; + return (process as unknown as { restrictUNCAccess?: boolean }).restrictUNCAccess === false; } diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 0725802cf9c..5d3f878144c 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -1107,7 +1107,7 @@ export namespace ProxyChannel { export function fromService(service: unknown, disposables: DisposableStore, options?: ICreateServiceChannelOptions): IServerChannel { const handler = service as { [key: string]: unknown }; - const disableMarshalling = options && options.disableMarshalling; + const disableMarshalling = options?.disableMarshalling; // Buffer any event that should be supported by // iterating over all property keys and finding them @@ -1184,7 +1184,7 @@ export namespace ProxyChannel { } export function toService(channel: IChannel, options?: ICreateProxyServiceOptions): T { - const disableMarshalling = options && options.disableMarshalling; + const disableMarshalling = options?.disableMarshalling; return new Proxy({}, { get(_target: T, propKey: PropertyKey) { diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 2c5ef506bf1..73630126fbc 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -93,7 +93,7 @@ export class Client implements IChannelClient, IDisposable { readonly onDidProcessExit = this._onDidProcessExit.event; constructor(private modulePath: string, private options: IIPCOptions) { - const timeout = options && options.timeout ? options.timeout : 60000; + const timeout = options.timeout || 60000; this.disposeDelayer = new Delayer(timeout); this.child = null; this._client = null; @@ -174,24 +174,24 @@ export class Client implements IChannelClient, IDisposable { private get client(): IPCClient { if (!this._client) { - const args = this.options && this.options.args ? this.options.args : []; + const args = this.options.args || []; const forkOpts: ForkOptions = Object.create(null); forkOpts.env = { ...deepClone(process.env), 'VSCODE_PARENT_PID': String(process.pid) }; - if (this.options && this.options.env) { + if (this.options.env) { forkOpts.env = { ...forkOpts.env, ...this.options.env }; } - if (this.options && this.options.freshExecArgv) { + if (this.options.freshExecArgv) { forkOpts.execArgv = []; } - if (this.options && typeof this.options.debug === 'number') { + if (typeof this.options.debug === 'number') { forkOpts.execArgv = ['--nolazy', '--inspect=' + this.options.debug]; } - if (this.options && typeof this.options.debugBrk === 'number') { + if (typeof this.options.debugBrk === 'number') { forkOpts.execArgv = ['--nolazy', '--inspect-brk=' + this.options.debugBrk]; } @@ -221,7 +221,7 @@ export class Client implements IChannelClient, IDisposable { }); const sender = this.options.useQueue ? createQueuedSender(this.child) : this.child; - const send = (r: VSBuffer) => this.child && this.child.connected && sender.send((r.buffer).toString('base64')); + const send = (r: VSBuffer) => this.child?.connected && sender.send((r.buffer).toString('base64')); const onMessage = onMessageEmitter.event; const protocol = { send, onMessage }; diff --git a/src/vs/base/parts/ipc/node/ipc.mp.ts b/src/vs/base/parts/ipc/node/ipc.mp.ts index df9cd52c58a..ade456373c0 100644 --- a/src/vs/base/parts/ipc/node/ipc.mp.ts +++ b/src/vs/base/parts/ipc/node/ipc.mp.ts @@ -20,7 +20,7 @@ class Protocol implements IMessagePassingProtocol { constructor(private port: MessagePortMain) { this.onMessage = Event.fromNodeEventEmitter(this.port, 'message', (e: MessageEvent) => { if (e.data) { - return VSBuffer.wrap(e.data); + return VSBuffer.wrap(e.data as Uint8Array); } return VSBuffer.alloc(0); }); diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 747f1f697ac..3d645af32dc 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -27,7 +27,7 @@ export function upgradeToISocket(req: http.IncomingMessage, socket: Socket, { skipWebSocketFrames?: boolean; disableWebSocketCompression?: boolean; }): NodeSocket | WebSocketNodeSocket | undefined { - if (req.headers['upgrade'] === undefined || req.headers['upgrade'].toLowerCase() !== 'websocket') { + if (req.headers.upgrade === undefined || req.headers.upgrade.toLowerCase() !== 'websocket') { socket.end('HTTP/1.1 400 Bad Request'); return; } diff --git a/src/vs/base/parts/sandbox/node/electronTypes.ts b/src/vs/base/parts/sandbox/node/electronTypes.ts index 37629888c19..4ed90e5b4d0 100644 --- a/src/vs/base/parts/sandbox/node/electronTypes.ts +++ b/src/vs/base/parts/sandbox/node/electronTypes.ts @@ -31,7 +31,7 @@ export interface MessagePortMain extends NodeJS.EventEmitter { * Sends a message from the port, and optionally, transfers ownership of objects to * other browsing contexts. */ - postMessage(message: any, transfer?: MessagePortMain[]): void; + postMessage(message: unknown, transfer?: MessagePortMain[]): void; /** * Starts the sending of messages queued on the port. Messages will be queued until * this method is called. @@ -40,7 +40,7 @@ export interface MessagePortMain extends NodeJS.EventEmitter { } export interface MessageEvent { - data: any; + data: unknown; ports: MessagePortMain[]; } @@ -60,7 +60,7 @@ export interface ParentPort extends NodeJS.EventEmitter { /** * Sends a message from the process to its parent. */ - postMessage(message: any): void; + postMessage(message: unknown): void; } export interface UtilityNodeJSProcess extends NodeJS.Process { diff --git a/src/vs/base/parts/storage/common/storage.ts b/src/vs/base/parts/storage/common/storage.ts index 9a3dab6dc70..38ed1e08c93 100644 --- a/src/vs/base/parts/storage/common/storage.ts +++ b/src/vs/base/parts/storage/common/storage.ts @@ -349,7 +349,7 @@ export class Storage extends Disposable implements IStorage { // the DB is not healthy. try { await this.doFlush(0 /* as soon as possible */); - } catch (error) { + } catch { // Ignore } diff --git a/src/vs/base/parts/storage/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts index 3822560cbff..1c685bb324a 100644 --- a/src/vs/base/parts/storage/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -118,7 +118,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { } // DELETE - if (toDelete && toDelete.size) { + if (toDelete?.size) { const keysChunks: (string[])[] = []; keysChunks.push([]); // seed with initial empty chunk @@ -291,7 +291,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { await fs.promises.unlink(path); try { await Promises.rename(this.toBackupPath(path), path, false /* no retry */); - } catch (error) { + } catch { // ignore } diff --git a/src/vs/code/electron-browser/workbench/workbench.ts b/src/vs/code/electron-browser/workbench/workbench.ts index b0fdcaeba29..7d6c8fac0c7 100644 --- a/src/vs/code/electron-browser/workbench/workbench.ts +++ b/src/vs/code/electron-browser/workbench/workbench.ts @@ -474,7 +474,7 @@ const importMapScript = document.createElement('script'); importMapScript.type = 'importmap'; importMapScript.setAttribute('nonce', '0c6a828f1297'); - // @ts-ignore + // @ts-expect-error importMapScript.textContent = ttp?.createScript(importMapSrc) ?? importMapSrc; window.document.head.appendChild(importMapScript); diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index b7c4fb99f8f..89c66b9b404 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -185,7 +185,7 @@ export async function main(argv: string[]): Promise { // Check for readonly status and chmod if so if we are told so let targetMode: number = 0; let restoreMode = false; - if (!!args['file-chmod']) { + if (args['file-chmod']) { targetMode = statSync(target).mode; if (!(targetMode & 0o200 /* File mode indicating writable by owner */)) { chmodSync(target, targetMode | 0o200); diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 7f08f43ea04..da60ab85a19 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -247,7 +247,7 @@ class CliMain extends Disposable { const appenders: ITelemetryAppender[] = []; const isInternal = isInternalTelemetry(productService, configurationService); if (supportsTelemetry(productService, environmentService)) { - if (productService.aiConfig && productService.aiConfig.ariaKey) { + if (productService.aiConfig?.ariaKey) { appenders.push(new OneDataSystemAppender(requestService, isInternal, 'monacoworkbench', null, productService.aiConfig.ariaKey)); } diff --git a/src/vs/platform/backup/common/backup.ts b/src/vs/platform/backup/common/backup.ts index bfae94c8c4b..4046635511f 100644 --- a/src/vs/platform/backup/common/backup.ts +++ b/src/vs/platform/backup/common/backup.ts @@ -19,9 +19,9 @@ export interface IFolderBackupInfo extends IBaseBackupInfo { } export function isFolderBackupInfo(curr: IWorkspaceBackupInfo | IFolderBackupInfo): curr is IFolderBackupInfo { - return curr && curr.hasOwnProperty('folderUri'); + return curr?.hasOwnProperty('folderUri'); } export function isWorkspaceBackupInfo(curr: IWorkspaceBackupInfo | IFolderBackupInfo): curr is IWorkspaceBackupInfo { - return curr && curr.hasOwnProperty('workspace'); + return curr?.hasOwnProperty('workspace'); } diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index 55b36989ae3..51e7460fc0a 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -347,11 +347,11 @@ export class BackupMainService implements IBackupMainService { if (backupSchemaChildren.length > 0) { return true; } - } catch (error) { + } catch { // invalid folder } } - } catch (error) { + } catch { // backup path does not exist } diff --git a/src/vs/platform/backup/node/backup.ts b/src/vs/platform/backup/node/backup.ts index 05d3f4c0ced..1bc98590b58 100644 --- a/src/vs/platform/backup/node/backup.ts +++ b/src/vs/platform/backup/node/backup.ts @@ -36,7 +36,7 @@ export function deserializeWorkspaceInfos(serializedBackupWorkspaces: ISerialize } )); } - } catch (e) { + } catch { // ignore URI parsing exceptions } @@ -59,7 +59,7 @@ export function deserializeFolderInfos(serializedBackupWorkspaces: ISerializedBa } )); } - } catch (e) { + } catch { // ignore URI parsing exceptions } diff --git a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts index 640f2eb5830..8d71ab00fa8 100644 --- a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts +++ b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts @@ -586,7 +586,7 @@ flakySuite('BackupMainService', () => { try { await fs.promises.mkdir(path.join(folderBackupPath, Schemas.file), { recursive: true }); await fs.promises.mkdir(path.join(workspaceBackupPath, Schemas.untitled), { recursive: true }); - } catch (error) { + } catch { // ignore - folder might exist already } diff --git a/src/vs/platform/dialogs/test/common/testDialogService.ts b/src/vs/platform/dialogs/test/common/testDialogService.ts index e491fe9c6d4..18d3d9f7614 100644 --- a/src/vs/platform/dialogs/test/common/testDialogService.ts +++ b/src/vs/platform/dialogs/test/common/testDialogService.ts @@ -16,7 +16,7 @@ export class TestDialogService implements IDialogService { constructor( private defaultConfirmResult: IConfirmationResult | undefined = undefined, - private defaultPromptResult: IPromptResult | undefined = undefined + private defaultPromptResult: IPromptResult | undefined = undefined ) { } private confirmResult: IConfirmationResult | undefined = undefined; @@ -40,7 +40,7 @@ export class TestDialogService implements IDialogService { prompt(prompt: IPrompt): Promise>; async prompt(prompt: IPrompt | IPromptWithCustomCancel): Promise | IPromptResultWithCancel> { if (this.defaultPromptResult) { - return this.defaultPromptResult; + return this.defaultPromptResult as IPromptResult; } const promptButtons: IPromptBaseButton[] = [...(prompt.buttons ?? [])]; if (prompt.cancelButton && typeof prompt.cancelButton !== 'string' && typeof prompt.cancelButton !== 'boolean') { diff --git a/src/vs/platform/environment/common/environmentService.ts b/src/vs/platform/environment/common/environmentService.ts index e60b83f27d4..6b6c82c6d5d 100644 --- a/src/vs/platform/environment/common/environmentService.ts +++ b/src/vs/platform/environment/common/environmentService.ts @@ -214,7 +214,7 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron const result: [string, string][] = []; for (const entry of this.args.log || []) { const matches = EXTENSION_IDENTIFIER_WITH_LOG_REGEX.exec(entry); - if (matches && matches[1] && matches[2]) { + if (matches?.[1] && matches[2]) { result.push([matches[1], matches[2]]); } } diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 17d0583cce3..9b0cf59752b 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -261,8 +261,8 @@ export function parseArgs(args: string[], options: OptionDescriptions, err const alias: { [key: string]: string } = {}; const stringOptions: string[] = ['_']; const booleanOptions: string[] = []; - const globalOptions: OptionDescriptions = {}; - let command: Subcommand | undefined = undefined; + const globalOptions: Record | Option<'string'> | Option<'string[]'>> = {}; + let command: Subcommand> | undefined = undefined; for (const optionId in options) { const o = options[optionId]; if (o.type === 'subcommand') { @@ -291,13 +291,13 @@ export function parseArgs(args: string[], options: OptionDescriptions, err } } if (command && firstPossibleCommand) { - const options = globalOptions; + const options: Record | Option<'string'> | Option<'string[]'> | Subcommand>> = globalOptions; for (const optionId in command.options) { options[optionId] = command.options[optionId]; } const newArgs = args.filter(a => a !== firstPossibleCommand); const reporter = errorReporter.getSubcommandReporter ? errorReporter.getSubcommandReporter(firstPossibleCommand) : undefined; - const subcommandOptions = parseArgs(newArgs, options, reporter); + const subcommandOptions = parseArgs(newArgs, options as OptionDescriptions>, reporter); // eslint-disable-next-line local/code-no-dangerous-type-assertions return { [firstPossibleCommand]: subcommandOptions, @@ -309,8 +309,8 @@ export function parseArgs(args: string[], options: OptionDescriptions, err // remove aliases to avoid confusion const parsedArgs = minimist(args, { string: stringOptions, boolean: booleanOptions, alias }); - const cleanedArgs: any = {}; - const remainingArgs: any = parsedArgs; + const cleanedArgs: Record = {}; + const remainingArgs: Record = parsedArgs; // https://github.com/microsoft/vscode/issues/58177, https://github.com/microsoft/vscode/issues/106617 cleanedArgs._ = parsedArgs._.map(arg => String(arg)).filter(arg => arg.length > 0); @@ -347,8 +347,8 @@ export function parseArgs(args: string[], options: OptionDescriptions, err val = [val]; } if (!o.allowEmptyValue) { - const sanitized = val.filter((v: string) => v.length > 0); - if (sanitized.length !== val.length) { + const sanitized = (val as string[]).filter((v: string) => v.length > 0); + if (sanitized.length !== (val as string[]).length) { errorReporter.onEmptyValue(optionId); val = sanitized.length > 0 ? sanitized : undefined; } @@ -356,7 +356,7 @@ export function parseArgs(args: string[], options: OptionDescriptions, err } else if (o.type === 'string') { if (Array.isArray(val)) { val = val.pop(); // take the last - errorReporter.onMultipleValues(optionId, val); + errorReporter.onMultipleValues(optionId, val as string); } else if (!val && !o.allowEmptyValue) { errorReporter.onEmptyValue(optionId); val = undefined; @@ -375,10 +375,10 @@ export function parseArgs(args: string[], options: OptionDescriptions, err errorReporter.onUnknownOption(key); } - return cleanedArgs; + return cleanedArgs as T; } -function formatUsage(optionId: string, option: Option) { +function formatUsage(optionId: string, option: Option<'boolean'> | Option<'string'> | Option<'string[]'>) { let args = ''; if (option.args) { if (Array.isArray(option.args)) { @@ -394,10 +394,10 @@ function formatUsage(optionId: string, option: Option) { } // exported only for testing -export function formatOptions(options: OptionDescriptions, columns: number): string[] { +export function formatOptions(options: OptionDescriptions | Record | Option<'string'> | Option<'string[]'>>, columns: number): string[] { const usageTexts: [string, string][] = []; for (const optionId in options) { - const o = options[optionId]; + const o = options[optionId as keyof typeof options] as Option<'boolean'> | Option<'string'> | Option<'string[]'>; const usageText = formatUsage(optionId, o); usageTexts.push([usageText, o.description!]); } @@ -443,7 +443,7 @@ function wrapText(text: string, columns: number): string[] { return lines; } -export function buildHelpMessage(productName: string, executableName: string, version: string, options: OptionDescriptions, capabilities?: { noPipe?: boolean; noInputFiles?: boolean; isChat?: boolean }): string { +export function buildHelpMessage(productName: string, executableName: string, version: string, options: OptionDescriptions | Record | Option<'string'> | Option<'string[]'> | Subcommand>>, capabilities?: { noPipe?: boolean; noInputFiles?: boolean; isChat?: boolean }): string { const columns = (process.stdout).isTTY && (process.stdout).columns || 80; const inputFiles = capabilities?.noInputFiles ? '' : capabilities?.isChat ? ` [${localize('cliPrompt', 'prompt')}]` : ` [${localize('paths', 'paths')}...]`; const subcommand = capabilities?.isChat ? ' chat' : ''; @@ -456,18 +456,19 @@ export function buildHelpMessage(productName: string, executableName: string, ve help.push(buildStdinMessage(executableName, capabilities?.isChat)); help.push(''); } - const optionsByCategory: { [P in keyof typeof helpCategories]?: OptionDescriptions } = {}; + const optionsByCategory: { [P in keyof typeof helpCategories]?: Record | Option<'string'> | Option<'string[]'>> } = {}; const subcommands: { command: string; description: string }[] = []; for (const optionId in options) { - const o = options[optionId]; + const o = options[optionId as keyof typeof options] as Option<'boolean'> | Option<'string'> | Option<'string[]'> | Subcommand>; if (o.type === 'subcommand') { if (o.description) { subcommands.push({ command: optionId, description: o.description }); } } else if (o.description && o.cat) { - let optionsByCat = optionsByCategory[o.cat]; + const cat = o.cat as keyof typeof helpCategories; + let optionsByCat = optionsByCategory[cat]; if (!optionsByCat) { - optionsByCategory[o.cat] = optionsByCat = {}; + optionsByCategory[cat] = optionsByCat = {}; } optionsByCat[optionId] = o; } diff --git a/src/vs/platform/environment/node/stdin.ts b/src/vs/platform/environment/node/stdin.ts index 93e8e9e5c1e..707a3e81ea4 100644 --- a/src/vs/platform/environment/node/stdin.ts +++ b/src/vs/platform/environment/node/stdin.ts @@ -12,7 +12,7 @@ import { resolveTerminalEncoding } from '../../../base/node/terminalEncoding.js' export function hasStdinWithoutTty() { try { return !process.stdin.isTTY; // Via https://twitter.com/MylesBorins/status/782009479382626304 - } catch (error) { + } catch { // Windows workaround for https://github.com/nodejs/node/issues/11656 } return false; diff --git a/src/vs/platform/files/browser/htmlFileSystemProvider.ts b/src/vs/platform/files/browser/htmlFileSystemProvider.ts index 43944112e16..747b9c37a6d 100644 --- a/src/vs/platform/files/browser/htmlFileSystemProvider.ts +++ b/src/vs/platform/files/browser/htmlFileSystemProvider.ts @@ -308,7 +308,7 @@ export class HTMLFileSystemProvider extends Disposable implements IFileSystemPro return; } - // eslint-disable-next-line local/code-no-any-casts + // eslint-disable-next-line local/code-no-any-casts, @typescript-eslint/no-explicit-any const observer = new (globalThis as any).FileSystemObserver((records: FileSystemObserverRecord[]) => { if (disposables.isDisposed) { return; diff --git a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts index 5da9d072880..1dd1bf57852 100644 --- a/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts +++ b/src/vs/platform/files/browser/indexedDBFileSystemProvider.ts @@ -221,58 +221,46 @@ export class IndexedDBFileSystemProvider extends Disposable implements IFileSyst } async readdir(resource: URI): Promise { - try { - const entry = (await this.getFiletree()).read(resource.path); - if (!entry) { - // Dirs aren't saved to disk, so empty dirs will be lost on reload. - // Thus we have two options for what happens when you try to read a dir and nothing is found: - // - Throw FileSystemProviderErrorCode.FileNotFound - // - Return [] - // We choose to return [] as creating a dir then reading it (even after reload) should not throw an error. - return []; - } - if (entry.type !== FileType.Directory) { - throw ERR_FILE_NOT_DIR; - } - else { - return [...entry.children.entries()].map(([name, node]) => [name, node.type]); - } - } catch (error) { - throw error; + const entry = (await this.getFiletree()).read(resource.path); + if (!entry) { + // Dirs aren't saved to disk, so empty dirs will be lost on reload. + // Thus we have two options for what happens when you try to read a dir and nothing is found: + // - Throw FileSystemProviderErrorCode.FileNotFound + // - Return [] + // We choose to return [] as creating a dir then reading it (even after reload) should not throw an error. + return []; + } + if (entry.type !== FileType.Directory) { + throw ERR_FILE_NOT_DIR; + } + else { + return [...entry.children.entries()].map(([name, node]) => [name, node.type]); } } async readFile(resource: URI): Promise { - try { - const result = await this.indexedDB.runInTransaction(this.store, 'readonly', objectStore => objectStore.get(resource.path)); - if (result === undefined) { - throw ERR_FILE_NOT_FOUND; - } - const buffer = result instanceof Uint8Array ? result : isString(result) ? VSBuffer.fromString(result).buffer : undefined; - if (buffer === undefined) { - throw ERR_UNKNOWN_INTERNAL(`IndexedDB entry at "${resource.path}" in unexpected format`); - } - - // update cache - const fileTree = await this.getFiletree(); - fileTree.add(resource.path, { type: 'file', size: buffer.byteLength }); - - return buffer; - } catch (error) { - throw error; + const result = await this.indexedDB.runInTransaction(this.store, 'readonly', objectStore => objectStore.get(resource.path)); + if (result === undefined) { + throw ERR_FILE_NOT_FOUND; } + const buffer = result instanceof Uint8Array ? result : isString(result) ? VSBuffer.fromString(result).buffer : undefined; + if (buffer === undefined) { + throw ERR_UNKNOWN_INTERNAL(`IndexedDB entry at "${resource.path}" in unexpected format`); + } + + // update cache + const fileTree = await this.getFiletree(); + fileTree.add(resource.path, { type: 'file', size: buffer.byteLength }); + + return buffer; } async writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise { - try { - const existing = await this.stat(resource).catch(() => undefined); - if (existing?.type === FileType.Directory) { - throw ERR_FILE_IS_DIR; - } - await this.bulkWrite([[resource, content]]); - } catch (error) { - throw error; + const existing = await this.stat(resource).catch(() => undefined); + if (existing?.type === FileType.Directory) { + throw ERR_FILE_IS_DIR; } + await this.bulkWrite([[resource, content]]); } async rename(from: URI, to: URI, opts: IFileOverwriteOptions): Promise { diff --git a/src/vs/platform/files/browser/webFileSystemAccess.ts b/src/vs/platform/files/browser/webFileSystemAccess.ts index f5e90b78a00..31bdfbf8c1a 100644 --- a/src/vs/platform/files/browser/webFileSystemAccess.ts +++ b/src/vs/platform/files/browser/webFileSystemAccess.ts @@ -10,8 +10,8 @@ */ export namespace WebFileSystemAccess { - export function supported(obj: any & Window): boolean { - if (typeof obj?.showDirectoryPicker === 'function') { + export function supported(obj: typeof globalThis): boolean { + if (typeof (obj as typeof globalThis & { showDirectoryPicker?: unknown })?.showDirectoryPicker === 'function') { return true; } @@ -38,8 +38,8 @@ export namespace WebFileSystemAccess { export namespace WebFileSystemObserver { - export function supported(obj: any & Window): boolean { - return typeof obj?.FileSystemObserver === 'function'; + export function supported(obj: typeof globalThis): boolean { + return typeof (obj as typeof globalThis & { FileSystemObserver?: unknown })?.FileSystemObserver === 'function'; } } @@ -85,3 +85,10 @@ export interface FileSystemObserverRecord { */ readonly relativePathMovedFrom?: string[]; } + +export declare class FileSystemObserver { + + constructor(callback: (records: FileSystemObserverRecord[], observer: FileSystemObserver) => void); + + observe(handle: FileSystemHandle, options?: { recursive: boolean }): Promise; +} diff --git a/src/vs/platform/files/node/diskFileSystemProvider.ts b/src/vs/platform/files/node/diskFileSystemProvider.ts index b2785c11ce2..ec8924c0bc4 100644 --- a/src/vs/platform/files/node/diskFileSystemProvider.ts +++ b/src/vs/platform/files/node/diskFileSystemProvider.ts @@ -21,8 +21,7 @@ import { localize } from '../../../nls.js'; import { createFileSystemProviderError, IFileAtomicReadOptions, IFileDeleteOptions, IFileOpenOptions, IFileOverwriteOptions, IFileReadStreamOptions, FileSystemProviderCapabilities, FileSystemProviderError, FileSystemProviderErrorCode, FileType, IFileWriteOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileCloneCapability, IFileSystemProviderWithFileFolderCopyCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, isFileOpenForWriteOptions, IStat, FilePermission, IFileSystemProviderWithFileAtomicWriteCapability, IFileSystemProviderWithFileAtomicDeleteCapability, IFileChange, IFileSystemProviderWithFileRealpathCapability } from '../common/files.js'; import { readFileIntoStream } from '../common/io.js'; import { AbstractNonRecursiveWatcherClient, AbstractUniversalWatcherClient, ILogMessage } from '../common/watcher.js'; -import { ILogService } from '../../log/common/log.js'; -import { AbstractDiskFileSystemProvider, IDiskFileSystemProviderOptions } from '../common/diskFileSystemProvider.js'; +import { AbstractDiskFileSystemProvider } from '../common/diskFileSystemProvider.js'; import { UniversalWatcherClient } from './watcher/watcherClient.js'; import { NodeJSWatcherClient } from './watcher/nodejs/nodejsClient.js'; @@ -39,13 +38,6 @@ export class DiskFileSystemProvider extends AbstractDiskFileSystemProvider imple private static TRACE_LOG_RESOURCE_LOCKS = false; // not enabled by default because very spammy - constructor( - logService: ILogService, - options?: IDiskFileSystemProviderOptions - ) { - super(logService, options); - } - //#region File Capabilities readonly onDidChangeCapabilities = Event.None; diff --git a/src/vs/platform/files/node/diskFileSystemProviderServer.ts b/src/vs/platform/files/node/diskFileSystemProviderServer.ts index 1b7219ec10c..99b735fc99d 100644 --- a/src/vs/platform/files/node/diskFileSystemProviderServer.ts +++ b/src/vs/platform/files/node/diskFileSystemProviderServer.ts @@ -33,37 +33,37 @@ export abstract class AbstractDiskFileSystemProviderChannel extends Disposabl super(); } - call(ctx: T, command: string, arg?: any): Promise { + call(ctx: T, command: string, args: unknown[]): Promise { const uriTransformer = this.getUriTransformer(ctx); switch (command) { - case 'stat': return this.stat(uriTransformer, arg[0]); - case 'realpath': return this.realpath(uriTransformer, arg[0]); - case 'readdir': return this.readdir(uriTransformer, arg[0]); - case 'open': return this.open(uriTransformer, arg[0], arg[1]); - case 'close': return this.close(arg[0]); - case 'read': return this.read(arg[0], arg[1], arg[2]); - case 'readFile': return this.readFile(uriTransformer, arg[0], arg[1]); - case 'write': return this.write(arg[0], arg[1], arg[2], arg[3], arg[4]); - case 'writeFile': return this.writeFile(uriTransformer, arg[0], arg[1], arg[2]); - case 'rename': return this.rename(uriTransformer, arg[0], arg[1], arg[2]); - case 'copy': return this.copy(uriTransformer, arg[0], arg[1], arg[2]); - case 'cloneFile': return this.cloneFile(uriTransformer, arg[0], arg[1]); - case 'mkdir': return this.mkdir(uriTransformer, arg[0]); - case 'delete': return this.delete(uriTransformer, arg[0], arg[1]); - case 'watch': return this.watch(uriTransformer, arg[0], arg[1], arg[2], arg[3]); - case 'unwatch': return this.unwatch(arg[0], arg[1]); + case 'stat': return this.stat(uriTransformer, args[0] as UriComponents) as Promise; + case 'realpath': return this.realpath(uriTransformer, args[0] as UriComponents) as Promise; + case 'readdir': return this.readdir(uriTransformer, args[0] as UriComponents) as Promise; + case 'open': return this.open(uriTransformer, args[0] as UriComponents, args[1] as IFileOpenOptions) as Promise; + case 'close': return this.close(args[0] as number) as Promise; + case 'read': return this.read(args[0] as number, args[1] as number, args[2] as number) as Promise; + case 'readFile': return this.readFile(uriTransformer, args[0] as UriComponents, args[1] as IFileAtomicReadOptions) as Promise; + case 'write': return this.write(args[0] as number, args[1] as number, args[2] as VSBuffer, args[3] as number, args[4] as number) as Promise; + case 'writeFile': return this.writeFile(uriTransformer, args[0] as UriComponents, args[1] as VSBuffer, args[2] as IFileWriteOptions) as Promise; + case 'rename': return this.rename(uriTransformer, args[0] as UriComponents, args[1] as UriComponents, args[2] as IFileOverwriteOptions) as Promise; + case 'copy': return this.copy(uriTransformer, args[0] as UriComponents, args[1] as UriComponents, args[2] as IFileOverwriteOptions) as Promise; + case 'cloneFile': return this.cloneFile(uriTransformer, args[0] as UriComponents, args[1] as UriComponents) as Promise; + case 'mkdir': return this.mkdir(uriTransformer, args[0] as UriComponents) as Promise; + case 'delete': return this.delete(uriTransformer, args[0] as UriComponents, args[1] as IFileDeleteOptions) as Promise; + case 'watch': return this.watch(uriTransformer, args[0] as string, args[1] as number, args[2] as UriComponents, args[3] as IWatchOptions) as Promise; + case 'unwatch': return this.unwatch(args[0] as string, args[1] as number) as Promise; } throw new Error(`IPC Command ${command} not found`); } - listen(ctx: T, event: string, arg: any): Event { + listen(ctx: T, event: string, args: unknown[]): Event { const uriTransformer = this.getUriTransformer(ctx); switch (event) { - case 'fileChange': return this.onFileChange(uriTransformer, arg[0]); - case 'readFileStream': return this.onReadFileStream(uriTransformer, arg[0], arg[1]); + case 'fileChange': return this.onFileChange(uriTransformer, args[0] as string) as Event; + case 'readFileStream': return this.onReadFileStream(uriTransformer, args[0] as URI, args[1] as IFileReadStreamOptions) as Event; } throw new Error(`Unknown event ${event}`); diff --git a/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts b/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts index 47d1f2664f0..a9f642f3277 100644 --- a/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts +++ b/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts @@ -151,7 +151,7 @@ export class NodeJSWatcher extends BaseWatcher implements INonRecursiveWatcher { requestsForCorrelation.set(path, request); } - return Array.from(mapCorrelationtoRequests.values()).map(requests => Array.from(requests.values())).flat(); + return Array.from(mapCorrelationtoRequests.values()).flatMap(requests => Array.from(requests.values())); } override async setVerboseLogging(enabled: boolean): Promise { diff --git a/src/vs/platform/ipc/electron-browser/services.ts b/src/vs/platform/ipc/electron-browser/services.ts index b03e23621d9..479c2981277 100644 --- a/src/vs/platform/ipc/electron-browser/services.ts +++ b/src/vs/platform/ipc/electron-browser/services.ts @@ -10,6 +10,7 @@ import { createDecorator, IInstantiationService, ServiceIdentifier } from '../.. import { IMainProcessService } from '../common/mainProcessService.js'; import { IRemoteService } from '../common/services.js'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any type ChannelClientCtor = { new(channel: IChannel, ...args: any[]): T }; type Remote = { getChannel(channelName: string): IChannel }; diff --git a/src/vs/platform/launch/electron-main/launchMainService.ts b/src/vs/platform/launch/electron-main/launchMainService.ts index df93721b40e..db2fd75d134 100644 --- a/src/vs/platform/launch/electron-main/launchMainService.ts +++ b/src/vs/platform/launch/electron-main/launchMainService.ts @@ -138,7 +138,7 @@ export class LaunchMainService implements ILaunchMainService { }; // Special case extension development - if (!!args.extensionDevelopmentPath) { + if (args.extensionDevelopmentPath) { await this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, baseConfig); } diff --git a/src/vs/platform/menubar/electron-main/menubar.ts b/src/vs/platform/menubar/electron-main/menubar.ts index 0667dd4d14d..772e21dcb0e 100644 --- a/src/vs/platform/menubar/electron-main/menubar.ts +++ b/src/vs/platform/menubar/electron-main/menubar.ts @@ -528,17 +528,17 @@ export class Menubar extends Disposable { menu.append(this.createMenuItem(item.label, item.id, false, item.checked)); } } else { - menu.append(this.createMenuItem(item.label, item.id, item.enabled === false ? false : true, !!item.checked)); + menu.append(this.createMenuItem(item.label, item.id, item.enabled !== false, !!item.checked)); } } else { - menu.append(this.createMenuItem(item.label, item.id, item.enabled === false ? false : true, !!item.checked)); + menu.append(this.createMenuItem(item.label, item.id, item.enabled !== false, !!item.checked)); } } }); } private setMenuById(menu: Menu, menuId: string): void { - if (this.menubarMenus && this.menubarMenus[menuId]) { + if (this.menubarMenus?.[menuId]) { this.setMenu(menu, this.menubarMenus[menuId].items); } } @@ -586,7 +586,7 @@ export class Menubar extends Disposable { return !!(event.triggeredByAccelerator || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey); } - private createRoleMenuItem(label: string, commandId: string, role: any): MenuItem { + private createRoleMenuItem(label: string, commandId: string, role: 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteAndMatchStyle' | 'delete' | 'selectAll' | 'reload' | 'forceReload' | 'toggleDevTools' | 'resetZoom' | 'zoomIn' | 'zoomOut' | 'toggleSpellChecker' | 'togglefullscreen' | 'window' | 'minimize' | 'close' | 'help' | 'about' | 'services' | 'hide' | 'hideOthers' | 'unhide' | 'quit' | 'showSubstitutions' | 'toggleSmartQuotes' | 'toggleSmartDashes' | 'toggleTextReplacement' | 'startSpeaking' | 'stopSpeaking' | 'zoom' | 'front' | 'appMenu' | 'fileMenu' | 'editMenu' | 'viewMenu' | 'shareMenu' | 'recentDocuments' | 'toggleTabBar' | 'selectNextTab' | 'selectPreviousTab' | 'showAllTabs' | 'mergeAllWindows' | 'clearRecentDocuments' | 'moveTabToNewWindow' | 'windowMenu'): MenuItem { const options: MenuItemConstructorOptions = { label: this.mnemonicLabel(label), role, @@ -674,25 +674,18 @@ export class Menubar extends Disposable { } } - private createMenuItem(label: string, commandId: string | string[], enabled?: boolean, checked?: boolean): MenuItem; - private createMenuItem(label: string, click: () => void, enabled?: boolean, checked?: boolean): MenuItem; - private createMenuItem(arg1: string, arg2: any, arg3?: boolean, arg4?: boolean): MenuItem { - const label = this.mnemonicLabel(arg1); - const click: () => void = (typeof arg2 === 'function') ? arg2 : (menuItem: MenuItem & IMenuItemWithKeybinding, win: BrowserWindow, event: KeyboardEvent) => { + private createMenuItem(labelOpt: string, commandId: string, enabledOpt?: boolean, checkedOpt?: boolean): MenuItem { + const label = this.mnemonicLabel(labelOpt); + const click = (menuItem: MenuItem & IMenuItemWithKeybinding, window: BaseWindow | undefined, event: KeyboardEvent) => { const userSettingsLabel = menuItem ? menuItem.userSettingsLabel : null; - let commandId = arg2; - if (Array.isArray(arg2)) { - commandId = this.isOptionClick(event) ? arg2[1] : arg2[0]; // support alternative action if we got multiple action Ids and the option key was pressed while invoking - } - if (userSettingsLabel && event.triggeredByAccelerator) { this.runActionInRenderer({ type: 'keybinding', userSettingsLabel }); } else { this.runActionInRenderer({ type: 'commandId', commandId }); } }; - const enabled = typeof arg3 === 'boolean' ? arg3 : this.windowsMainService.getWindowCount() > 0; - const checked = typeof arg4 === 'boolean' ? arg4 : false; + const enabled = typeof enabledOpt === 'boolean' ? enabledOpt : this.windowsMainService.getWindowCount() > 0; + const checked = typeof checkedOpt === 'boolean' ? checkedOpt : false; const options: MenuItemConstructorOptions = { label, @@ -705,13 +698,6 @@ export class Menubar extends Disposable { options.checked = checked; } - let commandId: string | undefined; - if (typeof arg2 === 'string') { - commandId = arg2; - } else if (Array.isArray(arg2)) { - commandId = arg2[0]; - } - if (isMacintosh) { // Add role for special case menu items diff --git a/src/vs/platform/native/common/nativeHostService.ts b/src/vs/platform/native/common/nativeHostService.ts index 7d16cba7c66..2ef4689e6a5 100644 --- a/src/vs/platform/native/common/nativeHostService.ts +++ b/src/vs/platform/native/common/nativeHostService.ts @@ -7,7 +7,7 @@ import { ProxyChannel } from '../../../base/parts/ipc/common/ipc.js'; import { IMainProcessService } from '../../ipc/common/mainProcessService.js'; import { INativeHostService } from './native.js'; -// @ts-ignore: interface is implemented via proxy +// @ts-expect-error: interface is implemented via proxy export class NativeHostService implements INativeHostService { declare readonly _serviceBrand: undefined; diff --git a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts index a9b7f5a4e47..f3177fe4d50 100644 --- a/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts +++ b/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts @@ -148,11 +148,12 @@ export class SharedProcess extends Disposable { this.utilityProcess = this._register(new UtilityProcess(this.logService, NullTelemetryService, this.lifecycleMainService)); // Install a log listener for very early shared process warnings and errors - this.utilityProcessLogListener = this.utilityProcess.onMessage((e: any) => { - if (typeof e.warning === 'string') { - this.logService.warn(e.warning); - } else if (typeof e.error === 'string') { - this.logService.error(e.error); + this.utilityProcessLogListener = this.utilityProcess.onMessage(e => { + const logValue = e as { warning?: unknown; error?: unknown }; + if (typeof logValue.warning === 'string') { + this.logService.warn(logValue.warning); + } else if (typeof logValue.error === 'string') { + this.logService.error(logValue.error); } }); diff --git a/src/vs/platform/storage/common/storageIpc.ts b/src/vs/platform/storage/common/storageIpc.ts index 117052ea26c..9bcc394353b 100644 --- a/src/vs/platform/storage/common/storageIpc.ts +++ b/src/vs/platform/storage/common/storageIpc.ts @@ -131,10 +131,6 @@ export class ApplicationStorageDatabaseClient extends BaseProfileAwareStorageDat export class ProfileStorageDatabaseClient extends BaseProfileAwareStorageDatabaseClient { - constructor(channel: IChannel, profile: UriDto) { - super(channel, profile); - } - async close(): Promise { // The profile storage database is shared across all instances of diff --git a/src/vs/platform/storage/electron-main/storageIpc.ts b/src/vs/platform/storage/electron-main/storageIpc.ts index 153856a170c..50e72f57610 100644 --- a/src/vs/platform/storage/electron-main/storageIpc.ts +++ b/src/vs/platform/storage/electron-main/storageIpc.ts @@ -71,6 +71,7 @@ export class StorageDatabaseChannel extends Disposable implements IServerChannel }; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any listen(_: unknown, event: string, arg: IBaseSerializableStorageRequest): Event { switch (event) { case 'onDidChangeStorage': { @@ -98,6 +99,7 @@ export class StorageDatabaseChannel extends Disposable implements IServerChannel //#endregion + // eslint-disable-next-line @typescript-eslint/no-explicit-any async call(_: unknown, command: string, arg: IBaseSerializableStorageRequest): Promise { const profile = arg.profile ? revive(arg.profile) : undefined; const workspace = reviveIdentifier(arg.workspace); @@ -134,6 +136,7 @@ export class StorageDatabaseChannel extends Disposable implements IServerChannel if (typeof path === 'string') { return this.storageMainService.isUsed(path); } + return false; } default: diff --git a/src/vs/platform/storage/electron-main/storageMain.ts b/src/vs/platform/storage/electron-main/storageMain.ts index 8c945fe6019..7d343af1f03 100644 --- a/src/vs/platform/storage/electron-main/storageMain.ts +++ b/src/vs/platform/storage/electron-main/storageMain.ts @@ -310,14 +310,6 @@ class BaseProfileAwareStorageMain extends BaseStorageMain { export class ProfileStorageMain extends BaseProfileAwareStorageMain { - constructor( - profile: IUserDataProfile, - options: IStorageMainOptions, - logService: ILogService, - fileService: IFileService - ) { - super(profile, options, logService, fileService); - } } export class ApplicationStorageMain extends BaseProfileAwareStorageMain { diff --git a/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts b/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts index baeab608b4d..14ea85b3a20 100644 --- a/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts +++ b/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts @@ -261,8 +261,8 @@ export class UtilityProcess extends Disposable { return true; } - private createEnv(configuration: IUtilityProcessConfiguration): { [key: string]: any } { - const env: { [key: string]: any } = configuration.env ? { ...configuration.env } : { ...deepClone(process.env) }; + private createEnv(configuration: IUtilityProcessConfiguration): NodeJS.ProcessEnv { + const env: NodeJS.ProcessEnv = configuration.env ? { ...configuration.env } : { ...deepClone(process.env) }; // Apply supported environment variables from config env['VSCODE_ESM_ENTRYPOINT'] = configuration.entryPoint; diff --git a/src/vs/platform/window/common/window.ts b/src/vs/platform/window/common/window.ts index 1b604886ace..35257980ea7 100644 --- a/src/vs/platform/window/common/window.ts +++ b/src/vs/platform/window/common/window.ts @@ -395,7 +395,7 @@ export interface INativeOpenFileRequest extends IOpenFileRequest { export interface INativeRunActionInWindowRequest { readonly id: string; readonly from: 'menu' | 'touchbar' | 'mouse'; - readonly args?: any[]; + readonly args?: unknown[]; } export interface INativeRunKeybindingInWindowRequest { @@ -471,7 +471,7 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native * https://github.com/electron/electron/blob/master/docs/api/web-contents.md#contentssetzoomlevellevel */ export function zoomLevelToZoomFactor(zoomLevel = 0): number { - return Math.pow(1.2, zoomLevel); + return 1.2 ** zoomLevel; } export const DEFAULT_EMPTY_WINDOW_SIZE = { width: 1200, height: 800 } as const; diff --git a/src/vs/platform/window/electron-main/window.ts b/src/vs/platform/window/electron-main/window.ts index 02efd8bccc8..13268e716ef 100644 --- a/src/vs/platform/window/electron-main/window.ts +++ b/src/vs/platform/window/electron-main/window.ts @@ -77,8 +77,8 @@ export interface ICodeWindow extends IBaseWindow { getBounds(): electron.Rectangle; - send(channel: string, ...args: any[]): void; - sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void; + send(channel: string, ...args: unknown[]): void; + sendWhenReady(channel: string, token: CancellationToken, ...args: unknown[]): void; updateTouchBar(items: ISerializableCommandAction[][]): void; diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index 72de68b9d38..1254f93b7e2 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -902,7 +902,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { // Unresponsive if (type === WindowError.UNRESPONSIVE) { - if (this.isExtensionDevelopmentHost || this.isExtensionTestHost || (this._win && this._win.webContents && this._win.webContents.isDevToolsOpened())) { + if (this.isExtensionDevelopmentHost || this.isExtensionTestHost || this._win?.webContents?.isDevToolsOpened()) { // TODO@electron Workaround for https://github.com/microsoft/vscode/issues/56994 // In certain cases the window can report unresponsiveness because a breakpoint was hit // and the process is stopped executing. The most typical cases are: @@ -1473,7 +1473,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { this._win?.close(); } - sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { + sendWhenReady(channel: string, token: CancellationToken, ...args: unknown[]): void { if (this.isReady) { this.send(channel, ...args); } else { @@ -1485,7 +1485,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { } } - send(channel: string, ...args: any[]): void { + send(channel: string, ...args: unknown[]): void { if (this._win) { if (this._win.isDestroyed() || this._win.webContents.isDestroyed()) { this.logService.warn(`Sending IPC message to channel '${channel}' for window that is destroyed`); diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 57d8b534e68..429bd9620c6 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -42,9 +42,9 @@ export interface IWindowsMainService { openExistingWindow(window: ICodeWindow, openConfig: IOpenConfiguration): void; - sendToFocused(channel: string, ...args: any[]): void; - sendToOpeningWindow(channel: string, ...args: any[]): void; - sendToAll(channel: string, payload?: any, windowIdsToIgnore?: number[]): void; + sendToFocused(channel: string, ...args: unknown[]): void; + sendToOpeningWindow(channel: string, ...args: unknown[]): void; + sendToAll(channel: string, payload?: unknown, windowIdsToIgnore?: number[]): void; getWindows(): ICodeWindow[]; getWindowCount(): number; diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 94224fb708d..2a8aa60380d 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -389,7 +389,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic // Otherwise, find a good window based on open params else { - const focusLastActive = this.windowsStateHandler.state.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length); + const focusLastActive = this.windowsStateHandler.state.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !openConfig.urisToOpen?.length; let focusLastOpened = true; let focusLastWindow = true; @@ -1410,7 +1410,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic cliArgs = cliArgs.filter(path => { const uri = URI.file(path); - if (!!findWindowOnWorkspaceOrFolder(this.getWindows(), uri)) { + if (findWindowOnWorkspaceOrFolder(this.getWindows(), uri)) { return false; } @@ -1419,7 +1419,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic folderUris = folderUris.filter(folderUriStr => { const folderUri = this.cliArgToUri(folderUriStr); - if (folderUri && !!findWindowOnWorkspaceOrFolder(this.getWindows(), folderUri)) { + if (folderUri && findWindowOnWorkspaceOrFolder(this.getWindows(), folderUri)) { return false; } @@ -1428,7 +1428,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic fileUris = fileUris.filter(fileUriStr => { const fileUri = this.cliArgToUri(fileUriStr); - if (fileUri && !!findWindowOnWorkspaceOrFolder(this.getWindows(), fileUri)) { + if (fileUri && findWindowOnWorkspaceOrFolder(this.getWindows(), fileUri)) { return false; } @@ -1609,7 +1609,6 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic configuration['disable-extensions'] = currentWindowConfig['disable-extensions']; configuration['disable-extension'] = currentWindowConfig['disable-extension']; } - configuration.loggers = configuration.loggers; } // Update window identifier and session now @@ -1735,19 +1734,19 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic return getLastFocused(windows); } - sendToFocused(channel: string, ...args: any[]): void { + sendToFocused(channel: string, ...args: unknown[]): void { const focusedWindow = this.getFocusedWindow() || this.getLastActiveWindow(); focusedWindow?.sendWhenReady(channel, CancellationToken.None, ...args); } - sendToOpeningWindow(channel: string, ...args: any[]): void { + sendToOpeningWindow(channel: string, ...args: unknown[]): void { this._register(Event.once(this.onDidSignalReadyWindow)(window => { window.sendWhenReady(channel, CancellationToken.None, ...args); })); } - sendToAll(channel: string, payload?: any, windowIdsToIgnore?: number[]): void { + sendToAll(channel: string, payload?: unknown, windowIdsToIgnore?: number[]): void { for (const window of this.getWindows()) { if (windowIdsToIgnore && windowIdsToIgnore.indexOf(window.id) >= 0) { continue; // do not send if we are instructed to ignore it diff --git a/src/vs/platform/windows/electron-main/windowsStateHandler.ts b/src/vs/platform/windows/electron-main/windowsStateHandler.ts index 1d04c4ac17e..0336fb4be72 100644 --- a/src/vs/platform/windows/electron-main/windowsStateHandler.ts +++ b/src/vs/platform/windows/electron-main/windowsStateHandler.ts @@ -479,7 +479,7 @@ export function getWindowsStateStoreData(windowsState: IWindowsState): IWindowsS function serializeWindowState(windowState: IWindowState): ISerializedWindowState { return { workspaceIdentifier: windowState.workspace && { id: windowState.workspace.id, configURIPath: windowState.workspace.configPath.toString() }, - folder: windowState.folderUri && windowState.folderUri.toString(), + folder: windowState.folderUri?.toString(), backupPath: windowState.backupPath, remoteAuthority: windowState.remoteAuthority, uiState: windowState.uiState diff --git a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts index 0dcfde67393..a6edf301a4a 100644 --- a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts +++ b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts @@ -30,7 +30,7 @@ suite('WindowsFinder', () => { }; const testWorkspaceFolders = toWorkspaceFolders([{ path: join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase); - const localWorkspaceResolver = async (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : undefined; }; + const localWorkspaceResolver = async (workspace: IWorkspaceIdentifier) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : undefined; }; function createTestCodeWindow(options: { lastFocusTime: number; openedFolderUri?: URI; openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow { return new class implements ICodeWindow { @@ -64,8 +64,8 @@ suite('WindowsFinder', () => { focus(options?: { mode: FocusMode }): void { throw new Error('Method not implemented.'); } close(): void { throw new Error('Method not implemented.'); } getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); } - send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); } - sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { throw new Error('Method not implemented.'); } + send(channel: string, ...args: unknown[]): void { throw new Error('Method not implemented.'); } + sendWhenReady(channel: string, token: CancellationToken, ...args: unknown[]): void { throw new Error('Method not implemented.'); } toggleFullScreen(): void { throw new Error('Method not implemented.'); } setRepresentedFilename(name: string): void { throw new Error('Method not implemented.'); } getRepresentedFilename(): string | undefined { throw new Error('Method not implemented.'); } @@ -75,7 +75,7 @@ suite('WindowsFinder', () => { serializeWindowState(): IWindowState { throw new Error('Method not implemented'); } updateWindowControls(options: { height?: number | undefined; backgroundColor?: string | undefined; foregroundColor?: string | undefined }): void { throw new Error('Method not implemented.'); } notifyZoomLevel(level: number): void { throw new Error('Method not implemented.'); } - matches(webContents: any): boolean { throw new Error('Method not implemented.'); } + matches(webContents: Electron.WebContents): boolean { throw new Error('Method not implemented.'); } dispose(): void { } }; } diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 7dddb7f3764..a2cf9529a74 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -316,16 +316,22 @@ interface ISerializedRecentlyOpened { export type RecentlyOpenedStorageData = object; -function isSerializedRecentWorkspace(data: any): data is ISerializedRecentWorkspace { - return data.workspace && typeof data.workspace === 'object' && typeof data.workspace.id === 'string' && typeof data.workspace.configPath === 'string'; +function isSerializedRecentWorkspace(data: unknown): data is ISerializedRecentWorkspace { + const candidate = data as ISerializedRecentWorkspace | undefined; + + return typeof candidate?.workspace === 'object' && typeof candidate.workspace.id === 'string' && typeof candidate.workspace.configPath === 'string'; } -function isSerializedRecentFolder(data: any): data is ISerializedRecentFolder { - return typeof data.folderUri === 'string'; +function isSerializedRecentFolder(data: unknown): data is ISerializedRecentFolder { + const candidate = data as ISerializedRecentFolder | undefined; + + return typeof candidate?.folderUri === 'string'; } -function isSerializedRecentFile(data: any): data is ISerializedRecentFile { - return typeof data.fileUri === 'string'; +function isSerializedRecentFile(data: unknown): data is ISerializedRecentFile { + const candidate = data as ISerializedRecentFile | undefined; + + return typeof candidate?.fileUri === 'string'; } export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefined, logService: ILogService): IRecentlyOpened { diff --git a/src/vs/workbench/api/node/extensionHostProcess.ts b/src/vs/workbench/api/node/extensionHostProcess.ts index 2f5e8f2c243..7ab576f0a08 100644 --- a/src/vs/workbench/api/node/extensionHostProcess.ts +++ b/src/vs/workbench/api/node/extensionHostProcess.ts @@ -169,7 +169,7 @@ function _createExtHostProtocol(): Promise { const withPorts = (ports: MessagePortMain[]) => { const port = ports[0]; const onMessage = new BufferedEmitter(); - port.on('message', (e) => onMessage.fire(VSBuffer.wrap(e.data))); + port.on('message', (e) => onMessage.fire(VSBuffer.wrap(e.data as Uint8Array))); port.on('close', () => { onTerminate('renderer closed the MessagePort'); }); diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 74d5227eb6f..a9e5dc08d17 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -389,7 +389,7 @@ class ToggleScreencastModeAction extends Action2 { const fromCommandsRegistry = CommandsRegistry.getCommand(commandId); - if (fromCommandsRegistry && fromCommandsRegistry.metadata?.description) { + if (fromCommandsRegistry?.metadata?.description) { return { title: typeof fromCommandsRegistry.metadata.description === 'string' ? fromCommandsRegistry.metadata.description : fromCommandsRegistry.metadata.description.value }; } diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 2fb9c8edbb3..7ba99ce6b2c 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -6,7 +6,7 @@ import { localize, localize2 } from '../../../nls.js'; import { IWindowOpenable } from '../../../platform/window/common/window.js'; import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; -import { MenuRegistry, MenuId, Action2, registerAction2, IAction2Options } from '../../../platform/actions/common/actions.js'; +import { MenuRegistry, MenuId, Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; import { KeyChord, KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; import { IsMainWindowFullscreenContext } from '../../common/contextkeys.js'; import { IsMacNativeContext, IsDevelopmentContext, IsWebContext, IsIOSContext } from '../../../platform/contextkey/common/contextkeys.js'; @@ -62,10 +62,6 @@ abstract class BaseOpenRecentAction extends Action2 { tooltip: localize('dirtyRecentlyOpenedWorkspace', "Workspace With Unsaved Files"), }; - constructor(desc: Readonly) { - super(desc); - } - protected abstract isQuickNavigate(): boolean; override async run(accessor: ServicesAccessor): Promise { diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index a6e4bd17298..c9a3c2ddd5a 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -241,8 +241,8 @@ CommandsRegistry.registerCommand({ const commandService = accessor.get(ICommandService); const commandOptions: IOpenEmptyWindowOptions = { - forceReuseWindow: options && options.reuseWindow, - remoteAuthority: options && options.remoteAuthority + forceReuseWindow: options?.reuseWindow, + remoteAuthority: options?.remoteAuthority }; return commandService.executeCommand('_files.newWindow', commandOptions); diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index d4c3a8b56d5..dc801de5208 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -31,7 +31,7 @@ import { IBaseActionViewItemOptions } from '../../base/browser/ui/actionbar/acti * layout(), focus(), dispose(). During use of the workbench, a composite will often receive a setVisible, * layout and focus call, but only one create and dispose call. */ -export abstract class Composite extends Component implements IComposite { +export abstract class Composite extends Component implements IComposite { private readonly _onTitleAreaUpdate = this._register(new Emitter()); readonly onTitleAreaUpdate = this._onTitleAreaUpdate.event; diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 16bddbd0ea1..794712c925b 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -470,7 +470,7 @@ export class CompositeDragAndDropObserver extends Disposable { private readDragData(type: ViewType): CompositeDragAndDropData | undefined { if (this.transferData.hasData(type === 'view' ? DraggedViewIdentifier.prototype : DraggedCompositeIdentifier.prototype)) { const data = this.transferData.getData(type === 'view' ? DraggedViewIdentifier.prototype : DraggedCompositeIdentifier.prototype); - if (data && data[0]) { + if (data?.[0]) { return new CompositeDragAndDropData(type, data[0].id); } } diff --git a/src/vs/workbench/browser/panecomposite.ts b/src/vs/workbench/browser/panecomposite.ts index 86dbfe14fd9..fe21eedbcb7 100644 --- a/src/vs/workbench/browser/panecomposite.ts +++ b/src/vs/workbench/browser/panecomposite.ts @@ -24,7 +24,7 @@ import { VIEWPANE_FILTER_ACTION } from './parts/views/viewPane.js'; import { IBoundarySashes } from '../../base/browser/ui/sash/sash.js'; import { IBaseActionViewItemOptions } from '../../base/browser/ui/actionbar/actionViewItems.js'; -export abstract class PaneComposite extends Composite implements IPaneComposite { +export abstract class PaneComposite extends Composite implements IPaneComposite { private viewPaneContainer?: ViewPaneContainer; diff --git a/src/vs/workbench/browser/part.ts b/src/vs/workbench/browser/part.ts index 8b113183fc1..d66a8f5f0ee 100644 --- a/src/vs/workbench/browser/part.ts +++ b/src/vs/workbench/browser/part.ts @@ -30,7 +30,7 @@ export interface ILayoutContentResult { * Parts are layed out in the workbench and have their own layout that * arranges an optional title and mandatory content area to show content. */ -export abstract class Part extends Component implements ISerializableView { +export abstract class Part extends Component implements ISerializableView { private _dimension: Dimension | undefined; get dimension(): Dimension | undefined { return this._dimension; } @@ -265,7 +265,7 @@ export interface IMultiWindowPart { readonly element: HTMLElement; } -export abstract class MultiWindowParts extends Component { +export abstract class MultiWindowParts extends Component { protected readonly _parts = new Set(); get parts() { return Array.from(this._parts); } diff --git a/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts b/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts index cca1343bed1..18ed28fd725 100644 --- a/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts +++ b/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts @@ -63,12 +63,12 @@ export class AuxiliaryBarPart extends AbstractPaneCompositePart { const activeComposite = this.getActivePaneComposite(); if (!activeComposite) { - return; + return undefined; } const width = activeComposite.getOptimalWidth(); if (typeof width !== 'number') { - return; + return undefined; } return Math.max(width, 300); diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index cbc65f19067..52c1ea3f817 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -71,7 +71,7 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop { if (dragData.type === 'view') { const viewToMove = this.viewDescriptorService.getViewDescriptorById(dragData.id)!; - if (viewToMove && viewToMove.canMoveView) { + if (viewToMove.canMoveView) { this.viewDescriptorService.moveViewToLocation(viewToMove, this.targetContainerLocation, 'dnd'); const newContainer = this.viewDescriptorService.getViewContainerByViewId(viewToMove.id)!; diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 793fd69668c..097fae86071 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -56,7 +56,7 @@ interface CompositeItem { readonly progress: IProgressIndicator; } -export abstract class CompositePart extends Part { +export abstract class CompositePart extends Part { protected readonly onDidCompositeOpen = this._register(new Emitter<{ composite: IComposite; focus: boolean }>()); protected readonly onDidCompositeClose = this._register(new Emitter()); diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 7f1727a3bf4..ec56befa3db 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -12,7 +12,7 @@ import { IWorkbenchLayoutService, Parts } from '../../../services/layout/browser import { GoFilter, IHistoryService } from '../../../services/history/common/history.js'; import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; -import { CLOSE_EDITOR_COMMAND_ID, MOVE_ACTIVE_EDITOR_COMMAND_ID, SelectedEditorsMoveCopyArguments, SPLIT_EDITOR_LEFT, SPLIT_EDITOR_RIGHT, SPLIT_EDITOR_UP, SPLIT_EDITOR_DOWN, splitEditor, LAYOUT_EDITOR_GROUPS_COMMAND_ID, UNPIN_EDITOR_COMMAND_ID, COPY_ACTIVE_EDITOR_COMMAND_ID, SPLIT_EDITOR, TOGGLE_MAXIMIZE_EDITOR_GROUP, MOVE_EDITOR_INTO_NEW_WINDOW_COMMAND_ID, COPY_EDITOR_INTO_NEW_WINDOW_COMMAND_ID, MOVE_EDITOR_GROUP_INTO_NEW_WINDOW_COMMAND_ID, COPY_EDITOR_GROUP_INTO_NEW_WINDOW_COMMAND_ID, NEW_EMPTY_EDITOR_WINDOW_COMMAND_ID as NEW_EMPTY_EDITOR_WINDOW_COMMAND_ID, MOVE_EDITOR_INTO_RIGHT_GROUP, MOVE_EDITOR_INTO_LEFT_GROUP, MOVE_EDITOR_INTO_ABOVE_GROUP, MOVE_EDITOR_INTO_BELOW_GROUP } from './editorCommands.js'; +import { CLOSE_EDITOR_COMMAND_ID, MOVE_ACTIVE_EDITOR_COMMAND_ID, SelectedEditorsMoveCopyArguments, SPLIT_EDITOR_LEFT, SPLIT_EDITOR_RIGHT, SPLIT_EDITOR_UP, SPLIT_EDITOR_DOWN, splitEditor, LAYOUT_EDITOR_GROUPS_COMMAND_ID, UNPIN_EDITOR_COMMAND_ID, COPY_ACTIVE_EDITOR_COMMAND_ID, SPLIT_EDITOR, TOGGLE_MAXIMIZE_EDITOR_GROUP, MOVE_EDITOR_INTO_NEW_WINDOW_COMMAND_ID, COPY_EDITOR_INTO_NEW_WINDOW_COMMAND_ID, MOVE_EDITOR_GROUP_INTO_NEW_WINDOW_COMMAND_ID, COPY_EDITOR_GROUP_INTO_NEW_WINDOW_COMMAND_ID, NEW_EMPTY_EDITOR_WINDOW_COMMAND_ID, MOVE_EDITOR_INTO_RIGHT_GROUP, MOVE_EDITOR_INTO_LEFT_GROUP, MOVE_EDITOR_INTO_ABOVE_GROUP, MOVE_EDITOR_INTO_BELOW_GROUP } from './editorCommands.js'; import { IEditorGroupsService, IEditorGroup, GroupsArrangement, GroupLocation, GroupDirection, preferredSideBySideGroupDirection, IFindGroupScope, GroupOrientation, EditorGroupLayout, GroupsOrder, MergeGroupMode } from '../../../services/editor/common/editorGroupsService.js'; import { IEditorService } from '../../../services/editor/common/editorService.js'; import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index cae1244e405..51128210543 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -1276,7 +1276,7 @@ function registerOtherEditorCommands(): void { const configurationService = accessor.get(IConfigurationService); const currentSetting = configurationService.getValue('workbench.editor.enablePreview'); - const newSetting = currentSetting === true ? false : true; + const newSetting = currentSetting !== true; configurationService.updateValue('workbench.editor.enablePreview', newSetting); } }); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 1e8b15256e5..85178c7e7fd 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -336,6 +336,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { case GroupModelChangeKind.EDITOR_CLOSE: groupActiveEditorPinnedContext.set(this.model.activeEditor ? this.model.isPinned(this.model.activeEditor) : false); groupActiveEditorStickyContext.set(this.model.activeEditor ? this.model.isSticky(this.model.activeEditor) : false); + break; case GroupModelChangeKind.EDITOR_OPEN: case GroupModelChangeKind.EDITOR_MOVE: groupActiveEditorFirstContext.set(this.model.isFirst(this.model.activeEditor)); @@ -1802,7 +1803,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // However, we only do this unless a custom confirm handler is installed // that may not be fit to be asked a second time right after. if (!editor.closeHandler && !this.shouldConfirmClose(editor)) { - return confirmation === ConfirmResult.CANCEL ? true : false; + return confirmation === ConfirmResult.CANCEL; } // Otherwise, handle accordingly diff --git a/src/vs/workbench/browser/parts/editor/editorPane.ts b/src/vs/workbench/browser/parts/editor/editorPane.ts index bb868efd2f1..c7be4a6cd63 100644 --- a/src/vs/workbench/browser/parts/editor/editorPane.ts +++ b/src/vs/workbench/browser/parts/editor/editorPane.ts @@ -16,7 +16,6 @@ import { URI } from '../../../../base/common/uri.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { isEmptyObject } from '../../../../base/common/types.js'; import { DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS } from './editor.js'; -import { MementoObject } from '../../../common/memento.js'; import { joinPath, IExtUri, isEqual } from '../../../../base/common/resources.js'; import { indexOfPath } from '../../../../base/common/extpath.js'; import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js'; @@ -47,7 +46,7 @@ import { getWindowById } from '../../../../base/browser/dom.js'; * * This class is only intended to be subclassed and not instantiated. */ -export abstract class EditorPane extends Composite implements IEditorPane { +export abstract class EditorPane extends Composite implements IEditorPane { //#region Events @@ -220,7 +219,7 @@ export class EditorMemento extends Disposable implements IEditorMemento { constructor( readonly id: string, private readonly key: string, - private readonly memento: MementoObject, + private readonly memento: T, private readonly limit: number, private readonly editorGroupService: IEditorGroupsService, private readonly configurationService: ITextResourceConfigurationService @@ -387,7 +386,7 @@ export class EditorMemento extends Disposable implements IEditorMemento { this.cache = new LRUCache>(this.limit); // Restore from serialized map state - const rawEditorMemento = this.memento[this.key]; + const rawEditorMemento = this.memento[this.key as keyof T]; if (Array.isArray(rawEditorMemento)) { this.cache.fromJSON(rawEditorMemento); } @@ -405,7 +404,7 @@ export class EditorMemento extends Disposable implements IEditorMemento { this.cleanedUp = true; } - this.memento[this.key] = cache.toJSON(); + (this.memento as Record)[this.key] = cache.toJSON(); } private cleanUp(): void { diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 354d12cb363..cb830aecd0e 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -22,7 +22,7 @@ import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget import { ISerializedEditorGroupModel, isSerializedEditorGroupModel } from '../../../common/editor/editorGroupModel.js'; import { EditorDropTarget } from './editorDropTarget.js'; import { Color } from '../../../../base/common/color.js'; -import { CenteredViewLayout } from '../../../../base/browser/ui/centered/centeredViewLayout.js'; +import { CenteredViewLayout, CenteredViewState } from '../../../../base/browser/ui/centered/centeredViewLayout.js'; import { onUnexpectedError } from '../../../../base/common/errors.js'; import { Parts, IWorkbenchLayoutService, Position } from '../../../services/layout/browser/layoutService.js'; import { DeepPartial, assertType } from '../../../../base/common/types.js'; @@ -43,6 +43,11 @@ export interface IEditorPartUIState { readonly mostRecentActiveGroups: GroupIdentifier[]; } +interface IEditorPartMemento { + 'editorpart.state'?: IEditorPartUIState; + 'editorpart.centeredview'?: CenteredViewState; +} + class GridWidgetView implements IView { readonly element: HTMLElement = $('.grid-view-container'); @@ -83,7 +88,7 @@ class GridWidgetView implements IView { } } -export class EditorPart extends Part implements IEditorPart, IEditorGroupsView { +export class EditorPart extends Part implements IEditorPart, IEditorGroupsView { private static readonly EDITOR_PART_UI_STATE_STORAGE_KEY = 'editorpart.state'; private static readonly EDITOR_PART_CENTERED_VIEW_STORAGE_KEY = 'editorpart.centeredview'; diff --git a/src/vs/workbench/browser/parts/editor/editorParts.ts b/src/vs/workbench/browser/parts/editor/editorParts.ts index 5b29a7020bc..4e7ff2d640f 100644 --- a/src/vs/workbench/browser/parts/editor/editorParts.ts +++ b/src/vs/workbench/browser/parts/editor/editorParts.ts @@ -43,7 +43,11 @@ interface IEditorWorkingSetState extends IEditorWorkingSet { readonly auxiliary: IEditorPartsUIState; } -export class EditorParts extends MultiWindowParts implements IEditorGroupsService, IEditorPartsView { +interface IEditorPartsMemento { + 'editorparts.state'?: IEditorPartsUIState; +} + +export class EditorParts extends MultiWindowParts implements IEditorGroupsService, IEditorPartsView { declare readonly _serviceBrand: undefined; @@ -534,7 +538,7 @@ export class EditorParts extends MultiWindowParts implements IEditor break; } - return parts.map(part => part.getGroups(order)).flat(); + return parts.flatMap(part => part.getGroups(order)); } return this.mainPart.getGroups(order); diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 94e0e278fa2..77bfedeabb0 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -305,7 +305,7 @@ class TabFocusMode extends Disposable { this.registerListeners(); - const tabFocusModeConfig = configurationService.getValue('editor.tabFocusMode') === true ? true : false; + const tabFocusModeConfig = configurationService.getValue('editor.tabFocusMode') === true; TabFocus.setTabFocusMode(tabFocusModeConfig); } @@ -314,7 +314,7 @@ class TabFocusMode extends Disposable { this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('editor.tabFocusMode')) { - const tabFocusModeConfig = this.configurationService.getValue('editor.tabFocusMode') === true ? true : false; + const tabFocusModeConfig = this.configurationService.getValue('editor.tabFocusMode') === true; TabFocus.setTabFocusMode(tabFocusModeConfig); this._onDidChange.fire(tabFocusModeConfig); diff --git a/src/vs/workbench/browser/parts/editor/editorWithViewState.ts b/src/vs/workbench/browser/parts/editor/editorWithViewState.ts index 8cfd84b64c1..70a0c0b1260 100644 --- a/src/vs/workbench/browser/parts/editor/editorWithViewState.ts +++ b/src/vs/workbench/browser/parts/editor/editorWithViewState.ts @@ -126,7 +126,7 @@ export abstract class AbstractEditorWithViewState extends Edit // new editor: check with workbench.editor.restoreViewState setting if (context?.newInGroup) { - return this.textResourceConfigurationService.getValue(EditorResourceAccessor.getOriginalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }), 'workbench.editor.restoreViewState') === false ? false : true /* restore by default */; + return this.textResourceConfigurationService.getValue(EditorResourceAccessor.getOriginalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }), 'workbench.editor.restoreViewState') !== false /* restore by default */; } // existing editor: always restore viewstate diff --git a/src/vs/workbench/browser/parts/editor/editorsObserver.ts b/src/vs/workbench/browser/parts/editor/editorsObserver.ts index 19dd4c3b511..4c5ca3582b5 100644 --- a/src/vs/workbench/browser/parts/editor/editorsObserver.ts +++ b/src/vs/workbench/browser/parts/editor/editorsObserver.ts @@ -273,7 +273,7 @@ export class EditorsObserver extends Disposable { // Remove from key map const map = this.keyMap.get(group.id); - if (map && map.delete(key.editor) && map.size === 0) { + if (map?.delete(key.editor) && map.size === 0) { this.keyMap.delete(group.id); } diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css index c5b4faf8e49..e41d6f4824a 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css @@ -13,7 +13,6 @@ .monaco-workbench .notifications-list-container .notification-list-item { display: flex; - flex-direction: column; flex-direction: column-reverse; /* the details row appears first in order for better keyboard access to notification buttons */ padding: 10px 5px; height: 100%; diff --git a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts index ab770c9580b..6512492cae4 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts @@ -65,7 +65,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate 1 */)}px`; diff --git a/src/vs/workbench/browser/parts/paneCompositePart.ts b/src/vs/workbench/browser/parts/paneCompositePart.ts index fda9c918852..af2a9da5350 100644 --- a/src/vs/workbench/browser/parts/paneCompositePart.ts +++ b/src/vs/workbench/browser/parts/paneCompositePart.ts @@ -324,7 +324,7 @@ export abstract class AbstractPaneCompositePart extends CompositePart { let childrenGroups: ITreeItem[][]; let checkboxesUpdated: ITreeItem[] = []; - if (nodes && nodes.every((node): node is Required => !!node.children)) { + if (nodes?.every((node): node is Required => !!node.children)) { childrenGroups = nodes.map(node => node.children); } else { nodes = nodes ?? [self.root]; @@ -1331,7 +1331,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer { + const matches = (treeItemLabel?.highlights && label) ? treeItemLabel.highlights.map(([start, end]) => { if (start < 0) { start = label.length + start; } diff --git a/src/vs/workbench/browser/parts/views/viewPane.ts b/src/vs/workbench/browser/parts/views/viewPane.ts index 8235fb5dff8..a047efbb82f 100644 --- a/src/vs/workbench/browser/parts/views/viewPane.ts +++ b/src/vs/workbench/browser/parts/views/viewPane.ts @@ -245,7 +245,7 @@ class ViewWelcomeController { if (linkedText.nodes.length === 1 && typeof linkedText.nodes[0] !== 'string') { const node = linkedText.nodes[0]; const buttonContainer = append(this.element!, $('.button-container')); - const button = new Button(buttonContainer, { title: node.title, supportIcons: true, secondary: renderSecondaryButtons && buttonsCount > 0 ? true : false, ...defaultButtonStyles, }); + const button = new Button(buttonContainer, { title: node.title, supportIcons: true, secondary: !!(renderSecondaryButtons && buttonsCount > 0), ...defaultButtonStyles, }); button.label = node.label; button.onDidClick(_ => { this.openerService.open(node.href, { allowCommands: true }); diff --git a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts index 1b1188d09ad..f823ecfd051 100644 --- a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts +++ b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts @@ -288,7 +288,7 @@ class ViewPaneDropOverlay extends Themable { } } -export class ViewPaneContainer extends Component implements IViewPaneContainer { +export class ViewPaneContainer extends Component implements IViewPaneContainer { readonly viewContainer: ViewContainer; private lastFocusedPane: ViewPane | undefined; @@ -424,7 +424,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(parent, { onDragEnter: (e) => { bounds = getOverlayBounds(); - if (overlay && overlay.disposed) { + if (overlay?.disposed) { overlay = undefined; } @@ -453,7 +453,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { } }, onDragOver: (e) => { - if (overlay && overlay.disposed) { + if (overlay?.disposed) { overlay = undefined; } diff --git a/src/vs/workbench/common/component.ts b/src/vs/workbench/common/component.ts index c579f0c1e53..644667ceb66 100644 --- a/src/vs/workbench/common/component.ts +++ b/src/vs/workbench/common/component.ts @@ -3,15 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Memento, MementoObject } from './memento.js'; +import { Memento } from './memento.js'; import { IThemeService, Themable } from '../../platform/theme/common/themeService.js'; import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from '../../platform/storage/common/storage.js'; import { DisposableStore } from '../../base/common/lifecycle.js'; import { Event } from '../../base/common/event.js'; -export class Component extends Themable { +export class Component extends Themable { - private readonly memento: Memento; + private readonly memento: Memento; constructor( private readonly id: string, @@ -36,12 +36,12 @@ export class Component extends Themable { return this.id; } - protected getMemento(scope: StorageScope, target: StorageTarget): MementoObject { + protected getMemento(scope: StorageScope, target: StorageTarget): Partial { return this.memento.getMemento(scope, target); } protected reloadMemento(scope: StorageScope): void { - return this.memento.reloadMemento(scope); + this.memento.reloadMemento(scope); } protected onDidChangeMementoValue(scope: StorageScope, disposables: DisposableStore): Event { diff --git a/src/vs/workbench/common/configuration.ts b/src/vs/workbench/common/configuration.ts index 46f42503e1c..e1191861eda 100644 --- a/src/vs/workbench/common/configuration.ts +++ b/src/vs/workbench/common/configuration.ts @@ -58,8 +58,9 @@ export const Extensions = { ConfigurationMigration: 'base.contributions.configuration.migration' }; -export type ConfigurationValue = { value: any | undefined /* Remove */ }; +type ConfigurationValue = { value: unknown | undefined /* Remove */ }; export type ConfigurationKeyValuePairs = [string, ConfigurationValue][]; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type ConfigurationMigrationFn = (value: any, valueAccessor: (key: string) => any) => ConfigurationValue | ConfigurationKeyValuePairs | Promise; export type ConfigurationMigration = { key: string; migrateFn: ConfigurationMigrationFn }; @@ -115,7 +116,7 @@ export class ConfigurationMigrationWorkbenchContribution extends Disposable impl private async migrateConfigurationsForFolderAndOverride(migration: ConfigurationMigration, resource?: URI): Promise { const inspectData = this.configurationService.inspect(migration.key, { resource }); - const targetPairs: [keyof IConfigurationValue, ConfigurationTarget][] = this.workspaceService.getWorkbenchState() === WorkbenchState.WORKSPACE ? [ + const targetPairs: [keyof IConfigurationValue, ConfigurationTarget][] = this.workspaceService.getWorkbenchState() === WorkbenchState.WORKSPACE ? [ ['user', ConfigurationTarget.USER], ['userLocal', ConfigurationTarget.USER_LOCAL], ['userRemote', ConfigurationTarget.USER_REMOTE], @@ -128,7 +129,7 @@ export class ConfigurationMigrationWorkbenchContribution extends Disposable impl ['workspace', ConfigurationTarget.WORKSPACE], ]; for (const [dataKey, target] of targetPairs) { - const inspectValue = inspectData[dataKey] as IInspectValue | undefined; + const inspectValue = inspectData[dataKey] as IInspectValue | undefined; if (!inspectValue) { continue; } @@ -159,10 +160,10 @@ export class ConfigurationMigrationWorkbenchContribution extends Disposable impl } } - private async runMigration(migration: ConfigurationMigration, dataKey: keyof IConfigurationValue, value: any, resource: URI | undefined, overrideIdentifiers: string[] | undefined): Promise { + private async runMigration(migration: ConfigurationMigration, dataKey: keyof IConfigurationValue, value: unknown, resource: URI | undefined, overrideIdentifiers: string[] | undefined): Promise { const valueAccessor = (key: string) => { const inspectData = this.configurationService.inspect(key, { resource }); - const inspectValue = inspectData[dataKey] as IInspectValue | undefined; + const inspectValue = inspectData[dataKey] as IInspectValue | undefined; if (!inspectValue) { return undefined; } @@ -271,7 +272,7 @@ export class DynamicWindowConfiguration extends Disposable implements IWorkbench 'type': ['string', 'null'], 'default': null, 'enum': [...this.userDataProfilesService.profiles.map(profile => profile.name), null], - 'enumItemLabels': [...this.userDataProfilesService.profiles.map(p => ''), localize('active window', "Active Window")], + 'enumItemLabels': [...this.userDataProfilesService.profiles.map(() => ''), localize('active window', "Active Window")], 'description': localize('newWindowProfile', "Specifies the profile to use when opening a new window. If a profile name is provided, the new window will use that profile. If no profile name is provided, the new window will use the profile of the active window or the Default profile if no active window exists."), 'scope': ConfigurationScope.APPLICATION, } diff --git a/src/vs/workbench/common/editor/editorGroupModel.ts b/src/vs/workbench/common/editor/editorGroupModel.ts index f7c03af3c2c..d16fc13213f 100644 --- a/src/vs/workbench/common/editor/editorGroupModel.ts +++ b/src/vs/workbench/common/editor/editorGroupModel.ts @@ -640,7 +640,7 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { } setActive(candidate: EditorInput | undefined): EditorInput | undefined { - let result: EditorInput | undefined = undefined; + let result: EditorInput | undefined; if (!candidate) { this.setGroupActive(); @@ -1231,7 +1231,7 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { } this.editors = coalesce(data.editors.map((e, index) => { - let editor: EditorInput | undefined = undefined; + let editor: EditorInput | undefined; const editorSerializer = registry.getEditorSerializer(e.id); if (editorSerializer) { diff --git a/src/vs/workbench/common/editor/resourceEditorInput.ts b/src/vs/workbench/common/editor/resourceEditorInput.ts index 360b534bdc9..221d0f32db8 100644 --- a/src/vs/workbench/common/editor/resourceEditorInput.ts +++ b/src/vs/workbench/common/editor/resourceEditorInput.ts @@ -198,7 +198,7 @@ export abstract class AbstractResourceEditorInput extends EditorInput implements // resource scheme. const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource); - let configuredSizeLimit: number | undefined = undefined; + let configuredSizeLimit: number | undefined; const configuredSizeLimitMb = this.textResourceConfigurationService.inspect(this.resource, null, 'workbench.editorLargeFileConfirmation'); if (isConfigured(configuredSizeLimitMb)) { diff --git a/src/vs/workbench/common/memento.ts b/src/vs/workbench/common/memento.ts index f97a811e64b..b251e739f6c 100644 --- a/src/vs/workbench/common/memento.ts +++ b/src/vs/workbench/common/memento.ts @@ -9,13 +9,11 @@ import { onUnexpectedError } from '../../base/common/errors.js'; import { DisposableStore } from '../../base/common/lifecycle.js'; import { Event } from '../../base/common/event.js'; -export type MementoObject = { [key: string]: any }; +export class Memento { -export class Memento { - - private static readonly applicationMementos = new Map(); - private static readonly profileMementos = new Map(); - private static readonly workspaceMementos = new Map(); + private static readonly applicationMementos = new Map>(); + private static readonly profileMementos = new Map>(); + private static readonly workspaceMementos = new Map>(); private static readonly COMMON_PREFIX = 'memento/'; @@ -25,7 +23,7 @@ export class Memento { this.id = Memento.COMMON_PREFIX + id; } - getMemento(scope: StorageScope, target: StorageTarget): MementoObject { + getMemento(scope: StorageScope, target: StorageTarget): Partial { switch (scope) { case StorageScope.WORKSPACE: { let workspaceMemento = Memento.workspaceMementos.get(this.id); @@ -70,7 +68,7 @@ export class Memento { } reloadMemento(scope: StorageScope): void { - let memento: ScopedMemento | undefined; + let memento: ScopedMemento | undefined; switch (scope) { case StorageScope.APPLICATION: memento = Memento.applicationMementos.get(this.id); @@ -101,17 +99,17 @@ export class Memento { } } -class ScopedMemento { +class ScopedMemento { - private mementoObj: MementoObject; + private mementoObj: Partial; constructor(private id: string, private scope: StorageScope, private target: StorageTarget, private storageService: IStorageService) { this.mementoObj = this.doLoad(); } - private doLoad(): MementoObject { + private doLoad(): Partial { try { - return this.storageService.getObject(this.id, this.scope, {}); + return this.storageService.getObject(this.id, this.scope, {}); } catch (error) { // Seeing reports from users unable to open editors // from memento parsing exceptions. Log the contents @@ -123,7 +121,7 @@ class ScopedMemento { return {}; } - getMemento(): MementoObject { + getMemento(): Partial { return this.mementoObj; } @@ -131,7 +129,7 @@ class ScopedMemento { // Clear old for (const name of Object.getOwnPropertyNames(this.mementoObj)) { - delete this.mementoObj[name]; + delete this.mementoObj[name as keyof Partial]; } // Assign new diff --git a/src/vs/workbench/common/notifications.ts b/src/vs/workbench/common/notifications.ts index 08861595cb0..ff1ddb45f96 100644 --- a/src/vs/workbench/common/notifications.ts +++ b/src/vs/workbench/common/notifications.ts @@ -736,8 +736,8 @@ export class NotificationViewItem extends Disposable implements INotificationVie return false; } - const primaryActions = (this._actions && this._actions.primary) || []; - const otherPrimaryActions = (other.actions && other.actions.primary) || []; + const primaryActions = this._actions?.primary || []; + const otherPrimaryActions = other.actions?.primary || []; return equals(primaryActions, otherPrimaryActions, (action, otherAction) => (action.id + action.label) === (otherAction.id + otherAction.label)); } } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 37e1b8f620c..8cfa0047966 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -660,7 +660,7 @@ export interface ITreeView extends IDisposable { readonly onDidChangeCheckboxState: Event; - readonly container: any | undefined; + readonly container: unknown /* HTMLElement */ | undefined; // checkboxesChanged is a subset of treeItems refresh(treeItems?: readonly ITreeItem[], checkboxesChanged?: readonly ITreeItem[]): Promise; @@ -685,7 +685,7 @@ export interface ITreeView extends IDisposable { setFocus(item?: ITreeItem): void; - show(container: any): void; + show(container: unknown /* HTMLElement */): void; } export interface IRevealOptions { diff --git a/src/vs/workbench/contrib/chat/browser/chatEditor.ts b/src/vs/workbench/contrib/chat/browser/chatEditor.ts index 5935dd397d0..9bfb0f0aeac 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditor.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditor.ts @@ -48,7 +48,7 @@ export class ChatEditor extends EditorPane { return this._scopedContextKeyService; } - private _memento: Memento | undefined; + private _memento: Memento | undefined; private _viewState: IChatViewState | undefined; private dimension = new dom.Dimension(0, 0); @@ -169,7 +169,7 @@ export class ChatEditor extends EditorPane { private updateModel(model: IChatModel, viewState?: IChatViewState): void { this._memento = new Memento('interactive-session-editor-' + CHAT_PROVIDER_ID, this.storageService); - this._viewState = viewState ?? this._memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as IChatViewState; + this._viewState = viewState ?? this._memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); this.widget.setModel(model, { ...this._viewState }); } diff --git a/src/vs/workbench/contrib/chat/browser/chatStatus.ts b/src/vs/workbench/contrib/chat/browser/chatStatus.ts index 05f6f0ec6cf..7024192bd84 100644 --- a/src/vs/workbench/contrib/chat/browser/chatStatus.ts +++ b/src/vs/workbench/contrib/chat/browser/chatStatus.ts @@ -610,7 +610,7 @@ class ChatStatusDashboard extends Disposable { } } - private runCommandAndClose(commandOrFn: string | Function, ...args: any[]): void { + private runCommandAndClose(commandOrFn: string | Function, ...args: unknown[]): void { if (typeof commandOrFn === 'function') { commandOrFn(...args); } else { diff --git a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts index 6beb02e2ad5..3b41a95bfc7 100644 --- a/src/vs/workbench/contrib/chat/browser/chatViewPane.ts +++ b/src/vs/workbench/contrib/chat/browser/chatViewPane.ts @@ -50,7 +50,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate { get widget(): ChatWidget { return this._widget; } private readonly modelDisposables = this._register(new DisposableStore()); - private memento: Memento; + private memento: Memento; private readonly viewState: IViewPaneState; private _restoringSession: Promise | undefined; @@ -78,11 +78,11 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate { // View state for the ViewPane is currently global per-provider basically, but some other strictly per-model state will require a separate memento. this.memento = new Memento('interactive-session-view-' + CHAT_PROVIDER_ID, this.storageService); - this.viewState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as IViewPaneState; + this.viewState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); if (this.chatOptions.location === ChatAgentLocation.Chat && !this.viewState.hasMigratedCurrentSession) { - const editsMemento = new Memento('interactive-session-view-' + CHAT_PROVIDER_ID + `-edits`, this.storageService); - const lastEditsState = editsMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as IViewPaneState; + const editsMemento = new Memento('interactive-session-view-' + CHAT_PROVIDER_ID + `-edits`, this.storageService); + const lastEditsState = editsMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); if (lastEditsState.sessionId) { this.logService.trace(`ChatViewPane: last edits session was ${lastEditsState.sessionId}`); if (!this.chatService.isPersistedSessionEmpty(lastEditsState.sessionId)) { diff --git a/src/vs/workbench/contrib/chat/common/chatTodoListService.ts b/src/vs/workbench/contrib/chat/common/chatTodoListService.ts index 3cbfbe2d75c..835af80fd20 100644 --- a/src/vs/workbench/contrib/chat/common/chatTodoListService.ts +++ b/src/vs/workbench/contrib/chat/common/chatTodoListService.ts @@ -29,7 +29,7 @@ export interface IChatTodoListService { } export class ChatTodoListStorage implements IChatTodoListStorage { - private memento: Memento; + private memento: Memento>; constructor(@IStorageService storageService: IStorageService) { this.memento = new Memento('chat-todo-list', storageService); diff --git a/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.ts b/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.ts index be1e5284771..4ed046e62a7 100644 --- a/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.ts +++ b/src/vs/workbench/contrib/chat/common/chatWidgetHistoryService.ts @@ -43,7 +43,7 @@ export interface IChatWidgetHistoryService { } interface IChatHistory { - history: { [providerId: string]: IChatHistoryEntry[] }; + history?: { [providerId: string]: IChatHistoryEntry[] }; } export const ChatInputHistoryMaxEntries = 40; @@ -51,7 +51,7 @@ export const ChatInputHistoryMaxEntries = 40; export class ChatWidgetHistoryService implements IChatWidgetHistoryService { _serviceBrand: undefined; - private memento: Memento; + private memento: Memento; private viewState: IChatHistory; private readonly _onDidClearHistory = new Emitter(); @@ -60,8 +60,8 @@ export class ChatWidgetHistoryService implements IChatWidgetHistoryService { constructor( @IStorageService storageService: IStorageService ) { - this.memento = new Memento('interactive-session', storageService); - const loadedState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as IChatHistory; + this.memento = new Memento('interactive-session', storageService); + const loadedState = this.memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); for (const provider in loadedState.history) { // Migration from old format loadedState.history[provider] = loadedState.history[provider].map(entry => typeof entry === 'string' ? { text: entry } : entry); diff --git a/src/vs/workbench/contrib/comments/browser/commentsView.ts b/src/vs/workbench/contrib/comments/browser/commentsView.ts index e9dcf952046..b97d67a4e1e 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsView.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsView.ts @@ -24,7 +24,7 @@ import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js'; import { CommentsViewFilterFocusContextKey, ICommentsView } from './comments.js'; import { CommentsFilters, CommentsFiltersChangeEvent, CommentsSortOrder } from './commentsViewActions.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; import { FilterOptions } from './commentsFilterOptions.js'; import { CommentThreadApplicability, CommentThreadState } from '../../../../editor/common/languages.js'; @@ -45,6 +45,14 @@ export const CONTEXT_KEY_SOME_COMMENTS_EXPANDED = new RawContextKey('co export const CONTEXT_KEY_COMMENT_FOCUSED = new RawContextKey('commentsView.commentFocused', false); const VIEW_STORAGE_ID = 'commentsViewState'; +interface CommentsViewState { + filter?: string; + filterHistory?: string[]; + showResolved?: boolean; + showUnresolved?: boolean; + sortBy?: CommentsSortOrder; +} + type CommentsTreeNode = CommentsModel | ResourceWithCommentThreads | CommentNode; function createResourceCommentsIterator(model: ICommentsModel): Iterable> { @@ -78,8 +86,8 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView { private currentHeight = 0; private currentWidth = 0; - private readonly viewState: MementoObject; - private readonly stateMemento: Memento; + private readonly viewState: CommentsViewState; + private readonly stateMemento: Memento; private cachedFilterStats: { total: number; filtered: number } | undefined = undefined; readonly onDidChangeVisibility = this.onDidChangeBodyVisibility; @@ -152,15 +160,15 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView { @IStorageService storageService: IStorageService, @IPathService private readonly pathService: IPathService, ) { - const stateMemento = new Memento(VIEW_STORAGE_ID, storageService); + const stateMemento = new Memento(VIEW_STORAGE_ID, storageService); const viewState = stateMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); super({ ...options, filterOptions: { placeholder: nls.localize('comments.filter.placeholder', "Filter (e.g. text, author)"), ariaLabel: nls.localize('comments.filter.ariaLabel', "Filter comments"), - history: viewState['filterHistory'] || [], - text: viewState['filter'] || '', + history: viewState.filterHistory || [], + text: viewState.filter || '', focusContextKey: CommentsViewFilterFocusContextKey.key } }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService); @@ -171,9 +179,9 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView { this.viewState = viewState; this.filters = this._register(new CommentsFilters({ - showResolved: this.viewState['showResolved'] !== false, - showUnresolved: this.viewState['showUnresolved'] !== false, - sortBy: this.viewState['sortBy'] ?? CommentsSortOrder.ResourceAscending, + showResolved: this.viewState.showResolved !== false, + showUnresolved: this.viewState.showUnresolved !== false, + sortBy: this.viewState.sortBy ?? CommentsSortOrder.ResourceAscending, }, this.contextKeyService)); this.filter = new Filter(new FilterOptions(this.filterWidget.getFilterText(), this.filters.showResolved, this.filters.showUnresolved)); @@ -189,11 +197,11 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView { } override saveState(): void { - this.viewState['filter'] = this.filterWidget.getFilterText(); - this.viewState['filterHistory'] = this.filterWidget.getHistory(); - this.viewState['showResolved'] = this.filters.showResolved; - this.viewState['showUnresolved'] = this.filters.showUnresolved; - this.viewState['sortBy'] = this.filters.sortBy; + this.viewState.filter = this.filterWidget.getFilterText(); + this.viewState.filterHistory = this.filterWidget.getHistory(); + this.viewState.showResolved = this.filters.showResolved; + this.viewState.showUnresolved = this.filters.showUnresolved; + this.viewState.sortBy = this.filters.sortBy; this.stateMemento.saveMemento(); super.saveState(); } diff --git a/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts b/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts index 849bd4d904f..fbf895d16ac 100644 --- a/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts +++ b/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts @@ -15,13 +15,17 @@ import { customEditorsExtensionPoint, ICustomEditorsExtensionPoint } from './ext import { RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js'; import { IExtensionPointUser } from '../../../services/extensions/common/extensionsRegistry.js'; +interface CustomEditorsMemento { + editors?: CustomEditorDescriptor[]; +} + export class ContributedCustomEditors extends Disposable { private static readonly CUSTOM_EDITORS_STORAGE_ID = 'customEditors'; private static readonly CUSTOM_EDITORS_ENTRY_ID = 'editors'; private readonly _editors = new Map(); - private readonly _memento: Memento; + private readonly _memento: Memento; constructor(storageService: IStorageService) { super(); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 9092f0d6e70..62485d9eade 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -45,7 +45,6 @@ import { alert } from '../../../../base/browser/ui/aria/aria.js'; import { EXTENSION_CATEGORIES } from '../../../../platform/extensions/common/extensions.js'; import { Registry } from '../../../../platform/registry/common/platform.js'; import { ILabelService } from '../../../../platform/label/common/label.js'; -import { MementoObject } from '../../../common/memento.js'; import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js'; import { IPreferencesService } from '../../../services/preferences/common/preferences.js'; import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND } from '../../../common/theme.js'; @@ -92,6 +91,10 @@ export const ExtensionsSearchValueContext = new RawContextKey('extension const REMOTE_CATEGORY: ILocalizedString = localize2({ key: 'remote', comment: ['Remote as in remote machine'] }, "Remote"); +interface IExtensionsViewletState { + 'query.value'?: string; +} + export class ExtensionsViewletViewsContribution extends Disposable implements IWorkbenchContribution { private readonly container: ViewContainer; @@ -506,7 +509,7 @@ export class ExtensionsViewletViewsContribution extends Disposable implements IW } -export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IExtensionsViewPaneContainer { +export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IExtensionsViewPaneContainer { private readonly extensionsSearchValueContextKey: IContextKey; private readonly defaultViewsContextKey: IContextKey; @@ -534,7 +537,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE private header: HTMLElement | undefined; private searchBox: SuggestEnabledInput | undefined; private notificationContainer: HTMLElement | undefined; - private readonly searchViewletState: MementoObject; + private readonly searchViewletState: IExtensionsViewletState; private extensionGalleryManifest: IExtensionGalleryManifest | null = null; constructor( diff --git a/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts b/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts index 118758dc1a0..c242cd03c29 100644 --- a/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts +++ b/src/vs/workbench/contrib/externalUriOpener/common/contributedOpeners.ts @@ -16,7 +16,7 @@ interface RegisteredExternalOpener { } interface OpenersMemento { - [id: string]: RegisteredExternalOpener; + [id: string]: RegisteredExternalOpener | undefined; } export class ContributedExternalUriOpenersStore extends Disposable { @@ -24,7 +24,7 @@ export class ContributedExternalUriOpenersStore extends Disposable { private static readonly STORAGE_ID = 'externalUriOpeners'; private readonly _openers = new Map(); - private readonly _memento: Memento; + private readonly _memento: Memento; private _mementoObject: OpenersMemento; constructor( @@ -36,7 +36,9 @@ export class ContributedExternalUriOpenersStore extends Disposable { this._memento = new Memento(ContributedExternalUriOpenersStore.STORAGE_ID, storageService); this._mementoObject = this._memento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); for (const [id, value] of Object.entries(this._mementoObject || {})) { - this.add(id, value.extensionId, { isCurrentlyRegistered: false }); + if (value) { + this.add(id, value.extensionId, { isCurrentlyRegistered: false }); + } } this.invalidateOpenersOnExtensionsChanged(); diff --git a/src/vs/workbench/contrib/files/browser/explorerService.ts b/src/vs/workbench/contrib/files/browser/explorerService.ts index 61f0ac0a8ff..b49c34fbc7c 100644 --- a/src/vs/workbench/contrib/files/browser/explorerService.ts +++ b/src/vs/workbench/contrib/files/browser/explorerService.ts @@ -446,7 +446,7 @@ export class ExplorerService implements IExplorerService { if (item === undefined || ignore) { return true; } - if (this.revealExcludeMatcher.matches(item.resource, name => !!(item.parent && item.parent.getChild(name)))) { + if (this.revealExcludeMatcher.matches(item.resource, name => !!(item.parent?.getChild(name)))) { return false; } const root = item.root; @@ -521,7 +521,7 @@ function doesFileEventAffect(item: ExplorerItem, view: IExplorerView, events: Fi } function getRevealExcludes(configuration: IFilesConfiguration): IExpression { - const revealExcludes = configuration && configuration.explorer && configuration.explorer.autoRevealExclude; + const revealExcludes = configuration?.explorer?.autoRevealExclude; if (!revealExcludes) { return {}; diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index 80b38b619e3..ecc6af48668 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -196,7 +196,7 @@ export class ExplorerViewPaneContainer extends ViewPaneContainer { let delay = 0; const config = this.configurationService.getValue(); - if (!!config.workbench?.editor?.enablePreview) { + if (config.workbench?.editor?.enablePreview) { // delay open editors view when preview is enabled // to accomodate for the user doing a double click // to pin the editor. diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 50f786ea2f7..bcb80404e4f 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -78,14 +78,6 @@ export const UPLOAD_LABEL = nls.localize('upload', "Upload..."); const CONFIRM_DELETE_SETTING_KEY = 'explorer.confirmDelete'; const MAX_UNDO_FILE_SIZE = 5000000; // 5mb -function onError(notificationService: INotificationService, error: any): void { - if (error.message === 'string') { - error = error.message; - } - - notificationService.error(toErrorMessage(error, false)); -} - async function refreshIfSeparator(value: string, explorerService: IExplorerService): Promise { if (value && ((value.indexOf('/') >= 0) || (value.indexOf('\\') >= 0))) { // New input contains separator, multiple resources will get created workaround for #68204 @@ -600,7 +592,7 @@ abstract class BaseSaveAllAction extends Action { try { await this.doRun(context); } catch (error) { - onError(this.notificationService, error); + this.notificationService.error(toErrorMessage(error, false)); } } } @@ -1281,7 +1273,7 @@ export const pasteFileHandler = async (accessor: ServicesAccessor, fileList?: Fi } } } catch (e) { - onError(notificationService, new Error(nls.localize('fileDeleted', "The file(s) to paste have been deleted or moved since you copied them. {0}", getErrorMessage(e)))); + notificationService.error(toErrorMessage(new Error(nls.localize('fileDeleted', "The file(s) to paste have been deleted or moved since you copied them. {0}", getErrorMessage(e))), false)); } finally { if (pasteShouldMove) { // Cut is done. Make sure to clear cut state. diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 0cc1fa6240f..28a46340a05 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -280,7 +280,7 @@ export class BrowserFileUpload { operation.filesTotal += childEntries.length; // Split up files from folders to upload - const folderTarget = target && target.getChild(entry.name) || undefined; + const folderTarget = target?.getChild(entry.name) || undefined; const fileChildEntries: IWebkitDataTransferItemEntry[] = []; const folderChildEntries: IWebkitDataTransferItemEntry[] = []; for (const childEntry of childEntries) { diff --git a/src/vs/workbench/contrib/files/browser/files.ts b/src/vs/workbench/contrib/files/browser/files.ts index 00307a068de..4ea8553bd60 100644 --- a/src/vs/workbench/contrib/files/browser/files.ts +++ b/src/vs/workbench/contrib/files/browser/files.ts @@ -159,7 +159,7 @@ export function getMultiSelectedResources(commandArg: unknown, listService: ILis } const result = getResourceForCommand(commandArg, editorSerice, listService); - return !!result ? [result] : []; + return result ? [result] : []; } export function getOpenEditorsViewMultiSelection(accessor: ServicesAccessor): Array | undefined { diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index c7056e38868..255dcf11f83 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -104,14 +104,14 @@ export function getContext(focus: ExplorerItem[], selection: ExplorerItem[], res } const compressedNavigationControllers = focusedStat && compressedNavigationControllerProvider.getCompressedNavigationController(focusedStat); - const compressedNavigationController = compressedNavigationControllers && compressedNavigationControllers.length ? compressedNavigationControllers[0] : undefined; + const compressedNavigationController = compressedNavigationControllers?.length ? compressedNavigationControllers[0] : undefined; focusedStat = compressedNavigationController ? compressedNavigationController.current : focusedStat; const selectedStats: ExplorerItem[] = []; for (const stat of selection) { const controllers = compressedNavigationControllerProvider.getCompressedNavigationController(stat); - const controller = controllers && controllers.length ? controllers[0] : undefined; + const controller = controllers?.at(0); if (controller && focusedStat && controller === compressedNavigationController) { if (stat === focusedStat) { selectedStats.push(stat); @@ -550,7 +550,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { this._register(this.tree.onDidChangeCollapseState(e => { const element = e.node.element?.element; if (element) { - const navigationControllers = this.renderer.getCompressedNavigationController(element instanceof Array ? element[0] : element); + const navigationControllers = this.renderer.getCompressedNavigationController(Array.isArray(element) ? element[0] : element); navigationControllers?.forEach(controller => controller.updateCollapsed(e.node.collapsed)); } // Update showing expand / collapse button @@ -643,7 +643,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { let arg: URI | {}; if (stat instanceof ExplorerItem) { const compressedControllers = this.renderer.getCompressedNavigationController(stat); - arg = compressedControllers && compressedControllers.length ? compressedControllers[0].current.resource : stat.resource; + arg = compressedControllers?.length ? compressedControllers[0].current.resource : stat.resource; } else { arg = roots.length === 1 ? roots[0].resource : {}; } @@ -665,7 +665,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } private onFocusChanged(elements: readonly ExplorerItem[]): void { - const stat = elements && elements.length ? elements[0] : undefined; + const stat = elements.at(0); this.setContextKeys(stat); if (stat) { @@ -738,7 +738,7 @@ export class ExplorerView extends ViewPane implements IExplorerView { } let viewState: IAsyncDataTreeViewState | undefined; - if (this.tree && this.tree.getInput()) { + if (this.tree?.getInput()) { viewState = this.tree.getViewState(); } else { const rawViewState = this.storageService.get(ExplorerView.TREE_VIEW_STATE_STORAGE_KEY, StorageScope.WORKSPACE); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index cf13074b632..791c2aa1941 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -170,16 +170,7 @@ export class ExplorerDataSource implements IAsyncDataSource { } const stat = this.explorerService.findClosest(e.resource); - if (stat && stat.isExcluded) { + if (stat?.isExcluded) { // A filtered resource suddenly became visible since user opened an editor shouldFire = true; break; @@ -1419,9 +1410,9 @@ export class FilesFilter implements ITreeFilter { // Hide those that match Hidden Patterns const cached = this.hiddenExpressionPerRoot.get(stat.root.resource.toString()); - const globMatch = cached?.parsed(path.relative(stat.root.resource.path, stat.resource.path), stat.name, name => !!(stat.parent && stat.parent.getChild(name))); + const globMatch = cached?.parsed(path.relative(stat.root.resource.path, stat.resource.path), stat.name, name => !!(stat.parent?.getChild(name))); // Small optimization to only run isHiddenResource (traverse gitIgnore) if the globMatch from fileExclude returned nothing - const isHiddenResource = !!globMatch ? true : this.isIgnored(stat.resource, stat.root.resource, stat.isDirectory); + const isHiddenResource = globMatch ? true : this.isIgnored(stat.resource, stat.root.resource, stat.isDirectory); if (isHiddenResource || stat.parent?.isExcluded) { stat.isExcluded = true; const editors = this.editorService.visibleEditors; @@ -1781,7 +1772,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { onDragStart(data: IDragAndDropData, originalEvent: DragEvent): void { const items = FileDragAndDrop.getStatsFromDragAndDropData(data as ElementsDragAndDropData, originalEvent); - if (items && items.length && originalEvent.dataTransfer) { + if (items.length && originalEvent.dataTransfer) { // Apply some datatransfer types to allow for dragging the element outside of the application this.instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, items, originalEvent)); diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index b46e3b12fe2..e276393c2e1 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -321,7 +321,7 @@ export class OpenEditorsView extends ViewPane { dirtyEditorFocusedContext.set(element.editor.isDirty() && !element.editor.isSaving()); readonlyEditorFocusedContext.set(!!element.editor.isReadonly()); resourceContext.set(resource ?? null); - } else if (!!element) { + } else if (element) { groupFocusedContext.set(true); } })); diff --git a/src/vs/workbench/contrib/files/common/explorerFileNestingTrie.ts b/src/vs/workbench/contrib/files/common/explorerFileNestingTrie.ts index 34c11e94e2a..4e5fa25a2ec 100644 --- a/src/vs/workbench/contrib/files/common/explorerFileNestingTrie.ts +++ b/src/vs/workbench/contrib/files/common/explorerFileNestingTrie.ts @@ -110,8 +110,6 @@ export class PreTrie { private map: Map = new Map(); - constructor() { } - add(key: string, value: string) { if (key === '') { this.value.add(key, value); @@ -161,8 +159,6 @@ export class SufTrie { private map: Map = new Map(); hasItems: boolean = false; - constructor() { } - add(key: string, value: string) { this.hasItems = true; if (key === '*') { diff --git a/src/vs/workbench/contrib/markers/browser/markersView.ts b/src/vs/workbench/contrib/markers/browser/markersView.ts index d62dbd05f11..61aec18cdc7 100644 --- a/src/vs/workbench/contrib/markers/browser/markersView.ts +++ b/src/vs/workbench/contrib/markers/browser/markersView.ts @@ -46,7 +46,7 @@ import { ResourceListDnDHandler } from '../../../browser/dnd.js'; import { ResourceLabels } from '../../../browser/labels.js'; import { FilterViewPane, IViewPaneOptions } from '../../../browser/parts/views/viewPane.js'; import { EditorResourceAccessor, SideBySideEditor } from '../../../common/editor.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { IViewDescriptorService } from '../../../common/views.js'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from '../../../services/editor/common/editorService.js'; import { Markers, MarkersContextKeys, MarkersViewMode } from '../common/markers.js'; @@ -67,6 +67,18 @@ function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterab }); } +interface IMarkersPanelState { + filter?: string; + filterHistory?: string[]; + showErrors?: boolean; + showWarnings?: boolean; + showInfos?: boolean; + useFilesExclude?: boolean; + activeFile?: boolean; + multiline?: boolean; + viewMode?: MarkersViewMode; +} + export interface IProblemsWidget { get contextKeyService(): IContextKeyService; @@ -115,8 +127,8 @@ export class MarkersView extends FilterViewPane implements IMarkersView { private currentHeight = 0; private currentWidth = 0; - private readonly memento: Memento; - private readonly panelState: MementoObject; + private readonly memento: Memento; + private readonly panelState: IMarkersPanelState; private cachedFilterStats: { total: number; filtered: number } | undefined = undefined; @@ -142,7 +154,7 @@ export class MarkersView extends FilterViewPane implements IMarkersView { @IThemeService themeService: IThemeService, @IHoverService hoverService: IHoverService, ) { - const memento = new Memento(Markers.MARKERS_VIEW_STORAGE_ID, storageService); + const memento = new Memento(Markers.MARKERS_VIEW_STORAGE_ID, storageService); const panelState = memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); super({ ...options, @@ -150,15 +162,15 @@ export class MarkersView extends FilterViewPane implements IMarkersView { ariaLabel: Messages.MARKERS_PANEL_FILTER_ARIA_LABEL, placeholder: Messages.MARKERS_PANEL_FILTER_PLACEHOLDER, focusContextKey: MarkersContextKeys.MarkerViewFilterFocusContextKey.key, - text: panelState['filter'] || '', - history: panelState['filterHistory'] || [] + text: panelState.filter || '', + history: panelState.filterHistory || [] } }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService); this.memento = memento; this.panelState = panelState; this.markersModel = this._register(instantiationService.createInstance(MarkersModel)); - this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline'], this.panelState['viewMode'] ?? this.getDefaultViewMode())); + this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState.multiline, this.panelState.viewMode ?? this.getDefaultViewMode())); this._register(this.onDidChangeVisibility(visible => this.onDidChangeMarkersViewVisibility(visible))); this._register(this.markersViewModel.onDidChangeViewMode(_ => this.onDidChangeViewMode())); @@ -171,12 +183,12 @@ export class MarkersView extends FilterViewPane implements IMarkersView { this.rangeHighlightDecorations = this._register(this.instantiationService.createInstance(RangeHighlightDecorations)); this.filters = this._register(new MarkersFilters({ - filterHistory: this.panelState['filterHistory'] || [], - showErrors: this.panelState['showErrors'] !== false, - showWarnings: this.panelState['showWarnings'] !== false, - showInfos: this.panelState['showInfos'] !== false, - excludedFiles: !!this.panelState['useFilesExclude'], - activeFile: !!this.panelState['activeFile'], + filterHistory: this.panelState.filterHistory || [], + showErrors: this.panelState.showErrors !== false, + showWarnings: this.panelState.showWarnings !== false, + showInfos: this.panelState.showInfos !== false, + excludedFiles: !!this.panelState.useFilesExclude, + activeFile: !!this.panelState.activeFile, }, this.contextKeyService)); // Update filter, whenever the "files.exclude" setting is changed @@ -884,15 +896,15 @@ export class MarkersView extends FilterViewPane implements IMarkersView { } override saveState(): void { - this.panelState['filter'] = this.filterWidget.getFilterText(); - this.panelState['filterHistory'] = this.filters.filterHistory; - this.panelState['showErrors'] = this.filters.showErrors; - this.panelState['showWarnings'] = this.filters.showWarnings; - this.panelState['showInfos'] = this.filters.showInfos; - this.panelState['useFilesExclude'] = this.filters.excludedFiles; - this.panelState['activeFile'] = this.filters.activeFile; - this.panelState['multiline'] = this.markersViewModel.multiline; - this.panelState['viewMode'] = this.markersViewModel.viewMode; + this.panelState.filter = this.filterWidget.getFilterText(); + this.panelState.filterHistory = this.filters.filterHistory; + this.panelState.showErrors = this.filters.showErrors; + this.panelState.showWarnings = this.filters.showWarnings; + this.panelState.showInfos = this.filters.showInfos; + this.panelState.useFilesExclude = this.filters.excludedFiles; + this.panelState.activeFile = this.filters.activeFile; + this.panelState.multiline = this.markersViewModel.multiline; + this.panelState.viewMode = this.markersViewModel.viewMode; this.memento.saveMemento(); super.saveState(); diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts b/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts index dea7c33359e..07a95e55229 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/gettingStarted/notebookGettingStarted.ts @@ -24,6 +24,11 @@ import { LifecyclePhase } from '../../../../../services/lifecycle/common/lifecyc const hasOpenedNotebookKey = 'hasOpenedNotebook'; const hasShownGettingStartedKey = 'hasShownNotebookGettingStarted'; +interface INotebookGettingStartedMemento { + hasOpenedNotebook?: boolean; + hasShownNotebookGettingStarted?: boolean; +} + /** * Sets a context key when a notebook has ever been opened by the user */ @@ -39,7 +44,7 @@ export class NotebookGettingStarted extends Disposable implements IWorkbenchCont super(); const hasOpenedNotebook = HAS_OPENED_NOTEBOOK.bindTo(_contextKeyService); - const memento = new Memento('notebookGettingStarted2', _storageService); + const memento = new Memento('notebookGettingStarted2', _storageService); const storedValue = memento.getMemento(StorageScope.PROFILE, StorageTarget.USER); if (storedValue[hasOpenedNotebookKey]) { hasOpenedNotebook.set(true); @@ -89,7 +94,7 @@ registerAction2(class NotebookClearNotebookLayoutAction extends Action2 { } run(accessor: ServicesAccessor): void { const storageService = accessor.get(IStorageService); - const memento = new Memento('notebookGettingStarted', storageService); + const memento = new Memento('notebookGettingStarted', storageService); const storedValue = memento.getMemento(StorageScope.PROFILE, StorageTarget.USER); storedValue[hasOpenedNotebookKey] = undefined; diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookKeymapServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookKeymapServiceImpl.ts index 0e68bf1e0fd..b0dcc87a4e0 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookKeymapServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookKeymapServiceImpl.ts @@ -16,7 +16,7 @@ import { ILifecycleService } from '../../../../services/lifecycle/common/lifecyc import { IExtensionIdentifier, IExtensionManagementService, InstallOperation } from '../../../../../platform/extensionManagement/common/extensionManagement.js'; import { areSameExtensions } from '../../../../../platform/extensionManagement/common/extensionManagementUtil.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../../platform/storage/common/storage.js'; -import { Memento, MementoObject } from '../../../../common/memento.js'; +import { Memento } from '../../../../common/memento.js'; import { distinct } from '../../../../../base/common/arrays.js'; function onExtensionChanged(accessor: ServicesAccessor): Event { @@ -43,11 +43,15 @@ function onExtensionChanged(accessor: ServicesAccessor): Event; + private notebookKeymap: NotebookKeymapMemento; constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts index 7d7136f41e3..7cb95efe2a6 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts @@ -22,7 +22,7 @@ import { IResourceEditorInput } from '../../../../../platform/editor/common/edit import { IFileService } from '../../../../../platform/files/common/files.js'; import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../../platform/storage/common/storage.js'; -import { Memento, MementoObject } from '../../../../common/memento.js'; +import { Memento } from '../../../../common/memento.js'; import { INotebookEditorContribution, notebookPreloadExtensionPoint, notebookRendererExtensionPoint, notebooksExtensionPoint } from '../notebookExtensionPoint.js'; import { INotebookEditorOptions } from '../notebookBrowser.js'; import { NotebookDiffEditorInput } from '../../common/notebookDiffEditorInput.js'; @@ -50,12 +50,16 @@ import { CancellationToken } from '../../../../../base/common/cancellation.js'; import { CancellationError } from '../../../../../base/common/errors.js'; import { ICellRange } from '../../common/notebookRange.js'; +interface NotebookProviderInfoStoreMemento { + editors: NotebookProviderInfo[]; +} + export class NotebookProviderInfoStore extends Disposable { private static readonly CUSTOM_EDITORS_STORAGE_ID = 'notebookEditors'; private static readonly CUSTOM_EDITORS_ENTRY_ID = 'editors'; - private readonly _memento: Memento; + private readonly _memento: Memento; private _handled: boolean = false; private readonly _contributedEditors = new Map(); @@ -411,10 +415,14 @@ export class NotebookProviderInfoStore extends Disposable { } } +interface NotebookOutputRendererInfoStoreMemento { + [notebookType: string]: { [mimeType: string]: string } | undefined; +} + export class NotebookOutputRendererInfoStore { private readonly contributedRenderers = new Map(); - private readonly preferredMimetypeMemento: Memento; - private readonly preferredMimetype = new Lazy<{ [notebookType: string]: { [mimeType: string]: /* rendererId */ string } }>( + private readonly preferredMimetypeMemento: Memento; + private readonly preferredMimetype = new Lazy( () => this.preferredMimetypeMemento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE)); constructor( @@ -517,12 +525,16 @@ class ModelData implements IDisposable, INotebookDocument { } } +interface NotebookServiceMemento { + [viewType: string]: string | undefined; +} + export class NotebookService extends Disposable implements INotebookService { declare readonly _serviceBrand: undefined; private static _storageNotebookViewTypeProvider = 'notebook.viewTypeProvider'; - private readonly _memento: Memento; - private readonly _viewTypeCache: MementoObject; + private readonly _memento: Memento; + private readonly _viewTypeCache: NotebookServiceMemento; private readonly _notebookProviders; private _notebookProviderInfoStore: NotebookProviderInfoStore | undefined; diff --git a/src/vs/workbench/contrib/output/browser/outputView.ts b/src/vs/workbench/contrib/output/browser/outputView.ts index 934ea7a8bf2..cf69f38c55e 100644 --- a/src/vs/workbench/contrib/output/browser/outputView.ts +++ b/src/vs/workbench/contrib/output/browser/outputView.ts @@ -44,12 +44,22 @@ import { IEditorContribution, IEditorDecorationsCollection } from '../../../../e import { IModelDeltaDecoration, ITextModel } from '../../../../editor/common/model.js'; import { Range } from '../../../../editor/common/core/range.js'; import { FindDecorations } from '../../../../editor/contrib/find/browser/findDecorations.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { Markers } from '../../markers/common/markers.js'; import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js'; import { viewFilterSubmenu } from '../../../browser/parts/views/viewFilter.js'; import { escapeRegExpCharacters } from '../../../../base/common/strings.js'; +interface IOutputViewState { + filter?: string; + showTrace?: boolean; + showDebug?: boolean; + showInfo?: boolean; + showWarning?: boolean; + showError?: boolean; + categories?: string; +} + export class OutputViewPane extends FilterViewPane { private readonly editor: OutputEditor; @@ -60,8 +70,8 @@ export class OutputViewPane extends FilterViewPane { get scrollLock(): boolean { return !!this.scrollLockContextKey.get(); } set scrollLock(scrollLock: boolean) { this.scrollLockContextKey.set(scrollLock); } - private readonly memento: Memento; - private readonly panelState: MementoObject; + private readonly memento: Memento; + private readonly panelState: IOutputViewState; constructor( options: IViewPaneOptions, @@ -77,14 +87,14 @@ export class OutputViewPane extends FilterViewPane { @IOutputService private readonly outputService: IOutputService, @IStorageService storageService: IStorageService, ) { - const memento = new Memento(Markers.MARKERS_VIEW_STORAGE_ID, storageService); + const memento = new Memento(Markers.MARKERS_VIEW_STORAGE_ID, storageService); const viewState = memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); super({ ...options, filterOptions: { placeholder: localize('outputView.filter.placeholder', "Filter"), focusContextKey: OUTPUT_FILTER_FOCUS_CONTEXT.key, - text: viewState['filter'] || '', + text: viewState.filter || '', history: [] } }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService); @@ -92,13 +102,13 @@ export class OutputViewPane extends FilterViewPane { this.panelState = viewState; const filters = outputService.filters; - filters.text = this.panelState['filter'] || ''; - filters.trace = this.panelState['showTrace'] ?? true; - filters.debug = this.panelState['showDebug'] ?? true; - filters.info = this.panelState['showInfo'] ?? true; - filters.warning = this.panelState['showWarning'] ?? true; - filters.error = this.panelState['showError'] ?? true; - filters.categories = this.panelState['categories'] ?? ''; + filters.text = this.panelState.filter || ''; + filters.trace = this.panelState.showTrace ?? true; + filters.debug = this.panelState.showDebug ?? true; + filters.info = this.panelState.showInfo ?? true; + filters.warning = this.panelState.showWarning ?? true; + filters.error = this.panelState.showError ?? true; + filters.categories = this.panelState.categories ?? ''; this.scrollLockContextKey = CONTEXT_OUTPUT_SCROLL_LOCK.bindTo(this.contextKeyService); @@ -202,13 +212,13 @@ export class OutputViewPane extends FilterViewPane { override saveState(): void { const filters = this.outputService.filters; - this.panelState['filter'] = filters.text; - this.panelState['showTrace'] = filters.trace; - this.panelState['showDebug'] = filters.debug; - this.panelState['showInfo'] = filters.info; - this.panelState['showWarning'] = filters.warning; - this.panelState['showError'] = filters.error; - this.panelState['categories'] = filters.categories; + this.panelState.filter = filters.text; + this.panelState.showTrace = filters.trace; + this.panelState.showDebug = filters.debug; + this.panelState.showInfo = filters.info; + this.panelState.showWarning = filters.warning; + this.panelState.showError = filters.error; + this.panelState.categories = filters.categories; this.memento.saveMemento(); super.saveState(); diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index 5bfdf4536f1..076761078d5 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -67,7 +67,11 @@ import { IAccessibilityService } from '../../../../platform/accessibility/common const $ = DOM.$; -export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorPane { +interface IKeybindingsEditorMemento { + searchHistory?: string[]; +} + +export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorPane { static readonly ID: string = 'workbench.editor.keybindings'; @@ -365,7 +369,7 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP ariaLabelledBy: 'keybindings-editor-aria-label-element', recordEnter: true, quoteRecordedKeys: true, - history: new Set(this.getMemento(StorageScope.PROFILE, StorageTarget.USER)['searchHistory'] ?? []), + history: new Set((this.getMemento(StorageScope.PROFILE, StorageTarget.USER)).searchHistory ?? []), inputBoxStyles: getInputBoxStyle({ inputBorder: settingsTextInputBorder }) @@ -578,14 +582,14 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP this.renderKeybindingsEntries(this.searchWidget.hasFocus()); this.searchHistoryDelayer.trigger(() => { this.searchWidget.inputBox.addToHistory(); - this.getMemento(StorageScope.PROFILE, StorageTarget.USER)['searchHistory'] = this.searchWidget.inputBox.getHistory(); + (this.getMemento(StorageScope.PROFILE, StorageTarget.USER)).searchHistory = this.searchWidget.inputBox.getHistory(); this.saveState(); }); } public clearKeyboardShortcutSearchHistory(): void { this.searchWidget.inputBox.clearHistory(); - this.getMemento(StorageScope.PROFILE, StorageTarget.USER)['searchHistory'] = this.searchWidget.inputBox.getHistory(); + (this.getMemento(StorageScope.PROFILE, StorageTarget.USER)).searchHistory = this.searchWidget.inputBox.getHistory(); this.saveState(); } diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 94cedd1af7e..c90211bf5f9 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -52,7 +52,7 @@ import { ResourceListDnDHandler } from '../../../browser/dnd.js'; import { ResourceLabels } from '../../../browser/labels.js'; import { IViewPaneOptions, ViewPane } from '../../../browser/parts/views/viewPane.js'; import { IEditorPane } from '../../../common/editor.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { IViewDescriptorService } from '../../../common/views.js'; import { NotebookEditor } from '../../notebook/browser/notebookEditor.js'; import { ExcludePatternInputWidget, IncludePatternInputWidget } from './patternInputWidget.js'; @@ -93,6 +93,35 @@ export enum SearchViewPosition { Panel } +interface ISearchViewStateQuery { + contentPattern?: string; + replaceText?: string | false; + regex?: boolean; + wholeWords?: boolean; + caseSensitive?: boolean; + filePatterns?: string; + folderExclusions?: string; + folderIncludes?: string; + onlyOpenEditors?: boolean; + queryDetailsExpanded?: string | boolean; + useExcludesAndIgnoreFiles?: boolean; + preserveCase?: boolean; + searchHistory?: string[]; + replaceHistory?: string[]; + isInNotebookMarkdownInput?: boolean; + isInNotebookMarkdownPreview?: boolean; + isInNotebookCellInput?: boolean; + isInNotebookCellOutput?: boolean; +} + +interface ISearchViewState { + query?: ISearchViewStateQuery; + view?: { + showReplace?: boolean; + treeLayout?: boolean; + }; +} + const SEARCH_CANCELLED_MESSAGE = nls.localize('searchCanceled', "Search was canceled before any results could be found - "); const DEBOUNCE_DELAY = 75; export class SearchView extends ViewPane { @@ -104,7 +133,7 @@ export class SearchView extends ViewPane { private container!: HTMLElement; private queryBuilder: QueryBuilder; private viewModel: ISearchModel; - private memento: Memento; + private memento: Memento; private viewletVisible: IContextKey; private inputBoxFocused: IContextKey; @@ -131,7 +160,7 @@ export class SearchView extends ViewPane { private tree!: WorkbenchCompressibleAsyncDataTree; private treeLabels!: ResourceLabels; - private viewletState: MementoObject; + private viewletState: ISearchViewState; private messagesElement!: HTMLElement; private readonly messageDisposables: DisposableStore = new DisposableStore(); private searchWidgetsContainerElement!: HTMLElement; @@ -280,7 +309,7 @@ export class SearchView extends ViewPane { this.triggerQueryDelayer = this._register(new Delayer(0)); this.treeAccessibilityProvider = this.instantiationService.createInstance(SearchAccessibilityProvider, this); - this.isTreeLayoutViewVisible = this.viewletState['view.treeLayout'] ?? (this.searchConfig.defaultViewMode === ViewMode.Tree); + this.isTreeLayoutViewVisible = this.viewletState.view?.treeLayout ?? (this.searchConfig.defaultViewMode === ViewMode.Tree); this._refreshResultsScheduler = this._register(new RunOnceScheduler(this._updateResults.bind(this), 80)); @@ -431,16 +460,16 @@ export class SearchView extends ViewPane { this.createSearchWidget(this.searchWidgetsContainerElement); const history = this.searchHistoryService.load(); - const filePatterns = this.viewletState['query.filePatterns'] || ''; - const patternExclusions = this.viewletState['query.folderExclusions'] || ''; + const filePatterns = this.viewletState.query?.filePatterns || ''; + const patternExclusions = this.viewletState.query?.folderExclusions || ''; const patternExclusionsHistory: string[] = history.exclude || []; - const patternIncludes = this.viewletState['query.folderIncludes'] || ''; + const patternIncludes = this.viewletState.query?.folderIncludes || ''; const patternIncludesHistory: string[] = history.include || []; - const onlyOpenEditors = this.viewletState['query.onlyOpenEditors'] || false; + const onlyOpenEditors = this.viewletState.query?.onlyOpenEditors || false; - const queryDetailsExpanded = this.viewletState['query.queryDetailsExpanded'] || ''; - const useExcludesAndIgnoreFiles = typeof this.viewletState['query.useExcludesAndIgnoreFiles'] === 'boolean' ? - this.viewletState['query.useExcludesAndIgnoreFiles'] : true; + const queryDetailsExpanded = this.viewletState.query?.queryDetailsExpanded || ''; + const useExcludesAndIgnoreFiles = typeof this.viewletState.query?.useExcludesAndIgnoreFiles === 'boolean' ? + this.viewletState.query.useExcludesAndIgnoreFiles : true; this.queryDetails = dom.append(this.searchWidgetsContainerElement, $('.query-details')); @@ -590,22 +619,21 @@ export class SearchView extends ViewPane { } private createSearchWidget(container: HTMLElement): void { - const contentPattern = this.viewletState['query.contentPattern'] || ''; - const replaceText = this.viewletState['query.replaceText'] || ''; - const isRegex = this.viewletState['query.regex'] === true; - const isWholeWords = this.viewletState['query.wholeWords'] === true; - const isCaseSensitive = this.viewletState['query.caseSensitive'] === true; + const contentPattern = this.viewletState.query?.contentPattern || ''; + const replaceText = this.viewletState.query?.replaceText || ''; + const isRegex = this.viewletState.query?.regex === true; + const isWholeWords = this.viewletState.query?.wholeWords === true; + const isCaseSensitive = this.viewletState.query?.caseSensitive === true; const history = this.searchHistoryService.load(); - const searchHistory = history.search || this.viewletState['query.searchHistory'] || []; - const replaceHistory = history.replace || this.viewletState['query.replaceHistory'] || []; - const showReplace = typeof this.viewletState['view.showReplace'] === 'boolean' ? this.viewletState['view.showReplace'] : true; - const preserveCase = this.viewletState['query.preserveCase'] === true; - - const isInNotebookMarkdownInput = this.viewletState['query.isInNotebookMarkdownInput'] ?? true; - const isInNotebookMarkdownPreview = this.viewletState['query.isInNotebookMarkdownPreview'] ?? true; - const isInNotebookCellInput = this.viewletState['query.isInNotebookCellInput'] ?? true; - const isInNotebookCellOutput = this.viewletState['query.isInNotebookCellOutput'] ?? true; + const searchHistory = history.search || this.viewletState.query?.searchHistory || []; + const replaceHistory = history.replace || this.viewletState.query?.replaceHistory || []; + const showReplace = typeof this.viewletState.view?.showReplace === 'boolean' ? this.viewletState.view.showReplace : true; + const preserveCase = this.viewletState.query?.preserveCase === true; + const isInNotebookMarkdownInput = this.viewletState.query?.isInNotebookMarkdownInput ?? true; + const isInNotebookMarkdownPreview = this.viewletState.query?.isInNotebookMarkdownPreview ?? true; + const isInNotebookCellInput = this.viewletState.query?.isInNotebookCellInput ?? true; + const isInNotebookCellOutput = this.viewletState.query?.isInNotebookCellOutput ?? true; this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, container, { value: contentPattern, @@ -1460,14 +1488,15 @@ export class SearchView extends ViewPane { } toggleQueryDetails(moveFocus = true, show?: boolean, skipLayout?: boolean, reverse?: boolean): void { - const cls = 'more'; - show = typeof show === 'undefined' ? !this.queryDetails.classList.contains(cls) : Boolean(show); - this.viewletState['query.queryDetailsExpanded'] = show; + show = typeof show === 'undefined' ? !this.queryDetails.classList.contains('more') : Boolean(show); + if (!this.viewletState.query) { + this.viewletState.query = {}; + } + this.viewletState.query.queryDetailsExpanded = show; skipLayout = Boolean(skipLayout); - if (show) { this.toggleQueryDetailsButton.setAttribute('aria-expanded', 'true'); - this.queryDetails.classList.add(cls); + this.queryDetails.classList.add('more'); if (moveFocus) { if (reverse) { this.inputPatternExcludes.focus(); @@ -1479,7 +1508,7 @@ export class SearchView extends ViewPane { } } else { this.toggleQueryDetailsButton.setAttribute('aria-expanded', 'false'); - this.queryDetails.classList.remove(cls); + this.queryDetails.classList.remove('more'); if (moveFocus) { this.searchWidget.focus(); } @@ -2320,6 +2349,10 @@ export class SearchView extends ViewPane { const useExcludesAndIgnoreFiles = this.inputPatternExcludes?.useExcludesAndIgnoreFiles() ?? true; const preserveCase = this.viewModel.preserveCase; + if (!this.viewletState.query) { + this.viewletState.query = {}; + } + if (this.searchWidget.searchInput) { const isRegex = this.searchWidget.searchInput.getRegex(); const isWholeWords = this.searchWidget.searchInput.getWholeWords(); @@ -2331,27 +2364,32 @@ export class SearchView extends ViewPane { const isInNotebookMarkdownInput = this.searchWidget.getNotebookFilters().markupInput; const isInNotebookMarkdownPreview = this.searchWidget.getNotebookFilters().markupPreview; - this.viewletState['query.contentPattern'] = contentPattern; - this.viewletState['query.regex'] = isRegex; - this.viewletState['query.wholeWords'] = isWholeWords; - this.viewletState['query.caseSensitive'] = isCaseSensitive; + this.viewletState.query.contentPattern = contentPattern; + this.viewletState.query.regex = isRegex; + this.viewletState.query.wholeWords = isWholeWords; + this.viewletState.query.caseSensitive = isCaseSensitive; - this.viewletState['query.isInNotebookMarkdownInput'] = isInNotebookMarkdownInput; - this.viewletState['query.isInNotebookMarkdownPreview'] = isInNotebookMarkdownPreview; - this.viewletState['query.isInNotebookCellInput'] = isInNotebookCellInput; - this.viewletState['query.isInNotebookCellOutput'] = isInNotebookCellOutput; + this.viewletState.query.isInNotebookMarkdownInput = isInNotebookMarkdownInput; + this.viewletState.query.isInNotebookMarkdownPreview = isInNotebookMarkdownPreview; + this.viewletState.query.isInNotebookCellInput = isInNotebookCellInput; + this.viewletState.query.isInNotebookCellOutput = isInNotebookCellOutput; } - this.viewletState['query.folderExclusions'] = patternExcludes; - this.viewletState['query.folderIncludes'] = patternIncludes; - this.viewletState['query.useExcludesAndIgnoreFiles'] = useExcludesAndIgnoreFiles; - this.viewletState['query.preserveCase'] = preserveCase; - this.viewletState['query.onlyOpenEditors'] = onlyOpenEditors; + this.viewletState.query.folderExclusions = patternExcludes; + this.viewletState.query.folderIncludes = patternIncludes; + this.viewletState.query.useExcludesAndIgnoreFiles = useExcludesAndIgnoreFiles; + this.viewletState.query.preserveCase = preserveCase; + this.viewletState.query.onlyOpenEditors = onlyOpenEditors; const isReplaceShown = this.searchAndReplaceWidget.isReplaceShown(); - this.viewletState['view.showReplace'] = isReplaceShown; - this.viewletState['view.treeLayout'] = this.isTreeLayoutViewVisible; - this.viewletState['query.replaceText'] = isReplaceShown && this.searchWidget.getReplaceValue(); + + if (!this.viewletState.view) { + this.viewletState.view = {}; + } + + this.viewletState.view.showReplace = isReplaceShown; + this.viewletState.view.treeLayout = this.isTreeLayoutViewVisible; + this.viewletState.query.replaceText = isReplaceShown && this.searchWidget.getReplaceValue(); this._saveSearchHistoryService(); diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index e514db6bb60..16046e1e4e7 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -64,7 +64,7 @@ export class SearchEditorInput extends EditorInput { return capabilities; } - private memento: Memento; + private memento: Memento<{ searchConfig: SearchConfiguration }>; private dirty: boolean = false; @@ -362,7 +362,7 @@ export const getOrMakeSearchEditorInput = ( const reuseOldSettings = searchEditorSettings.reusePriorSearchConfiguration; const defaultNumberOfContextLines = searchEditorSettings.defaultNumberOfContextLines; - const priorConfig: SearchConfiguration = reuseOldSettings ? new Memento(SearchEditorInput.ID, storageService).getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE).searchConfig : {}; + const priorConfig = reuseOldSettings ? new Memento<{ searchConfig?: SearchConfiguration }>(SearchEditorInput.ID, storageService).getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE).searchConfig ?? {} : {}; const defaultConfig = defaultSearchConfig(); const config = { ...defaultConfig, ...priorConfig, ...existingData.config }; diff --git a/src/vs/workbench/contrib/webview/browser/webview.ts b/src/vs/workbench/contrib/webview/browser/webview.ts index 49f49e0c258..936b635aa6c 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.ts @@ -18,7 +18,7 @@ import { ExtensionIdentifier } from '../../../../platform/extensions/common/exte import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; import { IWebviewPortMapping } from '../../../../platform/webview/common/webviewPortMapping.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; /** * Set when the find widget in a webview in a webview is visible. @@ -348,8 +348,8 @@ export interface IOverlayWebview extends IWebview { */ export class WebviewOriginStore { - private readonly _memento: Memento; - private readonly _state: MementoObject; + private readonly _memento: Memento>; + private readonly _state: Record; constructor( rootStorageKey: string, diff --git a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts index 5ec6e750839..cfb107654c8 100644 --- a/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts +++ b/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.ts @@ -20,7 +20,7 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo import { IThemeService } from '../../../../platform/theme/common/themeService.js'; import { ViewPane, ViewPaneShowActions } from '../../../browser/parts/views/viewPane.js'; import { IViewletViewOptions } from '../../../browser/parts/views/viewsViewlet.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { IViewBadge, IViewDescriptorService } from '../../../common/views.js'; import { IViewsService } from '../../../services/views/common/viewsService.js'; import { ExtensionKeyedWebviewOriginStore, IOverlayWebview, IWebviewService, WebviewContentPurpose } from '../../webview/browser/webview.js'; @@ -34,6 +34,10 @@ const storageKeys = { webviewState: 'webviewState', } as const; +interface WebviewViewState { + [storageKeys.webviewState]?: string | undefined; +} + export class WebviewViewPane extends ViewPane { private static _originStore?: ExtensionKeyedWebviewOriginStore; @@ -57,8 +61,8 @@ export class WebviewViewPane extends ViewPane { private badge: IViewBadge | undefined; private readonly activity = this._register(new MutableDisposable()); - private readonly memento: Memento; - private readonly viewState: MementoObject; + private readonly memento: Memento; + private readonly viewState: WebviewViewState; private readonly extensionId?: ExtensionIdentifier; private _repositionTimeout?: Timeout; diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts index ea52ece81c1..d672ea7b95e 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService.ts @@ -130,7 +130,7 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ private readonly _onDidProgressStep = new Emitter(); readonly onDidProgressStep: Event = this._onDidProgressStep.event; - private memento: Memento; + private memento: Memento>; private stepProgress: Record; private sessionEvents = new Set(); diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index b542b8d7344..cdea22c73a4 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -21,7 +21,7 @@ import { INativeHostService } from '../../../platform/native/common/native.js'; import { Codicon } from '../../../base/common/codicons.js'; import { ThemeIcon } from '../../../base/common/themables.js'; import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from '../../../platform/workspace/common/workspace.js'; -import { Action2, IAction2Options, MenuId } from '../../../platform/actions/common/actions.js'; +import { Action2, MenuId } from '../../../platform/actions/common/actions.js'; import { Categories } from '../../../platform/action/common/actionCommonCategories.js'; import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; @@ -70,10 +70,6 @@ abstract class BaseZoomAction extends Action2 { private static readonly ZOOM_LEVEL_SETTING_KEY = 'window.zoomLevel'; private static readonly ZOOM_PER_WINDOW_SETTING_KEY = 'window.zoomPerWindow'; - constructor(desc: Readonly) { - super(desc); - } - protected async setZoomLevel(accessor: ServicesAccessor, levelOrReset: number | true): Promise { const configurationService = accessor.get(IConfigurationService); @@ -220,10 +216,6 @@ abstract class BaseSwitchWindow extends Action2 { alwaysVisible: true }; - constructor(desc: Readonly) { - super(desc); - } - protected abstract isQuickNavigate(): boolean; override async run(accessor: ServicesAccessor): Promise { diff --git a/src/vs/workbench/electron-browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/electron-browser/parts/titlebar/titlebarPart.ts index 5acf8788abb..bd903f55933 100644 --- a/src/vs/workbench/electron-browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/electron-browser/parts/titlebar/titlebarPart.ts @@ -13,7 +13,7 @@ import { INativeWorkbenchEnvironmentService } from '../../../services/environmen import { IHostService } from '../../../services/host/browser/host.js'; import { isMacintosh, isWindows, isLinux, isBigSurOrNewer } from '../../../../base/common/platform.js'; import { IMenuService, MenuId } from '../../../../platform/actions/common/actions.js'; -import { BrowserTitlebarPart as BrowserTitlebarPart, BrowserTitleService, IAuxiliaryTitlebarPart } from '../../../browser/parts/titlebar/titlebarPart.js'; +import { BrowserTitlebarPart, BrowserTitleService, IAuxiliaryTitlebarPart } from '../../../browser/parts/titlebar/titlebarPart.js'; import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js'; import { IThemeService } from '../../../../platform/theme/common/themeService.js'; import { IWorkbenchLayoutService, Parts } from '../../../services/layout/browser/layoutService.js'; @@ -125,11 +125,9 @@ export class NativeTitlebarPart extends BrowserTitlebarPart { private onUpdateAppIconDragBehavior(): void { const setting = this.configurationService.getValue('window.doubleClickIconToClose'); if (setting && this.appIcon) { - // eslint-disable-next-line local/code-no-any-casts - (this.appIcon.style as any)['-webkit-app-region'] = 'no-drag'; + (this.appIcon.style as CSSStyleDeclaration & { '-webkit-app-region': string })['-webkit-app-region'] = 'no-drag'; } else if (this.appIcon) { - // eslint-disable-next-line local/code-no-any-casts - (this.appIcon.style as any)['-webkit-app-region'] = 'drag'; + (this.appIcon.style as CSSStyleDeclaration & { '-webkit-app-region': string })['-webkit-app-region'] = 'drag'; } } diff --git a/src/vs/workbench/services/assignment/common/assignmentService.ts b/src/vs/workbench/services/assignment/common/assignmentService.ts index d57ebc9207b..6d82a59b340 100644 --- a/src/vs/workbench/services/assignment/common/assignmentService.ts +++ b/src/vs/workbench/services/assignment/common/assignmentService.ts @@ -6,7 +6,7 @@ import { localize } from '../../../../nls.js'; import { createDecorator, IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import type { IKeyValueStorage, IExperimentationTelemetry, ExperimentationService as TASClient } from 'tas-client-umd'; -import { MementoObject, Memento } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { ITelemetryService, TelemetryLevel } from '../../../../platform/telemetry/common/telemetry.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; import { ITelemetryData } from '../../../../base/common/actions.js'; @@ -33,14 +33,14 @@ export interface IWorkbenchAssignmentService extends IAssignmentService { class MementoKeyValueStorage implements IKeyValueStorage { - private readonly mementoObj: MementoObject; + private readonly mementoObj: Record; - constructor(private readonly memento: Memento) { + constructor(private readonly memento: Memento>) { this.mementoObj = memento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE); } async getValue(key: string, defaultValue?: T | undefined): Promise { - const value = await this.mementoObj[key]; + const value = await this.mementoObj[key] as T | undefined; return value || defaultValue; } @@ -136,7 +136,7 @@ export class WorkbenchAssignmentService extends Disposable implements IAssignmen this.telemetry = this._register(new WorkbenchAssignmentServiceTelemetry(telemetryService, productService)); this._register(this.telemetry.onDidUpdateAssignmentContext(() => this._onDidRefetchAssignments.fire())); - this.keyValueStorage = new MementoKeyValueStorage(new Memento('experiment.service.memento', storageService)); + this.keyValueStorage = new MementoKeyValueStorage(new Memento>('experiment.service.memento', storageService)); // For development purposes, configure the delay until tas local tas treatment ovverrides are available const overrideDelaySetting = configurationService.getValue('experiments.overrideDelay'); diff --git a/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts b/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts index 443f02dde9f..c99f5309eea 100644 --- a/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts +++ b/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts @@ -237,7 +237,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService // Normal Menu Item else { let type: 'radio' | 'checkbox' | undefined = undefined; - if (!!entry.checked) { + if (entry.checked) { if (typeof delegate.getCheckedActionsRepresentation === 'function') { type = delegate.getCheckedActionsRepresentation(entry); } else { @@ -262,7 +262,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService } }; - const keybinding = !!delegate.getKeyBinding ? delegate.getKeyBinding(entry) : this.keybindingService.lookupKeybinding(entry.id); + const keybinding = delegate.getKeyBinding ? delegate.getKeyBinding(entry) : this.keybindingService.lookupKeybinding(entry.id); if (keybinding) { const electronAccelerator = keybinding.getElectronAccelerator(); if (electronAccelerator) { diff --git a/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts b/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts index 988cada21b0..20fb991dde8 100644 --- a/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts +++ b/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts @@ -308,7 +308,7 @@ export abstract class AbstractFileDialogService implements IFileDialogService { } protected getFileSystemSchema(options: { availableFileSystems?: readonly string[]; defaultUri?: URI }): string { - return options.availableFileSystems && options.availableFileSystems[0] || this.getSchemeFilterForWindow(options.defaultUri?.scheme); + return options.availableFileSystems?.[0] || this.getSchemeFilterForWindow(options.defaultUri?.scheme); } abstract pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise; diff --git a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts index 4c7a927bd43..478f44398b8 100644 --- a/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts @@ -639,7 +639,7 @@ export class SimpleFileDialog extends Disposable implements ISimpleFileDialog { } catch (e) { // do nothing } - if (stat && stat.isDirectory && (resources.basename(valueUri) !== '.') && this.endsWithSlash(value)) { + if (stat?.isDirectory && (resources.basename(valueUri) !== '.') && this.endsWithSlash(value)) { valueUri = this.tryAddTrailingSeparatorToDirectory(valueUri, stat); return await this.updateItems(valueUri) ? UpdateResult.UpdatedWithTrailing : UpdateResult.Updated; } else if (this.endsWithSlash(value)) { @@ -662,7 +662,7 @@ export class SimpleFileDialog extends Disposable implements ISimpleFileDialog { } catch (e) { // do nothing } - if (statWithoutTrailing && statWithoutTrailing.isDirectory) { + if (statWithoutTrailing?.isDirectory) { this.badPath = undefined; inputUriDirname = this.tryAddTrailingSeparatorToDirectory(inputUriDirname, statWithoutTrailing); return await this.updateItems(inputUriDirname, false, resources.basename(valueUri)) ? UpdateResult.UpdatedWithTrailing : UpdateResult.Updated; @@ -859,7 +859,7 @@ export class SimpleFileDialog extends Disposable implements ISimpleFileDialog { } if (this.requiresTrailing) { // save - if (stat && stat.isDirectory) { + if (stat?.isDirectory) { // Can't do this this.filePickBox.validationMessage = nls.localize('remoteFileDialog.validateFolder', 'The folder already exists. Please use a new file name.'); return Promise.resolve(false); diff --git a/src/vs/workbench/services/editor/browser/editorResolverService.ts b/src/vs/workbench/services/editor/browser/editorResolverService.ts index 821ba3e3ae9..51a1ac08b9b 100644 --- a/src/vs/workbench/services/editor/browser/editorResolverService.ts +++ b/src/vs/workbench/services/editor/browser/editorResolverService.ts @@ -605,7 +605,7 @@ export class EditorResolverService extends Disposable implements IEditorResolver }; // If the user has already made a choice for this editor we don't want to ask them again - if (storedChoices[globForResource] && storedChoices[globForResource].find(editorID => editorID === currentEditor.editorId)) { + if (storedChoices[globForResource]?.find(editorID => editorID === currentEditor.editorId)) { return; } diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index a50ad52689b..ec1a621d29e 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -70,7 +70,7 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi const result: [string, string][] = []; for (const entry of logLevelFromPayload.split(',')) { const matches = EXTENSION_IDENTIFIER_WITH_LOG_REGEX.exec(entry); - if (matches && matches[1] && matches[2]) { + if (matches?.[1] && matches[2]) { result.push([matches[1], matches[2]]); } } diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index dddecccdc52..02e6d4591aa 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -416,7 +416,7 @@ export class BrowserHostService extends Disposable implements IHostService { private preservePayload(isEmptyWindow: boolean, options?: IOpenWindowOptions): Array | undefined { // Selectively copy payload: for now only extension debugging properties are considered - const newPayload: Array = new Array(); + const newPayload: Array = []; if (!isEmptyWindow && this.environmentService.extensionDevelopmentLocationURI) { newPayload.push(['extensionDevelopmentPath', this.environmentService.extensionDevelopmentLocationURI.toString()]); diff --git a/src/vs/workbench/services/host/electron-browser/nativeHostService.ts b/src/vs/workbench/services/host/electron-browser/nativeHostService.ts index cb7dcc810e2..e0e7d669aa2 100644 --- a/src/vs/workbench/services/host/electron-browser/nativeHostService.ts +++ b/src/vs/workbench/services/host/electron-browser/nativeHostService.ts @@ -112,7 +112,7 @@ class WorkbenchHostService extends Disposable implements IHostService { private doOpenWindow(toOpen: IWindowOpenable[], options?: IOpenWindowOptions): Promise { const remoteAuthority = this.environmentService.remoteAuthority; - if (!!remoteAuthority) { + if (remoteAuthority) { toOpen.forEach(openable => openable.label = openable.label || this.getRecentLabel(openable)); if (options?.remoteAuthority === undefined) { diff --git a/src/vs/workbench/services/label/common/labelService.ts b/src/vs/workbench/services/label/common/labelService.ts index c1ffd0a11e3..7aa12c81fa2 100644 --- a/src/vs/workbench/services/label/common/labelService.ts +++ b/src/vs/workbench/services/label/common/labelService.ts @@ -138,7 +138,7 @@ export class LabelService extends Disposable implements ILabelService { private readonly _onDidChangeFormatters = this._register(new Emitter({ leakWarningThreshold: 400 })); readonly onDidChangeFormatters = this._onDidChangeFormatters.event; - private readonly storedFormattersMemento: Memento; + private readonly storedFormattersMemento: Memento; private readonly storedFormatters: IStoredFormatters; private os: OperatingSystem; private userHome: URI | undefined; diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index e58cd1d0ddf..a9cb5d55ba2 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -147,7 +147,7 @@ export class ProgressService extends Disposable implements IProgressService { const [options, progress] = this.windowProgressStack[idx]; const progressTitle = options.title; - const progressMessage = progress.value && progress.value.message; + const progressMessage = progress.value?.message; const progressCommand = (options).command; let text: string; let title: string; diff --git a/src/vs/workbench/services/views/browser/viewsService.ts b/src/vs/workbench/services/views/browser/viewsService.ts index e0662097ef8..4938ebb966b 100644 --- a/src/vs/workbench/services/views/browser/viewsService.ts +++ b/src/vs/workbench/services/views/browser/viewsService.ts @@ -313,7 +313,7 @@ export class ViewsService extends Disposable implements IViewsService { const compositeDescriptor = this.getComposite(viewContainer.id, location!); if (compositeDescriptor) { const paneComposite = await this.openComposite(compositeDescriptor.id, location!) as IPaneComposite | undefined; - if (paneComposite && paneComposite.openView) { + if (paneComposite?.openView) { return paneComposite.openView(id, focus) || null; } else if (focus) { paneComposite?.focus(); @@ -424,7 +424,7 @@ export class ViewsService extends Disposable implements IViewsService { f1: true }); } - public async run(serviceAccessor: ServicesAccessor): Promise { + public async run(serviceAccessor: ServicesAccessor): Promise { const editorGroupService = serviceAccessor.get(IEditorGroupsService); const viewDescriptorService = serviceAccessor.get(IViewDescriptorService); const layoutService = serviceAccessor.get(IWorkbenchLayoutService); @@ -512,7 +512,7 @@ export class ViewsService extends Disposable implements IViewsService { } }); } - public async run(serviceAccessor: ServicesAccessor, options?: { preserveFocus?: boolean }): Promise { + public async run(serviceAccessor: ServicesAccessor, options?: { preserveFocus?: boolean }): Promise { const editorGroupService = serviceAccessor.get(IEditorGroupsService); const viewDescriptorService = serviceAccessor.get(IViewDescriptorService); const layoutService = serviceAccessor.get(IWorkbenchLayoutService); @@ -686,8 +686,7 @@ export class ViewsService extends Disposable implements IViewsService { } private createViewPaneContainer(element: HTMLElement, viewContainer: ViewContainer, viewContainerLocation: ViewContainerLocation, disposables: DisposableStore, instantiationService: IInstantiationService): ViewPaneContainer { - // eslint-disable-next-line local/code-no-any-casts - const viewPaneContainer: ViewPaneContainer = (instantiationService as any).createInstance(viewContainer.ctorDescriptor.ctor, ...(viewContainer.ctorDescriptor.staticArguments || [])); + const viewPaneContainer: ViewPaneContainer = instantiationService.createInstance(viewContainer.ctorDescriptor.ctor, ...(viewContainer.ctorDescriptor.staticArguments || [])); this.viewPaneContainers.set(viewPaneContainer.getId(), viewPaneContainer); disposables.add(toDisposable(() => this.viewPaneContainers.delete(viewPaneContainer.getId()))); diff --git a/src/vs/workbench/services/workingCopy/common/fileWorkingCopyManager.ts b/src/vs/workbench/services/workingCopy/common/fileWorkingCopyManager.ts index 017d52d081e..37562ac6420 100644 --- a/src/vs/workbench/services/workingCopy/common/fileWorkingCopyManager.ts +++ b/src/vs/workbench/services/workingCopy/common/fileWorkingCopyManager.ts @@ -184,7 +184,7 @@ export class FileWorkingCopyManager { const result = await this.saveAs(workingCopy.resource, undefined, options); - return result ? true : false; + return !!result; }, fileService, labelService, logService, workingCopyBackupService, workingCopyService )); diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts index c12163d118e..eedb4a2c02c 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts @@ -572,7 +572,7 @@ export class StoredFileWorkingCopy extend }, true /* dirty (resolved from backup) */); // Restore orphaned flag based on state - if (backup.meta && backup.meta.orphaned) { + if (backup.meta?.orphaned) { this.setOrphaned(true); } } diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts index 8ced7d7bbff..f747a3468ab 100644 --- a/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts +++ b/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts @@ -528,10 +528,6 @@ export class InMemoryWorkingCopyBackupService extends Disposable implements IWor private backups = new ResourceMap<{ typeId: string; content: VSBuffer; meta?: IWorkingCopyBackupMeta }>(); - constructor() { - super(); - } - hasBackupSync(identifier: IWorkingCopyIdentifier, versionId?: number): boolean { const backupResource = this.toBackupResource(identifier); diff --git a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts index be885f55a7d..13df68b01a2 100644 --- a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts @@ -355,7 +355,7 @@ export abstract class AbstractWorkspaceEditingService extends Disposable impleme abstract enterWorkspace(workspaceUri: URI): Promise; protected async doEnterWorkspace(workspaceUri: URI): Promise { - if (!!this.environmentService.extensionTestsLocationURI) { + if (this.environmentService.extensionTestsLocationURI) { throw new Error('Entering a new workspace is not possible in tests.'); } @@ -381,7 +381,7 @@ export abstract class AbstractWorkspaceEditingService extends Disposable impleme private doCopyWorkspaceSettings(toWorkspace: IWorkspaceIdentifier, filter?: (config: IConfigurationPropertySchema) => boolean): Promise { const configurationProperties = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties(); - const targetWorkspaceConfiguration: any = {}; + const targetWorkspaceConfiguration: Record = {}; for (const key of this.configurationService.keys().workspace) { if (configurationProperties[key]) { if (filter && !filter(configurationProperties[key])) { diff --git a/src/vs/workbench/services/workspaces/common/workspaceIdentityService.ts b/src/vs/workbench/services/workspaces/common/workspaceIdentityService.ts index b0f2c10fda3..aa2eb2f78dc 100644 --- a/src/vs/workbench/services/workspaces/common/workspaceIdentityService.ts +++ b/src/vs/workbench/services/workspaces/common/workspaceIdentityService.ts @@ -16,7 +16,7 @@ import { IWorkspaceContextService, IWorkspaceFolder } from '../../../../platform export const IWorkspaceIdentityService = createDecorator('IWorkspaceIdentityService'); export interface IWorkspaceIdentityService { _serviceBrand: undefined; - matches(folders: IWorkspaceStateFolder[], cancellationToken: CancellationToken): Promise<((obj: any) => unknown) | false>; + matches(folders: IWorkspaceStateFolder[], cancellationToken: CancellationToken): Promise<((obj: unknown) => unknown) | false>; getWorkspaceStateFolders(cancellationToken: CancellationToken): Promise; } @@ -40,7 +40,7 @@ export class WorkspaceIdentityService implements IWorkspaceIdentityService { return workspaceStateFolders; } - async matches(incomingWorkspaceFolders: IWorkspaceStateFolder[], cancellationToken: CancellationToken): Promise<((value: any) => unknown) | false> { + async matches(incomingWorkspaceFolders: IWorkspaceStateFolder[], cancellationToken: CancellationToken): Promise<((value: unknown) => unknown) | false> { const incomingToCurrentWorkspaceFolderUris: { [key: string]: string } = {}; const incomingIdentitiesToIncomingWorkspaceFolders: { [key: string]: string } = {}; @@ -107,14 +107,13 @@ export class WorkspaceIdentityService implements IWorkspaceIdentityService { // Recursively look for any URIs in the provided object and // replace them with the URIs of the current workspace folders - const uriReplacer = (obj: any, depth = 0) => { + const uriReplacer = (obj: unknown, depth = 0) => { if (!obj || depth > 200) { return obj; } if (obj instanceof VSBuffer || obj instanceof Uint8Array) { - // eslint-disable-next-line local/code-no-any-casts - return obj; + return obj; } if (URI.isUri(obj)) { @@ -129,7 +128,7 @@ export class WorkspaceIdentityService implements IWorkspaceIdentityService { // walk object for (const key in obj) { if (Object.hasOwnProperty.call(obj, key)) { - obj[key] = uriReplacer(obj[key], depth + 1); + (obj as Record)[key] = uriReplacer((obj as Record)[key], depth + 1); } } } diff --git a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts index e11ae3c24e2..0ab8fb637dd 100644 --- a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts +++ b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts @@ -17,7 +17,7 @@ import { isVirtualResource } from '../../../../platform/workspace/common/virtual import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; import { ISingleFolderWorkspaceIdentifier, isSavedWorkspace, isSingleFolderWorkspaceIdentifier, isTemporaryWorkspace, IWorkspace, IWorkspaceContextService, IWorkspaceFolder, toWorkspaceIdentifier, WorkbenchState } from '../../../../platform/workspace/common/workspace.js'; import { WorkspaceTrustRequestOptions, IWorkspaceTrustManagementService, IWorkspaceTrustInfo, IWorkspaceTrustUriInfo, IWorkspaceTrustRequestService, IWorkspaceTrustTransitionParticipant, WorkspaceTrustUriResponse, IWorkspaceTrustEnablementService } from '../../../../platform/workspace/common/workspaceTrust.js'; -import { Memento, MementoObject } from '../../../common/memento.js'; +import { Memento } from '../../../common/memento.js'; import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js'; import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js'; import { isEqualAuthority } from '../../../../base/common/resources.js'; @@ -850,10 +850,15 @@ class WorkspaceTrustTransitionManager extends Disposable { } } +interface WorkspaceTrustMementoData { + acceptsOutOfWorkspaceFiles?: boolean; + isEmptyWorkspaceTrusted?: boolean | undefined; +} + class WorkspaceTrustMemento { - private readonly _memento?: Memento; - private readonly _mementoObject: MementoObject; + private readonly _memento?: Memento; + private readonly _mementoObject: WorkspaceTrustMementoData; private readonly _acceptsOutOfWorkspaceFilesKey = 'acceptsOutOfWorkspaceFiles'; private readonly _isEmptyWorkspaceTrustedKey = 'isEmptyWorkspaceTrusted'; diff --git a/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts b/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts index 5aacdf29e02..cfdb4074f6c 100644 --- a/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts +++ b/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts @@ -9,7 +9,7 @@ import { InstantiationType, registerSingleton } from '../../../../platform/insta import { ProxyChannel } from '../../../../base/parts/ipc/common/ipc.js'; import { INativeHostService } from '../../../../platform/native/common/native.js'; -// @ts-ignore: interface is implemented via proxy +// @ts-expect-error: interface is implemented via proxy export class NativeWorkspacesService implements IWorkspacesService { declare readonly _serviceBrand: undefined; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index a12332aba7d..f9a599137ff 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -1715,12 +1715,12 @@ export class TestEditorPart extends MainEditorPart implements IEditorGroupsServi } clearState(): void { - const workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); + const workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as Record; for (const key of Object.keys(workspaceMemento)) { delete workspaceMemento[key]; } - const profileMemento = this.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); + const profileMemento = this.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE) as Record; for (const key of Object.keys(profileMemento)) { delete profileMemento[key]; } diff --git a/src/vs/workbench/test/common/memento.test.ts b/src/vs/workbench/test/common/memento.test.ts index 6b7a565e931..389d3d624ba 100644 --- a/src/vs/workbench/test/common/memento.test.ts +++ b/src/vs/workbench/test/common/memento.test.ts @@ -26,7 +26,7 @@ suite('Memento', () => { }); test('Loading and Saving Memento with Scopes', () => { - const myMemento = new Memento('memento.test', storage); + const myMemento = new Memento<{ foo: number[] | string }>('memento.test', storage); // Application let memento = myMemento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE); @@ -101,7 +101,7 @@ suite('Memento', () => { }); test('Save and Load', () => { - const myMemento = new Memento('memento.test', storage); + const myMemento = new Memento<{ foo: number[] | string }>('memento.test', storage); // Profile let memento = myMemento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); @@ -165,8 +165,8 @@ suite('Memento', () => { }); test('Save and Load - 2 Components with same id', () => { - const myMemento = new Memento('memento.test', storage); - const myMemento2 = new Memento('memento.test', storage); + const myMemento = new Memento('memento.test', storage); + const myMemento2 = new Memento('memento.test', storage); // Profile let memento = myMemento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE); @@ -207,7 +207,7 @@ suite('Memento', () => { }); test('Clear Memento', () => { - let myMemento = new Memento('memento.test', storage); + let myMemento = new Memento<{ foo: string; bar: string }>('memento.test', storage); // Profile let profileMemento = myMemento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE);