diff --git a/CHANGELOG.md b/CHANGELOG.md index afce83ff21e56..7641ea362bf2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ - [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/) +## v1.39.0 - 06/29/2023 + +[Breaking Changes:](#breaking_changes_1.39.0) + +- [repo] with the upgrade to Inversify 6.0, a few initialization methods were adjusted. See also [this migration guide entry](https://github.com/eclipse-theia/theia/blob/master/doc/Migration.md#inversify-60). Additionally, other changes include: [#12425](https://github.com/eclipse-theia/theia/pull/12425) + - The type expected by the `PreferenceProxySchema` symbol has been changed from `PromiseLike` to `() => PromiseLike` + - The symbol `OnigasmPromise` has been changed to `OnigasmProvider` and injects a function of type `() => Promise` + - The symbol `PreferenceTransactionPrelude` has been changed to `PreferenceTransactionPreludeProvider ` and injects a function of type `() => Promise` + ## v1.38.0 - 05/25/2023 - [application-manager] fixed regression preventing browser-only builds from succeeding [#12491](https://github.com/eclipse-theia/theia/pull/12491) diff --git a/doc/Migration.md b/doc/Migration.md index 7beb17420a0ec..70b26953306a9 100644 --- a/doc/Migration.md +++ b/doc/Migration.md @@ -44,6 +44,48 @@ For example: } ``` +### v1.38.0 + +#### Inversify 6.0 + +With Inversify 6, the library has introduced a strict split between sync and async dependency injection contexts. +Theia uses the sync dependency injection context, and therefore no async dependencies cannot be used as dependencies in Theia. + +This might require a few changes in your Theia extensions, if you've been using async dependencies before. These include: +1. Injecting promises directly into services +2. Classes with `@postConstruct` methods which return a `Promise` instance. + +In order to work around 1., you can just wrap the promise inside of a function: + +```diff +const PromiseSymbol = Symbol(); +const promise = startLongRunningOperation(); + +-bind(PromiseSymbol).toConstantValue(promise); ++bind(PromiseSymbol).toConstantValue(() => promise); +``` + +The newly bound function needs to be handled appropriately at the injection side. + +For 2., `@postConstruct` methods can be refactored into a sync and an async method: + +```diff +-@postConstruct() +-protected async init(): Promise { +- await longRunningOperation(); +-} ++@postConstruct() ++protected init(): void { ++ this.doInit(); ++} ++ ++protected async doInit(): Promise { ++ await longRunningOperation(); ++} +``` + +Note that this release includes a few breaking changes that also perform this refactoring on our own classes. +If you've been overriding some of these `init()` methods, it might make sense to override `doInit()` instead. ### v1.37.0 diff --git a/examples/api-samples/src/browser/file-watching/sample-file-watching-contribution.ts b/examples/api-samples/src/browser/file-watching/sample-file-watching-contribution.ts index 5f24ddfc85b96..7020a4967d0fe 100644 --- a/examples/api-samples/src/browser/file-watching/sample-file-watching-contribution.ts +++ b/examples/api-samples/src/browser/file-watching/sample-file-watching-contribution.ts @@ -65,7 +65,7 @@ class SampleFileWatchingContribution implements FrontendApplicationContribution protected readonly fileWatchingPreferences: FileWatchingPreferences; @postConstruct() - protected postConstruct(): void { + protected init(): void { this.verbose = this.fileWatchingPreferences['sample.file-watching.verbose']; this.fileWatchingPreferences.onPreferenceChanged(e => { if (e.preferenceName === 'sample.file-watching.verbose') { diff --git a/packages/console/src/browser/console-widget.ts b/packages/console/src/browser/console-widget.ts index 8c008f0df1559..2cd70ddc3c11c 100644 --- a/packages/console/src/browser/console-widget.ts +++ b/packages/console/src/browser/console-widget.ts @@ -83,7 +83,11 @@ export class ConsoleWidget extends BaseWidget implements StatefulWidget { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const { id, title, inputFocusContextKey } = this.options; const { label, iconClass, caption } = Object.assign({}, title); this.id = id; diff --git a/packages/core/README.md b/packages/core/README.md index c2324fa98be29..9cab65e83d0e8 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -92,7 +92,7 @@ export class SomeClass { - `@theia/request/lib/node-request-service` (from [`@theia/request@1.38.0`](https://www.npmjs.com/package/@theia/request/v/1.38.0)) - `fs-extra` (from [`fs-extra@^4.0.2`](https://www.npmjs.com/package/fs-extra)) - `fuzzy` (from [`fuzzy@^0.1.3`](https://www.npmjs.com/package/fuzzy)) - - `inversify` (from [`inversify@^5.1.1`](https://www.npmjs.com/package/inversify)) + - `inversify` (from [`inversify@^6.0.1`](https://www.npmjs.com/package/inversify)) - `react-dom` (from [`react-dom@^18.2.0`](https://www.npmjs.com/package/react-dom)) - `react-dom/client` (from [`react-dom@^18.2.0`](https://www.npmjs.com/package/react-dom)) - `react-virtuoso` (from [`react-virtuoso@^2.17.0`](https://www.npmjs.com/package/react-virtuoso)) diff --git a/packages/core/package.json b/packages/core/package.json index d4ce49cca5873..0de85da3ddadd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -49,7 +49,7 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "iconv-lite": "^0.6.0", - "inversify": "^5.1.1", + "inversify": "^6.0.1", "jschardet": "^2.1.1", "keytar": "7.2.0", "lodash.debounce": "^4.0.8", diff --git a/packages/core/src/browser/about-dialog.tsx b/packages/core/src/browser/about-dialog.tsx index c56703f75a0f6..36c0fcfbf660e 100644 --- a/packages/core/src/browser/about-dialog.tsx +++ b/packages/core/src/browser/about-dialog.tsx @@ -55,7 +55,11 @@ export class AboutDialog extends ReactDialog { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.applicationInfo = await this.appServer.getApplicationInfo(); this.extensionsInfos = await this.appServer.getExtensionsInfos(); this.update(); diff --git a/packages/core/src/browser/frontend-application-bindings.ts b/packages/core/src/browser/frontend-application-bindings.ts index 587ea2f018fb5..b9f6df9af7272 100644 --- a/packages/core/src/browser/frontend-application-bindings.ts +++ b/packages/core/src/browser/frontend-application-bindings.ts @@ -49,7 +49,7 @@ export function bindPreferenceService(bind: interfaces.Bind): void { bind(PreferenceProxyFactory).toFactory(({ container }) => (schema: MaybePromise, options: PreferenceProxyOptions = {}) => { const child = container.createChild(); child.bind(PreferenceProxyOptions).toConstantValue(options ?? {}); - child.bind(PreferenceProxySchema).toConstantValue(schema); + child.bind(PreferenceProxySchema).toConstantValue(() => schema); const handler = child.get(InjectablePreferenceProxy); return new Proxy(Object.create(null), handler); // eslint-disable-line no-null/no-null }); diff --git a/packages/core/src/browser/frontend-application-module.ts b/packages/core/src/browser/frontend-application-module.ts index 9a53a96a74eee..8240b681327d9 100644 --- a/packages/core/src/browser/frontend-application-module.ts +++ b/packages/core/src/browser/frontend-application-module.ts @@ -121,7 +121,7 @@ import { BreadcrumbsService, DefaultBreadcrumbRenderer, } from './breadcrumbs'; -import { RendererHost } from './widgets'; +import { DockPanel, RendererHost } from './widgets'; import { TooltipService, TooltipServiceImpl } from './tooltip-service'; import { BackendRequestService, RequestService, REQUEST_SERVICE_PATH } from '@theia/request'; import { bindFrontendStopwatch, bindBackendStopwatch } from './performance'; @@ -190,7 +190,7 @@ export const frontendApplicationModule = new ContainerModule((bind, _unbind, _is const hoverService = container.get(HoverService); return new TabBarRenderer(contextMenuRenderer, tabBarDecoratorService, iconThemeService, selectionService, commandService, corePreferences, hoverService); }); - bind(TheiaDockPanel.Factory).toFactory(({ container }) => options => { + bind(TheiaDockPanel.Factory).toFactory(({ container }) => (options?: DockPanel.IOptions) => { const corePreferences = container.get(CorePreferences); return new TheiaDockPanel(options, corePreferences); }); diff --git a/packages/core/src/browser/keyboard/browser-keyboard-layout-provider.ts b/packages/core/src/browser/keyboard/browser-keyboard-layout-provider.ts index 247fb5f5b0817..4672f6fa456f4 100644 --- a/packages/core/src/browser/keyboard/browser-keyboard-layout-provider.ts +++ b/packages/core/src/browser/keyboard/browser-keyboard-layout-provider.ts @@ -59,7 +59,11 @@ export class BrowserKeyboardLayoutProvider implements KeyboardLayoutProvider, Ke } @postConstruct() - protected async initialize(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.loadState(); const keyboard = (navigator as NavigatorExtension).keyboard; if (keyboard && keyboard.addEventListener) { diff --git a/packages/core/src/browser/preferences/injectable-preference-proxy.ts b/packages/core/src/browser/preferences/injectable-preference-proxy.ts index 38a7573f3c272..6759095dc3775 100644 --- a/packages/core/src/browser/preferences/injectable-preference-proxy.ts +++ b/packages/core/src/browser/preferences/injectable-preference-proxy.ts @@ -48,7 +48,7 @@ export class InjectablePreferenceProxy> impl @inject(PreferenceProxyOptions) protected readonly options: PreferenceProxyOptions; @inject(PreferenceService) protected readonly preferences: PreferenceService; - @inject(PreferenceProxySchema) protected readonly promisedSchema: PreferenceSchema | Promise; + @inject(PreferenceProxySchema) protected readonly promisedSchema: () => PreferenceSchema | Promise; @inject(PreferenceProxyFactory) protected readonly factory: PreferenceProxyFactory; protected toDispose = new DisposableCollection(); protected _onPreferenceChangedEmitter: Emitter> | undefined; @@ -95,10 +95,11 @@ export class InjectablePreferenceProxy> impl @postConstruct() protected init(): void { - if (this.promisedSchema instanceof Promise) { - this.promisedSchema.then(schema => this.schema = schema); + const schema = this.promisedSchema(); + if (schema instanceof Promise) { + schema.then(resolvedSchema => this.schema = resolvedSchema); } else { - this.schema = this.promisedSchema; + this.schema = schema; } } diff --git a/packages/core/src/common/logger.ts b/packages/core/src/common/logger.ts index 77bce3e717de9..6aae665f55b24 100644 --- a/packages/core/src/common/logger.ts +++ b/packages/core/src/common/logger.ts @@ -14,7 +14,7 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 // ***************************************************************************** -import { inject, injectable } from 'inversify'; +import { inject, injectable, postConstruct } from 'inversify'; import { LoggerWatcher } from './logger-watcher'; import { ILoggerServer, LogLevel, ConsoleLogger, rootLoggerName } from './logger-protocol'; @@ -235,30 +235,28 @@ export class Logger implements ILogger { /* A promise resolved when the logger has been created by the backend. */ protected created: Promise; - /** - * Build a new Logger. - */ - constructor( - @inject(ILoggerServer) protected readonly server: ILoggerServer, - @inject(LoggerWatcher) protected readonly loggerWatcher: LoggerWatcher, - @inject(LoggerFactory) protected readonly factory: LoggerFactory, - @inject(LoggerName) protected name: string) { + @inject(ILoggerServer) protected readonly server: ILoggerServer; + @inject(LoggerWatcher) protected readonly loggerWatcher: LoggerWatcher; + @inject(LoggerFactory) protected readonly factory: LoggerFactory; + @inject(LoggerName) protected name: string; - if (name !== rootLoggerName) { + @postConstruct() + protected init(): void { + if (this.name !== rootLoggerName) { /* Creating a child logger. */ - this.created = server.child(name); + this.created = this.server.child(this.name); } else { /* Creating the root logger (it already exists at startup). */ this.created = Promise.resolve(); } /* Fetch the log level so it's cached in the frontend. */ - this._logLevel = this.created.then(_ => this.server.getLogLevel(name)); + this._logLevel = this.created.then(_ => this.server.getLogLevel(this.name)); /* Update the log level if it changes in the backend. */ - loggerWatcher.onLogLevelChanged(event => { + this.loggerWatcher.onLogLevelChanged(event => { this.created.then(() => { - if (event.loggerName === name) { + if (event.loggerName === this.name) { this._logLevel = Promise.resolve(event.newLogLevel); } }); diff --git a/packages/core/src/common/messaging/proxy-factory.ts b/packages/core/src/common/messaging/proxy-factory.ts index 0562ada54e1bb..a18f54305af96 100644 --- a/packages/core/src/common/messaging/proxy-factory.ts +++ b/packages/core/src/common/messaging/proxy-factory.ts @@ -241,6 +241,10 @@ export class JsonRpcProxyFactory implements ProxyHandler { if (p === 'onDidCloseConnection') { return this.onDidCloseConnectionEmitter.event; } + if (p === 'then') { + // Prevent inversify from identifying this proxy as a promise object. + return undefined; + } const isNotify = this.isNotification(p); return (...args: any[]) => { const method = p.toString(); diff --git a/packages/core/src/common/performance/stopwatch.ts b/packages/core/src/common/performance/stopwatch.ts index 9b13085e69604..0d5936db485aa 100644 --- a/packages/core/src/common/performance/stopwatch.ts +++ b/packages/core/src/common/performance/stopwatch.ts @@ -50,7 +50,7 @@ export abstract class Stopwatch { @inject(ILogger) protected readonly logger: ILogger; - protected constructor(protected readonly defaultLogOptions: LogOptions) { + constructor(protected readonly defaultLogOptions: LogOptions) { if (!defaultLogOptions.defaultLogLevel) { defaultLogOptions.defaultLogLevel = DEFAULT_LOG_LEVEL; } diff --git a/packages/core/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts b/packages/core/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts index 651e2ecdecdf5..069f05f98934a 100644 --- a/packages/core/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts +++ b/packages/core/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts @@ -32,7 +32,7 @@ export class ElectronKeyboardLayoutChangeNotifier implements KeyboardLayoutChang } @postConstruct() - protected initialize(): void { + protected init(): void { window.electronTheiaCore.onKeyboardLayoutChanged((newLayout: NativeKeyboardLayout) => this.nativeLayoutChanged.fire(newLayout)); } diff --git a/packages/core/src/electron-browser/menu/electron-context-menu-renderer.ts b/packages/core/src/electron-browser/menu/electron-context-menu-renderer.ts index 93e6ed9892f49..85c208182a8f4 100644 --- a/packages/core/src/electron-browser/menu/electron-context-menu-renderer.ts +++ b/packages/core/src/electron-browser/menu/electron-context-menu-renderer.ts @@ -90,7 +90,11 @@ export class ElectronContextMenuRenderer extends BrowserContextMenuRenderer { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.useNativeStyle = await window.electronTheiaCore.getTitleBarStyleAtStartup() === 'native'; } diff --git a/packages/core/src/electron-browser/preload.ts b/packages/core/src/electron-browser/preload.ts index b35ea68817a6d..33b816c592aa9 100644 --- a/packages/core/src/electron-browser/preload.ts +++ b/packages/core/src/electron-browser/preload.ts @@ -71,7 +71,7 @@ const api: TheiaCoreAPI = { commandHandlers.set(mainMenuId, handlers); ipcRenderer.send(CHANNEL_SET_MENU, mainMenuId, convertMenu(menu, handlers)); }, - getSecurityToken: () => ipcRenderer.invoke(CHANNEL_GET_SECURITY_TOKEN), + getSecurityToken: () => ipcRenderer.sendSync(CHANNEL_GET_SECURITY_TOKEN), focusWindow: (name: string) => ipcRenderer.send(CHANNEL_FOCUS_WINDOW, name), showItemInFolder: fsPath => { ipcRenderer.send(CHANNEL_SHOW_ITEM_IN_FOLDER, fsPath); diff --git a/packages/core/src/electron-common/electron-api.ts b/packages/core/src/electron-common/electron-api.ts index c9b6ed691f635..5ebc5cc13d43d 100644 --- a/packages/core/src/electron-common/electron-api.ts +++ b/packages/core/src/electron-common/electron-api.ts @@ -41,7 +41,7 @@ export type InternalMenuDto = Omit & { export type WindowEvent = 'maximize' | 'unmaximize' | 'focus'; export interface TheiaCoreAPI { - getSecurityToken: () => Promise; + getSecurityToken: () => string; attachSecurityToken: (endpoint: string) => Promise; setMenuBarVisible(visible: boolean, windowName?: string): void; diff --git a/packages/core/src/electron-main/electron-api-main.ts b/packages/core/src/electron-main/electron-api-main.ts index e83418a864590..0061c4acb1b2f 100644 --- a/packages/core/src/electron-main/electron-api-main.ts +++ b/packages/core/src/electron-main/electron-api-main.ts @@ -64,7 +64,9 @@ export class TheiaMainApi implements ElectronMainApplicationContribution { onStart(application: ElectronMainApplication): MaybePromise { // electron security token - ipcMain.handle(CHANNEL_GET_SECURITY_TOKEN, () => this.electronSecurityToken.value); + ipcMain.on(CHANNEL_GET_SECURITY_TOKEN, event => { + event.returnValue = this.electronSecurityToken.value; + }); ipcMain.handle(CHANNEL_ATTACH_SECURITY_TOKEN, (event, endpoint) => session.defaultSession.cookies.set({ url: endpoint, diff --git a/packages/core/src/electron-node/token/electron-token-validator.ts b/packages/core/src/electron-node/token/electron-token-validator.ts index 39004a92c9858..2504306c49bf9 100644 --- a/packages/core/src/electron-node/token/electron-token-validator.ts +++ b/packages/core/src/electron-node/token/electron-token-validator.ts @@ -31,7 +31,7 @@ export class ElectronTokenValidator implements WsRequestValidatorContribution { protected electronSecurityToken: ElectronSecurityToken; @postConstruct() - protected postConstruct(): void { + protected init(): void { this.electronSecurityToken = this.getToken(); } diff --git a/packages/core/src/node/backend-application.ts b/packages/core/src/node/backend-application.ts index cd8401f652971..4547ce4d97d63 100644 --- a/packages/core/src/node/backend-application.ts +++ b/packages/core/src/node/backend-application.ts @@ -196,6 +196,10 @@ export class BackendApplication { } @postConstruct() + protected init(): void { + this.configure(); + } + protected async configure(): Promise { // Do not await the initialization because contributions are expected to handle // concurrent initialize/configure in undefined order if they provide both diff --git a/packages/core/src/node/hosting/backend-application-hosts.ts b/packages/core/src/node/hosting/backend-application-hosts.ts index 6400b8e9a5527..516ecbc197db5 100644 --- a/packages/core/src/node/hosting/backend-application-hosts.ts +++ b/packages/core/src/node/hosting/backend-application-hosts.ts @@ -39,7 +39,7 @@ export class BackendApplicationHosts { } @postConstruct() - protected postConstruct(): void { + protected init(): void { const theiaHostsEnv = process.env['THEIA_HOSTS']; if (theiaHostsEnv) { theiaHostsEnv.split(',').forEach(host => { diff --git a/packages/debug/src/browser/debug-configuration-manager.ts b/packages/debug/src/browser/debug-configuration-manager.ts index 0a02b2dbc9860..f6b503ed5d06e 100644 --- a/packages/debug/src/browser/debug-configuration-manager.ts +++ b/packages/debug/src/browser/debug-configuration-manager.ts @@ -98,7 +98,11 @@ export class DebugConfigurationManager { protected recentDynamicOptionsTracker: DynamicDebugConfigurationSessionOptions[] = []; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.debugConfigurationTypeKey = this.contextKeyService.createKey('debugConfigurationType', undefined); this.initialized = this.preferences.ready.then(() => { this.preferences.onPreferenceChanged(e => { diff --git a/packages/debug/src/browser/debug-prefix-configuration.ts b/packages/debug/src/browser/debug-prefix-configuration.ts index 613b5c4d71c47..b03250412fa2c 100644 --- a/packages/debug/src/browser/debug-prefix-configuration.ts +++ b/packages/debug/src/browser/debug-prefix-configuration.ts @@ -68,7 +68,7 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan }); @postConstruct() - protected initialize(): void { + protected init(): void { this.handleDebugStatusBarVisibility(); this.preference.onPreferenceChanged(e => { if (e.preferenceName === 'debug.showInStatusBar') { diff --git a/packages/debug/src/browser/editor/debug-breakpoint-widget.tsx b/packages/debug/src/browser/editor/debug-breakpoint-widget.tsx index c37fb63aff93a..acbb154e08d9d 100644 --- a/packages/debug/src/browser/editor/debug-breakpoint-widget.tsx +++ b/packages/debug/src/browser/editor/debug-breakpoint-widget.tsx @@ -93,7 +93,11 @@ export class DebugBreakpointWidget implements Disposable { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.toDispose.push(this.zone = new MonacoEditorZoneWidget(this.editor.getControl())); this.zone.containerNode.classList.add('theia-debug-breakpoint-widget'); diff --git a/packages/debug/src/browser/editor/debug-exception-widget.tsx b/packages/debug/src/browser/editor/debug-exception-widget.tsx index 2658bd727acf3..0ea29db362142 100644 --- a/packages/debug/src/browser/editor/debug-exception-widget.tsx +++ b/packages/debug/src/browser/editor/debug-exception-widget.tsx @@ -59,7 +59,11 @@ export class DebugExceptionWidget implements Disposable { protected readonly toDispose = new DisposableCollection(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.toDispose.push(this.zone = new DebugExceptionMonacoEditorZoneWidget(this.editor.getControl())); this.zone.containerNode.classList.add('theia-debug-exception-widget'); this.containerNodeRoot = createRoot(this.zone.containerNode); diff --git a/packages/external-terminal/src/electron-browser/external-terminal-preference.ts b/packages/external-terminal/src/electron-browser/external-terminal-preference.ts index 3080d37d28f75..c98a8f50de013 100644 --- a/packages/external-terminal/src/electron-browser/external-terminal-preference.ts +++ b/packages/external-terminal/src/electron-browser/external-terminal-preference.ts @@ -15,12 +15,8 @@ // ***************************************************************************** import { inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify'; -import { - createPreferenceProxy, - PreferenceSchema, - PreferenceService, - PreferenceProxy -} from '@theia/core/lib/browser'; +import { PreferenceSchema, PreferenceProxy } from '@theia/core/lib/browser'; +import { PreferenceProxyFactory } from '@theia/core/lib/browser/preferences/injectable-preference-proxy'; import { PreferenceSchemaProvider } from '@theia/core/lib/browser/preferences/preference-contribution'; import { isWindows, isOSX } from '@theia/core/lib/common/os'; import { ExternalTerminalService, ExternalTerminalConfiguration } from '../common/external-terminal'; @@ -29,20 +25,23 @@ import { nls } from '@theia/core/lib/common/nls'; export const ExternalTerminalPreferences = Symbol('ExternalTerminalPreferences'); export type ExternalTerminalPreferences = PreferenceProxy; -export const ExternalTerminalSchemaPromise = Symbol('ExternalTerminalSchemaPromise'); -export type ExternalTerminalSchemaPromise = Promise; +export const ExternalTerminalSchemaProvider = Symbol('ExternalTerminalSchemaPromise'); +export type ExternalTerminalSchemaProvider = () => Promise; export function bindExternalTerminalPreferences(bind: interfaces.Bind): void { - bind(ExternalTerminalSchemaPromise).toDynamicValue( - ctx => getExternalTerminalSchema(ctx.container.get(ExternalTerminalService)) - ).inSingletonScope(); - bind(ExternalTerminalPreferences).toDynamicValue( - ctx => createPreferenceProxy( - ctx.container.get(PreferenceService), - ctx.container.get(ExternalTerminalSchemaPromise), - ) - ).inSingletonScope(); bind(ExternalTerminalPreferenceService).toSelf().inSingletonScope(); + bind(ExternalTerminalSchemaProvider) + .toProvider(ctx => { + const schema = getExternalTerminalSchema(ctx.container.get(ExternalTerminalService)); + return () => schema; + }); + bind(ExternalTerminalPreferences) + .toDynamicValue(ctx => { + const factory = ctx.container.get(PreferenceProxyFactory); + const schemaProvider = ctx.container.get(ExternalTerminalSchemaProvider); + return factory(schemaProvider()); + }) + .inSingletonScope(); } @injectable() @@ -54,12 +53,16 @@ export class ExternalTerminalPreferenceService { @inject(PreferenceSchemaProvider) protected readonly preferenceSchemaProvider: PreferenceSchemaProvider; - @inject(ExternalTerminalSchemaPromise) - protected readonly promisedSchema: ExternalTerminalSchemaPromise; + @inject(ExternalTerminalSchemaProvider) + protected readonly promisedSchema: ExternalTerminalSchemaProvider; @postConstruct() protected init(): void { - this.promisedSchema.then(schema => this.preferenceSchemaProvider.setSchema(schema)); + this.doInit(); + } + + protected async doInit(): Promise { + this.preferenceSchemaProvider.setSchema(await this.promisedSchema()); } /** diff --git a/packages/filesystem/src/browser/location/location-renderer.tsx b/packages/filesystem/src/browser/location/location-renderer.tsx index 12bfa6e85aa11..9cf085756f0d8 100644 --- a/packages/filesystem/src/browser/location/location-renderer.tsx +++ b/packages/filesystem/src/browser/location/location-renderer.tsx @@ -112,7 +112,11 @@ export class LocationListRenderer extends ReactRenderer { } @postConstruct() - async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const homeDirWithPrefix = await this.variablesServer.getHomeDirUri(); this.homeDir = (new URI(homeDirWithPrefix)).path.toString(); } diff --git a/packages/getting-started/src/browser/getting-started-widget.tsx b/packages/getting-started/src/browser/getting-started-widget.tsx index 99f7335b9a812..352a0528cfc32 100644 --- a/packages/getting-started/src/browser/getting-started-widget.tsx +++ b/packages/getting-started/src/browser/getting-started-widget.tsx @@ -98,7 +98,11 @@ export class GettingStartedWidget extends ReactWidget { protected readonly workspaceService: WorkspaceService; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.id = GettingStartedWidget.ID; this.title.label = GettingStartedWidget.LABEL; this.title.caption = GettingStartedWidget.LABEL; diff --git a/packages/git/src/browser/dirty-diff/dirty-diff-manager.ts b/packages/git/src/browser/dirty-diff/dirty-diff-manager.ts index 7670132d58b0a..3881c371e8abd 100644 --- a/packages/git/src/browser/dirty-diff/dirty-diff-manager.ts +++ b/packages/git/src/browser/dirty-diff/dirty-diff-manager.ts @@ -54,7 +54,11 @@ export class DirtyDiffManager { protected readonly preferences: GitPreferences; @postConstruct() - protected async initialize(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.editorManager.onCreated(async e => this.handleEditorCreated(e)); this.repositoryTracker.onGitEvent(throttle(async (event: GitStatusChangeEvent | undefined) => this.handleGitStatusUpdate(event && event.source, event && event.status), 500)); diff --git a/packages/git/src/browser/git-repository-provider.spec.ts b/packages/git/src/browser/git-repository-provider.spec.ts index 0057d0abbf5db..95386074113df 100644 --- a/packages/git/src/browser/git-repository-provider.spec.ts +++ b/packages/git/src/browser/git-repository-provider.spec.ts @@ -119,7 +119,7 @@ describe('GitRepositoryProvider', () => { (mockFilesystem.exists).resolves(true); (mockGit.repositories).withArgs(folderA.resource.toString(), {}).resolves(allRepos); - await gitRepositoryProvider['initialize'](); + await gitRepositoryProvider['doInit'](); expect(gitRepositoryProvider.allRepositories.length).to.eq(allRepos.length); expect(gitRepositoryProvider.allRepositories[0].localUri).to.eq(allRepos[0].localUri); expect(gitRepositoryProvider.allRepositories[1].localUri).to.eq(allRepos[1].localUri); @@ -153,7 +153,7 @@ describe('GitRepositoryProvider', () => { done(); } }); - gitRepositoryProvider['initialize']().then(() => { + gitRepositoryProvider['doInit']().then(() => { const newRoots = [folderA, folderB]; stubWsRoots.returns(newRoots); sinon.stub(mockWorkspaceService, 'roots').resolves(newRoots); @@ -195,7 +195,7 @@ describe('GitRepositoryProvider', () => { done(); } }); - gitRepositoryProvider['initialize']().then(() => + gitRepositoryProvider['doInit']().then(() => mockFileChangeEmitter.fire(new FileChangesEvent([])) ).catch(e => done(new Error('gitRepositoryProvider.initialize() throws an error')) @@ -215,7 +215,7 @@ describe('GitRepositoryProvider', () => { (mockFilesystem.exists).withArgs(folderB.resource.toString()).resolves(false); // folderB does not exist (mockGit.repositories).withArgs(folderA.resource.toString(), {}).resolves(allReposA); - await gitRepositoryProvider['initialize'](); + await gitRepositoryProvider['doInit'](); expect(gitRepositoryProvider.allRepositories.length).to.eq(allReposA.length); expect(gitRepositoryProvider.allRepositories[0].localUri).to.eq(allReposA[0].localUri); expect(gitRepositoryProvider.allRepositories[1].localUri).to.eq(allReposA[1].localUri); @@ -237,7 +237,7 @@ describe('GitRepositoryProvider', () => { (mockGit.repositories).withArgs(folderB.resource.toString(), {}).resolves(allReposB); (mockGit.repositories).withArgs(folderB.resource.toString(), { maxCount: 1 }).resolves([allReposB[0]]); - await gitRepositoryProvider['initialize'](); + await gitRepositoryProvider['doInit'](); expect(gitRepositoryProvider.selectedRepository && gitRepositoryProvider.selectedRepository.localUri).to.eq(allReposA[0].localUri); }); }); diff --git a/packages/git/src/browser/git-repository-provider.ts b/packages/git/src/browser/git-repository-provider.ts index f89ad586d4b74..b67e58e329d57 100644 --- a/packages/git/src/browser/git-repository-provider.ts +++ b/packages/git/src/browser/git-repository-provider.ts @@ -53,7 +53,11 @@ export class GitRepositoryProvider { protected readonly fileService: FileService; @postConstruct() - protected async initialize(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const [selectedRepository, allRepositories] = await Promise.all([ this.storageService.getData(this.selectedRepoStorageKey), this.storageService.getData(this.allRepoStorageKey) diff --git a/packages/git/src/browser/git-repository-tracker.ts b/packages/git/src/browser/git-repository-tracker.ts index bc56da326fce0..aa924b3dcdd0f 100644 --- a/packages/git/src/browser/git-repository-tracker.ts +++ b/packages/git/src/browser/git-repository-tracker.ts @@ -40,7 +40,11 @@ export class GitRepositoryTracker { ) { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.updateStatus(); this.repositoryProvider.onDidChangeRepository(() => this.updateStatus()); } diff --git a/packages/git/src/browser/history/git-commit-detail-header-widget.tsx b/packages/git/src/browser/history/git-commit-detail-header-widget.tsx index 93c1009988da4..2010debc293e2 100644 --- a/packages/git/src/browser/history/git-commit-detail-header-widget.tsx +++ b/packages/git/src/browser/history/git-commit-detail-header-widget.tsx @@ -48,7 +48,11 @@ export class GitCommitDetailHeaderWidget extends ReactWidget { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.authorAvatar = await this.avatarService.getAvatar(this.commitDetailOptions.authorEmail); } diff --git a/packages/git/src/node/git-exec-provider.ts b/packages/git/src/node/git-exec-provider.ts index a0eef59a81b18..64458543d6e58 100644 --- a/packages/git/src/node/git-exec-provider.ts +++ b/packages/git/src/node/git-exec-provider.ts @@ -31,7 +31,11 @@ import { IGitExecutionOptions } from 'dugite-extra/lib/core/git'; * protected deferred = new Deferred(); * * @postConstruct() - * protected async init(): Promise { + * protected init(): void { + * this.doInit(); + * } + * + * protected async doInit(): Promise { * const connection = await new SSH().connect({ * host: 'your-host', * username: 'your-username', diff --git a/packages/keymaps/src/browser/keymaps-service.ts b/packages/keymaps/src/browser/keymaps-service.ts index 3d855b61c1637..6976eb135c811 100644 --- a/packages/keymaps/src/browser/keymaps-service.ts +++ b/packages/keymaps/src/browser/keymaps-service.ts @@ -60,7 +60,11 @@ export class KeymapsService { * Initialize the keybinding service. */ @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const reference = await this.textModelService.createModelReference(UserStorageUri.resolve('keymaps.json')); this.model = reference.object; this.deferredModel.resolve(this.model); diff --git a/packages/memory-inspector/src/browser/editable-widget/memory-editable-table-widget.tsx b/packages/memory-inspector/src/browser/editable-widget/memory-editable-table-widget.tsx index 7c5324a89919c..6320cfb9825ba 100644 --- a/packages/memory-inspector/src/browser/editable-widget/memory-editable-table-widget.tsx +++ b/packages/memory-inspector/src/browser/editable-widget/memory-editable-table-widget.tsx @@ -16,7 +16,7 @@ import { Key, KeyCode } from '@theia/core/lib/browser'; import { Deferred } from '@theia/core/lib/common/promise-util'; -import { injectable, postConstruct } from '@theia/core/shared/inversify'; +import { injectable } from '@theia/core/shared/inversify'; import * as React from '@theia/core/shared/react'; import * as Long from 'long'; import { DebugProtocol } from '@vscode/debugprotocol'; @@ -45,10 +45,9 @@ export class MemoryEditableTableWidget extends MemoryTableWidget { protected doShowMoreMemoryBefore = false; protected doShowMoreMemoryAfter = false; - @postConstruct() - protected override async init(): Promise { + protected override async doInit(): Promise { this.memoryEditsCompleted.resolve(); - await super.init(); + await super.doInit(); this.addClass('editable'); } diff --git a/packages/memory-inspector/src/browser/memory-widget/memory-table-widget.tsx b/packages/memory-inspector/src/browser/memory-widget/memory-table-widget.tsx index f392488e1d197..1a2c5f719eb6e 100644 --- a/packages/memory-inspector/src/browser/memory-widget/memory-table-widget.tsx +++ b/packages/memory-inspector/src/browser/memory-widget/memory-table-widget.tsx @@ -113,7 +113,11 @@ export class MemoryTableWidget extends ReactWidget { protected deferredScrollContainer = new Deferred(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.id = MemoryTableWidget.ID; this.addClass(MemoryTableWidget.ID); this.scrollOptions = { ...this.scrollOptions, suppressScrollX: false }; diff --git a/packages/memory-inspector/src/browser/memory-widget/memory-widget.ts b/packages/memory-inspector/src/browser/memory-widget/memory-widget.ts index da1621eff4d65..497adbf68718f 100644 --- a/packages/memory-inspector/src/browser/memory-widget/memory-widget.ts +++ b/packages/memory-inspector/src/browser/memory-widget/memory-widget.ts @@ -25,7 +25,7 @@ import { MemoryTableWidget } from './memory-table-widget'; export class MemoryWidget< O extends MemoryOptionsWidget = MemoryOptionsWidget, T extends MemoryTableWidget = MemoryTableWidget - > +> extends BaseWidget { static readonly ID = 'memory-view-wrapper'; static readonly LABEL = nls.localize('theia/memory-inspector/memoryTitle', 'Memory'); @@ -78,7 +78,11 @@ export class MemoryWidget< } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.id = MemoryWidget.getIdentifier(this.memoryWidgetOptions.identifier.toString()); this.addClass(MemoryWidget.ID); diff --git a/packages/memory-inspector/src/browser/register-widget/register-filter-service.ts b/packages/memory-inspector/src/browser/register-widget/register-filter-service.ts index dfec161e043e9..9d9e5390b8a95 100644 --- a/packages/memory-inspector/src/browser/register-widget/register-filter-service.ts +++ b/packages/memory-inspector/src/browser/register-widget/register-filter-service.ts @@ -50,13 +50,12 @@ export class RegisterFilterServiceImpl implements RegisterFilterService { } @postConstruct() - protected init(): Promise { + protected init(): void { this.filters.set(AllOrCustom.All, undefined); this.filters.set(AllOrCustom.Custom, new Set()); for (const [key, values] of Object.entries(this.options)) { this.filters.set(key, new Set(values)); } - return Promise.resolve(); } setFilter(filterLabel: string): void { diff --git a/packages/memory-inspector/src/browser/register-widget/register-table-widget.tsx b/packages/memory-inspector/src/browser/register-widget/register-table-widget.tsx index a7ab35a3a450f..4f1da24f68bf9 100644 --- a/packages/memory-inspector/src/browser/register-widget/register-table-widget.tsx +++ b/packages/memory-inspector/src/browser/register-widget/register-table-widget.tsx @@ -15,7 +15,7 @@ ********************************************************************************/ import { Key, KeyCode } from '@theia/core/lib/browser'; -import { inject, postConstruct } from '@theia/core/shared/inversify'; +import { inject } from '@theia/core/shared/inversify'; import * as React from '@theia/core/shared/react'; import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items'; import { EMPTY_MEMORY } from '../memory-widget/memory-options-widget'; @@ -69,8 +69,7 @@ export class RegisterTableWidget extends MemoryTableWidget { protected override options: RegisterOptions; protected override memory: Interfaces.WidgetMemoryState = { ...EMPTY_MEMORY, variables: [] }; - @postConstruct() - protected override async init(): Promise { + protected override async doInit(): Promise { this.id = RegisterTableWidget.ID; this.addClass(RegisterTableWidget.ID); this.scrollOptions = { ...this.scrollOptions, suppressScrollX: false }; diff --git a/packages/memory-inspector/src/browser/wrapper-widgets/memory-layout-widget.tsx b/packages/memory-inspector/src/browser/wrapper-widgets/memory-layout-widget.tsx index 9f5b8ff79b39f..2a92de2327ddf 100644 --- a/packages/memory-inspector/src/browser/wrapper-widgets/memory-layout-widget.tsx +++ b/packages/memory-inspector/src/browser/wrapper-widgets/memory-layout-widget.tsx @@ -48,7 +48,11 @@ export class MemoryLayoutWidget extends Panel implements Disposable, Application protected hasGeneratedWidgetAutomatically = false; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.id = MemoryLayoutWidget.ID; this.addClass(MemoryLayoutWidget.ID); this.title.label = MemoryLayoutWidget.LABEL; diff --git a/packages/messages/src/browser/notifications-manager.ts b/packages/messages/src/browser/notifications-manager.ts index 1e3017424fe25..b4068e6cd8580 100644 --- a/packages/messages/src/browser/notifications-manager.ts +++ b/packages/messages/src/browser/notifications-manager.ts @@ -84,10 +84,15 @@ export class NotificationManager extends MessageClient { protected notificationCenterVisibleKey: ContextKey; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.notificationToastsVisibleKey = this.contextKeyService.createKey('notificationToastsVisible', false); this.notificationCenterVisibleKey = this.contextKeyService.createKey('notificationCenterVisible', false); } + protected updateContextKeys(): void { this.notificationToastsVisibleKey.set(this.toastsVisible); this.notificationCenterVisibleKey.set(this.centerVisible); diff --git a/packages/mini-browser/src/browser/environment/mini-browser-environment.ts b/packages/mini-browser/src/browser/environment/mini-browser-environment.ts index 7bedffa341a5c..083fc469227fc 100644 --- a/packages/mini-browser/src/browser/environment/mini-browser-environment.ts +++ b/packages/mini-browser/src/browser/environment/mini-browser-environment.ts @@ -35,7 +35,7 @@ export class MiniBrowserEnvironment implements FrontendApplicationContribution { protected environment: EnvVariablesServer; @postConstruct() - protected postConstruct(): void { + protected init(): void { this._hostPatternPromise = this.getHostPattern() .then(pattern => this._hostPattern = pattern); } diff --git a/packages/mini-browser/src/node/mini-browser-ws-validator.ts b/packages/mini-browser/src/node/mini-browser-ws-validator.ts index ec79279420883..298d90dd31ec3 100644 --- a/packages/mini-browser/src/node/mini-browser-ws-validator.ts +++ b/packages/mini-browser/src/node/mini-browser-ws-validator.ts @@ -31,7 +31,7 @@ export class MiniBrowserWsRequestValidator implements WsRequestValidatorContribu protected serveSameOrigin: boolean = false; @postConstruct() - protected postConstruct(): void { + protected init(): void { const pattern = process.env[MiniBrowserEndpoint.HOST_PATTERN_ENV] || MiniBrowserEndpoint.HOST_PATTERN_DEFAULT; if (pattern === '{{hostname}}') { this.serveSameOrigin = true; diff --git a/packages/monaco/src/browser/monaco-frontend-module.ts b/packages/monaco/src/browser/monaco-frontend-module.ts index 3a6449aa72f3b..242b08dd5fc3d 100644 --- a/packages/monaco/src/browser/monaco-frontend-module.ts +++ b/packages/monaco/src/browser/monaco-frontend-module.ts @@ -38,7 +38,7 @@ import { PreferenceService, PreferenceSchemaProvider, createPreferenceProxy, PreferenceScope, PreferenceChange, OVERRIDE_PROPERTY_PATTERN, QuickInputService, StylingParticipant } from '@theia/core/lib/browser'; -import { TextEditorProvider, DiffNavigatorProvider } from '@theia/editor/lib/browser'; +import { TextEditorProvider, DiffNavigatorProvider, TextEditor } from '@theia/editor/lib/browser'; import { StrictEditorTextFocusContext } from '@theia/editor/lib/browser/editor-keybinding-contexts'; import { MonacoEditorProvider, MonacoEditorFactory } from './monaco-editor-provider'; import { MonacoEditorMenuContribution } from './monaco-menu'; @@ -138,7 +138,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(MonacoDiffNavigatorFactory).toSelf().inSingletonScope(); bind(DiffNavigatorProvider).toFactory(context => - editor => context.container.get(MonacoEditorProvider).getDiffNavigator(editor) + (editor: TextEditor) => context.container.get(MonacoEditorProvider).getDiffNavigator(editor) ); bind(MonacoOutlineContribution).toSelf().inSingletonScope(); diff --git a/packages/monaco/src/browser/monaco-text-model-service.ts b/packages/monaco/src/browser/monaco-text-model-service.ts index 9386a8643d5b4..07ec11200745f 100644 --- a/packages/monaco/src/browser/monaco-text-model-service.ts +++ b/packages/monaco/src/browser/monaco-text-model-service.ts @@ -79,7 +79,7 @@ export class MonacoTextModelService implements ITextModelService { protected readonly fileService: FileService; @postConstruct() - public init(): void { + protected init(): void { const resourcePropertiesService = StandaloneServices.get(ITextResourcePropertiesService); if (resourcePropertiesService) { diff --git a/packages/monaco/src/browser/textmate/monaco-textmate-frontend-bindings.ts b/packages/monaco/src/browser/textmate/monaco-textmate-frontend-bindings.ts index de116e3a10818..deda1fdccca4b 100644 --- a/packages/monaco/src/browser/textmate/monaco-textmate-frontend-bindings.ts +++ b/packages/monaco/src/browser/textmate/monaco-textmate-frontend-bindings.ts @@ -23,7 +23,7 @@ import { MonacoTextmateService } from './monaco-textmate-service'; import { MonacoThemeRegistry } from './monaco-theme-registry'; import { loadWASM, createOnigScanner, OnigScanner, createOnigString, OnigString } from 'vscode-oniguruma'; import { IOnigLib, IRawGrammar, parseRawGrammar, Registry } from 'vscode-textmate'; -import { OnigasmPromise, TextmateRegistryFactory, ThemeMix } from './monaco-theme-types'; +import { OnigasmProvider, TextmateRegistryFactory, ThemeMix } from './monaco-theme-types'; export class OnigasmLib implements IOnigLib { createOnigScanner(sources: string[]): OnigScanner { @@ -35,17 +35,18 @@ export class OnigasmLib implements IOnigLib { } export default (bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => { - bind(OnigasmPromise).toDynamicValue(dynamicOnigasmLib).inSingletonScope(); + const onigLib = createOnigasmLib(); + bind(OnigasmProvider).toConstantValue(() => onigLib); bind(MonacoTextmateService).toSelf().inSingletonScope(); bind(FrontendApplicationContribution).toService(MonacoTextmateService); bindContributionProvider(bind, LanguageGrammarDefinitionContribution); bind(TextmateRegistry).toSelf().inSingletonScope(); bind(MonacoThemeRegistry).toSelf().inSingletonScope(); bind(TextmateRegistryFactory).toFactory(({ container }) => (theme?: ThemeMix) => { - const onigLib = container.get(OnigasmPromise); + const onigProvider = container.get(OnigasmProvider); const textmateRegistry = container.get(TextmateRegistry); return new Registry({ - onigLib, + onigLib: onigProvider(), theme, loadGrammar: async (scopeName: string) => { const provider = textmateRegistry.getProvider(scopeName); @@ -72,10 +73,6 @@ export default (bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: inter }); }; -export async function dynamicOnigasmLib(ctx: interfaces.Context): Promise { - return createOnigasmLib(); -} - export async function createOnigasmLib(): Promise { if (!isBasicWasmSupported) { throw new Error('wasm not supported'); diff --git a/packages/monaco/src/browser/textmate/monaco-textmate-service.ts b/packages/monaco/src/browser/textmate/monaco-textmate-service.ts index f398b1ce6a405..9a770a58745b7 100644 --- a/packages/monaco/src/browser/textmate/monaco-textmate-service.ts +++ b/packages/monaco/src/browser/textmate/monaco-textmate-service.ts @@ -31,7 +31,7 @@ import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/stan import { ILanguageService } from '@theia/monaco-editor-core/esm/vs/editor/common/languages/language'; import { TokenizationSupportAdapter } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneLanguages'; import { LanguageService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/languageService'; -import { OnigasmPromise, TextmateRegistryFactory } from './monaco-theme-types'; +import { OnigasmProvider, TextmateRegistryFactory } from './monaco-theme-types'; @injectable() export class MonacoTextmateService implements FrontendApplicationContribution { @@ -53,8 +53,8 @@ export class MonacoTextmateService implements FrontendApplicationContribution { @inject(ILogger) protected readonly logger: ILogger; - @inject(OnigasmPromise) - protected readonly onigasmPromise: OnigasmPromise; + @inject(OnigasmProvider) + protected readonly onigasmProvider: OnigasmProvider; @inject(ThemeService) protected readonly themeService: ThemeService; @@ -151,7 +151,7 @@ export class MonacoTextmateService implements FrontendApplicationContribution { const configuration = this.textmateRegistry.getGrammarConfiguration(languageId); const initialLanguage = getEncodedLanguageId(languageId); - await this.onigasmPromise; + await this.onigasmProvider(); if (toDispose.disposed) { return; } diff --git a/packages/monaco/src/browser/textmate/monaco-theme-types.ts b/packages/monaco/src/browser/textmate/monaco-theme-types.ts index 9b088416f0332..ce5be20f3f463 100644 --- a/packages/monaco/src/browser/textmate/monaco-theme-types.ts +++ b/packages/monaco/src/browser/textmate/monaco-theme-types.ts @@ -24,8 +24,8 @@ export interface MixStandaloneTheme extends IStandaloneTheme { themeData: ThemeMix } -export const OnigasmPromise = Symbol('OnigasmPromise'); -export type OnigasmPromise = Promise; +export const OnigasmProvider = Symbol('OnigasmProvider'); +export type OnigasmProvider = () => Promise; export const TextmateRegistryFactory = Symbol('TextmateRegistryFactory'); export type TextmateRegistryFactory = (currentTheme?: ThemeMix) => Registry; diff --git a/packages/navigator/src/browser/navigator-contribution.ts b/packages/navigator/src/browser/navigator-contribution.ts index c450fc8f6589b..0e955c302165c 100644 --- a/packages/navigator/src/browser/navigator-contribution.ts +++ b/packages/navigator/src/browser/navigator-contribution.ts @@ -170,7 +170,11 @@ export class FileNavigatorContribution extends AbstractViewContribution { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.fileNavigatorPreferences.ready; this.shell.onDidChangeCurrentWidget(() => this.onCurrentWidgetChangedHandler()); diff --git a/packages/navigator/src/browser/navigator-filter.ts b/packages/navigator/src/browser/navigator-filter.ts index 35d6ea238278f..8d301a5b9d242 100644 --- a/packages/navigator/src/browser/navigator-filter.ts +++ b/packages/navigator/src/browser/navigator-filter.ts @@ -41,7 +41,11 @@ export class FileNavigatorFilter { ) { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.filterPredicate = this.createFilterPredicate(this.filesPreferences['files.exclude']); this.filesPreferences.onPreferenceChanged(event => this.onFilesPreferenceChanged(event)); this.preferences.onPreferenceChanged(event => this.onPreferenceChanged(event)); diff --git a/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts b/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts index 1d32e764dc46d..943fcc219d325 100644 --- a/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts +++ b/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts @@ -129,7 +129,11 @@ export class HostedPluginManagerClient { protected readonly fileDialogService: FileDialogService; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.openNewTabAskDialog = new OpenHostedInstanceLinkDialog(this.windowService); // is needed for case when page is loaded when hosted instance is already running. diff --git a/packages/plugin-ext/src/main/browser/webview/webview-context-keys.ts b/packages/plugin-ext/src/main/browser/webview/webview-context-keys.ts index 36c2ebbd1d239..50623a374d7b0 100644 --- a/packages/plugin-ext/src/main/browser/webview/webview-context-keys.ts +++ b/packages/plugin-ext/src/main/browser/webview/webview-context-keys.ts @@ -34,7 +34,7 @@ export class WebviewContextKeys { protected contextKeyService: ContextKeyService; @postConstruct() - protected postConstruct(): void { + protected init(): void { this.activeWebviewPanelId = this.contextKeyService.createKey('activeWebviewPanelId', ''); this.applicationShell.onDidChangeCurrentWidget(this.handleDidChangeCurrentWidget, this); } diff --git a/packages/plugin-ext/src/main/browser/webview/webview-environment.ts b/packages/plugin-ext/src/main/browser/webview/webview-environment.ts index cedace946770d..bd199670d721b 100644 --- a/packages/plugin-ext/src/main/browser/webview/webview-environment.ts +++ b/packages/plugin-ext/src/main/browser/webview/webview-environment.ts @@ -33,7 +33,11 @@ export class WebviewEnvironment { protected readonly environments: EnvVariablesServer; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this._hostPatternPromise = this.getHostPattern(); try { const endpointPattern = await this.hostPatternPromise; diff --git a/packages/plugin-ext/src/main/node/plugin-service.ts b/packages/plugin-ext/src/main/node/plugin-service.ts index aeded55c83188..d58c6e935cae6 100644 --- a/packages/plugin-ext/src/main/node/plugin-service.ts +++ b/packages/plugin-ext/src/main/node/plugin-service.ts @@ -34,7 +34,7 @@ export class PluginApiContribution implements BackendApplicationContribution, Ws protected serveSameOrigin: boolean = false; @postConstruct() - protected postConstruct(): void { + protected init(): void { const webviewExternalEndpoint = this.webviewExternalEndpoint(); console.log(`Configuring to accept webviews on '${webviewExternalEndpoint}' hostname.`); this.webviewExternalEndpointRegExp = new RegExp(webviewExternalEndpoint, 'i'); diff --git a/packages/preferences/src/browser/abstract-resource-preference-provider.ts b/packages/preferences/src/browser/abstract-resource-preference-provider.ts index 3ffb661966ac6..cae253f8a06a6 100644 --- a/packages/preferences/src/browser/abstract-resource-preference-provider.ts +++ b/packages/preferences/src/browser/abstract-resource-preference-provider.ts @@ -54,7 +54,11 @@ export abstract class AbstractResourcePreferenceProvider extends PreferenceProvi @inject(PreferenceConfigurations) protected readonly configurations: PreferenceConfigurations; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const uri = this.getUri(); this.toDispose.push(Disposable.create(() => this.loading.reject(new Error(`Preference provider for '${uri}' was disposed.`)))); await this.readPreferencesFromFile(); diff --git a/packages/preferences/src/browser/folders-preferences-provider.ts b/packages/preferences/src/browser/folders-preferences-provider.ts index c5517a53ce614..bd9c957ac42bc 100644 --- a/packages/preferences/src/browser/folders-preferences-provider.ts +++ b/packages/preferences/src/browser/folders-preferences-provider.ts @@ -39,7 +39,11 @@ export class FoldersPreferencesProvider extends PreferenceProvider { protected readonly providers = new Map(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.workspaceService.roots; this.updateProviders(); diff --git a/packages/preferences/src/browser/preference-transaction-manager.ts b/packages/preferences/src/browser/preference-transaction-manager.ts index 9d90655e5dbfa..7535aa06903bf 100644 --- a/packages/preferences/src/browser/preference-transaction-manager.ts +++ b/packages/preferences/src/browser/preference-transaction-manager.ts @@ -71,7 +71,11 @@ export abstract class Transaction { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const release = await this.queue.acquire(); try { const status = await this.setUp(); @@ -176,22 +180,22 @@ export interface PreferenceContext { getScope(): PreferenceScope; } export const PreferenceContext = Symbol('PreferenceContext'); -export const PreferenceTransactionPrelude = Symbol('PreferenceTransactionPrelude'); +export const PreferenceTransactionPreludeProvider = Symbol('PreferenceTransactionPreludeProvider'); +export type PreferenceTransactionPreludeProvider = () => Promise; @injectable() export class PreferenceTransaction extends Transaction<[string, string[], unknown], boolean> { reference: IReference | undefined; @inject(PreferenceContext) protected readonly context: PreferenceContext; - @inject(PreferenceTransactionPrelude) protected readonly prelude?: Promise; + @inject(PreferenceTransactionPreludeProvider) protected readonly prelude?: PreferenceTransactionPreludeProvider; @inject(MonacoTextModelService) protected readonly textModelService: MonacoTextModelService; @inject(MonacoJSONCEditor) protected readonly jsoncEditor: MonacoJSONCEditor; @inject(MessageService) protected readonly messageService: MessageService; @inject(EditorManager) protected readonly editorManager: EditorManager; - @postConstruct() - protected override init(): Promise { - this.waitFor(this.prelude); - return super.init(); + protected override async doInit(): Promise { + this.waitFor(this.prelude?.()); + await super.doInit(); } protected async setUp(): Promise { @@ -278,6 +282,6 @@ export const preferenceTransactionFactoryCreator: interfaces.FactoryCreator) => { const child = container.createChild(); child.bind(PreferenceContext).toConstantValue(context); - child.bind(PreferenceTransactionPrelude).toConstantValue(waitFor); + child.bind(PreferenceTransactionPreludeProvider).toConstantValue(() => waitFor); return child.get(PreferenceTransaction); }; diff --git a/packages/preferences/src/browser/preference-tree-model.ts b/packages/preferences/src/browser/preference-tree-model.ts index d89c7e338d2d9..95202a47dab2d 100644 --- a/packages/preferences/src/browser/preference-tree-model.ts +++ b/packages/preferences/src/browser/preference-tree-model.ts @@ -97,7 +97,11 @@ export class PreferenceTreeModel extends TreeModelImpl { } @postConstruct() - protected override async init(): Promise { + protected override init(): void { + this.doInit(); + } + + protected async doInit(): Promise { super.init(); this.toDispose.pushAll([ this.treeGenerator.onSchemaChanged(newTree => this.handleNewSchema(newTree)), diff --git a/packages/preferences/src/browser/user-configs-preference-provider.ts b/packages/preferences/src/browser/user-configs-preference-provider.ts index 6e330c9b82757..966255be5829f 100644 --- a/packages/preferences/src/browser/user-configs-preference-provider.ts +++ b/packages/preferences/src/browser/user-configs-preference-provider.ts @@ -38,7 +38,11 @@ export class UserConfigsPreferenceProvider extends PreferenceProvider { protected readonly providers = new Map(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.createProviders(); const readyPromises: Promise[] = []; diff --git a/packages/preferences/src/browser/util/preference-tree-generator.ts b/packages/preferences/src/browser/util/preference-tree-generator.ts index d9544370ec025..a0e4e56d51075 100644 --- a/packages/preferences/src/browser/util/preference-tree-generator.ts +++ b/packages/preferences/src/browser/util/preference-tree-generator.ts @@ -78,7 +78,11 @@ export class PreferenceTreeGenerator { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.schemaProvider.ready; this.schemaProvider.onDidPreferenceSchemaChanged(() => this.handleChangedSchema()); this.handleChangedSchema(); diff --git a/packages/preferences/src/browser/views/preference-editor-widget.ts b/packages/preferences/src/browser/views/preference-editor-widget.ts index 2e85390c75cf2..46458a0dd9896 100644 --- a/packages/preferences/src/browser/views/preference-editor-widget.ts +++ b/packages/preferences/src/browser/views/preference-editor-widget.ts @@ -72,7 +72,11 @@ export class PreferencesEditorWidget extends BaseWidget implements StatefulWidge @inject(PreferencesScopeTabBar) protected readonly tabbar: PreferencesScopeTabBar; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.id = PreferencesEditorWidget.ID; this.title.label = PreferencesEditorWidget.LABEL; diff --git a/packages/preferences/src/browser/workspace-preference-provider.ts b/packages/preferences/src/browser/workspace-preference-provider.ts index 9959ebccd5c4c..e29d115d4bb42 100644 --- a/packages/preferences/src/browser/workspace-preference-provider.ts +++ b/packages/preferences/src/browser/workspace-preference-provider.ts @@ -38,7 +38,7 @@ export class WorkspacePreferenceProvider extends PreferenceProvider { protected readonly toDisposeOnEnsureDelegateUpToDate = new DisposableCollection(); @postConstruct() - protected async init(): Promise { + protected init(): void { this.workspaceService.ready.then(() => { // If there is no workspace after the workspace service is initialized, then no more work is needed for this provider to be ready. // If there is a workspace, then we wait for the new delegate to be ready before declaring this provider ready. diff --git a/packages/task/src/browser/task-configuration-manager.ts b/packages/task/src/browser/task-configuration-manager.ts index 0366cdd197dad..2c060d1264200 100644 --- a/packages/task/src/browser/task-configuration-manager.ts +++ b/packages/task/src/browser/task-configuration-manager.ts @@ -87,7 +87,7 @@ export class TaskConfigurationManager { protected workspaceDelegate: PreferenceProvider; @postConstruct() - protected async init(): Promise { + protected init(): void { this.createModels(); this.folderPreferences.onDidPreferencesChanged(e => { if (e['tasks']) { diff --git a/packages/task/src/browser/task-frontend-contribution.ts b/packages/task/src/browser/task-frontend-contribution.ts index 7e2cc28703dbe..c7b0bcddc3a56 100644 --- a/packages/task/src/browser/task-frontend-contribution.ts +++ b/packages/task/src/browser/task-frontend-contribution.ts @@ -167,7 +167,7 @@ export class TaskFrontendContribution implements CommandContribution, MenuContri protected readonly workspaceService: WorkspaceService; @postConstruct() - protected async init(): Promise { + protected init(): void { this.taskWatcher.onTaskCreated(() => this.updateRunningTasksItem()); this.taskWatcher.onTaskExit(() => this.updateRunningTasksItem()); } diff --git a/packages/toolbar/src/browser/application-shell-with-toolbar-override.ts b/packages/toolbar/src/browser/application-shell-with-toolbar-override.ts index 31db54d075fb1..21dfbe0ec9397 100644 --- a/packages/toolbar/src/browser/application-shell-with-toolbar-override.ts +++ b/packages/toolbar/src/browser/application-shell-with-toolbar-override.ts @@ -34,7 +34,11 @@ export class ApplicationShellWithToolbarOverride extends ApplicationShell { protected toolbar: Toolbar; @postConstruct() - protected override async init(): Promise { + protected override init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.toolbar = this.toolbarFactory(); this.toolbar.id = 'main-toolbar'; super.init(); diff --git a/packages/toolbar/src/browser/toolbar-controller.ts b/packages/toolbar/src/browser/toolbar-controller.ts index 9c3598dc5fc26..09f384d8512a8 100644 --- a/packages/toolbar/src/browser/toolbar-controller.ts +++ b/packages/toolbar/src/browser/toolbar-controller.ts @@ -93,7 +93,11 @@ export class ToolbarController { } @postConstruct() - async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.appState.reachedState('ready'); await this.storageProvider.ready; this.toolbarItems = await this.resolveToolbarItems(); diff --git a/packages/toolbar/src/browser/toolbar-storage-provider.ts b/packages/toolbar/src/browser/toolbar-storage-provider.ts index d372bf3b6216e..9238fd9ff66ae 100644 --- a/packages/toolbar/src/browser/toolbar-storage-provider.ts +++ b/packages/toolbar/src/browser/toolbar-storage-provider.ts @@ -68,7 +68,11 @@ export class ToolbarStorageProvider implements Disposable { toolbarItems: DeflatedToolbarTree | undefined; @postConstruct() - async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const reference = await this.textModelService.createModelReference(this.USER_TOOLBAR_URI); this.model = reference.object; this.toDispose.push(reference); diff --git a/packages/toolbar/src/browser/toolbar.tsx b/packages/toolbar/src/browser/toolbar.tsx index 338225ca010b9..a4efe336d9920 100644 --- a/packages/toolbar/src/browser/toolbar.tsx +++ b/packages/toolbar/src/browser/toolbar.tsx @@ -51,7 +51,11 @@ export class ToolbarImpl extends TabBarToolbar { protected isBusyDeferred = new Deferred(); @postConstruct() - async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { this.hide(); await this.model.ready.promise; diff --git a/packages/vsx-registry/src/browser/vsx-extensions-model.ts b/packages/vsx-registry/src/browser/vsx-extensions-model.ts index 83cb29e10ba34..3a12b34cd3116 100644 --- a/packages/vsx-registry/src/browser/vsx-extensions-model.ts +++ b/packages/vsx-registry/src/browser/vsx-extensions-model.ts @@ -62,7 +62,11 @@ export class VSXExtensionsModel { protected readonly initialized = new Deferred(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await Promise.all([ this.initInstalled(), this.initSearchResult(), diff --git a/packages/vsx-registry/src/browser/vsx-extensions-source.ts b/packages/vsx-registry/src/browser/vsx-extensions-source.ts index ace3298f50f9b..57ca40e988cd7 100644 --- a/packages/vsx-registry/src/browser/vsx-extensions-source.ts +++ b/packages/vsx-registry/src/browser/vsx-extensions-source.ts @@ -38,7 +38,7 @@ export class VSXExtensionsSource extends TreeSource { protected readonly model: VSXExtensionsModel; @postConstruct() - protected async init(): Promise { + protected init(): void { this.fireDidChange(); this.toDispose.push(this.model.onDidChange(() => this.scheduleFireDidChange())); } diff --git a/packages/workspace/src/browser/workspace-service.ts b/packages/workspace/src/browser/workspace-service.ts index a2c97a17fa6ad..41358edfaf916 100644 --- a/packages/workspace/src/browser/workspace-service.ts +++ b/packages/workspace/src/browser/workspace-service.ts @@ -95,7 +95,11 @@ export class WorkspaceService implements FrontendApplicationContribution { } @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const wsUriString = await this.getDefaultWorkspaceUri(); const wsStat = await this.toFileStat(wsUriString); await this.setWorkspace(wsStat); diff --git a/packages/workspace/src/browser/workspace-trust-service.ts b/packages/workspace/src/browser/workspace-trust-service.ts index f9528eb9131dd..0caeca90b5c06 100644 --- a/packages/workspace/src/browser/workspace-trust-service.ts +++ b/packages/workspace/src/browser/workspace-trust-service.ts @@ -52,7 +52,11 @@ export class WorkspaceTrustService { protected workspaceTrust = new Deferred(); @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { await this.workspaceService.ready; await this.resolveWorkspaceTrust(); this.preferences.onPreferenceChanged(change => this.handlePreferenceChange(change)); diff --git a/packages/workspace/src/browser/workspace-uri-contribution.ts b/packages/workspace/src/browser/workspace-uri-contribution.ts index bfddb45985d08..f9973fd6d8ffe 100644 --- a/packages/workspace/src/browser/workspace-uri-contribution.ts +++ b/packages/workspace/src/browser/workspace-uri-contribution.ts @@ -28,7 +28,7 @@ export class WorkspaceUriLabelProviderContribution extends DefaultUriLabelProvid @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; @postConstruct() - override async init(): Promise { + override init(): void { // no-op, backward compatibility } diff --git a/packages/workspace/src/node/default-workspace-server.ts b/packages/workspace/src/node/default-workspace-server.ts index 60ef11bcddce6..564b27f6a9286 100644 --- a/packages/workspace/src/node/default-workspace-server.ts +++ b/packages/workspace/src/node/default-workspace-server.ts @@ -101,7 +101,11 @@ export class DefaultWorkspaceServer implements WorkspaceServer, BackendApplicati protected readonly utils: CommonWorkspaceUtils; @postConstruct() - protected async init(): Promise { + protected init(): void { + this.doInit(); + } + + protected async doInit(): Promise { const root = await this.getRoot(); this.root.resolve(root); } diff --git a/yarn.lock b/yarn.lock index e3f2f869b6fab..e9238875ce7ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6138,10 +6138,10 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -inversify@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.1.1.tgz#6fbd668c591337404e005a1946bfe0d802c08730" - integrity sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ== +inversify@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-6.0.1.tgz#b20d35425d5d8c5cd156120237aad0008d969f02" + integrity sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ== ip@^2.0.0: version "2.0.0"