Merge with master

This commit is contained in:
Gabriel DeBacker
2019-01-23 07:37:50 -08:00
168 changed files with 3972 additions and 1767 deletions

View File

@@ -55,7 +55,7 @@ export class OpenFolderAPICommand {
uri = correctedUri;
}
return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow);
return executor.executeCommand('_files.windowOpen', { folderURIs: [uri], forceNewWindow });
}
}
CommandsRegistry.registerCommand(OpenFolderAPICommand.ID, adjustHandler(OpenFolderAPICommand.execute));

View File

@@ -112,7 +112,7 @@ export function createApiFactory(
const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures));
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors));
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService, extHostCommands));
const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands));
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, schemeTransformer, extHostLogService));
@@ -255,7 +255,10 @@ export function createApiFactory(
},
get clipboard(): vscode.Clipboard {
return extHostClipboard;
}
},
open: proposedApiFunction(extension, (uri: URI) => {
return extHostWindow.openUri(uri);
})
});
// namespace: extensions
@@ -496,10 +499,7 @@ export function createApiFactory(
},
createInputBox(): vscode.InputBox {
return extHostQuickOpen.createInputBox(extension.identifier);
},
open: proposedApiFunction(extension, (uri: URI) => {
return extHostWindow.openUri(uri);
})
}
};
// namespace: workspace

View File

