extHost.api.impl.ts 54.9 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

A
Alex Dima 已提交
6 7 8
import { localize } from 'vs/nls';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
J
Joao Moreno 已提交
9
import { Emitter, Event } from 'vs/base/common/event';
10
import { TernarySearchTree } from 'vs/base/common/map';
11
import * as path from 'vs/base/common/path';
A
Alex Dima 已提交
12 13 14 15 16 17 18
import Severity from 'vs/base/common/severity';
import { URI } from 'vs/base/common/uri';
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
import { OverviewRulerLane } from 'vs/editor/common/model';
import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration';
import { score } from 'vs/editor/common/modes/languageSelector';
import * as files from 'vs/platform/files/common/files';
D
Dirk Baeumer 已提交
19
import { ExtHostContext, IInitData, IMainContext, MainContext, MainThreadKeytarShape, IEnvironment, MainThreadWindowShape, MainThreadTelemetryShape } from 'vs/workbench/api/common/extHost.protocol';
J
Johannes Rieken 已提交
20 21 22 23 24
import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands';
import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostComments } from 'vs/workbench/api/common/extHostComments';
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
A
Alex Dima 已提交
25
import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
J
Johannes Rieken 已提交
26 27 28 29 30 31 32
import { ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations';
import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics';
import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs';
import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders';
import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
33
import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator';
A
Alex Dima 已提交
34
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
J
Johannes Rieken 已提交
35 36 37 38 39
import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem';
import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService';
import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService';
import { ExtHostLanguageFeatures, ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages';
J
Johannes Rieken 已提交
40
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
J
Johannes Rieken 已提交
41
import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService';
42 43
import { ExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
import { LogOutputChannelFactory } from 'vs/workbench/api/node/extHostOutputService';
J
Johannes Rieken 已提交
44 45 46
import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress';
import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen';
import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM';
A
Alex Dima 已提交
47
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
J
Johannes Rieken 已提交
48 49
import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar';
import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
A
Alex Dima 已提交
50
import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
J
Johannes Rieken 已提交
51
import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService';
J
Johannes Rieken 已提交
52 53 54 55 56 57 58 59
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { ExtHostWindow } from 'vs/workbench/api/common/extHostWindow';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
60
import { throwProposedApiError, checkProposedApiEnabled, nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
J
Johannes Rieken 已提交
61
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
62
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
A
Alex Dima 已提交
63
import * as vscode from 'vscode';
64
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
65
import { originalFSPath } from 'vs/base/common/resources';
66
import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer';
67
import { withNullAsUndefined } from 'vs/base/common/types';
J
Johannes Rieken 已提交
68
import { values } from 'vs/base/common/collections';
D
Dirk Baeumer 已提交
69
import { endsWith } from 'vs/base/common/strings';
E
Erich Gamma 已提交
70

71
export interface IExtensionApiFactory {
72
	(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
73 74
}

75
function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
76
	if (extension.enableProposedApi) {
77 78
		return fn;
	} else {
79
		return throwProposedApiError.bind(null, extension) as any as T;
80 81 82
	}
}

E
Erich Gamma 已提交
83
/**
84
 * This method instantiates and returns the extension API surface
E
Erich Gamma 已提交
85
 */
86 87
export function createApiFactory(
	initData: IInitData,
88
	rpcProtocol: IMainContext,
89 90
	extHostWorkspace: ExtHostWorkspace,
	extHostConfiguration: ExtHostConfiguration,
J
Joao Moreno 已提交
91
	extensionService: ExtHostExtensionService,
92 93
	extHostLogService: ExtHostLogService,
	extHostStorage: ExtHostStorage
94
): IExtensionApiFactory {
95

96
	const schemeTransformer: ISchemeTransformer | null = null;
A
Alex Dima 已提交
97

98
	// Addressable instances
99
	rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService);
A
Alex Dima 已提交
100 101
	const extHostHeapService = rpcProtocol.set(ExtHostContext.ExtHostHeapService, new ExtHostHeapService());
	const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol));
M
Matt Bierner 已提交
102
	const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol));
J
Joao Moreno 已提交
103
	const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol));
104
	const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol));
A
Alex Dima 已提交
105
	const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
106
	const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
107
	const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors)));
A
Alex Dima 已提交
108
	const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
109
	const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostHeapService, extHostLogService));
S
Sandeep Somavarapu 已提交
110
	const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
A
Alex Dima 已提交
111 112 113
	rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
	rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
	const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol));
114
	const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics, extHostLogService));
115
	const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures));
116
	const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors));
A
Alex Dima 已提交
117
	const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
118
	const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
119
	const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands));
120
	const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
P
Peng Lyu 已提交
121
	const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
R
Rob Lourens 已提交
122
	const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, schemeTransformer, extHostLogService));
123
	const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService));
A
Alex Dima 已提交
124 125
	const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
	rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
126
	const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
127
	const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(LogOutputChannelFactory, initData.logsLocation, rpcProtocol));
128
	rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage);
129 130 131 132
	if (initData.remoteAuthority) {
		const cliServer = new CLIServer(extHostCommands);
		process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;
	}
133 134

	// Check that no named customers are missing
J
Johannes Rieken 已提交
135
	const expected: ProxyIdentifier<any>[] = values(ExtHostContext);
A
Alex Dima 已提交
136
	rpcProtocol.assertRegistered(expected);
137

138
	// Other instances
139
	const extHostClipboard = new ExtHostClipboard(rpcProtocol);
A
Alex Dima 已提交
140 141 142
	const extHostMessageService = new ExtHostMessageService(rpcProtocol);
	const extHostDialogs = new ExtHostDialogs(rpcProtocol);
	const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
143
	const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments);
144

145
	// Register an output channel for exthost log
A
Tweaks  
Alex Dima 已提交
146 147
	const name = localize('extensionsLog', "Extension Host");
	extHostOutputService.createOutputChannelFromLogFile(name, extHostLogService.logFile);
148

149
	// Register API-ish commands
150
	ExtHostApiCommands.register(extHostCommands);
151

