Revert "Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)" (#5983)

This reverts commit d15a3fcc98.
This commit is contained in:
Karl Burtram
2019-06-11 12:35:58 -07:00
committed by GitHub
parent 95a50b7892
commit 5a7562a37b
926 changed files with 11394 additions and 19540 deletions

View File

@@ -19,6 +19,7 @@ import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { withNullAsUndefined } from 'vs/base/common/types';
import { ILogService } from 'vs/platform/log/common/log';
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
// we don't (yet) throw when extensions parse
// uris that have no scheme
@@ -52,7 +53,9 @@ export class ExtensionHostMain {
hostUtils: IHostUtils,
consolePatchFn: IConsolePatchFn,
logServiceFn: ILogServiceFn,
uriTransformer: IURITransformer | null
uriTransformer: IURITransformer | null,
schemeTransformer: ISchemeTransformer | null,
outputChannelName: string,
) {
this._isTerminating = false;
this._hostUtils = hostUtils;
@@ -83,7 +86,8 @@ export class ExtensionHostMain {
extHostConfiguraiton,
initData.environment,
this._extHostLogService,
uriTransformer
schemeTransformer,
outputChannelName
);
// error forwarding and stack trace scanning

View File

@@ -3,6 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { startExtensionHostProcess } from 'vs/workbench/services/extensions/node/extensionHostProcessSetup';
startExtensionHostProcess().catch((err) => console.log(err));
startExtensionHostProcess(
_ => null,
_ => null,
_ => nls.localize('extension host Log', "Extension Host")
).catch((err) => console.log(err));

View File

@@ -5,33 +5,23 @@
import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net';
import * as minimist from 'minimist';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Event, Emitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { PersistentProtocol, ProtocolConstants, createBufferedEvent } from 'vs/base/parts/ipc/common/ipc.net';
import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
import { PersistentProtocol, ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
import product from 'vs/platform/product/node/product';
import { IInitData, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol';
import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
import { ExtensionHostMain, IExitFn, ILogServiceFn } from 'vs/workbench/services/extensions/node/extensionHostMain';
import { VSBuffer } from 'vs/base/common/buffer';
import { createBufferSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
import { IURITransformer, URITransformer, IRawURITransformer } from 'vs/base/common/uriIpc';
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { exists } from 'vs/base/node/pfs';
import { realpath } from 'vs/base/node/extpath';
import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService';
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
interface ParsedExtHostArgs {
uriTransformerPath?: string;
}
const args = minimist(process.argv.slice(2), {
string: [
'uriTransformerPath'
]
}) as ParsedExtHostArgs;
// With Electron 2.x and node.js 8.x the "natives" module
// can cause a native crash (see https://github.com/nodejs/node/issues/19891 and
@@ -82,7 +72,7 @@ function patchPatchedConsole(mainThreadConsole: MainThreadConsoleShape): void {
};
}
const createLogService: ILogServiceFn = initData => new SpdLogService(ExtensionHostLogFileName, initData.logsLocation.fsPath, initData.logLevel);
const createLogService: ILogServiceFn = initData => createBufferSpdLogService(ExtensionHostLogFileName, initData.logLevel, initData.logsLocation.fsPath);
interface IRendererConnection {
protocol: IMessagePassingProtocol;
@@ -111,41 +101,27 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
process.on('message', (msg: IExtHostSocketMessage, handle: net.Socket) => {
if (msg && msg.type === 'VSCODE_EXTHOST_IPC_SOCKET') {
const initialDataChunk = VSBuffer.wrap(Buffer.from(msg.initialDataChunk, 'base64'));
let socket: NodeSocket | WebSocketNodeSocket;
if (msg.skipWebSocketFrames) {
socket = new NodeSocket(handle);
} else {
socket = new WebSocketNodeSocket(new NodeSocket(handle));
}
if (protocol) {
// reconnection case
if (disconnectWaitTimer) {
clearTimeout(disconnectWaitTimer);
disconnectWaitTimer = null;
}
protocol.beginAcceptReconnection(socket, initialDataChunk);
protocol.beginAcceptReconnection(new NodeSocket(handle), initialDataChunk);
protocol.endAcceptReconnection();
} else {
clearTimeout(timer);
protocol = new PersistentProtocol(socket, initialDataChunk);
protocol = new PersistentProtocol(new NodeSocket(handle), initialDataChunk);
protocol.onClose(() => onTerminate());
resolve(protocol);
if (msg.skipWebSocketFrames) {
// Wait for rich client to reconnect
protocol.onSocketClose(() => {
// The socket has closed, let's give the renderer a certain amount of time to reconnect
disconnectWaitTimer = setTimeout(() => {
disconnectWaitTimer = null;
onTerminate();
}, ProtocolConstants.ReconnectionGraceTime);
});
} else {
// Do not wait for web companion to reconnect
protocol.onSocketClose(() => {
protocol.onSocketClose(() => {
// The socket has closed, let's give the renderer a certain amount of time to reconnect
disconnectWaitTimer = setTimeout(() => {
disconnectWaitTimer = null;
onTerminate();
});
}
}, ProtocolConstants.ReconnectionGraceTime);
});
}
}
});
@@ -179,22 +155,16 @@ async function createExtHostProtocol(): Promise<IMessagePassingProtocol> {
return new class implements IMessagePassingProtocol {
private readonly _onMessage = new Emitter<VSBuffer>();
readonly onMessage: Event<VSBuffer> = createBufferedEvent(this._onMessage.event);
private _terminating = false;
private _terminating: boolean;
constructor() {
this._terminating = false;
protocol.onMessage((msg) => {
if (isMessageOfType(msg, MessageType.Terminate)) {
this._terminating = true;
onTerminate();
} else {
this._onMessage.fire(msg);
}
});
}
readonly onMessage: Event<any> = Event.filter(protocol.onMessage, msg => {
if (!isMessageOfType(msg, MessageType.Terminate)) {
return true;
}
this._terminating = true;
onTerminate();
return false;
});
send(msg: any): void {
if (!this._terminating) {
@@ -302,7 +272,11 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRenderer
}
})();
export async function startExtensionHostProcess(): Promise<void> {
export async function startExtensionHostProcess(
uriTransformerFn: (initData: IInitData) => IURITransformer | null,
schemeTransformerFn: (initData: IInitData) => ISchemeTransformer | null,
outputChannelNameFn: (initData: IInitData) => string,
): Promise<void> {
const protocol = await createExtHostProtocol();
const renderer = await connectToRenderer(protocol);
@@ -317,17 +291,6 @@ export async function startExtensionHostProcess(): Promise<void> {
realpath(path: string) { return realpath(path); }
};
// Attempt to load uri transformer
let uriTransformer: IURITransformer | null = null;
if (initData.remoteAuthority && args.uriTransformerPath) {
try {
const rawURITransformerFactory = <any>require.__$__nodeRequire(args.uriTransformerPath);
const rawURITransformer = <IRawURITransformer>rawURITransformerFactory(initData.remoteAuthority);
uriTransformer = new URITransformer(rawURITransformer);
} catch (e) {
console.error(e);
}
}
const extensionHostMain = new ExtensionHostMain(
renderer.protocol,
@@ -335,7 +298,9 @@ export async function startExtensionHostProcess(): Promise<void> {
hostUtils,
patchPatchedConsole,
createLogService,
uriTransformer
uriTransformerFn(initData),
schemeTransformerFn(initData),
outputChannelNameFn(initData)
);
// rewrite onTerminate-function to be a proper shutdown

View File

@@ -12,13 +12,40 @@ import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
import * as types from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { getGalleryExtensionId, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { getGalleryExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Translations, ILog } from 'vs/workbench/services/extensions/common/extensionPoints';
import { ExtensionIdentifier, ExtensionIdentifierWithVersion, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
const MANIFEST_FILE = 'package.json';
export interface Translations {
[id: string]: string;
}
namespace Translations {
export function equals(a: Translations, b: Translations): boolean {
if (a === b) {
return true;
}
let aKeys = Object.keys(a);
let bKeys: Set<string> = new Set<string>();
for (let key of Object.keys(b)) {
bKeys.add(key);
}
if (aKeys.length !== bKeys.size) {
return false;
}
for (let key of aKeys) {
if (a[key] !== b[key]) {
return false;
}
bKeys.delete(key);
}
return bKeys.size === 0;
}
}
export interface NlsConfiguration {
readonly devMode: boolean;
readonly locale: string | undefined;
@@ -26,6 +53,12 @@ export interface NlsConfiguration {
readonly translations: Translations;
}
export interface ILog {
error(source: string, message: string): void;
warn(source: string, message: string): void;
info(source: string, message: string): void;
}
abstract class ExtensionManifestHandler {
protected readonly _ourVersion: string;

View File

@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IExtensionManifest } 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 { isNonEmptyArray } from 'vs/base/common/arrays';
import product from 'vs/platform/product/node/product';
export function isUIExtension(manifest: IExtensionManifest, 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(product.uiExtensions) && product.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;
}
}
}
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];
}
}
return manifest.extensionKind;
}

View File

@@ -16,11 +16,10 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { localize } from 'vs/nls';
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { isUIExtension } from 'vs/workbench/services/extensions/node/extensionsUtil';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { values } from 'vs/base/common/map';
import { IProductService } from 'vs/platform/product/common/product';
export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService {
@@ -36,8 +35,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
constructor(
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService private readonly productService: IProductService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super();
this.servers = this.extensionManagementServerService.remoteExtensionManagementServer ? [this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer] : [this.extensionManagementServerService.localExtensionManagementServer];
@@ -87,7 +85,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
private async uninstallInServer(extension: ILocalExtension, server: IExtensionManagementServer, force?: boolean): Promise<void> {
if (server === this.extensionManagementServerService.localExtensionManagementServer) {
const installedExtensions = await this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getInstalled(ExtensionType.User);
const dependentNonUIExtensions = installedExtensions.filter(i => !isUIExtension(i.manifest, this.productService, this.configurationService)
const dependentNonUIExtensions = installedExtensions.filter(i => !isUIExtension(i.manifest, this.configurationService)
&& i.manifest.extensionDependencies && i.manifest.extensionDependencies.some(id => areSameExtensions({ id }, extension.identifier)));
if (dependentNonUIExtensions.length) {
return Promise.reject(new Error(this.getDependentsErrorMessage(extension, dependentNonUIExtensions)));
@@ -142,7 +140,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
const [extensionIdentifier] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix)));
return extensionIdentifier;
}
if (isUIExtension(manifest, this.productService, this.configurationService)) {
if (isUIExtension(manifest, this.configurationService)) {
// Install only on local server
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix);
}
@@ -163,7 +161,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
// Install on both servers
return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(() => undefined);
}
if (isUIExtension(manifest, this.productService, this.configurationService)) {
if (isUIExtension(manifest, this.configurationService)) {
// Install only on local server
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
}
@@ -212,7 +210,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
for (let idx = 0; idx < extensions.length; idx++) {
const extension = extensions[idx];
const manifest = manifests[idx];
if (manifest && isUIExtension(manifest, this.productService, this.configurationService)) {
if (manifest && isUIExtension(manifest, this.configurationService)) {
result.set(extension.identifier.id.toLowerCase(), extension);
uiExtensionsManifests.push(manifest);
}

View File

@@ -457,8 +457,8 @@ async function readCaCertificates() {
return undefined;
}
async function readWindowsCaCertificates() {
const winCA = await import('vscode-windows-ca-certs');
function readWindowsCaCertificates() {
const winCA = require.__$__nodeRequire<any>('vscode-windows-ca-certs');
let ders: any[] = [];
const store = winCA();
@@ -481,14 +481,7 @@ async function readWindowsCaCertificates() {
}
async function readMacCaCertificates() {
const stdout = await new Promise<string>((resolve, reject) => {
const child = cp.spawn('/usr/bin/security', ['find-certificate', '-a', '-p']);
const stdout: string[] = [];
child.stdout.setEncoding('utf8');
child.stdout.on('data', str => stdout.push(str));
child.on('error', reject);
child.on('exit', code => code ? reject(code) : resolve(stdout.join('')));
});
const stdout = (await promisify(cp.execFile)('/usr/bin/security', ['find-certificate', '-a', '-p'], { encoding: 'utf8', maxBuffer: 1024 * 1024 })).stdout;
const seen = {};
const certs = stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g)
.filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true));