Не подтверждена Коммит 6dd6e703 создал по автору Sandeep Somavarapu's avatar Sandeep Somavarapu Зафиксировано автором GitHub
Просмотр файлов

Handle resolver extension points before activating (#233721)

* Reapply "fix #229955 (#229959)" (#233567)

This reverts commit 86a992ae.

* Handle resolver extension points before activating - fixes #224236

* Revert "Reapply "fix #229955 (#229959)" (#233567)"

This reverts commit 3e435d65.

* improve handling resolver extensions

* move check into for loop

* clean up

* revert to fix failing test

* use existing method

* review feedback - stream resolved extensions

* fix

* undo
владелец 9847bdc7
......@@ -132,7 +132,8 @@ const defaultConfigurationExtPoint = ExtensionsRegistry.registerExtensionPoint<I
extensionPoint: 'configurationDefaults',
jsonSchema: {
$ref: configurationDefaultsSchemaId,
}
},
canHandleResolver: true
});
defaultConfigurationExtPoint.setHandler((extensions, { added, removed }) => {
......@@ -195,7 +196,8 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IConfigu
items: configurationEntrySchema
}
]
}
},
canHandleResolver: true
});
const extensionConfigurations: ExtensionIdentifierMap<IConfigurationNode[]> = new ExtensionIdentifierMap<IConfigurationNode[]>();
......
......@@ -26,7 +26,7 @@ import { IBrowserWorkbenchEnvironmentService } from '../../environment/browser/e
import { IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from '../../extensionManagement/common/extensionManagement.js';
import { IWebWorkerExtensionHostDataProvider, IWebWorkerExtensionHostInitData, WebWorkerExtensionHost } from './webWorkerExtensionHost.js';
import { FetchFileSystemProvider } from './webWorkerFileSystemProvider.js';
import { AbstractExtensionService, IExtensionHostFactory, ResolvedExtensions, checkEnabledAndProposedAPI } from '../common/abstractExtensionService.js';
import { AbstractExtensionService, IExtensionHostFactory, LocalExtensions, RemoteExtensions, ResolvedExtensions, ResolverExtensions, checkEnabledAndProposedAPI, isResolverExtension } from '../common/abstractExtensionService.js';
import { ExtensionDescriptionRegistrySnapshot } from '../common/extensionDescriptionRegistry.js';
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString, extensionRunningPreferenceToString } from '../common/extensionHostKind.js';
import { IExtensionManifestPropertiesService } from '../common/extensionManifestPropertiesService.js';
......@@ -41,6 +41,7 @@ import { IRemoteAgentService } from '../../remote/common/remoteAgentService.js';
import { IRemoteExplorerService } from '../../remote/common/remoteExplorerService.js';
import { IUserDataInitializationService } from '../../userData/browser/userDataInit.js';
import { IUserDataProfileService } from '../../userDataProfile/common/userDataProfile.js';
import { AsyncIterableEmitter, AsyncIterableObject } from '../../../../base/common/async.js';
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
......@@ -80,6 +81,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
logService
);
super(
{ hasLocalProcess: false, allowRemoteExtensionsInLocalWebWorker: true },
extensionsProposedApi,
extensionHostFactory,
new BrowserExtensionHostKindPicker(logService),
......@@ -117,32 +119,45 @@ export class ExtensionService extends AbstractExtensionService implements IExten
this._register(this._fileService.registerProvider(Schemas.https, provider));
}
private _scanWebExtensionsPromise: Promise<IExtensionDescription[]> | undefined;
private async _scanWebExtensions(): Promise<IExtensionDescription[]> {
const system: IExtensionDescription[] = [], user: IExtensionDescription[] = [], development: IExtensionDescription[] = [];
try {
await Promise.all([
this._webExtensionsScannerService.scanSystemExtensions().then(extensions => system.push(...extensions.map(e => toExtensionDescription(e)))),
this._webExtensionsScannerService.scanUserExtensions(this._userDataProfileService.currentProfile.extensionsResource, { skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))),
this._webExtensionsScannerService.scanExtensionsUnderDevelopment().then(extensions => development.push(...extensions.map(e => toExtensionDescription(e, true))))
]);
} catch (error) {
this._logService.error(error);
if (!this._scanWebExtensionsPromise) {
this._scanWebExtensionsPromise = (async () => {
const system: IExtensionDescription[] = [], user: IExtensionDescription[] = [], development: IExtensionDescription[] = [];
try {
await Promise.all([
this._webExtensionsScannerService.scanSystemExtensions().then(extensions => system.push(...extensions.map(e => toExtensionDescription(e)))),
this._webExtensionsScannerService.scanUserExtensions(this._userDataProfileService.currentProfile.extensionsResource, { skipInvalidExtensions: true }).then(extensions => user.push(...extensions.map(e => toExtensionDescription(e)))),
this._webExtensionsScannerService.scanExtensionsUnderDevelopment().then(extensions => development.push(...extensions.map(e => toExtensionDescription(e, true))))
]);
} catch (error) {
this._logService.error(error);
}
return dedupExtensions(system, user, [], development, this._logService);
})();
}
return dedupExtensions(system, user, [], development, this._logService);
return this._scanWebExtensionsPromise;
}
protected async _resolveExtensionsDefault() {
private async _resolveExtensionsDefault(emitter: AsyncIterableEmitter<ResolvedExtensions>) {
const [localExtensions, remoteExtensions] = await Promise.all([
this._scanWebExtensions(),
this._remoteExtensionsScannerService.scanExtensions()
]);
return new ResolvedExtensions(localExtensions, remoteExtensions, /*hasLocalProcess*/false, /*allowRemoteExtensionsInLocalWebWorker*/true);
if (remoteExtensions.length) {
emitter.emitOne(new RemoteExtensions(remoteExtensions));
}
emitter.emitOne(new LocalExtensions(localExtensions));
}
protected _resolveExtensions(): AsyncIterable<ResolvedExtensions> {
return new AsyncIterableObject(emitter => this._doResolveExtensions(emitter));
}
protected async _resolveExtensions(): Promise<ResolvedExtensions> {
private async _doResolveExtensions(emitter: AsyncIterableEmitter<ResolvedExtensions>): Promise<void> {
if (!this._browserEnvironmentService.expectsResolverExtension) {
return this._resolveExtensionsDefault();
return this._resolveExtensionsDefault(emitter);
}
const remoteAuthority = this._environmentService.remoteAuthority!;
......@@ -152,6 +167,11 @@ export class ExtensionService extends AbstractExtensionService implements IExten
// override the trust state through the resolver result.
await this._workspaceTrustManagementService.workspaceResolved;
const localExtensions = await this._scanWebExtensions();
const resolverExtensions = localExtensions.filter(extension => isResolverExtension(extension));
if (resolverExtensions.length) {
emitter.emitOne(new ResolverExtensions(resolverExtensions));
}
let resolverResult: ResolverResult;
try {
......@@ -163,7 +183,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
this._remoteAuthorityResolverService._setResolvedAuthorityError(remoteAuthority, err);
// Proceed with the local extension host
return this._resolveExtensionsDefault();
return this._resolveExtensionsDefault(emitter);
}
// set the resolved authority
......@@ -181,7 +201,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
connection.onReconnecting(() => this._resolveAuthorityAgain());
}
return this._resolveExtensionsDefault();
return this._resolveExtensionsDefault(emitter);
}
protected async _onExtensionHostExit(code: number): Promise<void> {
......
......@@ -61,6 +61,9 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
public _serviceBrand: undefined;
private readonly _hasLocalProcess: boolean;
private readonly _allowRemoteExtensionsInLocalWebWorker: boolean;
private readonly _onDidRegisterExtensions = this._register(new Emitter<void>());
public readonly onDidRegisterExtensions = this._onDidRegisterExtensions.event;
......@@ -95,6 +98,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
private _resolveAuthorityAttempt: number = 0;
constructor(
options: { hasLocalProcess: boolean; allowRemoteExtensionsInLocalWebWorker: boolean },
private readonly _extensionsProposedApi: ExtensionsProposedApi,
private readonly _extensionHostFactory: IExtensionHostFactory,
private readonly _extensionHostKindPicker: IExtensionHostKindPicker,
......@@ -118,6 +122,9 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
) {
super();
this._hasLocalProcess = options.hasLocalProcess;
this._allowRemoteExtensionsInLocalWebWorker = options.allowRemoteExtensionsInLocalWebWorker;
// help the file service to activate providers by activating extensions by file system event
this._register(this._fileService.onWillActivateFileSystemProvider(e => {
if (e.scheme !== Schemas.vscodeRemote) {
......@@ -318,7 +325,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
this._extensionsProposedApi.updateEnabledApiProposals(toAdd);
// Update extension points
this._doHandleExtensionPoints((<IExtensionDescription[]>[]).concat(toAdd).concat(toRemove));
this._doHandleExtensionPoints((<IExtensionDescription[]>[]).concat(toAdd).concat(toRemove), false);
// Update the extension host
await this._updateExtensionsOnExtHosts(result.versionId, toAdd, toRemove.map(e => e.identifier));
......@@ -453,10 +460,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
const lock = await this._registry.acquireLock('_initialize');
try {
const resolvedExtensions = await this._resolveExtensions();
this._processExtensions(lock, resolvedExtensions);
await this._resolveAndProcessExtensions(lock);
// Start extension hosts which are not automatically started
const snapshot = this._registry.getSnapshot();
for (const extHostManager of this._extensionHostManagers) {
......@@ -474,10 +478,24 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
await this._handleExtensionTests();
}
private _processExtensions(lock: ExtensionDescriptionRegistryLock, resolvedExtensions: ResolvedExtensions): void {
const { allowRemoteExtensionsInLocalWebWorker, hasLocalProcess } = resolvedExtensions;
const localExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, resolvedExtensions.local, false);
let remoteExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, resolvedExtensions.remote, false);
private async _resolveAndProcessExtensions(lock: ExtensionDescriptionRegistryLock,): Promise<void> {
let resolverExtensions: IExtensionDescription[] = [];
let localExtensions: IExtensionDescription[] = [];
let remoteExtensions: IExtensionDescription[] = [];
for await (const extensions of this._resolveExtensions()) {
if (extensions instanceof ResolverExtensions) {
resolverExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, extensions.extensions, false);
this._registry.deltaExtensions(lock, resolverExtensions, []);
this._doHandleExtensionPoints(resolverExtensions, true);
}
if (extensions instanceof LocalExtensions) {
localExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, extensions.extensions, false);
}
if (extensions instanceof RemoteExtensions) {
remoteExtensions = checkEnabledAndProposedAPI(this._logService, this._extensionEnablementService, this._extensionsProposedApi, extensions.extensions, false);
}
}
// `initializeRunningLocation` will look at the complete picture (e.g. an extension installed on both sides),
// takes care of duplicates and picks a running location for each extension
......@@ -486,8 +504,8 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
this._startExtensionHostsIfNecessary(true, []);
// Some remote extensions could run locally in the web worker, so store them
const remoteExtensionsThatNeedToRunLocally = (allowRemoteExtensionsInLocalWebWorker ? this._runningLocations.filterByExtensionHostKind(remoteExtensions, ExtensionHostKind.LocalWebWorker) : []);
const localProcessExtensions = (hasLocalProcess ? this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalProcess) : []);
const remoteExtensionsThatNeedToRunLocally = (this._allowRemoteExtensionsInLocalWebWorker ? this._runningLocations.filterByExtensionHostKind(remoteExtensions, ExtensionHostKind.LocalWebWorker) : []);
const localProcessExtensions = (this._hasLocalProcess ? this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalProcess) : []);
const localWebWorkerExtensions = this._runningLocations.filterByExtensionHostKind(localExtensions, ExtensionHostKind.LocalWebWorker);
remoteExtensions = this._runningLocations.filterByExtensionHostKind(remoteExtensions, ExtensionHostKind.Remote);
......@@ -499,8 +517,22 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
}
const allExtensions = remoteExtensions.concat(localProcessExtensions).concat(localWebWorkerExtensions);
let toAdd = allExtensions;
if (resolverExtensions.length) {
// Add extensions that are not registered as resolvers but are in the final resolved set
toAdd = allExtensions.filter(extension => !resolverExtensions.some(e => ExtensionIdentifier.equals(e.identifier, extension.identifier) && e.extensionLocation.toString() === extension.extensionLocation.toString()));
// Remove extensions that are registered as resolvers but are not in the final resolved set
if (allExtensions.length < toAdd.length + resolverExtensions.length) {
const toRemove = resolverExtensions.filter(registered => !allExtensions.some(e => ExtensionIdentifier.equals(e.identifier, registered.identifier) && e.extensionLocation.toString() === registered.extensionLocation.toString()));
if (toRemove.length) {
this._registry.deltaExtensions(lock, [], toRemove.map(e => e.identifier));
this._doHandleExtensionPoints(toRemove, true);
}
}
}
const result = this._registry.deltaExtensions(lock, allExtensions, []);
const result = this._registry.deltaExtensions(lock, toAdd, []);
if (result.removedDueToLooping.length > 0) {
this._notificationService.notify({
severity: Severity.Error,
......@@ -508,7 +540,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
});
}
this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions());
this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions(), false);
}
private async _handleExtensionTests(): Promise<void> {
......@@ -1031,7 +1063,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
}
}
private _doHandleExtensionPoints(affectedExtensions: IExtensionDescription[]): void {
private _doHandleExtensionPoints(affectedExtensions: IExtensionDescription[], onlyResolverExtensionPoints: boolean): void {
const affectedExtensionPoints: { [extPointName: string]: boolean } = Object.create(null);
for (const extensionDescription of affectedExtensions) {
if (extensionDescription.contributes) {
......@@ -1046,15 +1078,15 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
const messageHandler = (msg: IMessage) => this._handleExtensionPointMessage(msg);
const availableExtensions = this._registry.getAllExtensionDescriptions();
const extensionPoints = ExtensionsRegistry.getExtensionPoints();
perf.mark('code/willHandleExtensionPoints');
perf.mark(onlyResolverExtensionPoints ? 'code/willHandleResolverExtensionPoints' : 'code/willHandleExtensionPoints');
for (const extensionPoint of extensionPoints) {
if (affectedExtensionPoints[extensionPoint.name]) {
if (affectedExtensionPoints[extensionPoint.name] && (!onlyResolverExtensionPoints || extensionPoint.canHandleResolver)) {
perf.mark(`code/willHandleExtensionPoint/${extensionPoint.name}`);
AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler);
perf.mark(`code/didHandleExtensionPoint/${extensionPoint.name}`);
}
}
perf.mark('code/didHandleExtensionPoints');
perf.mark(onlyResolverExtensionPoints ? 'code/didHandleResolverExtensionPoints' : 'code/didHandleExtensionPoints');
}
private _getOrCreateExtensionStatus(extensionId: ExtensionIdentifier): ExtensionStatus {
......@@ -1192,7 +1224,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
//#endregion
protected abstract _resolveExtensions(): Promise<ResolvedExtensions>;
protected abstract _resolveExtensions(): AsyncIterable<ResolvedExtensions>;
protected abstract _onExtensionHostExit(code: number): Promise<void>;
protected abstract _resolveAuthority(remoteAuthority: string): Promise<ResolverResult>;
}
......@@ -1280,15 +1312,26 @@ class ExtensionHostManagerData {
}
}
export class ResolvedExtensions {
export class ResolverExtensions {
constructor(
public readonly local: IExtensionDescription[],
public readonly remote: IExtensionDescription[],
public readonly hasLocalProcess: boolean,
public readonly allowRemoteExtensionsInLocalWebWorker: boolean
public readonly extensions: IExtensionDescription[],
) { }
}
export class LocalExtensions {
constructor(
public readonly extensions: IExtensionDescription[],
) { }
}
export class RemoteExtensions {
constructor(
public readonly extensions: IExtensionDescription[],
) { }
}
export type ResolvedExtensions = ResolverExtensions | LocalExtensions | RemoteExtensions;
export interface IExtensionHostFactory {
createExtensionHost(runningLocations: ExtensionRunningLocationTracker, runningLocation: ExtensionRunningLocation, isInitialStart: boolean): IExtensionHost | null;
}
......@@ -1300,6 +1343,10 @@ class DeltaExtensionsQueueItem {
) { }
}
export function isResolverExtension(extension: IExtensionDescription): boolean {
return !!extension.activationEvents?.some(activationEvent => activationEvent.startsWith('onResolveRemoteAuthority:'));
}
/**
* @argument extensions The extensions to be checked.
* @argument ignoreWorkspaceTrust Do not take workspace trust into account.
......
......@@ -70,6 +70,7 @@ export interface IExtensionPoint<T> {
readonly name: string;
setHandler(handler: IExtensionPointHandler<T>): IDisposable;
readonly defaultExtensionKind: ExtensionKind[] | undefined;
readonly canHandleResolver?: boolean;
}
export class ExtensionPointUserDelta<T> {
......@@ -109,14 +110,16 @@ export class ExtensionPoint<T> implements IExtensionPoint<T> {
public readonly name: string;
public readonly defaultExtensionKind: ExtensionKind[] | undefined;
public readonly canHandleResolver?: boolean;
private _handler: IExtensionPointHandler<T> | null;
private _users: IExtensionPointUser<T>[] | null;
private _delta: ExtensionPointUserDelta<T> | null;
constructor(name: string, defaultExtensionKind: ExtensionKind[] | undefined) {
constructor(name: string, defaultExtensionKind: ExtensionKind[] | undefined, canHandleResolver?: boolean) {
this.name = name;
this.defaultExtensionKind = defaultExtensionKind;
this.canHandleResolver = canHandleResolver;
this._handler = null;
this._users = null;
this._delta = null;
......@@ -608,6 +611,7 @@ export interface IExtensionPointDescriptor<T> {
deps?: IExtensionPoint<any>[];
jsonSchema: IJSONSchema;
defaultExtensionKind?: ExtensionKind[];
canHandleResolver?: boolean;
/**
* A function which runs before the extension point has been validated and which
* should collect automatic activation events from the contribution.
......@@ -623,7 +627,7 @@ export class ExtensionsRegistryImpl {
if (this._extensionPoints.has(desc.extensionPoint)) {
throw new Error('Duplicate extension point: ' + desc.extensionPoint);
}
const result = new ExtensionPoint<T>(desc.extensionPoint, desc.defaultExtensionKind);
const result = new ExtensionPoint<T>(desc.extensionPoint, desc.defaultExtensionKind, desc.canHandleResolver);
this._extensionPoints.set(desc.extensionPoint, result);
if (desc.activationEventsGenerator) {
ImplicitActivationEvents.register(desc.extensionPoint, desc.activationEventsGenerator);
......
......@@ -40,7 +40,7 @@ import { IWorkspaceTrustManagementService } from '../../../../platform/workspace
import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js';
import { EnablementState, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from '../../extensionManagement/common/extensionManagement.js';
import { IWebWorkerExtensionHostDataProvider, IWebWorkerExtensionHostInitData, WebWorkerExtensionHost } from '../browser/webWorkerExtensionHost.js';
import { AbstractExtensionService, ExtensionHostCrashTracker, IExtensionHostFactory, ResolvedExtensions, checkEnabledAndProposedAPI, extensionIsEnabled } from '../common/abstractExtensionService.js';
import { AbstractExtensionService, ExtensionHostCrashTracker, IExtensionHostFactory, LocalExtensions, RemoteExtensions, ResolvedExtensions, ResolverExtensions, checkEnabledAndProposedAPI, extensionIsEnabled, isResolverExtension } from '../common/abstractExtensionService.js';
import { ExtensionDescriptionRegistrySnapshot } from '../common/extensionDescriptionRegistry.js';
import { parseExtensionDevOptions } from '../common/extensionDevOptions.js';
import { ExtensionHostKind, ExtensionRunningPreference, IExtensionHostKindPicker, extensionHostKindToString, extensionRunningPreferenceToString } from '../common/extensionHostKind.js';
......@@ -58,6 +58,7 @@ import { IHostService } from '../../host/browser/host.js';
import { ILifecycleService, LifecyclePhase } from '../../lifecycle/common/lifecycle.js';
import { IRemoteAgentService } from '../../remote/common/remoteAgentService.js';
import { IRemoteExplorerService } from '../../remote/common/remoteExplorerService.js';
import { AsyncIterableEmitter, AsyncIterableObject } from '../../../../base/common/async.js';
export class NativeExtensionService extends AbstractExtensionService implements IExtensionService {
......@@ -103,6 +104,7 @@ export class NativeExtensionService extends AbstractExtensionService implements
logService
);
super(
{ hasLocalProcess: true, allowRemoteExtensionsInLocalWebWorker: false },
extensionsProposedApi,
extensionHostFactory,
new NativeExtensionHostKindPicker(environmentService, configurationService, logService),
......@@ -316,7 +318,11 @@ export class NativeExtensionService extends AbstractExtensionService implements
throw new Error(`Cannot get canonical URI because no extension is installed to resolve ${getRemoteAuthorityPrefix(remoteAuthority)}`);
}
protected async _resolveExtensions(): Promise<ResolvedExtensions> {
protected _resolveExtensions(): AsyncIterable<ResolvedExtensions> {
return new AsyncIterableObject(emitter => this._doResolveExtensions(emitter));
}
private async _doResolveExtensions(emitter: AsyncIterableEmitter<ResolvedExtensions>): Promise<void> {
this._extensionScanner.startScanningExtensions();
const remoteAuthority = this._environmentService.remoteAuthority;
......@@ -358,6 +364,12 @@ export class NativeExtensionService extends AbstractExtensionService implements
this._logService.info(`Finished waiting on IWorkspaceTrustManagementService.workspaceResolved.`);
}
const localExtensions = await this._scanAllLocalExtensions();
const resolverExtensions = localExtensions.filter(extension => isResolverExtension(extension));
if (resolverExtensions.length) {
emitter.emitOne(new ResolverExtensions(resolverExtensions));
}
let resolverResult: ResolverResult;
try {
resolverResult = await this._resolveAuthorityInitial(remoteAuthority);
......@@ -372,7 +384,7 @@ export class NativeExtensionService extends AbstractExtensionService implements
this._remoteAuthorityResolverService._setResolvedAuthorityError(remoteAuthority, err);
// Proceed with the local extension host
return this._startLocalExtensionHost();
return this._startLocalExtensionHost(emitter);
}
// set the resolved authority
......@@ -399,7 +411,7 @@ export class NativeExtensionService extends AbstractExtensionService implements
if (!remoteEnv) {
this._notificationService.notify({ severity: Severity.Error, message: nls.localize('getEnvironmentFailure', "Could not fetch remote environment") });
// Proceed with the local extension host
return this._startLocalExtensionHost();
return this._startLocalExtensionHost(emitter);
}
updateProxyConfigurationsScope(remoteEnv.useHostProxy ? ConfigurationScope.APPLICATION : ConfigurationScope.MACHINE);
......@@ -409,15 +421,19 @@ export class NativeExtensionService extends AbstractExtensionService implements
}
return this._startLocalExtensionHost(remoteExtensions);
return this._startLocalExtensionHost(emitter, remoteExtensions);
}
private async _startLocalExtensionHost(remoteExtensions: IExtensionDescription[] = []): Promise<ResolvedExtensions> {
private async _startLocalExtensionHost(emitter: AsyncIterableEmitter<ResolvedExtensions>, remoteExtensions: IExtensionDescription[] = []): Promise<void> {
// Ensure that the workspace trust state has been fully initialized so
// that the extension host can start with the correct set of extensions.
await this._workspaceTrustManagementService.workspaceTrustInitialized;
return new ResolvedExtensions(await this._scanAllLocalExtensions(), remoteExtensions, /*hasLocalProcess*/true, /*allowRemoteExtensionsInLocalWebWorker*/false);
if (remoteExtensions.length) {
emitter.emitOne(new RemoteExtensions(remoteExtensions));
}
emitter.emitOne(new LocalExtensions(await this._scanAllLocalExtensions()));
}
protected async _onExtensionHostExit(code: number): Promise<void> {
......
......@@ -163,6 +163,7 @@ suite('ExtensionService', () => {
}
};
super(
{ allowRemoteExtensionsInLocalWebWorker: false, hasLocalProcess: true },
extensionsProposedApi,
extensionHostFactory,
null!,
......@@ -209,7 +210,7 @@ suite('ExtensionService', () => {
}
};
}
protected _resolveExtensions(): Promise<ResolvedExtensions> {
protected _resolveExtensions(): AsyncIterable<ResolvedExtensions> {
throw new Error('Method not implemented.');
}
protected _scanSingleExtension(extension: IExtension): Promise<IExtensionDescription | null> {
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать