mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)
* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c * remove files we don't want * fix hygiene * update distro * update distro * fix hygiene * fix strict nulls * distro * distro * fix tests * fix tests * add another edit * fix viewlet icon * fix azure dialog * fix some padding * fix more padding issues
This commit is contained in:
@@ -20,7 +20,7 @@ import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEn
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { canExecuteOnWeb } 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';
|
||||
@@ -85,14 +85,14 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
protected _createExtensionHosts(_isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] {
|
||||
const result: ExtensionHostProcessManager[] = [];
|
||||
|
||||
const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService)));
|
||||
const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => canExecuteOnWeb(ext, this._productService, this._configService)));
|
||||
const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.file(this._environmentService.logsPath).with({ scheme: this._environmentService.logFile.scheme }));
|
||||
const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents);
|
||||
result.push(webHostProcessManager);
|
||||
|
||||
const remoteAgentConnection = this._remoteAgentService.getConnection();
|
||||
if (remoteAgentConnection) {
|
||||
const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !isWebExtension(ext, this._configService)));
|
||||
const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !canExecuteOnWeb(ext, this._productService, this._configService)));
|
||||
const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, remoteExtensions, this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory);
|
||||
const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents);
|
||||
result.push(remoteExtHostProcessManager);
|
||||
@@ -111,7 +111,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
let result: DeltaExtensionsResult;
|
||||
|
||||
// local: only enabled and web'ish extension
|
||||
localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService));
|
||||
localExtensions = localExtensions!.filter(ext => this._isEnabled(ext) && canExecuteOnWeb(ext, this._productService, this._configService));
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
|
||||
if (!remoteEnv) {
|
||||
@@ -119,7 +119,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
|
||||
} else {
|
||||
// remote: only enabled and none-web'ish extension
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService));
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !canExecuteOnWeb(extension, this._productService, this._configService));
|
||||
this._checkEnableProposedApi(remoteEnv.extensions);
|
||||
|
||||
// in case of overlap, the remote wins
|
||||
|
||||
@@ -428,4 +428,4 @@ export class ManageAuthorizedExtensionURIsAction extends Action {
|
||||
}
|
||||
|
||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ManageAuthorizedExtensionURIsAction, ManageAuthorizedExtensionURIsAction.ID, ManageAuthorizedExtensionURIsAction.LABEL), `Extensions: Manage Authorized Extension URIs...`, ExtensionsLabel);
|
||||
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ManageAuthorizedExtensionURIsAction, ManageAuthorizedExtensionURIsAction.ID, ManageAuthorizedExtensionURIsAction.LABEL), `Extensions: Manage Authorized Extension URIs...`, ExtensionsLabel);
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
* 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 { FileSystemProviderCapabilities, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileSystemProviderError, FileSystemProviderErrorCode, IFileSystemProviderWithFileReadWriteCapability } 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 {
|
||||
export class FetchFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapability {
|
||||
|
||||
readonly capabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite + FileSystemProviderCapabilities.PathCaseSensitive;
|
||||
readonly onDidChangeCapabilities = Event.None;
|
||||
|
||||
@@ -118,7 +118,12 @@ export class ExtensionDescriptionRegistry {
|
||||
|
||||
hasOnlyGoodArcs(id: string, good: Set<string>): boolean {
|
||||
const dependencies = G.getArcs(id);
|
||||
return dependencies.every(dependency => good.has(dependency));
|
||||
for (let i = 0; i < dependencies.length; i++) {
|
||||
if (!good.has(dependencies[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
getNodes(): string[] {
|
||||
|
||||
@@ -29,7 +29,7 @@ export function parseExtensionDevOptions(environmentService: IEnvironmentService
|
||||
|
||||
let isExtensionDevDebug = debugOk && typeof environmentService.debugExtensionHost.port === 'number';
|
||||
let isExtensionDevDebugBrk = debugOk && !!environmentService.debugExtensionHost.break;
|
||||
let isExtensionDevTestFromCli = isExtensionDevHost && !!environmentService.extensionTestsLocationURI && !environmentService.debugExtensionHost.break;
|
||||
let isExtensionDevTestFromCli = isExtensionDevHost && !!environmentService.extensionTestsLocationURI && !environmentService.debugExtensionHost.debugId;
|
||||
return {
|
||||
isExtensionDevHost,
|
||||
isExtensionDevDebug,
|
||||
|
||||
@@ -22,7 +22,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IUntitledResourceInput } from 'vs/workbench/common/editor';
|
||||
import { IUntitledTextResourceInput } from 'vs/workbench/common/editor';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -57,7 +57,7 @@ export class ExtensionHostProcessManager extends Disposable {
|
||||
constructor(
|
||||
public readonly isLocal: boolean,
|
||||
extensionHostProcessWorker: IExtensionHostStarter,
|
||||
private readonly _remoteAuthority: string,
|
||||
private readonly _remoteAuthority: string | null,
|
||||
initialActivationEvents: string[],
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
|
||||
@@ -185,7 +185,7 @@ export class ExtensionHostProcessManager extends Disposable {
|
||||
this._extensionHostProcessRPCProtocol = new RPCProtocol(protocol, logger);
|
||||
this._register(this._extensionHostProcessRPCProtocol.onDidChangeResponsiveState((responsiveState: ResponsiveState) => this._onDidChangeResponsiveState.fire(responsiveState)));
|
||||
const extHostContext: IExtHostContext = {
|
||||
remoteAuthority: this._remoteAuthority,
|
||||
remoteAuthority: this._remoteAuthority! /* TODO: alexdima, remove not-null assertion */,
|
||||
getProxy: <T>(identifier: ProxyIdentifier<T>): T => this._extensionHostProcessRPCProtocol!.getProxy(identifier),
|
||||
set: <T, R extends T>(identifier: ProxyIdentifier<T>, instance: R): R => this._extensionHostProcessRPCProtocol!.set(identifier, instance),
|
||||
assertRegistered: (identifiers: ProxyIdentifier<any>[]): void => this._extensionHostProcessRPCProtocol!.assertRegistered(identifiers),
|
||||
@@ -362,7 +362,7 @@ class RPCLogger implements IRPCProtocolLogger {
|
||||
}
|
||||
|
||||
interface ExtHostLatencyResult {
|
||||
remoteAuthority: string;
|
||||
remoteAuthority: string | null;
|
||||
up: number;
|
||||
down: number;
|
||||
latency: number;
|
||||
@@ -405,10 +405,13 @@ export class MeasureExtHostLatencyAction extends Action {
|
||||
|
||||
public async run(): Promise<any> {
|
||||
const measurements = await Promise.all(getLatencyTestProviders().map(provider => provider.measure()));
|
||||
this._editorService.openEditor({ contents: measurements.map(MeasureExtHostLatencyAction._print).join('\n\n'), options: { pinned: true } } as IUntitledResourceInput);
|
||||
this._editorService.openEditor({ contents: measurements.map(MeasureExtHostLatencyAction._print).join('\n\n'), options: { pinned: true } } as IUntitledTextResourceInput);
|
||||
}
|
||||
|
||||
private static _print(m: ExtHostLatencyResult): string {
|
||||
private static _print(m: ExtHostLatencyResult | null): string {
|
||||
if (!m) {
|
||||
return '';
|
||||
}
|
||||
return `${m.remoteAuthority ? `Authority: ${m.remoteAuthority}\n` : ``}Roundtrip latency: ${m.latency.toFixed(3)}ms\nUp: ${MeasureExtHostLatencyAction._printSpeed(m.up)}\nDown: ${MeasureExtHostLatencyAction._printSpeed(m.down)}\n`;
|
||||
}
|
||||
|
||||
@@ -424,4 +427,4 @@ export class MeasureExtHostLatencyAction extends Action {
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(MeasureExtHostLatencyAction, MeasureExtHostLatencyAction.ID, MeasureExtHostLatencyAction.LABEL), 'Developer: Measure Extension Host Latency', nls.localize('developer', "Developer"));
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.create(MeasureExtHostLatencyAction, MeasureExtHostLatencyAction.ID, MeasureExtHostLatencyAction.LABEL), 'Developer: Measure Extension Host Latency', nls.localize('developer', "Developer"));
|
||||
|
||||
@@ -146,8 +146,20 @@ export class ExtensionPoint<T> implements IExtensionPoint<T> {
|
||||
}
|
||||
}
|
||||
|
||||
const extensionKindSchema: IJSONSchema = {
|
||||
type: 'string',
|
||||
enum: [
|
||||
'ui',
|
||||
'workspace'
|
||||
],
|
||||
enumDescriptions: [
|
||||
nls.localize('ui', "UI extension kind. In a remote window, such extensions are enabled only when available on the local machine."),
|
||||
nls.localize('workspace', "Workspace extension kind. In a remote window, such extensions are enabled only when available on the remote.")
|
||||
],
|
||||
};
|
||||
|
||||
const schemaId = 'vscode://schemas/vscode-extensions';
|
||||
export const schema = {
|
||||
export const schema: IJSONSchema = {
|
||||
properties: {
|
||||
engines: {
|
||||
type: 'object',
|
||||
@@ -345,17 +357,32 @@ export const schema = {
|
||||
}
|
||||
},
|
||||
extensionKind: {
|
||||
description: nls.localize('extensionKind', "Define the kind of an extension. `ui` extensions are installed and run on the local machine while `workspace` extensions are run on the remote."),
|
||||
type: 'string',
|
||||
enum: [
|
||||
'ui',
|
||||
'workspace'
|
||||
],
|
||||
enumDescriptions: [
|
||||
nls.localize('ui', "UI extension kind. In a remote window, such extensions are enabled only when available on the local machine."),
|
||||
nls.localize('workspace', "Workspace extension kind. In a remote window, such extensions are enabled only when available on the remote.")
|
||||
],
|
||||
default: 'workspace'
|
||||
description: nls.localize('extensionKind', "Define the kind of an extension. `ui` extensions are installed and run on the local machine while `workspace` extensions run on the remote."),
|
||||
type: 'array',
|
||||
items: extensionKindSchema,
|
||||
default: ['workspace'],
|
||||
defaultSnippets: [
|
||||
{
|
||||
body: ['ui'],
|
||||
description: nls.localize('extensionKind.ui', "Define an extension which can run only on the local machine when connected to remote window.")
|
||||
},
|
||||
{
|
||||
body: ['workspace'],
|
||||
description: nls.localize('extensionKind.workspace', "Define an extension which can run only on the remote machine when connected remote window.")
|
||||
},
|
||||
{
|
||||
body: ['ui', 'workspace'],
|
||||
description: nls.localize('extensionKind.ui-workspace', "Define an extension which can run on either side, with a preference towards running on the local machine.")
|
||||
},
|
||||
{
|
||||
body: ['workspace', 'ui'],
|
||||
description: nls.localize('extensionKind.workspace-ui', "Define an extension which can run on either side, with a preference towards running on the remote machine.")
|
||||
},
|
||||
{
|
||||
body: [],
|
||||
description: nls.localize('extensionKind.empty', "Define an extension which cannot run in a remote context, neither on the local, nor on the remote machine.")
|
||||
}
|
||||
]
|
||||
},
|
||||
scripts: {
|
||||
type: 'object',
|
||||
@@ -395,7 +422,7 @@ export class ExtensionsRegistryImpl {
|
||||
const result = new ExtensionPoint<T>(desc.extensionPoint, desc.defaultExtensionKind);
|
||||
this._extensionPoints.set(desc.extensionPoint, result);
|
||||
|
||||
schema.properties['contributes'].properties[desc.extensionPoint] = desc.jsonSchema;
|
||||
schema.properties!['contributes'].properties![desc.extensionPoint] = desc.jsonSchema;
|
||||
schemaRegistry.registerSchema(schemaId, schema);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -4,55 +4,124 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionManifest, ExtensionKind, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { getGalleryExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export function isWebExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, configurationService);
|
||||
return extensionKind === 'web';
|
||||
export function prefersExecuteOnUI(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, productService, configurationService);
|
||||
return (extensionKind.length > 0 && extensionKind[0] === 'ui');
|
||||
}
|
||||
|
||||
export function isUIExtension(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const uiContributions = ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').map(e => e.name);
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
const extensionKind = getExtensionKind(manifest, configurationService);
|
||||
switch (extensionKind) {
|
||||
case 'ui': return true;
|
||||
case 'workspace': return false;
|
||||
default: {
|
||||
// Tagged as UI extension in product
|
||||
if (isNonEmptyArray(productService.uiExtensions) && productService.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) {
|
||||
return true;
|
||||
}
|
||||
// Not an UI extension if it has main
|
||||
if (manifest.main) {
|
||||
return false;
|
||||
}
|
||||
// Not an UI extension if it has dependencies or an extension pack
|
||||
if (isNonEmptyArray(manifest.extensionDependencies) || isNonEmptyArray(manifest.extensionPack)) {
|
||||
return false;
|
||||
}
|
||||
if (manifest.contributes) {
|
||||
// Not an UI extension if it has no ui contributions
|
||||
if (!uiContributions.length || Object.keys(manifest.contributes).some(contribution => uiContributions.indexOf(contribution) === -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export function prefersExecuteOnWorkspace(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, productService, configurationService);
|
||||
return (extensionKind.length > 0 && extensionKind[0] === 'workspace');
|
||||
}
|
||||
|
||||
function getExtensionKind(manifest: IExtensionManifest, configurationService: IConfigurationService): string | undefined {
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
const configuredExtensionKinds = configurationService.getValue<{ [key: string]: string }>('remote.extensionKind') || {};
|
||||
for (const id of Object.keys(configuredExtensionKinds)) {
|
||||
if (areSameExtensions({ id: extensionId }, { id })) {
|
||||
return configuredExtensionKinds[id];
|
||||
export function canExecuteOnUI(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, productService, configurationService);
|
||||
return extensionKind.some(kind => kind === 'ui');
|
||||
}
|
||||
|
||||
export function canExecuteOnWorkspace(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, productService, configurationService);
|
||||
return extensionKind.some(kind => kind === 'workspace');
|
||||
}
|
||||
|
||||
export function canExecuteOnWeb(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean {
|
||||
const extensionKind = getExtensionKind(manifest, productService, configurationService);
|
||||
return extensionKind.some(kind => kind === 'web');
|
||||
}
|
||||
|
||||
export function getExtensionKind(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): ExtensionKind[] {
|
||||
// check in config
|
||||
let result = getConfiguredExtensionKind(manifest, configurationService);
|
||||
if (typeof result !== 'undefined') {
|
||||
return toArray(result);
|
||||
}
|
||||
|
||||
// check product.json
|
||||
result = getProductExtensionKind(manifest, productService);
|
||||
if (typeof result !== 'undefined') {
|
||||
return toArray(result);
|
||||
}
|
||||
|
||||
// check the manifest itself
|
||||
result = manifest.extensionKind;
|
||||
if (typeof result !== 'undefined') {
|
||||
return toArray(result);
|
||||
}
|
||||
|
||||
// Not an UI extension if it has main
|
||||
if (manifest.main) {
|
||||
return ['workspace'];
|
||||
}
|
||||
|
||||
// Not an UI extension if it has dependencies or an extension pack
|
||||
if (isNonEmptyArray(manifest.extensionDependencies) || isNonEmptyArray(manifest.extensionPack)) {
|
||||
return ['workspace'];
|
||||
}
|
||||
|
||||
if (manifest.contributes) {
|
||||
// Not an UI extension if it has no ui contributions
|
||||
for (const contribution of Object.keys(manifest.contributes)) {
|
||||
if (!isUIExtensionPoint(contribution)) {
|
||||
return ['workspace'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return manifest.extensionKind;
|
||||
|
||||
return ['ui', 'workspace'];
|
||||
}
|
||||
|
||||
let _uiExtensionPoints: Set<string> | null = null;
|
||||
function isUIExtensionPoint(extensionPoint: string): boolean {
|
||||
if (_uiExtensionPoints === null) {
|
||||
const uiExtensionPoints = new Set<string>();
|
||||
ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').forEach(e => {
|
||||
uiExtensionPoints.add(e.name);
|
||||
});
|
||||
_uiExtensionPoints = uiExtensionPoints;
|
||||
}
|
||||
return _uiExtensionPoints.has(extensionPoint);
|
||||
}
|
||||
|
||||
let _productExtensionKindsMap: Map<string, ExtensionKind | ExtensionKind[]> | null = null;
|
||||
function getProductExtensionKind(manifest: IExtensionManifest, productService: IProductService): ExtensionKind | ExtensionKind[] | undefined {
|
||||
if (_productExtensionKindsMap === null) {
|
||||
const productExtensionKindsMap = new Map<string, ExtensionKind | ExtensionKind[]>();
|
||||
if (productService.extensionKind) {
|
||||
for (const id of Object.keys(productService.extensionKind)) {
|
||||
productExtensionKindsMap.set(ExtensionIdentifier.toKey(id), productService.extensionKind[id]);
|
||||
}
|
||||
}
|
||||
_productExtensionKindsMap = productExtensionKindsMap;
|
||||
}
|
||||
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
return _productExtensionKindsMap.get(ExtensionIdentifier.toKey(extensionId));
|
||||
}
|
||||
|
||||
let _configuredExtensionKindsMap: Map<string, ExtensionKind | ExtensionKind[]> | null = null;
|
||||
function getConfiguredExtensionKind(manifest: IExtensionManifest, configurationService: IConfigurationService): ExtensionKind | ExtensionKind[] | undefined {
|
||||
if (_configuredExtensionKindsMap === null) {
|
||||
const configuredExtensionKindsMap = new Map<string, ExtensionKind | ExtensionKind[]>();
|
||||
const configuredExtensionKinds = configurationService.getValue<{ [key: string]: ExtensionKind | ExtensionKind[] }>('remote.extensionKind') || {};
|
||||
for (const id of Object.keys(configuredExtensionKinds)) {
|
||||
configuredExtensionKindsMap.set(ExtensionIdentifier.toKey(id), configuredExtensionKinds[id]);
|
||||
}
|
||||
_configuredExtensionKindsMap = configuredExtensionKindsMap;
|
||||
}
|
||||
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
return _configuredExtensionKindsMap.get(ExtensionIdentifier.toKey(extensionId));
|
||||
}
|
||||
|
||||
function toArray(extensionKind: ExtensionKind | ExtensionKind[]): ExtensionKind[] {
|
||||
if (Array.isArray(extensionKind)) {
|
||||
return extensionKind;
|
||||
}
|
||||
return extensionKind === 'ui' ? ['ui', 'workspace'] : [extensionKind];
|
||||
}
|
||||
|
||||
@@ -543,10 +543,16 @@ class MessageBuffer {
|
||||
const el = arr[i];
|
||||
const elType = arrType[i];
|
||||
size += 1; // arg type
|
||||
if (elType === ArgType.String) {
|
||||
size += this.sizeLongString(el);
|
||||
} else {
|
||||
size += this.sizeVSBuffer(el);
|
||||
switch (elType) {
|
||||
case ArgType.String:
|
||||
size += this.sizeLongString(el);
|
||||
break;
|
||||
case ArgType.VSBuffer:
|
||||
size += this.sizeVSBuffer(el);
|
||||
break;
|
||||
case ArgType.Undefined:
|
||||
// empty...
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
@@ -557,19 +563,25 @@ class MessageBuffer {
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
const el = arr[i];
|
||||
const elType = arrType[i];
|
||||
if (elType === ArgType.String) {
|
||||
this.writeUInt8(ArgType.String);
|
||||
this.writeLongString(el);
|
||||
} else {
|
||||
this.writeUInt8(ArgType.VSBuffer);
|
||||
this.writeVSBuffer(el);
|
||||
switch (elType) {
|
||||
case ArgType.String:
|
||||
this.writeUInt8(ArgType.String);
|
||||
this.writeLongString(el);
|
||||
break;
|
||||
case ArgType.VSBuffer:
|
||||
this.writeUInt8(ArgType.VSBuffer);
|
||||
this.writeVSBuffer(el);
|
||||
break;
|
||||
case ArgType.Undefined:
|
||||
this.writeUInt8(ArgType.Undefined);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public readMixedArray(): Array<string | VSBuffer> {
|
||||
public readMixedArray(): Array<string | VSBuffer | undefined> {
|
||||
const arrLen = this._buff.readUInt8(this._offset); this._offset += 1;
|
||||
let arr: Array<string | VSBuffer> = new Array(arrLen);
|
||||
let arr: Array<string | VSBuffer | undefined> = new Array(arrLen);
|
||||
for (let i = 0; i < arrLen; i++) {
|
||||
const argType = <ArgType>this.readUInt8();
|
||||
switch (argType) {
|
||||
@@ -579,6 +591,9 @@ class MessageBuffer {
|
||||
case ArgType.VSBuffer:
|
||||
arr[i] = this.readVSBuffer();
|
||||
break;
|
||||
case ArgType.Undefined:
|
||||
arr[i] = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
@@ -587,12 +602,20 @@ class MessageBuffer {
|
||||
|
||||
class MessageIO {
|
||||
|
||||
private static _arrayContainsBuffer(arr: any[]): boolean {
|
||||
return arr.some(value => value instanceof VSBuffer);
|
||||
private static _arrayContainsBufferOrUndefined(arr: any[]): boolean {
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
if (arr[i] instanceof VSBuffer) {
|
||||
return true;
|
||||
}
|
||||
if (typeof arr[i] === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static serializeRequest(req: number, rpcId: number, method: string, args: any[], usesCancellationToken: boolean, replacer: JSONStringifyReplacer | null): VSBuffer {
|
||||
if (this._arrayContainsBuffer(args)) {
|
||||
if (this._arrayContainsBufferOrUndefined(args)) {
|
||||
let massagedArgs: VSBuffer[] = [];
|
||||
let massagedArgsType: ArgType[] = [];
|
||||
for (let i = 0, len = args.length; i < len; i++) {
|
||||
@@ -600,6 +623,9 @@ class MessageIO {
|
||||
if (arg instanceof VSBuffer) {
|
||||
massagedArgs[i] = arg;
|
||||
massagedArgsType[i] = ArgType.VSBuffer;
|
||||
} else if (typeof arg === 'undefined') {
|
||||
massagedArgs[i] = VSBuffer.alloc(0);
|
||||
massagedArgsType[i] = ArgType.Undefined;
|
||||
} else {
|
||||
massagedArgs[i] = VSBuffer.fromString(safeStringify(arg, replacer));
|
||||
massagedArgsType[i] = ArgType.String;
|
||||
@@ -767,5 +793,6 @@ const enum MessageType {
|
||||
|
||||
const enum ArgType {
|
||||
String = 1,
|
||||
VSBuffer = 2
|
||||
VSBuffer = 2,
|
||||
Undefined = 3
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import { parseExtensionDevOptions } from '../common/extensionDevOptions';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
|
||||
import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { isEqualOrParent } from 'vs/base/common/resources';
|
||||
import { isUntitledWorkspace } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
|
||||
export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
@@ -158,6 +158,8 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
'--nolazy',
|
||||
(this._isExtensionDevDebugBrk ? '--inspect-brk=' : '--inspect=') + portNumber
|
||||
];
|
||||
} else {
|
||||
opts.execArgv = ['--inspect-port=0'];
|
||||
}
|
||||
|
||||
const crashReporterOptions = undefined; // TODO@electron pass this in as options to the extension host after verifying this actually works
|
||||
@@ -170,10 +172,10 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
|
||||
// Catch all output coming from the extension host process
|
||||
type Output = { data: string, format: string[] };
|
||||
this._extensionHostProcess.stdout.setEncoding('utf8');
|
||||
this._extensionHostProcess.stderr.setEncoding('utf8');
|
||||
const onStdout = Event.fromNodeEventEmitter<string>(this._extensionHostProcess.stdout, 'data');
|
||||
const onStderr = Event.fromNodeEventEmitter<string>(this._extensionHostProcess.stderr, 'data');
|
||||
this._extensionHostProcess.stdout!.setEncoding('utf8');
|
||||
this._extensionHostProcess.stderr!.setEncoding('utf8');
|
||||
const onStdout = Event.fromNodeEventEmitter<string>(this._extensionHostProcess.stdout!, 'data');
|
||||
const onStderr = Event.fromNodeEventEmitter<string>(this._extensionHostProcess.stderr!, 'data');
|
||||
const onOutput = Event.any(
|
||||
Event.map(onStdout, o => ({ data: `%c${o}`, format: [''] })),
|
||||
Event.map(onStderr, o => ({ data: `%c${o}`, format: ['color: red'] }))
|
||||
@@ -411,7 +413,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
configuration: withNullAsUndefined(workspace.configuration),
|
||||
id: workspace.id,
|
||||
name: this._labelService.getWorkspaceLabel(workspace),
|
||||
isUntitled: workspace.configuration ? isEqualOrParent(workspace.configuration, this._environmentService.untitledWorkspacesHome) : false
|
||||
isUntitled: workspace.configuration ? isUntitledWorkspace(workspace.configuration, this._environmentService) : false
|
||||
},
|
||||
remote: {
|
||||
authority: this._environmentService.configuration.remoteAuthority,
|
||||
@@ -432,19 +434,19 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
|
||||
|
||||
private _logExtensionHostMessage(entry: IRemoteConsoleLog) {
|
||||
|
||||
// Send to local console unless we run tests from cli
|
||||
if (!this._isExtensionDevTestFromCli) {
|
||||
log(entry, 'Extension Host');
|
||||
}
|
||||
|
||||
// Log on main side if running tests from cli
|
||||
if (this._isExtensionDevTestFromCli) {
|
||||
logRemoteEntry(this._logService, entry);
|
||||
}
|
||||
|
||||
// Broadcast to other windows if we are in development mode
|
||||
else if (this._environmentService.debugExtensionHost.debugId && (!this._environmentService.isBuilt || this._isExtensionDevHost)) {
|
||||
this._extensionHostDebugService.logToSession(this._environmentService.debugExtensionHost.debugId, entry);
|
||||
// Log on main side if running tests from cli
|
||||
logRemoteEntry(this._logService, entry);
|
||||
} else {
|
||||
|
||||
// Send to local console
|
||||
log(entry, 'Extension Host');
|
||||
|
||||
// Broadcast to other windows if we are in development mode
|
||||
if (this._environmentService.debugExtensionHost.debugId && (!this._environmentService.isBuilt || this._isExtensionDevHost)) {
|
||||
this._extensionHostDebugService.logToSession(this._environmentService.debugExtensionHost.debugId, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { IInitDataProvider, RemoteExtensionHostClient } from 'vs/workbench/services/extensions/common/remoteExtensionHostClient';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { isUIExtension as isUIExtensionFunc } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { getExtensionKind } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
@@ -439,8 +439,6 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
}
|
||||
|
||||
protected async _scanAndHandleExtensions(): Promise<void> {
|
||||
const isUIExtension = (extension: IExtensionDescription) => isUIExtensionFunc(extension, this._productService, this._configurationService);
|
||||
|
||||
this._extensionScanner.startScanningExtensions(this.createLogger());
|
||||
|
||||
const remoteAuthority = this._environmentService.configuration.remoteAuthority;
|
||||
@@ -510,14 +508,38 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
// remove disabled extensions
|
||||
remoteEnv.extensions = remove(remoteEnv.extensions, extension => this._isDisabled(extension));
|
||||
|
||||
// Determine where each extension will execute, based on extensionKind
|
||||
const isInstalledLocally = new Set<string>();
|
||||
localExtensions.forEach(ext => isInstalledLocally.add(ExtensionIdentifier.toKey(ext.identifier)));
|
||||
|
||||
const isInstalledRemotely = new Set<string>();
|
||||
remoteEnv.extensions.forEach(ext => isInstalledRemotely.add(ExtensionIdentifier.toKey(ext.identifier)));
|
||||
|
||||
const enum RunningLocation { None, Local, Remote }
|
||||
const pickRunningLocation = (extension: IExtensionDescription): RunningLocation => {
|
||||
for (const extensionKind of getExtensionKind(extension, this._productService, this._configurationService)) {
|
||||
if (extensionKind === 'ui') {
|
||||
if (isInstalledLocally.has(ExtensionIdentifier.toKey(extension.identifier))) {
|
||||
return RunningLocation.Local;
|
||||
}
|
||||
} else if (extensionKind === 'workspace') {
|
||||
if (isInstalledRemotely.has(ExtensionIdentifier.toKey(extension.identifier))) {
|
||||
return RunningLocation.Remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RunningLocation.None;
|
||||
};
|
||||
|
||||
const runningLocation = new Map<string, RunningLocation>();
|
||||
localExtensions.forEach(ext => runningLocation.set(ExtensionIdentifier.toKey(ext.identifier), pickRunningLocation(ext)));
|
||||
remoteEnv.extensions.forEach(ext => runningLocation.set(ExtensionIdentifier.toKey(ext.identifier), pickRunningLocation(ext)));
|
||||
|
||||
// remove non-UI extensions from the local extensions
|
||||
localExtensions = remove(localExtensions, extension => !extension.isBuiltin && !isUIExtension(extension));
|
||||
localExtensions = localExtensions.filter(ext => runningLocation.get(ExtensionIdentifier.toKey(ext.identifier)) === RunningLocation.Local);
|
||||
|
||||
// in case of UI extensions overlap, the local extension wins
|
||||
remoteEnv.extensions = remove(remoteEnv.extensions, localExtensions.filter(extension => isUIExtension(extension)));
|
||||
|
||||
// in case of other extensions overlap, the remote extension wins
|
||||
localExtensions = remove(localExtensions, remoteEnv.extensions);
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(ext => runningLocation.get(ExtensionIdentifier.toKey(ext.identifier)) === RunningLocation.Remote);
|
||||
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData.set(remoteAuthority, remoteEnv);
|
||||
@@ -550,14 +572,12 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
}
|
||||
|
||||
public _onExtensionHostExit(code: number): void {
|
||||
// Expected development extension termination: When the extension host goes down we also shutdown the window
|
||||
if (!this._isExtensionDevTestFromCli) {
|
||||
this._electronService.closeWindow();
|
||||
}
|
||||
|
||||
// When CLI testing make sure to exit with proper exit code
|
||||
else {
|
||||
if (this._isExtensionDevTestFromCli) {
|
||||
// When CLI testing make sure to exit with proper exit code
|
||||
ipc.send('vscode:exit', code);
|
||||
} else {
|
||||
// Expected development extension termination: When the extension host goes down we also shutdown the window
|
||||
this._electronService.closeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { prefersExecuteOnUI } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -48,6 +48,10 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC
|
||||
}
|
||||
|
||||
private async doInstallFromGallery(extension: IGalleryExtension): Promise<ILocalExtension> {
|
||||
if (this.configurationService.getValue<boolean>('remote.downloadExtensionsLocally')) {
|
||||
this.logService.trace(`Download '${extension.identifier.id}' extension locally and install`);
|
||||
return this.downloadCompatibleAndInstall(extension);
|
||||
}
|
||||
try {
|
||||
const local = await super.installFromGallery(extension);
|
||||
return local;
|
||||
@@ -116,7 +120,7 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC
|
||||
for (let idx = 0; idx < extensions.length; idx++) {
|
||||
const extension = extensions[idx];
|
||||
const manifest = manifests[idx];
|
||||
if (manifest && isUIExtension(manifest, this.productService, this.configurationService) === uiExtension) {
|
||||
if (manifest && prefersExecuteOnUI(manifest, this.productService, this.configurationService) === uiExtension) {
|
||||
result.set(extension.identifier.id.toLowerCase(), extension);
|
||||
extensionsManifests.push(manifest);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,17 @@ interface ParsedExtHostArgs {
|
||||
uriTransformerPath?: string;
|
||||
}
|
||||
|
||||
// workaround for https://github.com/microsoft/vscode/issues/85490
|
||||
// remove --inspect-port=0 after start so that it doesn't trigger LSP debugging
|
||||
(function removeInspectPort() {
|
||||
for (let i = 0; i < process.execArgv.length; i++) {
|
||||
if (process.execArgv[i] === '--inspect-port=0') {
|
||||
process.execArgv.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
const args = minimist(process.argv.slice(2), {
|
||||
string: [
|
||||
'uriTransformerPath'
|
||||
|
||||
@@ -51,7 +51,7 @@ class ExtensionManifestParser extends ExtensionManifestHandler {
|
||||
return pfs.readFile(this._absoluteManifestPath).then((manifestContents) => {
|
||||
const errors: json.ParseError[] = [];
|
||||
const manifest = json.parse(manifestContents.toString(), errors);
|
||||
if (!!manifest && errors.length === 0) {
|
||||
if (errors.length === 0 && json.getNodeType(manifest) === 'object') {
|
||||
if (manifest.__metadata) {
|
||||
manifest.uuid = manifest.__metadata.id;
|
||||
}
|
||||
@@ -108,6 +108,9 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
|
||||
this._log.error(this._absoluteFolderPath, nls.localize('jsonsParseReportErrors', "Failed to parse {0}: {1}.", localized, getParseErrorMessage(error.error)));
|
||||
});
|
||||
};
|
||||
const reportInvalidFormat = (localized: string | null): void => {
|
||||
this._log.error(this._absoluteFolderPath, nls.localize('jsonInvalidFormat', "Invalid format {0}: JSON object expected.", localized));
|
||||
};
|
||||
|
||||
let extension = path.extname(this._absoluteManifestPath);
|
||||
let basename = this._absoluteManifestPath.substr(0, this._absoluteManifestPath.length - extension.length);
|
||||
@@ -122,6 +125,9 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
|
||||
if (errors.length > 0) {
|
||||
reportErrors(translationPath, errors);
|
||||
return { values: undefined, default: `${basename}.nls.json` };
|
||||
} else if (json.getNodeType(translationBundle) !== 'object') {
|
||||
reportInvalidFormat(translationPath);
|
||||
return { values: undefined, default: `${basename}.nls.json` };
|
||||
} else {
|
||||
let values = translationBundle.contents ? translationBundle.contents.package : undefined;
|
||||
return { values: values, default: `${basename}.nls.json` };
|
||||
@@ -144,6 +150,9 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
|
||||
if (errors.length > 0) {
|
||||
reportErrors(messageBundle.localized, errors);
|
||||
return { values: undefined, default: messageBundle.original };
|
||||
} else if (json.getNodeType(messages) !== 'object') {
|
||||
reportInvalidFormat(messageBundle.localized);
|
||||
return { values: undefined, default: messageBundle.original };
|
||||
}
|
||||
return { values: messages, default: messageBundle.original };
|
||||
}, (err) => {
|
||||
@@ -165,6 +174,9 @@ class ExtensionManifestNLSReplacer extends ExtensionManifestHandler {
|
||||
if (errors.length > 0) {
|
||||
reportErrors(localizedMessages.default, errors);
|
||||
return extensionDescription;
|
||||
} else if (json.getNodeType(localizedMessages) !== 'object') {
|
||||
reportInvalidFormat(localizedMessages.default);
|
||||
return extensionDescription;
|
||||
}
|
||||
const localized = localizedMessages.values || Object.create(null);
|
||||
ExtensionManifestNLSReplacer._replaceNLStrings(this._nlsConfig, extensionDescription, localized, defaults, this._log, this._absoluteFolderPath);
|
||||
@@ -397,7 +409,15 @@ class ExtensionManifestValidator extends ExtensionManifestHandler {
|
||||
}
|
||||
|
||||
private static _isStringArray(arr: string[]): boolean {
|
||||
return Array.isArray(arr) && arr.every(value => typeof value === 'string');
|
||||
if (!Array.isArray(arr)) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
if (typeof arr[i] !== 'string') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -343,9 +343,13 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType
|
||||
return original.apply(null, arguments as unknown as any[]);
|
||||
}
|
||||
|
||||
const optionsPatched = options.agent instanceof ProxyAgent;
|
||||
const originalAgent = options.agent;
|
||||
if (originalAgent === true) {
|
||||
throw new Error('Unexpected agent option: true');
|
||||
}
|
||||
const optionsPatched = originalAgent instanceof ProxyAgent;
|
||||
const config = onRequest && ((<any>options)._vscodeProxySupport || /* LS */ (<any>options)._vscodeSystemProxy) || proxySetting.config;
|
||||
const useProxySettings = !optionsPatched && (config === 'override' || config === 'on' && !options.agent);
|
||||
const useProxySettings = !optionsPatched && (config === 'override' || config === 'on' && originalAgent === undefined);
|
||||
const useSystemCertificates = !optionsPatched && certSetting.config && originals === https && !(options as https.RequestOptions).ca;
|
||||
|
||||
if (useProxySettings || useSystemCertificates) {
|
||||
@@ -367,7 +371,7 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType
|
||||
options.agent = new ProxyAgent({
|
||||
resolveProxy: resolveProxy.bind(undefined, { useProxySettings, useSystemCertificates }),
|
||||
defaultPort: originals === https ? 443 : 80,
|
||||
originalAgent: options.agent
|
||||
originalAgent
|
||||
});
|
||||
return original(options, callback);
|
||||
}
|
||||
@@ -469,7 +473,9 @@ async function readCaCertificates() {
|
||||
}
|
||||
|
||||
async function readWindowsCaCertificates() {
|
||||
const winCA = await import('vscode-windows-ca-certs');
|
||||
const winCA = await new Promise<any>((resolve, reject) => {
|
||||
require(['vscode-windows-ca-certs'], resolve, reject);
|
||||
});
|
||||
|
||||
let ders: any[] = [];
|
||||
const store = winCA();
|
||||
|
||||
@@ -200,4 +200,15 @@ suite('RPCProtocol', () => {
|
||||
done(null);
|
||||
});
|
||||
});
|
||||
|
||||
test('undefined arguments arrive as null', function () {
|
||||
delegate = (a1: any, a2: any) => {
|
||||
assert.equal(typeof a1, 'undefined');
|
||||
assert.equal(a2, null);
|
||||
return 7;
|
||||
};
|
||||
return bProxy.$m(undefined, null).then((res) => {
|
||||
assert.equal(res, 7);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,8 +12,8 @@ import { IExtHostCommands, ExtHostCommands } from 'vs/workbench/api/common/extHo
|
||||
import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { IExtHostTerminalService, WorkerExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
|
||||
// import { IExtHostTask, WorkerExtHostTask } from 'vs/workbench/api/common/extHostTask';
|
||||
// import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
|
||||
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
||||
// import { IExtHostDebugService, WorkerExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
|
||||
import { IExtHostSearch, ExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
|
||||
import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
|
||||
@@ -32,6 +32,7 @@ registerSingleton(IExtHostCommands, ExtHostCommands);
|
||||
registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors);
|
||||
registerSingleton(IExtHostStorage, ExtHostStorage);
|
||||
registerSingleton(IExtHostExtensionService, ExtHostExtensionService);
|
||||
registerSingleton(IExtHostSearch, ExtHostSearch);
|
||||
|
||||
// register services that only throw errors
|
||||
function NotImplementedProxy<T>(name: ServiceIdentifier<T>): { new(): T } {
|
||||
@@ -49,9 +50,8 @@ function NotImplementedProxy<T>(name: ServiceIdentifier<T>): { new(): T } {
|
||||
};
|
||||
}
|
||||
registerSingleton(IExtHostTerminalService, WorkerExtHostTerminalService);
|
||||
// registerSingleton(IExtHostTask, WorkerExtHostTask); {{SQL CARBON EDIT}} disable tasks
|
||||
// registerSingleton(IExtHostDebugService, class extends NotImplementedProxy(IExtHostDebugService) { }); {{SQL CARBON EDIT}} remove debug service
|
||||
registerSingleton(IExtHostSearch, class extends NotImplementedProxy(IExtHostSearch) { });
|
||||
// registerSingleton(IExtHostTask, WorkerExtHostTask); {{SQL CARBON EDIT}} disable
|
||||
// registerSingleton(IExtHostDebugService, WorkerExtHostDebugService); {{SQL CARBON EDIT}} disable
|
||||
registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) {
|
||||
whenReady = Promise.resolve();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user