152
	return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode {
153

154 155 156 157 158
		// Check document selectors for being overly generic. Technically this isn't a problem but
		// in practice many extensions say they support `fooLang` but need fs-access to do so. Those
		// extension should specify then the `file`-scheme, e.g `{ scheme: 'fooLang', language: 'fooLang' }`
		// We only inform once, it is not a warning because we just want to raise awareness and because
		// we cannot say if the extension is doing it right or wrong...
159
		const checkSelector = (function () {
A
Alex Dima 已提交
160
			let done = (!extension.isUnderDevelopment);
161 162
			function informOnce(selector: vscode.DocumentSelector) {
				if (!done) {
163
					console.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`);
164 165
					done = true;
				}
166
			}
167
			return function perform(selector: vscode.DocumentSelector): vscode.DocumentSelector {
168 169 170 171 172 173 174 175 176 177
				if (Array.isArray(selector)) {
					selector.forEach(perform);
				} else if (typeof selector === 'string') {
					informOnce(selector);
				} else {
					if (typeof selector.scheme === 'undefined') {
						informOnce(selector);
					}
					if (!extension.enableProposedApi && typeof selector.exclusive === 'boolean') {
						throwProposedApiError(extension);
178 179 180 181 182
					}
				}
				return selector;
			};
		})();
183

184

185 186
		// namespace: commands
		const commands: typeof vscode.commands = {
M
Matt Bierner 已提交
187
			registerCommand(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
188
				return extHostCommands.registerCommand(true, id, command, thisArgs);
189
			},
190
			registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable {
191
				return extHostCommands.registerCommand(true, id, (...args: any[]): any => {
192
					const activeTextEditor = extHostEditors.getActiveTextEditor();
193 194
					if (!activeTextEditor) {
						console.warn('Cannot execute ' + id + ' because there is no active text editor.');
195
						return undefined;
196
					}
197 198 199 200 201 202 203 204 205 206

					return activeTextEditor.edit((edit: vscode.TextEditorEdit) => {
						args.unshift(activeTextEditor, edit);
						callback.apply(thisArg, args);

					}).then((result) => {
						if (!result) {
							console.warn('Edits from command ' + id + ' were not applied.');
						}
					}, (err) => {
207
						console.warn('An error occurred while running command ' + id, err);
208
					});
209
				});
210 211
			},
			registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => {
212
				return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
213
					const activeTextEditor = extHostEditors.getActiveTextEditor();
214 215 216 217 218 219 220 221
					if (!activeTextEditor) {
						console.warn('Cannot execute ' + id + ' because there is no active text editor.');
						return undefined;
					}

					const diff = await extHostEditors.getDiffInformation(activeTextEditor.id);
					callback.apply(thisArg, [diff, ...args]);
				});
222
			}),
223
			executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
M
Matt Bierner 已提交
224
				return extHostCommands.executeCommand<T>(id, ...args);
225
			},
226 227 228
			getCommands(filterInternal: boolean = false): Thenable<string[]> {
				return extHostCommands.getCommands(filterInternal);
			}
229
		};
230

231 232
		// namespace: env
		const env: typeof vscode.env = Object.freeze({
233 234
			get machineId() { return initData.telemetryInfo.machineId; },
			get sessionId() { return initData.telemetryInfo.sessionId; },
235 236
			get language() { return initData.environment.appLanguage; },
			get appName() { return initData.environment.appName; },
237
			get appRoot() { return initData.environment.appRoot!.fsPath; },
238
			get uriScheme() { return initData.environment.appUriScheme; },
239 240
			get logLevel() {
				checkProposedApiEnabled(extension);
241
				return typeConverters.LogLevel.to(extHostLogService.getLevel());
242 243 244
			},
			get onDidChangeLogLevel() {
				checkProposedApiEnabled(extension);
J
Joao Moreno 已提交
245
				return Event.map(extHostLogService.onDidChangeLogLevel, l => typeConverters.LogLevel.to(l));
246 247 248
			},
			get clipboard(): vscode.Clipboard {
				return extHostClipboard;
249
			},
J
Johannes Rieken 已提交
250
			openExternal(uri: URI) {
251
				return extHostWindow.openUri(uri);
252
			}
253
		});
E
Erich Gamma 已提交
254

255 256
		// namespace: extensions
		const extensions: typeof vscode.extensions = {
257 258
			getExtension(extensionId: string): Extension<any> | undefined {
				const desc = extensionRegistry.getExtensionDescription(extensionId);
259 260 261
				if (desc) {
					return new Extension(extensionService, desc);
				}
262
				return undefined;
263 264
			},
			get all(): Extension<any>[] {
A
Alex Dima 已提交
265
				return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc));
266 267 268
			},
			get onDidChange() {
				return extensionRegistry.onDidChange;
E
Erich Gamma 已提交
269
			}
270
		};
E
Erich Gamma 已提交
271

272 273 274 275 276
		// namespace: languages
		const languages: typeof vscode.languages = {
			createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
				return extHostDiagnostics.createDiagnosticCollection(name);
			},
277 278 279
			get onDidChangeDiagnostics() {
				return extHostDiagnostics.onDidChangeDiagnostics;
			},
A
Alex Dima 已提交
280
			getDiagnostics: (resource?: vscode.Uri) => {
281 282
				return <any>extHostDiagnostics.getDiagnostics(resource);
			},
283
			getLanguages(): Thenable<string[]> {
284 285
				return extHostLanguages.getLanguages();
			},
286
			setTextDocumentLanguage(document: vscode.TextDocument, languageId: string): Thenable<vscode.TextDocument> {
M
mechatroner 已提交
287
				return extHostLanguages.changeLanguage(document.uri, languageId);
288
			},
289
			match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number {
290
				return score(typeConverters.LanguageSelector.from(selector), document.uri, document.languageId, true);
291
			},
292
			registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable {
293
				return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata);
294 295
			},
			registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
296
				return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
297
			},
R
Rob DeLine 已提交
298
			registerCodeInsetProvider(selector: vscode.DocumentSelector, provider: vscode.CodeInsetProvider): vscode.Disposable {
299
				checkProposedApiEnabled(extension);
R
Rob DeLine 已提交
300 301
				return extHostLanguageFeatures.registerCodeInsetProvider(extension, checkSelector(selector), provider);
			},
302
			registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
303
				return extHostLanguageFeatures.registerDefinitionProvider(extension, checkSelector(selector), provider);
304
			},
305 306 307
			registerDeclarationProvider(selector: vscode.DocumentSelector, provider: vscode.DeclarationProvider): vscode.Disposable {
				return extHostLanguageFeatures.registerDeclarationProvider(extension, checkSelector(selector), provider);
			},
M
Matt Bierner 已提交
308
			registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable {
309
				return extHostLanguageFeatures.registerImplementationProvider(extension, checkSelector(selector), provider);
310
			},
311
			registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
312
				return extHostLanguageFeatures.registerTypeDefinitionProvider(extension, checkSelector(selector), provider);
313
			},
314
			registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
315
				return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier);
316 317
			},
			registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
318
				return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider);
319 320
			},
			registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable {
321
				return extHostLanguageFeatures.registerReferenceProvider(extension, checkSelector(selector), provider);
322 323
			},
			registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
324
				return extHostLanguageFeatures.registerRenameProvider(extension, checkSelector(selector), provider);
325
			},
326 327
			registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider, metadata?: vscode.DocumentSymbolProviderMetadata): vscode.Disposable {
				return extHostLanguageFeatures.registerDocumentSymbolProvider(extension, checkSelector(selector), provider, metadata);
328 329
			},
			registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
330
				return extHostLanguageFeatures.registerWorkspaceSymbolProvider(extension, provider);
331 332
			},
			registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
333
				return extHostLanguageFeatures.registerDocumentFormattingEditProvider(extension, checkSelector(selector), provider);
334 335
			},
			registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable {
336
				return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(extension, checkSelector(selector), provider);
337 338
			},
			registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable {
339
				return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(extension, checkSelector(selector), provider, [firstTriggerCharacter].concat(moreTriggerCharacters));
340
			},
341 342
			registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, firstItem?: string | vscode.SignatureHelpProviderMetadata, ...remaining: string[]): vscode.Disposable {
				if (typeof firstItem === 'object') {
343
					return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, firstItem);
344
				}
345
				return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, typeof firstItem === 'undefined' ? [] : [firstItem, ...remaining]);
346 347
			},
			registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable {
348
				return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters);
349 350
			},
			registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {
351
				return extHostLanguageFeatures.registerDocumentLinkProvider(extension, checkSelector(selector), provider);
352
			},
353
			registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable {
354
				return extHostLanguageFeatures.registerColorProvider(extension, checkSelector(selector), provider);
355
			},
356
			registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable {
357
				return extHostLanguageFeatures.registerFoldingRangeProvider(extension, checkSelector(selector), provider);
358
			},
359 360 361
			registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable {
				return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider);
			},
362 363 364 365
			registerCallHierarchyProvider(selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable {
				checkProposedApiEnabled(extension);
				return extHostLanguageFeatures.registerCallHierarchyProvider(extension, selector, provider);
			},
366
			setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
367
				return extHostLanguageFeatures.setLanguageConfiguration(language, configuration);
368
			}
369
		};
E
Erich Gamma 已提交
370

371 372 373 374 375 376 377 378
		// namespace: window
		const window: typeof vscode.window = {
			get activeTextEditor() {
				return extHostEditors.getActiveTextEditor();
			},
			get visibleTextEditors() {
				return extHostEditors.getVisibleTextEditors();
			},
379
			get activeTerminal() {
D
Daniel Imms 已提交
380
				return extHostTerminalService.activeTerminal;
381
			},
D
Daniel Imms 已提交
382
			get terminals() {
D
Daniel Imms 已提交
383
				return extHostTerminalService.terminals;
D
Daniel Imms 已提交
384
			},
385
			showTextDocument(documentOrUri: vscode.TextDocument | vscode.Uri, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): Thenable<vscode.TextEditor> {
386
				let documentPromise: Promise<vscode.TextDocument>;
J
Johannes Rieken 已提交
387
				if (URI.isUri(documentOrUri)) {
388
					documentPromise = Promise.resolve(workspace.openTextDocument(documentOrUri));
B
Benjamin Pasero 已提交
389
				} else {
390
					documentPromise = Promise.resolve(<vscode.TextDocument>documentOrUri);
B
Benjamin Pasero 已提交
391 392 393 394
				}
				return documentPromise.then(document => {
					return extHostEditors.showTextDocument(document, columnOrOptions, preserveFocus);
				});
395 396 397 398
			},
			createTextEditorDecorationType(options: vscode.DecorationRenderOptions): vscode.TextEditorDecorationType {
				return extHostEditors.createTextEditorDecorationType(options);
			},
399 400 401
			onDidChangeActiveTextEditor(listener, thisArg?, disposables?) {
				return extHostEditors.onDidChangeActiveTextEditor(listener, thisArg, disposables);
			},
402 403 404
			onDidChangeVisibleTextEditors(listener, thisArg, disposables) {
				return extHostEditors.onDidChangeVisibleTextEditors(listener, thisArg, disposables);
			},
405
			onDidChangeTextEditorSelection(listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
406 407
				return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables);
			},
408
			onDidChangeTextEditorOptions(listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
409 410
				return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables);
			},
411
			onDidChangeTextEditorVisibleRanges(listener: (e: vscode.TextEditorVisibleRangesChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
412
				return extHostEditors.onDidChangeTextEditorVisibleRanges(listener, thisArgs, disposables);
413
			},
414 415 416
			onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) {
				return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables);
			},
417 418 419
			onDidCloseTerminal(listener, thisArg?, disposables?) {
				return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables);
			},
D
Daniel Imms 已提交
420
			onDidOpenTerminal(listener, thisArg?, disposables?) {
421
				return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables);
D
Daniel Imms 已提交
422
			},
D
Daniel Imms 已提交
423
			onDidChangeActiveTerminal(listener, thisArg?, disposables?) {
424
				return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables);
D
Daniel Imms 已提交
425
			},
426 427 428
			onDidChangeTerminalDimensions(listener, thisArg?, disposables?) {
				return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables);
			},
J
Joao Moreno 已提交
429 430
			get state() {
				return extHostWindow.state;
431
			},
J
Joao Moreno 已提交
432
			onDidChangeWindowState(listener, thisArg?, disposables?) {
J
Joao Moreno 已提交
433
				return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables);
J
Joao Moreno 已提交
434
			},
435
			showInformationMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array<string | vscode.MessageItem>) {
436
				return extHostMessageService.showMessage(extension, Severity.Info, message, first, rest);
437
			},
438
			showWarningMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array<string | vscode.MessageItem>) {
439
				return extHostMessageService.showMessage(extension, Severity.Warning, message, first, rest);
440
			},
441
			showErrorMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array<string | vscode.MessageItem>) {
442
				return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest);
443
			},
C
Christof Marti 已提交
444
			showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
445
				return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token);
446
			},
447
			showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
448
				return extHostQuickOpen.showWorkspaceFolderPick(options);
449
			},
450
			showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) {
451
				return extHostQuickOpen.showInput(options, token);
C
Christof Marti 已提交
452
			},
453 454 455 456 457 458
			showOpenDialog(options) {
				return extHostDialogs.showOpenDialog(options);
			},
			showSaveDialog(options) {
				return extHostDialogs.showSaveDialog(options);
			},
459
			createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
460
				return extHostStatusBar.createStatusBarEntry(extension.identifier, <number>position, priority);
461 462 463 464
			},
			setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
				return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
			},
465
			withScmProgress<R>(task: (progress: vscode.Progress<number>) => Thenable<R>) {
466
				console.warn(`[Deprecation Warning] function 'withScmProgress' is deprecated and should no longer be used. Use 'withProgress' instead.`);
467
				return extHostProgress.withProgress(extension, { location: extHostTypes.ProgressLocation.SourceControl }, (progress, token) => task({ report(n: number) { /*noop*/ } }));
J
Johannes Rieken 已提交
468
			},
469
			withProgress<R>(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable<R>) {
J
Johannes Rieken 已提交
470
				return extHostProgress.withProgress(extension, options, task);
471
			},
S
Sandeep Somavarapu 已提交
472 473
			createOutputChannel(name: string): vscode.OutputChannel {
				return extHostOutputService.createOutputChannel(name);
474
			},
475
			createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel {
476
				return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options);
477
			},
478
			createTerminal(nameOrOptions?: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
479 480 481
				if (typeof nameOrOptions === 'object') {
					return extHostTerminalService.createTerminalFromOptions(<vscode.TerminalOptions>nameOrOptions);
				}
D
Daniel Imms 已提交
482
				return extHostTerminalService.createTerminal(<string>nameOrOptions, shellPath, shellArgs);
483
			},
484
			createTerminalRenderer(name: string): vscode.TerminalRenderer {
485
				return extHostTerminalService.createTerminalRenderer(name);
486
			},
487
			registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
488
				return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension);
489
			},
490
			createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> {
491
				return extHostTreeViews.createTreeView(viewId, options, extension);
S
Sandeep Somavarapu 已提交
492
			},
493 494 495
			registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
				return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer);
			},
496
			registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => {
497
				return extHostDecorations.registerDecorationProvider(provider, extension.identifier);
M
Matt Bierner 已提交
498
			}),
J
Joao Moreno 已提交
499
			registerUriHandler(handler: vscode.UriHandler) {
500
				return extHostUrls.registerUriHandler(extension.identifier, handler);
J
Joao Moreno 已提交
501
			},
C
Christof Marti 已提交
502
			createQuickPick<T extends vscode.QuickPickItem>(): vscode.QuickPick<T> {
M
Matt Bierner 已提交
503
				return extHostQuickOpen.createQuickPick(extension.identifier, !!extension.enableProposedApi);
C
Christof Marti 已提交
504 505
			},
			createInputBox(): vscode.InputBox {
506
				return extHostQuickOpen.createInputBox(extension.identifier);
507
			}
508
		};
E
Erich Gamma 已提交
509

510 511 512
		// namespace: workspace
		const workspace: typeof vscode.workspace = {
			get rootPath() {
513
				return extHostWorkspace.getPath();
514 515 516 517
			},
			set rootPath(value) {
				throw errors.readonly();
			},
518
			getWorkspaceFolder(resource) {
519
				return extHostWorkspace.getWorkspaceFolder(resource);
520
			},
521
			get workspaceFolders() {
522
				return extHostWorkspace.getWorkspaceFolders();
523
			},
524
			get name() {
525
				return extHostWorkspace.name;
526 527 528 529
			},
			set name(value) {
				throw errors.readonly();
			},
530
			updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => {
531
				return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd);
532
			},
533
			onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) {
534
				return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables);
535
			},
536
			asRelativePath: (pathOrUri, includeWorkspace?) => {
537
				return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace);
538 539
			},
			findFiles: (include, exclude, maxResults?, token?) => {
540
				return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(withNullAsUndefined(exclude)), maxResults, extension.identifier, token);
541
			},
542
			findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => {
543 544 545 546 547
				let options: vscode.FindTextInFilesOptions;
				let callback: (result: vscode.TextSearchResult) => void;

				if (typeof optionsOrCallback === 'object') {
					options = optionsOrCallback;
548
					callback = callbackOrToken as (result: vscode.TextSearchResult) => void;
549 550 551
				} else {
					options = {};
					callback = optionsOrCallback;
552
					token = callbackOrToken as vscode.CancellationToken;
553 554
				}

555
				return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token);
R
Rob Lourens 已提交
556
			},
557
			saveAll: (includeUntitled?) => {
558
				return extHostWorkspace.saveAll(includeUntitled);
559
			},
560
			applyEdit(edit: vscode.WorkspaceEdit): Thenable<boolean> {
561
				return extHostEditors.applyWorkspaceEdit(edit);
562 563
			},
			createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
564
				return extHostFileSystemEvent.createFileSystemWatcher(typeConverters.GlobPattern.from(pattern), ignoreCreate, ignoreChange, ignoreDelete);
565 566 567 568 569 570 571
			},
			get textDocuments() {
				return extHostDocuments.getAllDocumentData().map(data => data.document);
			},
			set textDocuments(value) {
				throw errors.readonly();
			},
572
			openTextDocument(uriOrFileNameOrOptions?: vscode.Uri | string | { language?: string; content?: string; }) {
573
				let uriPromise: Thenable<URI>;
B
Benjamin Pasero 已提交
574

575
				const options = uriOrFileNameOrOptions as { language?: string; content?: string; };
B
Benjamin Pasero 已提交
576
				if (typeof uriOrFileNameOrOptions === 'string') {
577
					uriPromise = Promise.resolve(URI.file(uriOrFileNameOrOptions));
B
Benjamin Pasero 已提交
578
				} else if (uriOrFileNameOrOptions instanceof URI) {
579
					uriPromise = Promise.resolve(uriOrFileNameOrOptions);
B
Benjamin Pasero 已提交
580 581
				} else if (!options || typeof options === 'object') {
					uriPromise = extHostDocuments.createDocumentData(options);
582
				} else {
B
Benjamin Pasero 已提交
583
					throw new Error('illegal argument - uriOrFileNameOrOptions');
584
				}
B
Benjamin Pasero 已提交
585 586 587

				return uriPromise.then(uri => {
					return extHostDocuments.ensureDocumentData(uri).then(() => {
M
Matt Bierner 已提交
588
						return extHostDocuments.getDocument(uri);
B
Benjamin Pasero 已提交
589
					});
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
				});
			},
			onDidOpenTextDocument: (listener, thisArgs?, disposables?) => {
				return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables);
			},
			onDidCloseTextDocument: (listener, thisArgs?, disposables?) => {
				return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables);
			},
			onDidChangeTextDocument: (listener, thisArgs?, disposables?) => {
				return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables);
			},
			onDidSaveTextDocument: (listener, thisArgs?, disposables?) => {
				return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables);
			},
			onWillSaveTextDocument: (listener, thisArgs?, disposables?) => {
605
				return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables);
606
			},
607
			onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
608
				return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
609
			},
610
			getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration {
R
Rob Lourens 已提交
611
				resource = arguments.length === 1 ? undefined : resource;
612
				return configProvider.getConfiguration(section, resource, extension.identifier);
613
			},
614 615
			registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
				return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
616
			},
617
			registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
618
				return extHostTask.registerTaskProvider(extension, provider);
J
Johannes Rieken 已提交
619
			},
620
			registerFileSystemProvider(scheme, provider, options) {
621
				return extHostFileSystem.registerFileSystemProvider(scheme, provider, options);
622
			},
B
Benjamin Pasero 已提交
623
			registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => {
624
				return extHostSearch.registerFileSearchProvider(scheme, provider);
M
Matt Bierner 已提交
625
			}),
B
Benjamin Pasero 已提交
626
			registerTextSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.TextSearchProvider) => {
627 628
				return extHostSearch.registerTextSearchProvider(scheme, provider);
			}),
629
			registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => {
630
				return extHostComment.registerDocumentCommentProvider(extension.identifier, provider);
631 632
			}),
			registerWorkspaceCommentProvider: proposedApiFunction(extension, (provider: vscode.WorkspaceCommentProvider) => {
633
				return extHostComment.registerWorkspaceCommentProvider(extension.identifier, provider);
634
			}),
A
Alex Dima 已提交
635 636 637
			registerRemoteAuthorityResolver: proposedApiFunction(extension, (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => {
				return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver);
			}),
638 639 640
			registerResourceLabelFormatter: proposedApiFunction(extension, (formatter: vscode.ResourceLabelFormatter) => {
				return extHostFileSystem.registerResourceLabelFormatter(formatter);
			}),
J
Johannes Rieken 已提交
641
			onDidRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => {
642
				return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables);
643
			}),
J
Johannes Rieken 已提交
644
			onWillRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileWillRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => {
645
				return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables);
J
Johannes Rieken 已提交
646
			})
647
		};
648

649 650
		// namespace: scm
		const scm: typeof vscode.scm = {
651
			get inputBox() {
652
				return extHostSCM.getLastInputBox(extension)!; // Strict null override - Deprecated api
653
			},
J
Joao Moreno 已提交
654 655
			createSourceControl(id: string, label: string, rootUri?: vscode.Uri) {
				return extHostSCM.createSourceControl(extension, id, label, rootUri);
J
Joao Moreno 已提交
656
			}
657
		};
J
Joao Moreno 已提交
658

659
		const comment: typeof vscode.comment = {
P
Peng Lyu 已提交
660 661
			createCommentController(id: string, label: string) {
				return extHostComment.createCommentController(extension, id, label);
662
			}
J
Joao Moreno 已提交
663
		};
664

665 666
		// namespace: debug
		const debug: typeof vscode.debug = {
667 668 669
			get activeDebugSession() {
				return extHostDebugService.activeDebugSession;
			},
670 671
			get activeDebugConsole() {
				return extHostDebugService.activeDebugConsole;
672
			},
673 674
			get breakpoints() {
				return extHostDebugService.breakpoints;
675
			},
676 677 678
			onDidStartDebugSession(listener, thisArg?, disposables?) {
				return extHostDebugService.onDidStartDebugSession(listener, thisArg, disposables);
			},
679
			onDidTerminateDebugSession(listener, thisArg?, disposables?) {
680
				return extHostDebugService.onDidTerminateDebugSession(listener, thisArg, disposables);
681
			},
A
Andre Weinand 已提交
682
			onDidChangeActiveDebugSession(listener, thisArg?, disposables?) {
683
				return extHostDebugService.onDidChangeActiveDebugSession(listener, thisArg, disposables);
A
Andre Weinand 已提交
684 685
			},
			onDidReceiveDebugSessionCustomEvent(listener, thisArg?, disposables?) {
A
Andre Weinand 已提交
686
				return extHostDebugService.onDidReceiveDebugSessionCustomEvent(listener, thisArg, disposables);
687
			},
688
			onDidChangeBreakpoints(listener, thisArgs?, disposables?) {
689 690
				return extHostDebugService.onDidChangeBreakpoints(listener, thisArgs, disposables);
			},
A
Andre Weinand 已提交
691
			registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider) {
692
				return extHostDebugService.registerDebugConfigurationProvider(debugType, provider);
693
			},
A
Andre Weinand 已提交
694 695
			registerDebugAdapterDescriptorFactory(debugType: string, factory: vscode.DebugAdapterDescriptorFactory) {
				return extHostDebugService.registerDebugAdapterDescriptorFactory(extension, debugType, factory);
696
			},
A
Andre Weinand 已提交
697 698
			registerDebugAdapterTrackerFactory(debugType: string, factory: vscode.DebugAdapterTrackerFactory) {
				return extHostDebugService.registerDebugAdapterTrackerFactory(debugType, factory);
699
			},
700 701
			startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession) {
				return extHostDebugService.startDebugging(folder, nameOrConfig, parentSession);
702 703
			},
			addBreakpoints(breakpoints: vscode.Breakpoint[]) {
704
				return extHostDebugService.addBreakpoints(breakpoints);
705 706
			},
			removeBreakpoints(breakpoints: vscode.Breakpoint[]) {
707
				return extHostDebugService.removeBreakpoints(breakpoints);
708
			}
709 710
		};

D
Dirk Baeumer 已提交
711 712 713 714
		const tasks: typeof vscode.tasks = {
			registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
				return extHostTask.registerTaskProvider(extension, provider);
			},
715
			fetchTasks: (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
D
Dirk Baeumer 已提交
716
				return extHostTask.fetchTasks(filter);
717 718
			},
			executeTask: (task: vscode.Task): Thenable<vscode.TaskExecution> => {
D
Dirk Baeumer 已提交
719
				return extHostTask.executeTask(extension, task);
720
			},
D
Dirk Baeumer 已提交
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
			get taskExecutions(): vscode.TaskExecution[] {
				return extHostTask.taskExecutions;
			},
			onDidStartTask: (listeners, thisArgs?, disposables?) => {
				return extHostTask.onDidStartTask(listeners, thisArgs, disposables);
			},
			onDidEndTask: (listeners, thisArgs?, disposables?) => {
				return extHostTask.onDidEndTask(listeners, thisArgs, disposables);
			},
			onDidStartTaskProcess: (listeners, thisArgs?, disposables?) => {
				return extHostTask.onDidStartTaskProcess(listeners, thisArgs, disposables);
			},
			onDidEndTaskProcess: (listeners, thisArgs?, disposables?) => {
				return extHostTask.onDidEndTaskProcess(listeners, thisArgs, disposables);
			}
		};
737

738
		return <typeof vscode>{
739
			version: initData.version,
740 741
			// namespaces
			commands,
742
			debug,
743 744 745
			env,
			extensions,
			languages,
J
Joao Moreno 已提交
746
			scm,
747
			comment,
D
Dirk Baeumer 已提交
748
			tasks,
749 750
			window,
			workspace,
751
			// types
752
			Breakpoint: extHostTypes.Breakpoint,
753
			CancellationTokenSource: CancellationTokenSource,
754
			CodeAction: extHostTypes.CodeAction,
M
Matt Bierner 已提交
755
			CodeActionKind: extHostTypes.CodeActionKind,
756
			CodeActionTrigger: extHostTypes.CodeActionTrigger,
757
			CodeLens: extHostTypes.CodeLens,
R
Rob DeLine 已提交
758
			CodeInset: extHostTypes.CodeInset,
759
			Color: extHostTypes.Color,
760
			ColorInformation: extHostTypes.ColorInformation,
761 762
			ColorPresentation: extHostTypes.ColorPresentation,
			CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState,
763 764 765
			CompletionItem: extHostTypes.CompletionItem,
			CompletionItemKind: extHostTypes.CompletionItemKind,
			CompletionList: extHostTypes.CompletionList,
M
Matt Bierner 已提交
766
			CompletionTriggerKind: extHostTypes.CompletionTriggerKind,
767
			ConfigurationTarget: extHostTypes.ConfigurationTarget,
768
			DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable,
769
			DebugAdapterServer: extHostTypes.DebugAdapterServer,
770
			DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior,
771
			Diagnostic: extHostTypes.Diagnostic,
772
			DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation,
773
			DiagnosticSeverity: extHostTypes.DiagnosticSeverity,
774
			DiagnosticTag: extHostTypes.DiagnosticTag,
775 776 777
			Disposable: extHostTypes.Disposable,
			DocumentHighlight: extHostTypes.DocumentHighlight,
			DocumentHighlightKind: extHostTypes.DocumentHighlightKind,
778
			DocumentLink: extHostTypes.DocumentLink,
779 780
			DocumentSymbol: extHostTypes.DocumentSymbol,
			EndOfLine: extHostTypes.EndOfLine,
781
			EventEmitter: Emitter,
G
Gabriel DeBacker 已提交
782
			CustomExecution: extHostTypes.CustomExecution,
783 784 785 786 787
			FileChangeType: extHostTypes.FileChangeType,
			FileSystemError: extHostTypes.FileSystemError,
			FileType: files.FileType,
			FoldingRange: extHostTypes.FoldingRange,
			FoldingRangeKind: extHostTypes.FoldingRangeKind,
788
			FunctionBreakpoint: extHostTypes.FunctionBreakpoint,
789
			Hover: extHostTypes.Hover,
790
			IndentAction: languageConfiguration.IndentAction,
791
			Location: extHostTypes.Location,
792
			LogLevel: extHostTypes.LogLevel,
793
			MarkdownString: extHostTypes.MarkdownString,
794
			OverviewRulerLane: OverviewRulerLane,
795 796
			ParameterInformation: extHostTypes.ParameterInformation,
			Position: extHostTypes.Position,
797 798
			ProcessExecution: extHostTypes.ProcessExecution,
			ProgressLocation: extHostTypes.ProgressLocation,
799
			QuickInputButtons: extHostTypes.QuickInputButtons,
800
			Range: extHostTypes.Range,
801
			RelativePattern: extHostTypes.RelativePattern,
A
Alex Dima 已提交
802
			ResolvedAuthority: extHostTypes.ResolvedAuthority,
803
			Selection: extHostTypes.Selection,
804
			SelectionRange: extHostTypes.SelectionRange,
805 806
			ShellExecution: extHostTypes.ShellExecution,
			ShellQuoting: extHostTypes.ShellQuoting,
M
Matt Bierner 已提交
807
			SignatureHelpTriggerKind: extHostTypes.SignatureHelpTriggerKind,
808 809 810
			SignatureHelp: extHostTypes.SignatureHelp,
			SignatureInformation: extHostTypes.SignatureInformation,
			SnippetString: extHostTypes.SnippetString,
811
			SourceBreakpoint: extHostTypes.SourceBreakpoint,
812
			SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
813 814 815
			StatusBarAlignment: extHostTypes.StatusBarAlignment,
			SymbolInformation: extHostTypes.SymbolInformation,
			SymbolKind: extHostTypes.SymbolKind,
816
			Task: extHostTypes.Task,
A
Alex Ross 已提交
817
			Task2: extHostTypes.Task,
818 819 820 821
			TaskGroup: extHostTypes.TaskGroup,
			TaskPanelKind: extHostTypes.TaskPanelKind,
			TaskRevealKind: extHostTypes.TaskRevealKind,
			TaskScope: extHostTypes.TaskScope,
822 823
			TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason,
			TextEdit: extHostTypes.TextEdit,
824
			TextEditorCursorStyle: TextEditorCursorStyle,
825
			TextEditorLineNumbersStyle: extHostTypes.TextEditorLineNumbersStyle,
826
			TextEditorRevealType: extHostTypes.TextEditorRevealType,
827
			TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind,
828 829 830
			ThemeColor: extHostTypes.ThemeColor,
			ThemeIcon: extHostTypes.ThemeIcon,
			TreeItem: extHostTypes.TreeItem,
831
			TreeItem2: extHostTypes.TreeItem,
832
			TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState,
833
			Uri: URI,
834 835
			ViewColumn: extHostTypes.ViewColumn,
			WorkspaceEdit: extHostTypes.WorkspaceEdit,
836 837 838
			// proposed
			CallHierarchyDirection: extHostTypes.CallHierarchyDirection,
			CallHierarchyItem: extHostTypes.CallHierarchyItem
839
		};
840
	};
E
Erich Gamma 已提交
841 842 843 844
}

class Extension<T> implements vscode.Extension<T> {

A
Alex Dima 已提交
845
	private _extensionService: ExtHostExtensionService;
846
	private _identifier: ExtensionIdentifier;
E
Erich Gamma 已提交
847 848 849

	public id: string;
	public extensionPath: string;
850
	public packageJSON: IExtensionDescription;
E
Erich Gamma 已提交
851

J
Johannes Rieken 已提交
852
	constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) {
A
Alex Dima 已提交
853
		this._extensionService = extensionService;
854 855
		this._identifier = description.identifier;
		this.id = description.identifier.value;
856
		this.extensionPath = path.normalize(originalFSPath(description.extensionLocation));
E
Erich Gamma 已提交
857 858 859 860
		this.packageJSON = description;
	}

	get isActive(): boolean {
861
		return this._extensionService.isActivated(this._identifier);
E
Erich Gamma 已提交
862 863 864
	}

	get exports(): T {
865
		if (this.packageJSON.api === 'none') {
866
			return undefined!; // Strict nulloverride - Public api
867
		}
868
		return <T>this._extensionService.getExtensionExports(this._identifier);
E
Erich Gamma 已提交
869 870 871
	}

	activate(): Thenable<T> {
872
		return this._extensionService.activateByIdWithErrors(this._identifier, new ExtensionActivatedByAPI(false)).then(() => this.exports);
E
Erich Gamma 已提交
873 874 875
	}
}

D
Dirk Baeumer 已提交
876 877 878 879
interface LoadFunction {
	(request: string, parent: { filename: string; }, isMain: any): any;
}

A
Alex Dima 已提交
880
interface INodeModuleFactory {
D
Dirk Baeumer 已提交
881
	readonly nodeModuleName: string | string[];
D
Dirk Baeumer 已提交
882
	load(request: string, parent: { filename: string; }, isMain: any, original: LoadFunction): any;
D
Dirk Baeumer 已提交
883
	alternaiveModuleName?(name: string): string | undefined;
A
Alex Dima 已提交
884 885
}

886
export class NodeModuleRequireInterceptor {
A
Alex Dima 已提交
887 888 889
	public static INSTANCE = new NodeModuleRequireInterceptor();

	private readonly _factories: Map<string, INodeModuleFactory>;
D
Dirk Baeumer 已提交
890
	private readonly _alternatives: ((moduleName: string) => string | undefined)[];
A
Alex Dima 已提交
891 892 893

	constructor() {
		this._factories = new Map<string, INodeModuleFactory>();
D
Dirk Baeumer 已提交
894 895
		this._alternatives = [];
		this._installInterceptor(this._factories, this._alternatives);
A
Alex Dima 已提交
896 897
	}

D
Dirk Baeumer 已提交
898
	private _installInterceptor(factories: Map<string, INodeModuleFactory>, alternatives: ((moduleName: string) => string | undefined)[]): void {
A
Alex Dima 已提交
899 900 901
		const node_module = <any>require.__$__nodeRequire('module');
		const original = node_module._load;
		node_module._load = function load(request: string, parent: { filename: string; }, isMain: any) {
D
Dirk Baeumer 已提交
902 903 904 905 906 907 908
			for (let alternativeModuleName of alternatives) {
				let alternative = alternativeModuleName(request);
				if (alternative) {
					request = alternative;
					break;
				}
			}
A
Alex Dima 已提交
909 910 911
			if (!factories.has(request)) {
				return original.apply(this, arguments);
			}
D
Dirk Baeumer 已提交
912
			return factories.get(request)!.load(request, parent, isMain, original);
A
Alex Dima 已提交
913 914 915 916
		};
	}

	public register(interceptor: INodeModuleFactory): void {
D
Dirk Baeumer 已提交
917 918 919 920 921 922 923 924 925 926 927 928
		if (Array.isArray(interceptor.nodeModuleName)) {
			for (let moduleName of interceptor.nodeModuleName) {
				this._factories.set(moduleName, interceptor);
			}
		} else {
			this._factories.set(interceptor.nodeModuleName, interceptor);
		}
		if (typeof interceptor.alternaiveModuleName === 'function') {
			this._alternatives.push((moduleName) => {
				return interceptor.alternaiveModuleName!(moduleName);
			});
		}
A
Alex Dima 已提交
929 930 931
	}
}

932
export class VSCodeNodeModuleFactory implements INodeModuleFactory {
A
Alex Dima 已提交
933
	public readonly nodeModuleName = 'vscode';
J
Johannes Rieken 已提交
934

A
Alex Dima 已提交
935 936
	private readonly _extApiImpl = new Map<string, typeof vscode>();
	private _defaultApiImpl: typeof vscode;
937

A
Alex Dima 已提交
938 939 940 941 942 943 944 945 946
	constructor(
		private readonly _apiFactory: IExtensionApiFactory,
		private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
		private readonly _extensionRegistry: ExtensionDescriptionRegistry,
		private readonly _configProvider: ExtHostConfigProvider
	) {
	}

	public load(request: string, parent: { filename: string; }): any {
947 948

		// get extension id from filename and api for extension
A
Alex Dima 已提交
949
		const ext = this._extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
950
		if (ext) {
A
Alex Dima 已提交
951
			let apiImpl = this._extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier));
952
			if (!apiImpl) {
A
Alex Dima 已提交
953 954
				apiImpl = this._apiFactory(ext, this._extensionRegistry, this._configProvider);
				this._extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl);
955 956 957 958 959
			}
			return apiImpl;
		}

		// fall back to a default implementation
A
Alex Dima 已提交
960
		if (!this._defaultApiImpl) {
961
			let extensionPathsPretty = '';
A
Alex Dima 已提交
962
			this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
963
			console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}. These are the extension path mappings: \n${extensionPathsPretty}`);
A
Alex Dima 已提交
964
			this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider);
E
Erich Gamma 已提交
965
		}
A
Alex Dima 已提交
966 967
		return this._defaultApiImpl;
	}
E
Erich Gamma 已提交
968
}
A
Alex Dima 已提交
969 970 971 972 973 974 975 976 977