@@ -37,13 +37,14 @@ import { IAdapterDescriptor, IConfig, ITerminalSettings } from 'vs/workbench/par
import { ITextQueryBuilderOptions } from 'vs/workbench/parts/search/common/queryBuilder';
import { ITerminalDimensions } from 'vs/workbench/parts/terminal/common/terminal';
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import { IRPCProtocol, ProxyIdentifier, createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { IRPCProtocol, createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import * as vscode from 'vscode';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IRemoteConsoleLog } from 'vs/base/node/console';
export interface IEnvironment {
isExtensionDevelopmentDebug: boolean;
@@ -66,6 +67,7 @@ export interface IInitData {
parentPid: number;
environment: IEnvironment;
workspace: IWorkspaceData;
resolvedExtensions: ExtensionIdentifier[];
extensions: IExtensionDescription[];
telemetryInfo: ITelemetryInfo;
logLevel: LogLevel;
@@ -231,6 +233,10 @@ export interface MainThreadErrorsShape extends IDisposable {
$onUnexpectedError(err: any | SerializedError): void;
}
export interface MainThreadConsoleShape extends IDisposable {
$logExtensionHostMessage(msg: IRemoteConsoleLog): void;
}
export interface ISerializedRegExp {
pattern: string;
flags?: string;
@@ -286,7 +292,7 @@ export interface ISerializedSignatureHelpProviderMetadata {
export interface MainThreadLanguageFeaturesShape extends IDisposable {
$unregister(handle: number): void;
$registerOutlineSupport(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number): void;
$emitCodeLensEvent(eventHandle: number, event?: any): void;
$registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
@@ -297,8 +303,8 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerDocumentHighlightProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerReferenceSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerQuickFixSupport(handle: number, selector: ISerializedDocumentFilter[], supportedKinds?: string[]): void;
$registerDocumentFormattingSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerRangeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerDocumentFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerRangeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerOnTypeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], autoFormatTriggerCharacters: string[]): void;
$registerNavigateTypeSupport(handle: number): void;
$registerRenameSupport(handle: number, selector: ISerializedDocumentFilter[], supportsResolveInitialValues: boolean): void;
@@ -623,7 +629,7 @@ export interface MainThreadDebugServiceShape extends IDisposable {
export interface MainThreadWindowShape extends IDisposable {
$getWindowVisibility(): Promise<boolean>;
$openUri(uri: UriComponents): Promise<any>;
$openUri(uri: UriComponents): Promise<boolean>;
}
// -- extension host
@@ -866,7 +872,7 @@ export interface CodeActionDto {
diagnostics?: IMarkerData[];
command?: modes.Command;
kind?: string;
canAutoApply?: boolean;
isPreferred?: boolean;
}
export interface ExtHostLanguageFeaturesShape {
@@ -1069,10 +1075,11 @@ export interface ExtHostStorageShape {
// --- proxy identifiers
export const MainContext = {
MainThreadClipboard: <ProxyIdentifier<MainThreadClipboardShape>>createMainId<MainThreadClipboardShape>('MainThreadClipboard'),
MainThreadCommands: <ProxyIdentifier<MainThreadCommandsShape>>createMainId<MainThreadCommandsShape>('MainThreadCommands'),
MainThreadClipboard: createMainId<MainThreadClipboardShape>('MainThreadClipboard'),
MainThreadCommands: createMainId<MainThreadCommandsShape>('MainThreadCommands'),
MainThreadComments: createMainId<MainThreadCommentsShape>('MainThreadComments'),
MainThreadConfiguration: createMainId<MainThreadConfigurationShape>('MainThreadConfiguration'),
MainThreadConsole: createMainId<MainThreadConsoleShape>('MainThreadConsole'),
MainThreadDebugService: createMainId<MainThreadDebugServiceShape>('MainThreadDebugService'),
MainThreadDecorations: createMainId<MainThreadDecorationsShape>('MainThreadDecorations'),
MainThreadDiagnostics: createMainId<MainThreadDiagnosticsShape>('MainThreadDiagnostics'),

View File

@@ -191,6 +191,7 @@ export type ExtensionActivationReason = ExtensionActivatedByEvent | ExtensionAct
export class ExtensionsActivator {
private readonly _registry: ExtensionDescriptionRegistry;
private readonly _resolvedExtensionsSet: Set<string>;
private readonly _host: IExtensionsActivatorHost;
private readonly _activatingExtensions: Map<string, Promise<void>>;
private readonly _activatedExtensions: Map<string, ActivatedExtension>;
@@ -199,8 +200,10 @@ export class ExtensionsActivator {
*/
private readonly _alreadyActivatedEvents: { [activationEvent: string]: boolean; };
constructor(registry: ExtensionDescriptionRegistry, host: IExtensionsActivatorHost) {
constructor(registry: ExtensionDescriptionRegistry, resolvedExtensions: ExtensionIdentifier[], host: IExtensionsActivatorHost) {
this._registry = registry;
this._resolvedExtensionsSet = new Set<string>();
resolvedExtensions.forEach((extensionId) => this._resolvedExtensionsSet.add(ExtensionIdentifier.toKey(extensionId)));
this._host = host;
this._activatingExtensions = new Map<string, Promise<void>>();
this._activatedExtensions = new Map<string, ActivatedExtension>();
@@ -251,12 +254,18 @@ export class ExtensionsActivator {
let currentExtensionGetsGreenLight = true;
for (let j = 0, lenJ = depIds.length; j < lenJ; j++) {
let depId = depIds[j];
let depDesc = this._registry.getExtensionDescription(depId);
const depId = depIds[j];
if (this._resolvedExtensionsSet.has(ExtensionIdentifier.toKey(depId))) {
// This dependency is already resolved
continue;
}
const depDesc = this._registry.getExtensionDescription(depId);
if (!depDesc) {
// Error condition 1: unknown dependency
this._host.showMessage(Severity.Error, nls.localize('unknownDep', "Cannot activate extension '{0}' as the depending extension '{1}' is not found. Please install or enable the depending extension and reload the window.", currentExtension.displayName || currentExtension.identifier.value, depId));
this._host.showMessage(Severity.Error, nls.localize('unknownDep', "Cannot activate extension '{0}' because it depends on extension '{1}', which is not installed or disabled. Please install or enable '{1}' and reload the window.", currentExtension.displayName || currentExtension.identifier.value, depId));
const error = new Error(`Unknown dependency '${depId}'`);
this._activatedExtensions.set(ExtensionIdentifier.toKey(currentExtension.identifier), new FailedExtension(error));
return;
@@ -266,7 +275,7 @@ export class ExtensionsActivator {
if (dep) {
if (dep.activationFailed) {
// Error condition 2: a dependency has already failed activation
this._host.showMessage(Severity.Error, nls.localize('failedDep1', "Cannot activate extension '{0}' as the depending extension '{1}' is failed to activate.", currentExtension.displayName || currentExtension.identifier.value, depId));
this._host.showMessage(Severity.Error, nls.localize('failedDep1', "Cannot activate extension '{0}' because it depends on extension '{1}', which failed to activate.", currentExtension.displayName || currentExtension.identifier.value, depId));
const error = new Error(`Dependency ${depId} failed to activate`);
(<any>error).detail = dep.activationFailedError;
this._activatedExtensions.set(ExtensionIdentifier.toKey(currentExtension.identifier), new FailedExtension(error));

View File

@@ -192,7 +192,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
this._storage = new ExtHostStorage(this._extHostContext);
this._storagePath = new ExtensionStoragePath(initData.workspace, initData.environment);
this._activator = new ExtensionsActivator(this._registry, {
this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, {
showMessage: (severity: Severity, message: string): void => {
this._mainThreadExtensionsProxy.$localShowMessage(severity, message);

View File

@@ -347,7 +347,7 @@ class CodeActionAdapter {
diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from),
edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit),
kind: candidate.kind && candidate.kind.value,
canAutoApply: candidate.canAutoApply,
isPreferred: candidate.isPreferred,
});
}
}
@@ -1018,12 +1018,16 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return handle;
}
private static _extLabel(ext: IExtensionDescription): string {
return ext.displayName || ext.name;
}
// --- outline
registerDocumentSymbolProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider, metadata?: vscode.DocumentSymbolProviderMetadata): vscode.Disposable {
const handle = this._addNewAdapter(new DocumentSymbolAdapter(this._documents, provider), extension);
const displayName = (metadata && metadata.label) || (extension && (extension.displayName || extension.name)) || undefined;
this._proxy.$registerOutlineSupport(handle, this._transformDocumentSelector(selector), displayName);
const displayName = (metadata && metadata.label) || ExtHostLanguageFeatures._extLabel(extension);
this._proxy.$registerDocumentSymbolProvider(handle, this._transformDocumentSelector(selector), displayName);
return this._createDisposable(handle);
}
@@ -1152,7 +1156,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
registerDocumentFormattingEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
const handle = this._addNewAdapter(new DocumentFormattingAdapter(this._documents, provider), extension);
this._proxy.$registerDocumentFormattingSupport(handle, this._transformDocumentSelector(selector));
this._proxy.$registerDocumentFormattingSupport(handle, this._transformDocumentSelector(selector), ExtHostLanguageFeatures._extLabel(extension));
return this._createDisposable(handle);
}
@@ -1162,7 +1166,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
registerDocumentRangeFormattingEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable {
const handle = this._addNewAdapter(new RangeFormattingAdapter(this._documents, provider), extension);
this._proxy.$registerRangeFormattingSupport(handle, this._transformDocumentSelector(selector));
this._proxy.$registerRangeFormattingSupport(handle, this._transformDocumentSelector(selector), ExtHostLanguageFeatures._extLabel(extension));
return this._createDisposable(handle);
}

View File

@@ -14,6 +14,10 @@ import { ILogService } from 'vs/platform/log/common/log';
import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/parts/terminal/common/terminal';
import { TerminalProcess } from 'vs/workbench/parts/terminal/node/terminalProcess';
import { timeout } from 'vs/base/common/async';
import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net';
import * as http from 'http';
import * as fs from 'fs';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
const RENDERER_NO_PROCESS_ID = -1;
@@ -245,6 +249,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
private _terminalProcesses: { [id: number]: TerminalProcess } = {};
private _terminalRenderers: ExtHostTerminalRenderer[] = [];
private _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};
private _cliServer: CLIServer | undefined;
public get activeTerminal(): ExtHostTerminal { return this._activeTerminal; }
public get terminals(): ExtHostTerminal[] { return this._terminals; }
@@ -264,7 +269,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
constructor(
mainContext: IMainContext,
private _extHostConfiguration: ExtHostConfiguration,
private _logService: ILogService
private _logService: ILogService,
private _commands: ExtHostCommands
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService);
}
@@ -442,10 +448,19 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// terminalEnvironment.mergeEnvironments(env, envFromConfig);
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
terminalEnvironment.sanitizeEnvironment(env);
// Continue env initialization, merging in the env from the launch
// config and adding keys that are needed to create the process
terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, terminalConfig.get('setLocaleVariables'));
if (!this._cliServer) {
this._cliServer = new CLIServer(this._commands);
}
env['VSCODE_IPC_HOOK_CLI'] = this._cliServer.ipcHandlePath;
// Fork the process and listen for messages
this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env);
this._terminalProcesses[id] = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty'));
@@ -455,6 +470,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
this._terminalProcesses[id].onProcessExit((exitCode) => this._onProcessExit(id, exitCode));
}
public $acceptProcessInput(id: number, data: string): void {
this._terminalProcesses[id].input(data);
}
@@ -483,6 +499,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Send exit event to main side
this._proxy.$sendProcessExit(id, exitCode);
if (this._cliServer && !Object.keys(this._terminalProcesses).length) {
this._cliServer.dispose();
this._cliServer = undefined;
}
}
private _getTerminalByIdEventually(id: number, retries: number = 5): Promise<ExtHostTerminal> {
@@ -554,3 +576,70 @@ class ApiRequest {
this._callback.apply(proxy, [id].concat(this._args));
}
}
class CLIServer {
private _server: http.Server;
private _ipcHandlePath: string | undefined;
constructor(private _commands: ExtHostCommands) {
this._server = http.createServer((req, res) => this.onRequest(req, res));
this.setup().catch(err => {
console.error(err);
return '';
});
}
public get ipcHandlePath() {
return this._ipcHandlePath;
}
private async setup(): Promise<string> {
this._ipcHandlePath = generateRandomPipeName();
try {
this._server.listen(this.ipcHandlePath);
this._server.on('error', err => console.error(err));
} catch (err) {
console.error('Could not start open from terminal server.');
}
return this.ipcHandlePath;
}
private toURIs(strs: string[]): URI[] {
const result: URI[] = [];
if (Array.isArray(strs)) {
for (const s of strs) {
try {
result.push(URI.parse(s));
} catch (e) {
// ignore
}
}
}
return result;
}
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
const chunks: string[] = [];
req.setEncoding('utf8');
req.on('data', (d: string) => chunks.push(d));
req.on('end', () => {
const { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow } = JSON.parse(chunks.join(''));
if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) {
this._commands.executeCommand('_files.windowOpen', { folderURIs: this.toURIs(folderURIs), fileURIs: this.toURIs(fileURIs), forceNewWindow, diffMode, addMode, forceReuseWindow });
}
res.writeHead(200);
res.end();
});
}
dispose(): void {
this._server.close();
if (this._ipcHandlePath && process.platform !== 'win32' && fs.existsSync(this._ipcHandlePath)) {
fs.unlinkSync(this._ipcHandlePath);
}
}
}

View File

@@ -1000,7 +1000,7 @@ export class CodeAction {
edit?: WorkspaceEdit;
dianostics?: Diagnostic[];
diagnostics?: Diagnostic[];
kind?: CodeActionKind;
@@ -1022,6 +1022,7 @@ export class CodeActionKind {
public static readonly RefactorRewrite = CodeActionKind.Refactor.append('rewrite');
public static readonly Source = CodeActionKind.Empty.append('source');
public static readonly SourceOrganizeImports = CodeActionKind.Source.append('organizeImports');
public static readonly SourceFixAll = CodeActionKind.Source.append('fixAll');
constructor(
public readonly value: string
@@ -1031,6 +1032,10 @@ export class CodeActionKind {
return new CodeActionKind(this.value ? this.value + CodeActionKind.sep + parts : parts);
}
public intersects(other: CodeActionKind): boolean {
return this.contains(other) || other.contains(this);
}
public contains(other: CodeActionKind): boolean {
return this.value === other.value || startsWith(other.value, this.value + CodeActionKind.sep);
}

View File

@@ -7,6 +7,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { ExtHostWindowShape, MainContext, MainThreadWindowShape, IMainContext } from './extHost.protocol';
import { WindowState } from 'vscode';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
export class ExtHostWindow implements ExtHostWindowShape {
@@ -37,6 +38,9 @@ export class ExtHostWindow implements ExtHostWindowShape {
}
openUri(uri: URI): Promise<boolean> {
if (uri.scheme === Schemas.command) {
return Promise.reject(`Invalid scheme '${uri.scheme}'`);
}
return this._proxy.$openUri(uri);
}
}