mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 11:08:31 -05:00
Merge from vscode 70dc55955d586ebd427658b43cdb344f2047f9c2 (#6789)
This commit is contained in:
@@ -22,10 +22,16 @@ import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
|
||||
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null;
|
||||
private _disposables = new DisposableStore();
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null = null;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@@ -37,6 +43,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
@IProductService productService: IProductService,
|
||||
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
@IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService,
|
||||
) {
|
||||
super(
|
||||
instantiationService,
|
||||
@@ -48,8 +55,19 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
productService,
|
||||
);
|
||||
|
||||
this._remoteExtensionsEnvironmentData = null;
|
||||
this._initialize();
|
||||
this._initFetchFileSystem();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _initFetchFileSystem(): void {
|
||||
const provider = new FetchFileSystemProvider();
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.http, provider));
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.https, provider));
|
||||
}
|
||||
|
||||
private _createProvider(remoteAuthority: string): IInitDataProvider {
|
||||
@@ -84,23 +102,31 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
|
||||
protected async _scanAndHandleExtensions(): Promise<void> {
|
||||
// fetch the remote environment
|
||||
const remoteEnv = (await this._remoteAgentService.getEnvironment())!;
|
||||
let [remoteEnv, localExtensions] = await Promise.all([
|
||||
<Promise<IRemoteAgentEnvironment>>this._remoteAgentService.getEnvironment(),
|
||||
this._staticExtensions.getExtensions()
|
||||
]);
|
||||
|
||||
// enable or disable proposed API per extension
|
||||
// local: only enabled and web'ish extension
|
||||
localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService));
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
|
||||
// remote: only enabled and none-web'ish extension
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService));
|
||||
this._checkEnableProposedApi(remoteEnv.extensions);
|
||||
|
||||
// remove disabled extensions
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension));
|
||||
// in case of overlap, the remote wins
|
||||
const isRemoteExtension = new Set<string>();
|
||||
remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData = remoteEnv;
|
||||
|
||||
// this._handleExtensionPoints((<IExtensionDescription[]>[]).concat(remoteEnv.extensions).concat(localExtensions));
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions, []);
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []);
|
||||
if (result.removedDueToLooping.length > 0) {
|
||||
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
|
||||
}
|
||||
|
||||
this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter {
|
||||
};
|
||||
|
||||
worker.onerror = (event) => {
|
||||
console.error(event.error);
|
||||
this._onDidExit.fire([81, event.error]);
|
||||
console.error(event.message, event.error);
|
||||
this._onDidExit.fire([81, event.message || event.error]);
|
||||
};
|
||||
|
||||
// keep for cleanup
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IFileSystemProvider, FileSystemProviderCapabilities, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileSystemProviderError, FileSystemProviderErrorCode } from 'vs/platform/files/common/files';
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NotImplementedError } from 'vs/base/common/errors';
|
||||
|
||||
export class FetchFileSystemProvider implements IFileSystemProvider {
|
||||
|
||||
readonly capabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite + FileSystemProviderCapabilities.PathCaseSensitive;
|
||||
readonly onDidChangeCapabilities = Event.None;
|
||||
readonly onDidChangeFile = Event.None;
|
||||
|
||||
// working implementations
|
||||
async readFile(resource: URI): Promise<Uint8Array> {
|
||||
try {
|
||||
const res = await fetch(resource.toString(true));
|
||||
if (res.status === 200) {
|
||||
return new Uint8Array(await res.arrayBuffer());
|
||||
}
|
||||
throw new FileSystemProviderError(res.statusText, FileSystemProviderErrorCode.Unknown);
|
||||
} catch (err) {
|
||||
throw new FileSystemProviderError(err, FileSystemProviderErrorCode.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
// fake implementations
|
||||
async stat(_resource: URI): Promise<IStat> {
|
||||
return {
|
||||
type: FileType.File,
|
||||
size: 0,
|
||||
mtime: 0,
|
||||
ctime: 0
|
||||
};
|
||||
}
|
||||
|
||||
watch(): IDisposable {
|
||||
return Disposable.None;
|
||||
}
|
||||
|
||||
// error implementations
|
||||
writeFile(_resource: URI, _content: Uint8Array, _opts: FileWriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
readdir(_resource: URI): Promise<[string, FileType][]> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
mkdir(_resource: URI): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
delete(_resource: URI, _opts: FileDeleteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
rename(_from: URI, _to: URI, _opts: FileOverwriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user