interface IKeytarModule {
	getPassword(service: string, account: string): Promise<string | null>;
	setPassword(service: string, account: string, password: string): Promise<void>;
	deletePassword(service: string, account: string): Promise<boolean>;
	findPassword(service: string): Promise<string | null>;
}

export class KeytarNodeModuleFactory implements INodeModuleFactory {
D
Dirk Baeumer 已提交
978
	public readonly nodeModuleName: string = 'keytar';
A
Alex Dima 已提交
979

D
Dirk Baeumer 已提交
980
	private alternativeNames: Set<string> | undefined;
A
Alex Dima 已提交
981 982
	private _impl: IKeytarModule;

D
Dirk Baeumer 已提交
983 984 985 986 987 988 989 990 991 992 993 994 995
	constructor(mainThreadKeytar: MainThreadKeytarShape, environment: IEnvironment) {
		if (environment.appRoot) {
			let appRoot = environment.appRoot.fsPath;
			if (process.platform === 'win32') {
				appRoot = appRoot.replace(/\\/g, '/');
			}
			if (appRoot[appRoot.length - 1] === '/') {
				appRoot = appRoot.substr(0, appRoot.length - 1);
			}
			this.alternativeNames = new Set();
			this.alternativeNames.add(`${appRoot}/node_modules.asar/keytar`);
			this.alternativeNames.add(`${appRoot}/node_modules/keytar`);
		}
A
Alex Dima 已提交
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
		this._impl = {
			getPassword: (service: string, account: string): Promise<string | null> => {
				return mainThreadKeytar.$getPassword(service, account);
			},
			setPassword: (service: string, account: string, password: string): Promise<void> => {
				return mainThreadKeytar.$setPassword(service, account, password);
			},
			deletePassword: (service: string, account: string): Promise<boolean> => {
				return mainThreadKeytar.$deletePassword(service, account);
			},
			findPassword: (service: string): Promise<string | null> => {
				return mainThreadKeytar.$findPassword(service);
			}
		};
	}

