UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

330 lines (327 loc) 15.2 kB
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js'; import { localize, localize2 } from 'vscode/vscode/vs/nls'; import { IExtensionManagementService, IGlobalExtensionEnablementService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement.service'; import { StorageScope, StorageTarget } from 'vscode/vscode/vs/platform/storage/common/storage'; import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service'; import { isResolverExtension, ExtensionType } from 'vscode/vscode/vs/platform/extensions/common/extensions'; import 'vscode/vscode/vs/platform/instantiation/common/extensions'; import { NotificationPriority } from 'vscode/vscode/vs/platform/notification/common/notification'; import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification.service'; import { IHostService } from 'vscode/vscode/vs/workbench/services/host/browser/host.service'; import { registerAction2, Action2, MenuId } from 'vscode/vscode/vs/platform/actions/common/actions'; import { RawContextKey, ContextKeyExpr } from 'vscode/vscode/vs/platform/contextkey/common/contextkey'; import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey.service'; import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs.service'; import { LifecyclePhase } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle'; import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform'; import { Extensions } from 'vscode/vscode/vs/workbench/common/contributions'; import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service'; import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service'; import { IProductService } from 'vscode/vscode/vs/platform/product/common/productService.service'; import { IWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/common/environmentService.service'; import { areSameExtensions } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil'; import { Categories } from 'vscode/vscode/vs/platform/action/common/actionCommonCategories'; import { IWorkbenchExtensionEnablementService } from 'vscode/vscode/vs/workbench/services/extensionManagement/common/extensionManagement.service'; import { IExtensionBisectService } from 'vscode/vscode/vs/workbench/services/extensionManagement/browser/extensionBisect.service'; import Severity$1 from 'vscode/vscode/vs/base/common/severity'; var ExtensionBisectService_1, ExtensionBisectUi_1; class BisectState { static fromJSON(raw) { if (!raw) { return undefined; } try { const data = JSON.parse(raw); return ( (new BisectState(data.extensions, data.low, data.high, data.mid)) ); } catch { return undefined; } } constructor(extensions, low, high, mid = ((low + high) / 2) | 0) { this.extensions = extensions; this.low = low; this.high = high; this.mid = mid; } } let ExtensionBisectService = class ExtensionBisectService { static { ExtensionBisectService_1 = this; } static { this._storageKey = 'extensionBisectState'; } constructor(logService, _storageService, _envService) { this._storageService = _storageService; this._envService = _envService; this._disabled = ( (new Map())); const raw = _storageService.get(ExtensionBisectService_1._storageKey, StorageScope.APPLICATION); this._state = BisectState.fromJSON(raw); if (this._state) { const { mid, high } = this._state; for (let i = 0; i < this._state.extensions.length; i++) { const isDisabled = i >= mid && i < high; this._disabled.set(this._state.extensions[i], isDisabled); } logService.warn('extension BISECT active', [...this._disabled]); } } get isActive() { return !!this._state; } get disabledCount() { return this._state ? this._state.high - this._state.mid : -1; } isDisabledByBisect(extension) { if (!this._state) { return false; } if (isResolverExtension(extension.manifest, this._envService.remoteAuthority)) { return false; } if (this._isEnabledInEnv(extension)) { return false; } const disabled = this._disabled.get(extension.identifier.id); return disabled ?? false; } _isEnabledInEnv(extension) { return Array.isArray(this._envService.enableExtensions) && ( (this._envService.enableExtensions.some(id => areSameExtensions({ id }, extension.identifier)))); } async start(extensions) { if (this._state) { throw ( (new Error('invalid state'))); } const extensionIds = ( (extensions.map(ext => ext.identifier.id))); const newState = ( (new BisectState(extensionIds, 0, extensionIds.length, 0))); this._storageService.store(ExtensionBisectService_1._storageKey, JSON.stringify(newState), StorageScope.APPLICATION, StorageTarget.MACHINE); await this._storageService.flush(); } async next(seeingBad) { if (!this._state) { throw ( (new Error('invalid state'))); } if (seeingBad && this._state.mid === 0 && this._state.high === this._state.extensions.length) { return { bad: true, id: '' }; } if (this._state.low === this._state.high - 1) { await this.reset(); return { id: this._state.extensions[this._state.low], bad: seeingBad }; } const nextState = ( (new BisectState( this._state.extensions, seeingBad ? this._state.low : this._state.mid, seeingBad ? this._state.mid : this._state.high ))); this._storageService.store(ExtensionBisectService_1._storageKey, JSON.stringify(nextState), StorageScope.APPLICATION, StorageTarget.MACHINE); await this._storageService.flush(); return undefined; } async reset() { this._storageService.remove(ExtensionBisectService_1._storageKey, StorageScope.APPLICATION); await this._storageService.flush(); } }; ExtensionBisectService = ExtensionBisectService_1 = ( (__decorate([ ( (__param(0, ILogService))), ( (__param(1, IStorageService))), ( (__param(2, IWorkbenchEnvironmentService))) ], ExtensionBisectService))); let ExtensionBisectUi = class ExtensionBisectUi { static { ExtensionBisectUi_1 = this; } static { this.ctxIsBisectActive = ( (new RawContextKey('isExtensionBisectActive', false))); } constructor(contextKeyService, _extensionBisectService, _notificationService, _commandService) { this._extensionBisectService = _extensionBisectService; this._notificationService = _notificationService; this._commandService = _commandService; if (_extensionBisectService.isActive) { ExtensionBisectUi_1.ctxIsBisectActive.bindTo(contextKeyService).set(true); this._showBisectPrompt(); } } _showBisectPrompt() { const goodPrompt = { label: ( localize(1138, "I can't reproduce")), run: () => this._commandService.executeCommand('extension.bisect.next', false) }; const badPrompt = { label: ( localize(1139, "I can reproduce")), run: () => this._commandService.executeCommand('extension.bisect.next', true) }; const stop = { label: 'Stop Bisect', run: () => this._commandService.executeCommand('extension.bisect.stop') }; const message = this._extensionBisectService.disabledCount === 1 ? ( localize( 1140, "Extension Bisect is active and has disabled 1 extension. Check if you can still reproduce the problem and proceed by selecting from these options." )) : ( localize( 1141, "Extension Bisect is active and has disabled {0} extensions. Check if you can still reproduce the problem and proceed by selecting from these options.", this._extensionBisectService.disabledCount )); this._notificationService.prompt(Severity$1.Info, message, [goodPrompt, badPrompt, stop], { sticky: true, priority: NotificationPriority.URGENT }); } }; ExtensionBisectUi = ExtensionBisectUi_1 = ( (__decorate([ ( (__param(0, IContextKeyService))), ( (__param(1, IExtensionBisectService))), ( (__param(2, INotificationService))), ( (__param(3, ICommandService))) ], ExtensionBisectUi))); ( (Registry.as(Extensions.Workbench))).registerWorkbenchContribution(ExtensionBisectUi, LifecyclePhase.Restored); registerAction2(class extends Action2 { constructor() { super({ id: 'extension.bisect.start', title: ( localize2(1142, 'Start Extension Bisect')), category: Categories.Help, f1: true, precondition: ( (ExtensionBisectUi.ctxIsBisectActive.negate())), menu: { id: MenuId.ViewContainerTitle, when: ( (ContextKeyExpr.equals('viewContainer', 'workbench.view.extensions'))), group: '2_enablement', order: 4 } }); } async run(accessor) { const dialogService = accessor.get(IDialogService); const hostService = accessor.get(IHostService); const extensionManagement = accessor.get(IExtensionManagementService); const extensionEnablementService = accessor.get(IWorkbenchExtensionEnablementService); const extensionsBisect = accessor.get(IExtensionBisectService); const extensions = (await extensionManagement.getInstalled(ExtensionType.User)).filter(ext => extensionEnablementService.isEnabled(ext)); const res = await dialogService.confirm({ message: ( localize(1143, "Extension Bisect")), detail: ( localize( 1144, "Extension Bisect will use binary search to find an extension that causes a problem. During the process the window reloads repeatedly (~{0} times). Each time you must confirm if you are still seeing problems.", 2 + Math.log2(extensions.length) | 0 )), primaryButton: ( localize(1145, "&&Start Extension Bisect")) }); if (res.confirmed) { await extensionsBisect.start(extensions); hostService.reload(); } } }); registerAction2(class extends Action2 { constructor() { super({ id: 'extension.bisect.next', title: ( localize2(1146, 'Continue Extension Bisect')), category: Categories.Help, f1: true, precondition: ExtensionBisectUi.ctxIsBisectActive }); } async run(accessor, seeingBad) { const dialogService = accessor.get(IDialogService); const hostService = accessor.get(IHostService); const bisectService = accessor.get(IExtensionBisectService); const productService = accessor.get(IProductService); const extensionEnablementService = accessor.get(IGlobalExtensionEnablementService); const commandService = accessor.get(ICommandService); if (!bisectService.isActive) { return; } if (seeingBad === undefined) { const goodBadStopCancel = await this._checkForBad(dialogService, bisectService); if (goodBadStopCancel === null) { return; } seeingBad = goodBadStopCancel; } if (seeingBad === undefined) { await bisectService.reset(); hostService.reload(); return; } const done = await bisectService.next(seeingBad); if (!done) { hostService.reload(); return; } if (done.bad) { await dialogService.info(( localize(1147, "Extension Bisect")), ( localize( 1148, "Extension Bisect is done but no extension has been identified. This might be a problem with {0}.", productService.nameShort ))); } else { const res = await dialogService.confirm({ type: Severity$1.Info, message: ( localize(1147, "Extension Bisect")), primaryButton: ( localize(1149, "&&Report Issue & Continue")), cancelButton: ( localize(1150, "Continue")), detail: ( localize( 1151, "Extension Bisect is done and has identified {0} as the extension causing the problem.", done.id )), checkbox: { label: ( localize(1152, "Keep this extension disabled")), checked: true } }); if (res.checkboxChecked) { await extensionEnablementService.disableExtension({ id: done.id }, undefined); } if (res.confirmed) { await commandService.executeCommand('workbench.action.openIssueReporter', done.id); } } await bisectService.reset(); hostService.reload(); } async _checkForBad(dialogService, bisectService) { const { result } = await dialogService.prompt({ type: Severity$1.Info, message: ( localize(1153, "Extension Bisect")), detail: ( localize( 1154, "Extension Bisect is active and has disabled {0} extensions. Check if you can still reproduce the problem and proceed by selecting from these options.", bisectService.disabledCount )), buttons: [ { label: ( localize(1155, "I ca&&n't reproduce")), run: () => false }, { label: ( localize(1156, "I can &&reproduce")), run: () => true }, { label: ( localize(1157, "&&Stop Bisect")), run: () => undefined } ], cancelButton: { label: ( localize(1158, "&&Cancel Bisect")), run: () => null } }); return result; } }); registerAction2(class extends Action2 { constructor() { super({ id: 'extension.bisect.stop', title: ( localize2(1159, 'Stop Extension Bisect')), category: Categories.Help, f1: true, precondition: ExtensionBisectUi.ctxIsBisectActive }); } async run(accessor) { const extensionsBisect = accessor.get(IExtensionBisectService); const hostService = accessor.get(IHostService); await extensionsBisect.reset(); hostService.reload(); } }); export { ExtensionBisectService };