Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -9,7 +9,7 @@ import * as path from 'vs/base/common/path';
import { createApiFactory, initializeExtensionApi, ISqlExtensionApiFactory } from 'sql/workbench/api/node/sqlExtHost.api.impl';
import { originalFSPath } from 'vs/base/common/resources';
import { Barrier } from 'vs/base/common/async';
import { dispose, toDisposable } from 'vs/base/common/lifecycle';
import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { TernarySearchTree } from 'vs/base/common/map';
import { URI } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
@@ -18,7 +18,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor';
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
@@ -29,25 +29,40 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
import * as vscode from 'vscode';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { IWorkspace } from 'vs/platform/workspace/common/workspace';
import { Schemas } from 'vs/base/common/network';
import { withNullAsUndefined } from 'vs/base/common/types';
import { VSBuffer } from 'vs/base/common/buffer';
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento';
import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths';
import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes';
import { IURITransformer } from 'vs/base/common/uriIpc';
interface ITestRunner {
/** Old test runner API, as exported from `vscode/lib/testrunner` */
run(testsRoot: string, clb: (error: Error, failures?: number) => void): void;
}
interface INewTestRunner {
/** New test runner API, as explained in the extension test doc */
run(): Promise<void>;
}
export interface IHostUtils {
exit(code?: number): void;
exists(path: string): Promise<boolean>;
realpath(path: string): Promise<string>;
}
type TelemetryActivationEventFragment = {
id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000;
@@ -78,6 +93,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private _started: boolean;
private readonly _disposables: DisposableStore;
constructor(
hostUtils: IHostUtils,
initData: IInitData,
@@ -86,8 +103,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
extHostConfiguration: ExtHostConfiguration,
environment: IEnvironment,
extHostLogService: ExtHostLogService,
schemeTransformer: ISchemeTransformer | null,
outputChannelName: string
uriTransformer: IURITransformer | null
) {
this._hostUtils = hostUtils;
this._initData = initData;
@@ -96,6 +112,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this._extHostConfiguration = extHostConfiguration;
this._environment = environment;
this._extHostLogService = extHostLogService;
this._disposables = new DisposableStore();
this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace);
this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry);
@@ -137,8 +154,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this,
this._extHostLogService,
this._storage,
schemeTransformer,
outputChannelName
uriTransformer
);
this._resolvers = Object.create(null);
@@ -160,7 +176,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
// NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider));
await initializeExtensionApi(this, this._extensionApiFactory, this._registry, configProvider);
NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._environment));
if (this._initData.remoteAuthority) {
if (this._initData.remote.isRemote) {
NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory(
this._extHostContext.getProxy(MainContext.MainThreadWindow),
this._extHostContext.getProxy(MainContext.MainThreadTelemetry),
@@ -314,23 +330,32 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._mainThreadTelemetryProxy.$publicLog('extensionActivationTimes', {
type ExtensionActivationTimesClassification = {
outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
} & TelemetryActivationEventFragment & ExtensionActivationTimesFragment;
type ExtensionActivationTimesEvent = {
outcome: string
} & ActivationTimesEvent & TelemetryActivationEvent;
type ActivationTimesEvent = {
startup?: boolean;
codeLoadingTime?: number;
activateCallTime?: number;
activateResolvedTime?: number;
};
this._mainThreadTelemetryProxy.$publicLog2<ExtensionActivationTimesEvent, ExtensionActivationTimesClassification>('extensionActivationTimes', {
...event,
...(activationTimes || {}),
outcome,
outcome
});
}
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
const event = getTelemetryActivationEvent(extensionDescription, reason);
/* __GDPR__
"activatePlugin" : {
"${include}": [
"${TelemetryActivationEvent}"
]
}
*/
this._mainThreadTelemetryProxy.$publicLog('activatePlugin', event);
type ActivatePluginClassification = {} & TelemetryActivationEventFragment;
this._mainThreadTelemetryProxy.$publicLog2<TelemetryActivationEvent, ActivatePluginClassification>('activatePlugin', event);
if (!extensionDescription.main) {
// Treat the extension as being empty => NOT AN ERROR CASE
return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE));
@@ -347,7 +372,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
});
}
private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise<IExtensionContext> {
private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise<vscode.ExtensionContext> {
const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage);
const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage);
@@ -368,7 +393,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
globalStoragePath: this._storagePath.globalValue(extensionDescription),
asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); },
logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier),
executionContext: this._initData.remoteAuthority ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local
executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local,
});
});
}
@@ -428,27 +453,33 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
console.error(err);
});
return this._handleWorkspaceContainsEagerExtensions(this._extHostWorkspace.workspace);
this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added)));
const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : [];
return this._handleWorkspaceContainsEagerExtensions(folders);
}
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace | undefined): Promise<void> {
if (!workspace || workspace.folders.length === 0) {
private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray<vscode.WorkspaceFolder>): Promise<void> {
if (folders.length === 0) {
return Promise.resolve(undefined);
}
return Promise.all(
this._registry.getAllExtensionDescriptions().map((desc) => {
return this._handleWorkspaceContainsEagerExtension(workspace, desc);
return this._handleWorkspaceContainsEagerExtension(folders, desc);
})
).then(() => { });
}
private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise<void> {
private _handleWorkspaceContainsEagerExtension(folders: ReadonlyArray<vscode.WorkspaceFolder>, desc: IExtensionDescription): Promise<void> {
const activationEvents = desc.activationEvents;
if (!activationEvents) {
return Promise.resolve(undefined);
}
if (this.isActivated(desc.identifier)) {
return Promise.resolve(undefined);
}
const fileNames: string[] = [];
const globPatterns: string[] = [];
@@ -467,16 +498,16 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
return Promise.resolve(undefined);
}
const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(workspace, desc.identifier, fileName))).then(() => { });
const globPatternPromise = this._activateIfGlobPatterns(desc.identifier, globPatterns);
const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(folders, desc.identifier, fileName))).then(() => { });
const globPatternPromise = this._activateIfGlobPatterns(folders, desc.identifier, globPatterns);
return Promise.all([fileNamePromise, globPatternPromise]).then(() => { });
}
private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
private async _activateIfFileName(folders: ReadonlyArray<vscode.WorkspaceFolder>, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
// find exact path
for (const { uri } of workspace.folders) {
for (const { uri } of folders) {
if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) {
// the file was found
return (
@@ -489,7 +520,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
return undefined;
}
private async _activateIfGlobPatterns(extensionId: ExtensionIdentifier, globPatterns: string[]): Promise<void> {
private async _activateIfGlobPatterns(folders: ReadonlyArray<vscode.WorkspaceFolder>, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise<void> {
this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`);
if (globPatterns.length === 0) {
@@ -497,7 +528,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
}
const tokenSource = new CancellationTokenSource();
const searchP = this._mainThreadWorkspaceProxy.$checkExists(globPatterns, tokenSource.token);
const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token);
const timer = setTimeout(async () => {
tokenSource.cancel();
@@ -545,7 +576,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
const extensionTestsPath = originalFSPath(extensionTestsLocationURI);
// Require the test runner via node require from the provided path
let testRunner: ITestRunner | undefined;
let testRunner: ITestRunner | INewTestRunner | undefined;
let requireError: Error | undefined;
try {
testRunner = <any>require.__$__nodeRequire(extensionTestsPath);
@@ -553,10 +584,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
requireError = error;
}
// Execute the runner if it follows our spec
// Execute the runner if it follows the old `run` spec
if (testRunner && typeof testRunner.run === 'function') {
return new Promise<void>((c, e) => {
testRunner!.run(extensionTestsPath, (error, failures) => {
const oldTestRunnerCallback = (error: Error, failures: number | undefined) => {
if (error) {
e(error.toString());
} else {
@@ -565,7 +596,22 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
// after tests have run, we shutdown the host
this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */);
});
};
const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback);
// Using the new API `run(): Promise<void>`
if (runResult && runResult.then) {
runResult
.then(() => {
c();
this._gracefulExit(0);
})
.catch((err: Error) => {
e(err.toString());
this._gracefulExit(1);
});
}
});
}
@@ -582,7 +628,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
// messages to the main process, we delay the exit() by some time
setTimeout(() => {
// If extension tests are running, give the exit code to the renderer
if (this._initData.remoteAuthority && !!this._initData.environment.extensionTestsLocationURI) {
if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) {
this._mainThreadExtensionsProxy.$onExtensionHostExit(code);
return;
}
@@ -735,22 +781,20 @@ function loadCommonJSModule<T>(logService: ILogService, modulePath: string, acti
return Promise.resolve(r);
}
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any {
type TelemetryActivationEvent = {
id: string;
name: string;
extensionVersion: string;
publisherDisplayName: string;
activationEvents: string | null;
isBuiltin: boolean;
reason: string;
};
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent {
const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent :
reason instanceof ExtensionActivatedByAPI ? 'api' :
'';
/* __GDPR__FRAGMENT__
"TelemetryActivationEvent" : {
"id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"extensionVersion": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
const event = {
id: extensionDescription.identifier.value,
name: extensionDescription.name,