	public load(request: string, parent: { filename: string; }): any {
		return this._impl;
	}
D
Dirk Baeumer 已提交
1015 1016 1017 1018 1019 1020 1021 1022

	public alternaiveModuleName(name: string): string | undefined {
		const length = name.length;
		// We need at least something like: `?/keytar` which requires
		// more than 7 characters.
		if (length <= 7 || !this.alternativeNames) {
			return undefined;
		}
D
Dirk Baeumer 已提交
1023 1024
		const sep = length - 7;
		if ((name.charAt(sep) === '/' || name.charAt(sep) === '\\') && endsWith(name, 'keytar')) {
D
Dirk Baeumer 已提交
1025 1026 1027 1028 1029 1030 1031
			name = name.replace(/\\/g, '/');
			if (this.alternativeNames.has(name)) {
				return 'keytar';
			}
		}
		return undefined;
	}
A
Alex Dima 已提交
1032
}
D
Dirk Baeumer 已提交
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110

interface OpenOptions {
	wait: boolean;
	app: string | string[];
}

interface IOriginalOpen {
	(target: string, options?: OpenOptions): Thenable<any>;
}

interface IOpenModule {
	(target: string, options?: OpenOptions): Thenable<void>;
}

export class OpenNodeModuleFactory implements INodeModuleFactory {

