Merge from vscode 591842cc4b71958c81947b254924a215fe3edcbd (#4886)

This commit is contained in:
Karl Burtram
2019-04-05 14:14:26 -07:00
committed by GitHub
parent 657adafb7d
commit 0532346f4f
117 changed files with 1691 additions and 1191 deletions

View File

@@ -16,8 +16,19 @@ export interface IExtensionDevOptions {
export function parseExtensionDevOptions(environmentService: IEnvironmentService): IExtensionDevOptions {
// handle extension host lifecycle a bit special when we know we are developing an extension that runs inside
let isExtensionDevHost = environmentService.isExtensionDevelopment;
const extDevLoc = environmentService.extensionDevelopmentLocationURI;
const debugOk = !extDevLoc || extDevLoc.scheme === Schemas.file;
let debugOk = true;
let extDevLoc = environmentService.extensionDevelopmentLocationURI;
if (Array.isArray(extDevLoc)) {
for (let x of extDevLoc) {
if (x.scheme !== Schemas.file) {
debugOk = false;
}
}
} else if (extDevLoc && extDevLoc.scheme !== Schemas.file) {
debugOk = false;
}
let isExtensionDevDebug = debugOk && typeof environmentService.debugExtensionHost.port === 'number';
let isExtensionDevDebugBrk = debugOk && !!environmentService.debugExtensionHost.break;
let isExtensionDevTestFromCli = isExtensionDevHost && !!environmentService.extensionTestsLocationURI && !environmentService.debugExtensionHost.break;

View File

@@ -294,10 +294,30 @@ export class CachedExtensionScanner {
// Always load developed extensions while extensions development
let developedExtensions: Promise<IExtensionDescription[]> = Promise.resolve([]);
if (environmentService.isExtensionDevelopment && environmentService.extensionDevelopmentLocationURI && environmentService.extensionDevelopmentLocationURI.scheme === Schemas.file) {
developedExtensions = ExtensionScanner.scanOneOrMultipleExtensions(
new ExtensionScannerInput(version, commit, locale, devMode, originalFSPath(environmentService.extensionDevelopmentLocationURI), false, true, translations), log
);
if (environmentService.isExtensionDevelopment) {
if (Array.isArray(environmentService.extensionDevelopmentLocationURI)) {
const extDescsP = environmentService.extensionDevelopmentLocationURI.filter(extLoc => extLoc.scheme === Schemas.file).map(extLoc => {
return ExtensionScanner.scanOneOrMultipleExtensions(
new ExtensionScannerInput(version, commit, locale, devMode, originalFSPath(extLoc), false, true, translations), log
);
});
developedExtensions = Promise.all(extDescsP).then((extDescArrays: IExtensionDescription[][]) => {
let extDesc: IExtensionDescription[] = [];
for (let eds of extDescArrays) {
extDesc = extDesc.concat(eds);
}
return extDesc;
});
} else if (environmentService.extensionDevelopmentLocationURI) {
if (environmentService.extensionDevelopmentLocationURI.scheme === Schemas.file) {
developedExtensions = ExtensionScanner.scanOneOrMultipleExtensions(
new ExtensionScannerInput(version, commit, locale, devMode, originalFSPath(environmentService.extensionDevelopmentLocationURI), false, true, translations), log
);
}
}
}
return Promise.all([finalBuiltinExtensions, userExtensions, developedExtensions]).then((extensionDescriptions: IExtensionDescription[][]) => {

View File

@@ -13,8 +13,9 @@ import { toErrorMessage } from 'vs/base/common/errorMessage';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import * as objects from 'vs/base/common/objects';
import { isWindows } from 'vs/base/common/platform';
import * as platform from 'vs/base/common/platform';
import { isEqual } from 'vs/base/common/resources';
import pkg from 'vs/platform/product/node/package';
import { URI } from 'vs/base/common/uri';
import { IRemoteConsoleLog, log, parse } from 'vs/base/common/console';
import { findFreePort, randomPort } from 'vs/base/node/ports';
@@ -102,12 +103,12 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
this._toDispose.push(this._lifecycleService.onWillShutdown(e => this._onWillShutdown(e)));
this._toDispose.push(this._lifecycleService.onShutdown(reason => this.terminate()));
this._toDispose.push(this._extensionHostDebugService.onClose(resource => {
if (this._isExtensionDevHost && isEqual(resource, this._environmentService.extensionDevelopmentLocationURI)) {
if (this._isExtensionDevHost && this.matchesExtDevLocations(resource)) {
this._windowService.closeWindow();
}
}));
this._toDispose.push(this._extensionHostDebugService.onReload(resource => {
if (this._isExtensionDevHost && isEqual(resource, this._environmentService.extensionDevelopmentLocationURI)) {
if (this._isExtensionDevHost && this.matchesExtDevLocations(resource)) {
this._windowService.reloadWindow();
}
}));
@@ -119,6 +120,18 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
}));
}
// returns true if the given resource url matches one of the extension development paths passed to VS Code
private matchesExtDevLocations(resource: URI): boolean {
const extDevLocs = this._environmentService.extensionDevelopmentLocationURI;
if (Array.isArray(extDevLocs)) {
return extDevLocs.some(extDevLoc => isEqual(extDevLoc, resource));
} else if (extDevLocs) {
return isEqual(extDevLocs, resource);
}
return false;
}
public dispose(): void {
this.terminate();
}
@@ -148,7 +161,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
// and detach under Linux and Mac create another process group.
// We detach because we have noticed that when the renderer exits, its child processes
// (i.e. extension host) are taken down in a brutal fashion by the OS
detached: !!isWindows,
detached: !!platform.isWindows,
execArgv: undefined as string[] | undefined,
silent: true
};
@@ -389,11 +402,15 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
const workspace = this._contextService.getWorkspace();
const r: IInitData = {
commit: product.commit,
version: pkg.version,
parentPid: process.pid,
environment: {
isExtensionDevelopmentDebug: this._isExtensionDevDebug,
appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined,
appSettingsHome: this._environmentService.appSettingsHome ? URI.file(this._environmentService.appSettingsHome) : undefined,
appName: product.nameLong,
appUriScheme: product.urlProtocol,
appLanguage: platform.language,
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
globalStorageHome: URI.file(this._environmentService.globalStorageHome),

View File

@@ -645,73 +645,84 @@ export class ExtensionService extends Disposable implements IExtensionService {
this._onDidChangeExtensionsStatus.fire(this._registry.getAllExtensionDescriptions().map(e => e.identifier));
}
private _getRuntimeExtensions(allExtensions: IExtensionDescription[]): Promise<IExtensionDescription[]> {
return this._extensionEnablementService.getDisabledExtensions()
.then(disabledExtensions => {
const runtimeExtensions: IExtensionDescription[] = [];
const extensionsToDisable: IExtensionDescription[] = [];
const userMigratedSystemExtensions: IExtensionIdentifier[] = [{ id: BetterMergeId }];
let enableProposedApiFor: string | string[] = this._environmentService.args['enable-proposed-api'] || [];
const notFound = (id: string) => nls.localize('notFound', "Extension \`{0}\` cannot use PROPOSED API as it cannot be found", id);
if (enableProposedApiFor.length) {
let allProposed = (enableProposedApiFor instanceof Array ? enableProposedApiFor : [enableProposedApiFor]);
allProposed.forEach(id => {
if (!allExtensions.some(description => ExtensionIdentifier.equals(description.identifier, id))) {
console.error(notFound(id));
}
});
// Make enabled proposed API be lowercase for case insensitive comparison
if (Array.isArray(enableProposedApiFor)) {
enableProposedApiFor = enableProposedApiFor.map(id => id.toLowerCase());
} else {
enableProposedApiFor = enableProposedApiFor.toLowerCase();
private isExtensionUnderDevelopment(extension: IExtensionDescription): boolean {
if (this._environmentService.isExtensionDevelopment) {
const extDevLoc = this._environmentService.extensionDevelopmentLocationURI;
const extLocation = extension.extensionLocation;
if (Array.isArray(extDevLoc)) {
for (let p of extDevLoc) {
if (isEqualOrParent(extLocation, p)) {
return true;
}
}
} else if (extDevLoc) {
return isEqualOrParent(extLocation, extDevLoc);
}
}
return false;
}
const enableProposedApiForAll = !this._environmentService.isBuilt ||
(!!this._environmentService.extensionDevelopmentLocationURI && product.nameLong !== 'Visual Studio Code') ||
(enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args);
private async _getRuntimeExtensions(allExtensions: IExtensionDescription[]): Promise<IExtensionDescription[]> {
for (const extension of allExtensions) {
const isExtensionUnderDevelopment = (
this._environmentService.isExtensionDevelopment
&& this._environmentService.extensionDevelopmentLocationURI
&& isEqualOrParent(extension.extensionLocation, this._environmentService.extensionDevelopmentLocationURI)
);
// Do not disable extensions under development
if (!isExtensionUnderDevelopment) {
if (disabledExtensions.some(disabled => areSameExtensions(disabled, { id: extension.identifier.value }))) {
continue;
}
}
const runtimeExtensions: IExtensionDescription[] = [];
const extensionsToDisable: IExtensionDescription[] = [];
const userMigratedSystemExtensions: IExtensionIdentifier[] = [{ id: BetterMergeId }];
if (!extension.isBuiltin) {
// Check if the extension is changed to system extension
const userMigratedSystemExtension = userMigratedSystemExtensions.filter(userMigratedSystemExtension => areSameExtensions(userMigratedSystemExtension, { id: extension.identifier.value }))[0];
if (userMigratedSystemExtension) {
extensionsToDisable.push(extension);
continue;
}
}
runtimeExtensions.push(this._updateEnableProposedApi(extension, enableProposedApiForAll, enableProposedApiFor));
}
let enableProposedApiFor: string | string[] = this._environmentService.args['enable-proposed-api'] || [];
this._telemetryService.publicLog('extensionsScanned', {
totalCount: runtimeExtensions.length,
disabledCount: disabledExtensions.length
});
const notFound = (id: string) => nls.localize('notFound', "Extension \`{0}\` cannot use PROPOSED API as it cannot be found", id);
if (extensionsToDisable.length) {
return this._extensionEnablementService.setEnablement(extensionsToDisable.map(e => toExtension(e)), EnablementState.Disabled)
.then(() => runtimeExtensions);
} else {
return runtimeExtensions;
if (enableProposedApiFor.length) {
let allProposed = (enableProposedApiFor instanceof Array ? enableProposedApiFor : [enableProposedApiFor]);
allProposed.forEach(id => {
if (!allExtensions.some(description => ExtensionIdentifier.equals(description.identifier, id))) {
console.error(notFound(id));
}
});
// Make enabled proposed API be lowercase for case insensitive comparison
if (Array.isArray(enableProposedApiFor)) {
enableProposedApiFor = enableProposedApiFor.map(id => id.toLowerCase());
} else {
enableProposedApiFor = enableProposedApiFor.toLowerCase();
}
}
const enableProposedApiForAll = !this._environmentService.isBuilt ||
(!!this._environmentService.extensionDevelopmentLocationURI && product.nameLong !== 'Visual Studio Code') ||
(enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args);
for (const extension of allExtensions) {
// Do not disable extensions under development
if (!this.isExtensionUnderDevelopment(extension)) {
if (!this._extensionEnablementService.isEnabled(toExtension(extension))) {
continue;
}
}
if (!extension.isBuiltin) {
// Check if the extension is changed to system extension
const userMigratedSystemExtension = userMigratedSystemExtensions.filter(userMigratedSystemExtension => areSameExtensions(userMigratedSystemExtension, { id: extension.identifier.value }))[0];
if (userMigratedSystemExtension) {
extensionsToDisable.push(extension);
continue;
}
}
runtimeExtensions.push(this._updateEnableProposedApi(extension, enableProposedApiForAll, enableProposedApiFor));
}
this._telemetryService.publicLog('extensionsScanned', {
totalCount: runtimeExtensions.length,
disabledCount: allExtensions.length - runtimeExtensions.length
});
if (extensionsToDisable.length) {
return this._extensionEnablementService.setEnablement(extensionsToDisable.map(e => toExtension(e)), EnablementState.Disabled)
.then(() => runtimeExtensions);
} else {
return runtimeExtensions;
}
}
private _updateEnableProposedApi(extension: IExtensionDescription, enableProposedApiForAll: boolean, enableProposedApiFor: string | string[]): IExtensionDescription {