	public readonly nodeModuleName: string[] = ['open', 'opn'];

	private _extensionId: string | undefined;
	private _original: IOriginalOpen;
	private _impl: IOpenModule;

	constructor(mainThreadWindow: MainThreadWindowShape, private _mainThreadTelemerty: MainThreadTelemetryShape, private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>) {
		this._impl = (target, options) => {
			const uri: URI = URI.parse(target);
			// If we have options use the original method.
			if (options) {
				return this.callOriginal(target, options);
			}
			if (uri.scheme === 'http' || uri.scheme === 'https') {
				return mainThreadWindow.$openUri(uri);
			} else if (uri.scheme === 'mailto') {
				return mainThreadWindow.$openUri(uri);
			}
			return this.callOriginal(target, options);
		};
	}

	public load(request: string, parent: { filename: string; }, isMain: any, original: LoadFunction): any {
		// get extension id from filename and api for extension
		const extension = this._extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
		if (extension) {
			this._extensionId = extension.identifier.value;
			this.sendShimmingTelemetry();
		}

		this._original = original(request, parent, isMain);
		return this._impl;
	}

	private callOriginal(target: string, options: OpenOptions | undefined): Thenable<any> {
		this.sendNoForwardTelemetry();
		return this._original(target, options);
	}

	private sendShimmingTelemetry(): void {
		if (!this._extensionId) {
			return;
		}
		/* __GDPR__
			"shimming.open" : {
				"extension": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
			}
		*/
		this._mainThreadTelemerty.$publicLog('shimming.open', { extension: this._extensionId });
	}

	private sendNoForwardTelemetry(): void {
		if (!this._extensionId) {
			return;
		}
		/* __GDPR__
			"shimming.open.call.noForward" : {
				"extension": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
			}
		*/
		this._mainThreadTelemerty.$publicLog('shimming.open.call.noForward', { extension: this._extensionId });
	}
A
Alex Dima 已提交
1111
}