Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)

This commit is contained in:
Anthony Dresser
2019-08-12 21:31:51 -07:00
committed by GitHub
parent 00250839fc
commit 7eba8c4c03
616 changed files with 9472 additions and 7087 deletions

View File

@@ -0,0 +1,936 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import * as path from 'vs/base/common/path';
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';
import { ExtHostContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands';
import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostComments } from 'vs/workbench/api/common/extHostComments';
import { ExtHostConfigProvider, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
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 { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator';
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem';
import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService';
import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures';
import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages';
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService';
import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress';
import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen';
import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM';
import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar';
import { IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
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 { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import * as vscode from 'vscode';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { originalFSPath } from 'vs/base/common/resources';
import { values } from 'vs/base/common/collections';
import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets';
import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations';
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { ILogService } from 'vs/platform/log/common/log';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
export interface IExtensionApiFactory {
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
}
function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
if (extension.enableProposedApi) {
return fn;
} else {
return throwProposedApiError.bind(null, extension) as any as T;
}
}
/**
* This method instantiates and returns the extension API surface
*/
export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): IExtensionApiFactory {
// services
const initData = accessor.get(IExtHostInitDataService);
const extensionService = accessor.get(IExtHostExtensionService);
const extHostWorkspace = accessor.get(IExtHostWorkspace);
const extHostConfiguration = accessor.get(IExtHostConfiguration);
const uriTransformer = accessor.get(IURITransformerService);
const rpcProtocol = accessor.get(IExtHostRpcService);
const extHostStorage = accessor.get(IExtHostStorage);
const extHostLogService = <ExtHostLogService>accessor.get(ILogService);
// register addressable instances
rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService);
rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace);
rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration);
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage);
// automatically create and register addressable instances
const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations));
const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, accessor.get(IExtHostDocumentsAndEditors));
const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService));
// const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); {{SQL CARBON EDIT}} remove debug service
const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch));
const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask));
const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService));
// manually create and register addressable instances
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment));
const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol));
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors)));
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment));
const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol));
const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, uriTransformer, extHostDocuments, extHostCommands, extHostDiagnostics, extHostLogService));
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 extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
// Check that no named customers are missing
// {{SQL CARBON EDIT}} filter out the services we don't expose
const filtered: ProxyIdentifier<any>[] = [ExtHostContext.ExtHostDebugService, ExtHostContext.ExtHostTask];
const expected: ProxyIdentifier<any>[] = values(ExtHostContext).filter(v => !filtered.includes(v));
rpcProtocol.assertRegistered(expected);
// Other instances
const extHostClipboard = new ExtHostClipboard(rpcProtocol);
const extHostMessageService = new ExtHostMessageService(rpcProtocol);
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments);
// Register an output channel for exthost log
const outputChannelName = initData.remote.isRemote ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host");
extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile);
// Register API-ish commands
ExtHostApiCommands.register(extHostCommands);
return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode {
// 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...
const checkSelector = (function () {
let done = (!extension.isUnderDevelopment);
function informOnce(selector: vscode.DocumentSelector) {
if (!done) {
console.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`);
done = true;
}
}
return function perform(selector: vscode.DocumentSelector): vscode.DocumentSelector {
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);
}
}
return selector;
};
})();
// namespace: commands
const commands: typeof vscode.commands = {
registerCommand(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
return extHostCommands.registerCommand(true, id, command, thisArgs);
},
registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable {
return extHostCommands.registerCommand(true, id, (...args: any[]): any => {
const activeTextEditor = extHostEditors.getActiveTextEditor();
if (!activeTextEditor) {
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
return undefined;
}
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) => {
console.warn('An error occurred while running command ' + id, err);
});
});
},
registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => {
return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
const activeTextEditor = extHostEditors.getActiveTextEditor();
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]);
});
}),
executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
return extHostCommands.executeCommand<T>(id, ...args);
},
getCommands(filterInternal: boolean = false): Thenable<string[]> {
return extHostCommands.getCommands(filterInternal);
},
onDidExecuteCommand: proposedApiFunction(extension, (listener, thisArgs?, disposables?) => {
checkProposedApiEnabled(extension);
return extHostCommands.onDidExecuteCommand(listener, thisArgs, disposables);
}),
};
// namespace: env
const env: typeof vscode.env = {
get machineId() { return initData.telemetryInfo.machineId; },
get sessionId() { return initData.telemetryInfo.sessionId; },
get language() { return initData.environment.appLanguage; },
get appName() { return initData.environment.appName; },
get appRoot() { return initData.environment.appRoot!.fsPath; },
get uriScheme() { return initData.environment.appUriScheme; },
get logLevel() {
checkProposedApiEnabled(extension);
return typeConverters.LogLevel.to(extHostLogService.getLevel());
},
get onDidChangeLogLevel() {
checkProposedApiEnabled(extension);
return Event.map(extHostLogService.onDidChangeLogLevel, l => typeConverters.LogLevel.to(l));
},
get clipboard(): vscode.Clipboard {
return extHostClipboard;
},
get shell() {
return extHostTerminalService.getDefaultShell(false, configProvider);
},
openExternal(uri: URI) {
return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote });
},
get remoteName() {
return getRemoteName(initData.remote.authority);
}
};
if (!initData.environment.extensionTestsLocationURI) {
// allow to patch env-function when running tests
Object.freeze(env);
}
const extensionKind = initData.remote.isRemote
? extHostTypes.ExtensionKind.Workspace
: extHostTypes.ExtensionKind.UI;
// namespace: extensions
const extensions: typeof vscode.extensions = {
getExtension(extensionId: string): Extension<any> | undefined {
const desc = extensionRegistry.getExtensionDescription(extensionId);
if (desc) {
return new Extension(extensionService, desc, extensionKind);
}
return undefined;
},
get all(): Extension<any>[] {
return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc, extensionKind));
},
get onDidChange() {
return extensionRegistry.onDidChange;
}
};
// namespace: languages
const languages: typeof vscode.languages = {
createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
return extHostDiagnostics.createDiagnosticCollection(name);
},
get onDidChangeDiagnostics() {
return extHostDiagnostics.onDidChangeDiagnostics;
},
getDiagnostics: (resource?: vscode.Uri) => {
return <any>extHostDiagnostics.getDiagnostics(resource);
},
getLanguages(): Thenable<string[]> {
return extHostLanguages.getLanguages();
},
setTextDocumentLanguage(document: vscode.TextDocument, languageId: string): Thenable<vscode.TextDocument> {
return extHostLanguages.changeLanguage(document.uri, languageId);
},
match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number {
return score(typeConverters.LanguageSelector.from(selector), document.uri, document.languageId, true);
},
registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable {
return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata);
},
registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider);
},
registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDefinitionProvider(extension, checkSelector(selector), provider);
},
registerDeclarationProvider(selector: vscode.DocumentSelector, provider: vscode.DeclarationProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDeclarationProvider(extension, checkSelector(selector), provider);
},
registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable {
return extHostLanguageFeatures.registerImplementationProvider(extension, checkSelector(selector), provider);
},
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
return extHostLanguageFeatures.registerTypeDefinitionProvider(extension, checkSelector(selector), provider);
},
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier);
},
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider);
},
registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable {
return extHostLanguageFeatures.registerReferenceProvider(extension, checkSelector(selector), provider);
},
registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
return extHostLanguageFeatures.registerRenameProvider(extension, checkSelector(selector), provider);
},
registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider, metadata?: vscode.DocumentSymbolProviderMetadata): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentSymbolProvider(extension, checkSelector(selector), provider, metadata);
},
registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
return extHostLanguageFeatures.registerWorkspaceSymbolProvider(extension, provider);
},
registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentFormattingEditProvider(extension, checkSelector(selector), provider);
},
registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(extension, checkSelector(selector), provider);
},
registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable {
return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(extension, checkSelector(selector), provider, [firstTriggerCharacter].concat(moreTriggerCharacters));
},
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, firstItem?: string | vscode.SignatureHelpProviderMetadata, ...remaining: string[]): vscode.Disposable {
if (typeof firstItem === 'object') {
return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, firstItem);
}
return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, typeof firstItem === 'undefined' ? [] : [firstItem, ...remaining]);
},
registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable {
return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters);
},
registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable {
return extHostLanguageFeatures.registerDocumentLinkProvider(extension, checkSelector(selector), provider);
},
registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable {
return extHostLanguageFeatures.registerColorProvider(extension, checkSelector(selector), provider);
},
registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable {
return extHostLanguageFeatures.registerFoldingRangeProvider(extension, checkSelector(selector), provider);
},
registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable {
return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider);
},
registerCallHierarchyProvider(selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable {
checkProposedApiEnabled(extension);
return extHostLanguageFeatures.registerCallHierarchyProvider(extension, selector, provider);
},
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
return extHostLanguageFeatures.setLanguageConfiguration(language, configuration);
}
};
// namespace: window
const window: typeof vscode.window = {
get activeTextEditor() {
return extHostEditors.getActiveTextEditor();
},
get visibleTextEditors() {
return extHostEditors.getVisibleTextEditors();
},
get activeTerminal() {
return extHostTerminalService.activeTerminal;
},
get terminals() {
return extHostTerminalService.terminals;
},
showTextDocument(documentOrUri: vscode.TextDocument | vscode.Uri, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): Thenable<vscode.TextEditor> {
let documentPromise: Promise<vscode.TextDocument>;
if (URI.isUri(documentOrUri)) {
documentPromise = Promise.resolve(workspace.openTextDocument(documentOrUri));
} else {
documentPromise = Promise.resolve(<vscode.TextDocument>documentOrUri);
}
return documentPromise.then(document => {
return extHostEditors.showTextDocument(document, columnOrOptions, preserveFocus);
});
},
createTextEditorDecorationType(options: vscode.DecorationRenderOptions): vscode.TextEditorDecorationType {
return extHostEditors.createTextEditorDecorationType(options);
},
onDidChangeActiveTextEditor(listener, thisArg?, disposables?) {
return extHostEditors.onDidChangeActiveTextEditor(listener, thisArg, disposables);
},
onDidChangeVisibleTextEditors(listener, thisArg, disposables) {
return extHostEditors.onDidChangeVisibleTextEditors(listener, thisArg, disposables);
},
onDidChangeTextEditorSelection(listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables);
},
onDidChangeTextEditorOptions(listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables);
},
onDidChangeTextEditorVisibleRanges(listener: (e: vscode.TextEditorVisibleRangesChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
return extHostEditors.onDidChangeTextEditorVisibleRanges(listener, thisArgs, disposables);
},
onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) {
return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables);
},
onDidCloseTerminal(listener, thisArg?, disposables?) {
return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables);
},
onDidOpenTerminal(listener, thisArg?, disposables?) {
return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables);
},
onDidChangeActiveTerminal(listener, thisArg?, disposables?) {
return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables);
},
onDidChangeTerminalDimensions(listener, thisArg?, disposables?) {
checkProposedApiEnabled(extension);
return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables);
},
onDidWriteTerminalData(listener, thisArg?, disposables?) {
checkProposedApiEnabled(extension);
return extHostTerminalService.onDidWriteTerminalData(listener, thisArg, disposables);
},
get state() {
return extHostWindow.state;
},
onDidChangeWindowState(listener, thisArg?, disposables?) {
return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables);
},
// {{SQL CARBON EDIT}} Typing needs to be disabled; enabled strict null checks allows the typing once we get there
showInformationMessage(message, first, ...rest) {
return extHostMessageService.showMessage(extension, Severity.Info, message, first, rest);
},
// {{SQL CARBON EDIT}} Typing needs to be disabled; enabled strict null checks allows the typing once we get there
showWarningMessage(message, first, ...rest) {
return extHostMessageService.showMessage(extension, Severity.Warning, message, first, rest);
},
// {{SQL CARBON EDIT}} Typing needs to be disabled; enabled strict null checks allows the typing once we get there
showErrorMessage(message, first, ...rest) {
return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest);
},
showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any {
return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token);
},
showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
return extHostQuickOpen.showWorkspaceFolderPick(options);
},
showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) {
return extHostQuickOpen.showInput(options, token);
},
showOpenDialog(options) {
return extHostDialogs.showOpenDialog(options);
},
showSaveDialog(options) {
return extHostDialogs.showSaveDialog(options);
},
createStatusBarItem(alignmentOrOptions?: vscode.StatusBarAlignment | vscode.window.StatusBarItemOptions, priority?: number): vscode.StatusBarItem {
let id: string;
let name: string;
let alignment: number | undefined;
if (alignmentOrOptions && typeof alignmentOrOptions !== 'number') {
id = alignmentOrOptions.id;
name = alignmentOrOptions.name;
alignment = alignmentOrOptions.alignment;
priority = alignmentOrOptions.priority;
} else {
id = extension.identifier.value;
name = nls.localize('extensionLabel', "{0} (Extension)", extension.displayName || extension.name);
alignment = alignmentOrOptions as number; // {{SQL CARBON EDIT}} strict-null-check
priority = priority;
}
return extHostStatusBar.createStatusBarEntry(id, name, alignment, priority);
},
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
},
withScmProgress<R>(task: (progress: vscode.Progress<number>) => Thenable<R>) {
console.warn(`[Deprecation Warning] function 'withScmProgress' is deprecated and should no longer be used. Use 'withProgress' instead.`);
return extHostProgress.withProgress(extension, { location: extHostTypes.ProgressLocation.SourceControl }, (progress, token) => task({ report(n: number) { /*noop*/ } }));
},
withProgress<R>(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable<R>) {
return extHostProgress.withProgress(extension, options, task);
},
createOutputChannel(name: string): vscode.OutputChannel {
return extHostOutputService.createOutputChannel(name);
},
createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel {
return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options);
},
createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions): vscode.WebviewEditorInset {
checkProposedApiEnabled(extension);
return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension);
},
createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
if (typeof nameOrOptions === 'object') {
if ('pty' in nameOrOptions) {
return extHostTerminalService.createExtensionTerminal(nameOrOptions);
}
return extHostTerminalService.createTerminalFromOptions(nameOrOptions);
}
return extHostTerminalService.createTerminal(<string>nameOrOptions, shellPath, shellArgs);
},
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension);
},
createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> {
return extHostTreeViews.createTreeView(viewId, options, extension);
},
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer);
},
registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => {
return extHostDecorations.registerDecorationProvider(provider, extension.identifier);
}),
registerUriHandler(handler: vscode.UriHandler) {
return extHostUrls.registerUriHandler(extension.identifier, handler);
},
createQuickPick<T extends vscode.QuickPickItem>(): vscode.QuickPick<T> {
return extHostQuickOpen.createQuickPick(extension.identifier, !!extension.enableProposedApi);
},
createInputBox(): vscode.InputBox {
return extHostQuickOpen.createInputBox(extension.identifier);
}
};
// namespace: workspace
const workspace: typeof vscode.workspace = {
get rootPath() {
return extHostWorkspace.getPath();
},
set rootPath(value) {
throw errors.readonly();
},
getWorkspaceFolder(resource) {
return extHostWorkspace.getWorkspaceFolder(resource);
},
get workspaceFolders() {
return extHostWorkspace.getWorkspaceFolders();
},
get name() {
return extHostWorkspace.name;
},
set name(value) {
throw errors.readonly();
},
get workspaceFile() {
return extHostWorkspace.workspaceFile;
},
set workspaceFile(value) {
throw errors.readonly();
},
updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => {
return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd);
},
onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) {
return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables);
},
asRelativePath: (pathOrUri, includeWorkspace?) => {
return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace);
},
findFiles: (include, exclude, maxResults?, token?) => {
// Note, undefined/null have different meanings on "exclude"
return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token);
},
findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => {
let options: vscode.FindTextInFilesOptions;
let callback: (result: vscode.TextSearchResult) => void;
if (typeof optionsOrCallback === 'object') {
options = optionsOrCallback;
callback = callbackOrToken as (result: vscode.TextSearchResult) => void;
} else {
options = {};
callback = optionsOrCallback;
token = callbackOrToken as vscode.CancellationToken;
}
return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token);
},
saveAll: (includeUntitled?) => {
return extHostWorkspace.saveAll(includeUntitled);
},
applyEdit(edit: vscode.WorkspaceEdit): Thenable<boolean> {
return extHostEditors.applyWorkspaceEdit(edit);
},
createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
return extHostFileSystemEvent.createFileSystemWatcher(typeConverters.GlobPattern.from(pattern), ignoreCreate, ignoreChange, ignoreDelete);
},
get textDocuments() {
return extHostDocuments.getAllDocumentData().map(data => data.document);
},
set textDocuments(value) {
throw errors.readonly();
},
openTextDocument(uriOrFileNameOrOptions?: vscode.Uri | string | { language?: string; content?: string; }) {
let uriPromise: Thenable<URI>;
const options = uriOrFileNameOrOptions as { language?: string; content?: string; };
if (typeof uriOrFileNameOrOptions === 'string') {
uriPromise = Promise.resolve(URI.file(uriOrFileNameOrOptions));
} else if (uriOrFileNameOrOptions instanceof URI) {
uriPromise = Promise.resolve(uriOrFileNameOrOptions);
} else if (!options || typeof options === 'object') {
uriPromise = extHostDocuments.createDocumentData(options);
} else {
throw new Error('illegal argument - uriOrFileNameOrOptions');
}
return uriPromise.then(uri => {
return extHostDocuments.ensureDocumentData(uri).then(() => {
return extHostDocuments.getDocument(uri);
});
});
},
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?) => {
return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables);
},
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
},
getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration {
resource = arguments.length === 1 ? undefined : resource;
return configProvider.getConfiguration(section, resource, extension.identifier);
},
registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
},
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
return extHostTask.registerTaskProvider(extension, type, provider);
},
registerFileSystemProvider(scheme, provider, options) {
return extHostFileSystem.registerFileSystemProvider(scheme, provider, options);
},
get fs() {
return extHostFileSystem.fileSystem;
},
registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => {
return extHostSearch.registerFileSearchProvider(scheme, provider);
}),
registerTextSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.TextSearchProvider) => {
return extHostSearch.registerTextSearchProvider(scheme, provider);
}),
registerRemoteAuthorityResolver: proposedApiFunction(extension, (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => {
return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver);
}),
registerResourceLabelFormatter: proposedApiFunction(extension, (formatter: vscode.ResourceLabelFormatter) => {
return extHostLabelService.$registerResourceLabelFormatter(formatter);
}),
onDidRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => {
return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables);
}),
onWillRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileWillRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => {
return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables);
})
};
// namespace: scm
const scm: typeof vscode.scm = {
get inputBox() {
return extHostSCM.getLastInputBox(extension)!; // Strict null override - Deprecated api
},
createSourceControl(id: string, label: string, rootUri?: vscode.Uri) {
return extHostSCM.createSourceControl(extension, id, label, rootUri);
}
};
const comment: typeof vscode.comments = {
createCommentController(id: string, label: string) {
return extHostComment.createCommentController(extension, id, label);
}
};
const comments = comment;
// {{SQL CARBON EDIT}} -- no-op debug extensibility API
// namespace: debug
const debug: typeof vscode.debug = {
get activeDebugSession() {
return undefined;
},
get activeDebugConsole() {
return undefined;
},
get breakpoints() {
return [];
},
onDidStartDebugSession(listener, thisArg?, disposables?) {
return undefined;
},
onDidTerminateDebugSession(listener, thisArg?, disposables?) {
return undefined;
},
onDidChangeActiveDebugSession(listener, thisArg?, disposables?) {
return undefined;
},
onDidReceiveDebugSessionCustomEvent(listener, thisArg?, disposables?) {
return undefined;
},
onDidChangeBreakpoints(listener, thisArgs?, disposables?) {
return undefined;
},
registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider) {
return undefined;
},
registerDebugAdapterDescriptorFactory(debugType: string, factory: vscode.DebugAdapterDescriptorFactory) {
return undefined;
},
registerDebugAdapterTrackerFactory(debugType: string, factory: vscode.DebugAdapterTrackerFactory) {
return undefined;
},
startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession) {
return undefined;
},
addBreakpoints(breakpoints: vscode.Breakpoint[]) {
return undefined;
},
removeBreakpoints(breakpoints: vscode.Breakpoint[]) {
return undefined;
}
};
const tasks: typeof vscode.tasks = {
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
return extHostTask.registerTaskProvider(extension, type, provider);
},
fetchTasks: (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
return extHostTask.fetchTasks(filter);
},
executeTask: (task: vscode.Task): Thenable<vscode.TaskExecution> => {
return extHostTask.executeTask(extension, task);
},
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);
}
};
return <typeof vscode>{
// {{SQL CARBON EDIT}} - Expose the VS Code version here for extensions that rely on it
version: initData.vscodeVersion,
// namespaces
commands,
debug,
env,
extensions,
languages,
scm,
comment,
comments,
tasks,
window,
workspace,
// types
Breakpoint: extHostTypes.Breakpoint,
CancellationTokenSource: CancellationTokenSource,
CodeAction: extHostTypes.CodeAction,
CodeActionKind: extHostTypes.CodeActionKind,
CodeActionTrigger: extHostTypes.CodeActionTrigger,
CodeLens: extHostTypes.CodeLens,
CodeInset: extHostTypes.CodeInset,
Color: extHostTypes.Color,
ColorInformation: extHostTypes.ColorInformation,
ColorPresentation: extHostTypes.ColorPresentation,
CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState,
CommentMode: extHostTypes.CommentMode,
CompletionItem: extHostTypes.CompletionItem,
CompletionItemKind: extHostTypes.CompletionItemKind,
CompletionList: extHostTypes.CompletionList,
CompletionTriggerKind: extHostTypes.CompletionTriggerKind,
ConfigurationTarget: extHostTypes.ConfigurationTarget,
DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable,
DebugAdapterServer: extHostTypes.DebugAdapterServer,
DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior,
Diagnostic: extHostTypes.Diagnostic,
DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation,
DiagnosticSeverity: extHostTypes.DiagnosticSeverity,
DiagnosticTag: extHostTypes.DiagnosticTag,
Disposable: extHostTypes.Disposable,
DocumentHighlight: extHostTypes.DocumentHighlight,
DocumentHighlightKind: extHostTypes.DocumentHighlightKind,
DocumentLink: extHostTypes.DocumentLink,
DocumentSymbol: extHostTypes.DocumentSymbol,
EndOfLine: extHostTypes.EndOfLine,
EventEmitter: Emitter,
ExtensionExecutionContext: extHostTypes.ExtensionExecutionContext,
ExtensionKind: extHostTypes.ExtensionKind,
CustomExecution2: extHostTypes.CustomExecution2,
FileChangeType: extHostTypes.FileChangeType,
FileSystemError: extHostTypes.FileSystemError,
FileType: files.FileType,
FoldingRange: extHostTypes.FoldingRange,
FoldingRangeKind: extHostTypes.FoldingRangeKind,
FunctionBreakpoint: extHostTypes.FunctionBreakpoint,
Hover: extHostTypes.Hover,
IndentAction: languageConfiguration.IndentAction,
Location: extHostTypes.Location,
LogLevel: extHostTypes.LogLevel,
MarkdownString: extHostTypes.MarkdownString,
OverviewRulerLane: OverviewRulerLane,
ParameterInformation: extHostTypes.ParameterInformation,
Position: extHostTypes.Position,
ProcessExecution: extHostTypes.ProcessExecution,
ProgressLocation: extHostTypes.ProgressLocation,
QuickInputButtons: extHostTypes.QuickInputButtons,
Range: extHostTypes.Range,
RelativePattern: extHostTypes.RelativePattern,
ResolvedAuthority: extHostTypes.ResolvedAuthority,
RemoteAuthorityResolverError: extHostTypes.RemoteAuthorityResolverError,
Selection: extHostTypes.Selection,
SelectionRange: extHostTypes.SelectionRange,
ShellExecution: extHostTypes.ShellExecution,
ShellQuoting: extHostTypes.ShellQuoting,
SignatureHelpTriggerKind: extHostTypes.SignatureHelpTriggerKind,
SignatureHelp: extHostTypes.SignatureHelp,
SignatureInformation: extHostTypes.SignatureInformation,
SnippetString: extHostTypes.SnippetString,
SourceBreakpoint: extHostTypes.SourceBreakpoint,
SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
StatusBarAlignment: extHostTypes.StatusBarAlignment,
SymbolInformation: extHostTypes.SymbolInformation,
SymbolKind: extHostTypes.SymbolKind,
Task: extHostTypes.Task,
Task2: extHostTypes.Task,
TaskGroup: extHostTypes.TaskGroup,
TaskPanelKind: extHostTypes.TaskPanelKind,
TaskRevealKind: extHostTypes.TaskRevealKind,
TaskScope: extHostTypes.TaskScope,
TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason,
TextEdit: extHostTypes.TextEdit,
TextEditorCursorStyle: TextEditorCursorStyle,
TextEditorLineNumbersStyle: extHostTypes.TextEditorLineNumbersStyle,
TextEditorRevealType: extHostTypes.TextEditorRevealType,
TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind,
ThemeColor: extHostTypes.ThemeColor,
ThemeIcon: extHostTypes.ThemeIcon,
TreeItem: extHostTypes.TreeItem,
TreeItem2: extHostTypes.TreeItem,
TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState,
Uri: URI,
ViewColumn: extHostTypes.ViewColumn,
WorkspaceEdit: extHostTypes.WorkspaceEdit,
// proposed
CallHierarchyDirection: extHostTypes.CallHierarchyDirection,
CallHierarchyItem: extHostTypes.CallHierarchyItem
};
};
}
class Extension<T> implements vscode.Extension<T> {
private _extensionService: IExtHostExtensionService;
private _identifier: ExtensionIdentifier;
readonly id: string;
readonly extensionPath: string;
readonly packageJSON: IExtensionDescription;
readonly extensionKind: vscode.ExtensionKind;
constructor(extensionService: IExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) {
this._extensionService = extensionService;
this._identifier = description.identifier;
this.id = description.identifier.value;
this.extensionPath = path.normalize(originalFSPath(description.extensionLocation));
this.packageJSON = description;
this.extensionKind = kind;
}
get isActive(): boolean {
return this._extensionService.isActivated(this._identifier);
}
get exports(): T {
if (this.packageJSON.api === 'none') {
return undefined!; // Strict nulloverride - Public api
}
return <T>this._extensionService.getExtensionExports(this._identifier);
}
activate(): Thenable<T> {
return this._extensionService.activateByIdWithErrors(this._identifier, new ExtensionActivatedByAPI(false)).then(() => this.exports);
}
}

View File

@@ -79,6 +79,7 @@ export interface IWorkspaceData extends IStaticWorkspaceData {
export interface IInitData {
version: string;
vscodeVersion: string; // {{SQL CARBON EDIT}} add vscodeVersion
commit?: string;
parentPid: number;
environment: IEnvironment;
@@ -135,7 +136,7 @@ export interface MainThreadCommentsShape extends IDisposable {
$unregisterCommentController(handle: number): void;
$updateCommentControllerFeatures(handle: number, features: CommentProviderFeatures): void;
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, extensionId: ExtensionIdentifier): modes.CommentThread | undefined;
$updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string, contextValue: string | undefined, comments: modes.Comment[], collapseState: modes.CommentThreadCollapsibleState): void;
$updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string | undefined, contextValue: string | undefined, comments: modes.Comment[], collapseState: modes.CommentThreadCollapsibleState): void;
$deleteCommentThread(handle: number, commentThreadHandle: number): void;
$onDidCommentThreadsChange(handle: number, event: modes.CommentThreadChangedEvent): void;
}
@@ -239,7 +240,7 @@ export interface MainThreadTextEditorsShape extends IDisposable {
$tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): Promise<void>;
$trySetSelections(id: string, selections: ISelection[]): Promise<void>;
$tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], opts: IApplyEditsOptions): Promise<boolean>;
$tryApplyWorkspaceEdit(workspaceEditDto: WorkspaceEditDto): Promise<boolean>;
$tryApplyWorkspaceEdit(workspaceEditDto: IWorkspaceEditDto): Promise<boolean>;
$tryInsertSnippet(id: string, template: string, selections: readonly IRange[], opts: IUndoStopOptions): Promise<boolean>;
$getDiffInformation(id: string): Promise<editorCommon.ILineChange[]>;
}
@@ -248,7 +249,7 @@ export interface MainThreadTreeViewsShape extends IDisposable {
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void;
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise<void>;
$reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void>;
$setMessage(treeViewId: string, message: string | IMarkdownString): void;
$setMessage(treeViewId: string, message: string): void;
}
export interface MainThreadDownloadServiceShape extends IDisposable {
@@ -270,28 +271,28 @@ export interface MainThreadKeytarShape extends IDisposable {
$findPassword(service: string): Promise<string | null>;
}
export interface ISerializedRegExp {
export interface IRegExpDto {
pattern: string;
flags?: string;
}
export interface ISerializedIndentationRule {
decreaseIndentPattern: ISerializedRegExp;
increaseIndentPattern: ISerializedRegExp;
indentNextLinePattern?: ISerializedRegExp;
unIndentedLinePattern?: ISerializedRegExp;
export interface IIndentationRuleDto {
decreaseIndentPattern: IRegExpDto;
increaseIndentPattern: IRegExpDto;
indentNextLinePattern?: IRegExpDto;
unIndentedLinePattern?: IRegExpDto;
}
export interface ISerializedOnEnterRule {
beforeText: ISerializedRegExp;
afterText?: ISerializedRegExp;
oneLineAboveText?: ISerializedRegExp;
export interface IOnEnterRuleDto {
beforeText: IRegExpDto;
afterText?: IRegExpDto;
oneLineAboveText?: IRegExpDto;
action: EnterAction;
}
export interface ISerializedLanguageConfiguration {
export interface ILanguageConfigurationDto {
comments?: CommentRule;
brackets?: CharacterPair[];
wordPattern?: ISerializedRegExp;
indentationRules?: ISerializedIndentationRule;
onEnterRules?: ISerializedOnEnterRule[];
wordPattern?: IRegExpDto;
indentationRules?: IIndentationRuleDto;
onEnterRules?: IOnEnterRuleDto[];
__electricCharacterSupport?: {
brackets?: any;
docComment?: {
@@ -312,7 +313,7 @@ export interface ISerializedLanguageConfiguration {
export type GlobPattern = string | { base: string; pattern: string };
export interface ISerializedDocumentFilter {
export interface IDocumentFilterDto {
$serialized: true;
language?: string;
scheme?: string;
@@ -320,37 +321,37 @@ export interface ISerializedDocumentFilter {
exclusive?: boolean;
}
export interface ISerializedSignatureHelpProviderMetadata {
export interface ISignatureHelpProviderMetadataDto {
readonly triggerCharacters: readonly string[];
readonly retriggerCharacters: readonly string[];
}
export interface MainThreadLanguageFeaturesShape extends IDisposable {
$unregister(handle: number): void;
$registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
$registerDocumentSymbolProvider(handle: number, selector: IDocumentFilterDto[], label: string): void;
$registerCodeLensSupport(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void;
$emitCodeLensEvent(eventHandle: number, event?: any): void;
$registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerImplementationSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerTypeDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerHoverProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$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[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerRangeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerOnTypeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
$registerDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerDeclarationSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerImplementationSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerTypeDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerHoverProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], supportedKinds?: string[]): void;
$registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerRangeFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void;
$registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void;
$registerNavigateTypeSupport(handle: number): void;
$registerRenameSupport(handle: number, selector: ISerializedDocumentFilter[], supportsResolveInitialValues: boolean): void;
$registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void;
$registerSignatureHelpProvider(handle: number, selector: ISerializedDocumentFilter[], metadata: ISerializedSignatureHelpProviderMetadata): void;
$registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerCallHierarchyProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$setLanguageConfiguration(handle: number, languageId: string, configuration: ISerializedLanguageConfiguration): void;
$registerRenameSupport(handle: number, selector: IDocumentFilterDto[], supportsResolveInitialValues: boolean): void;
$registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void;
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerSelectionRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
$setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void;
}
export interface MainThreadLanguagesShape extends IDisposable {
@@ -398,12 +399,14 @@ export interface TerminalLaunchConfig {
export interface MainThreadTerminalServiceShape extends IDisposable {
$createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string }>;
$createTerminalRenderer(name: string): Promise<number>;
$dispose(terminalId: number): void;
$hide(terminalId: number): void;
$sendText(terminalId: number, text: string, addNewLine: boolean): void;
$show(terminalId: number, preserveFocus: boolean): void;
/** @deprecated */
$registerOnDataListener(terminalId: number): void;
$startSendingDataEvents(): void;
$stopSendingDataEvents(): void;
// Process
$sendProcessTitle(terminalId: number, title: string): void;
@@ -414,12 +417,6 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$sendProcessCwd(terminalId: number, initialCwd: string): void;
$sendOverrideDimensions(terminalId: number, dimensions: ITerminalDimensions | undefined): void;
$sendResolvedLaunchConfig(terminalId: number, shellLaunchConfig: IShellLaunchConfig): void;
// Renderer
$terminalRendererSetName(terminalId: number, name: string): void;
$terminalRendererSetDimensions(terminalId: number, dimensions: ITerminalDimensions): void;
$terminalRendererWrite(terminalId: number, text: string): void;
$terminalRendererRegisterOnInputListener(terminalId: number): void;
}
export interface TransferQuickPickItems extends quickInput.IQuickPickItem {
@@ -652,7 +649,7 @@ export interface SCMProviderFeatures {
count?: number;
commitTemplate?: string;
acceptInputCommand?: modes.Command;
statusBarCommands?: CommandDto[];
statusBarCommands?: ICommandDto[];
}
export interface SCMGroupFeatures {
@@ -823,9 +820,6 @@ export interface ExtHostTreeViewsShape {
$setVisible(treeViewId: string, visible: boolean): void;
}
export interface ExtHostDownloadServiceShape {
}
export interface ExtHostWorkspaceShape {
$initializeWorkspace(workspace: IWorkspaceData | null): void;
$acceptWorkspaceData(workspace: IWorkspaceData | null): void;
@@ -932,7 +926,7 @@ export class IdObject {
}
}
export interface SuggestDataDto {
export interface ISuggestDataDto {
a/* label */: string;
b/* kind */: modes.CompletionItemKind;
c/* detail */?: string;
@@ -950,51 +944,51 @@ export interface SuggestDataDto {
x?: ChainedCacheId;
}
export interface SuggestResultDto {
export interface ISuggestResultDto {
x?: number;
a: IRange;
b: SuggestDataDto[];
b: ISuggestDataDto[];
c?: boolean;
}
export interface SignatureHelpDto {
export interface ISignatureHelpDto {
id: CacheId;
signatures: modes.SignatureInformation[];
activeSignature: number;
activeParameter: number;
}
export interface SignatureHelpContextDto {
export interface ISignatureHelpContextDto {
readonly triggerKind: modes.SignatureHelpTriggerKind;
readonly triggerCharacter?: string;
readonly isRetrigger: boolean;
readonly activeSignatureHelp?: SignatureHelpDto;
readonly activeSignatureHelp?: ISignatureHelpDto;
}
export interface LocationDto {
export interface ILocationDto {
uri: UriComponents;
range: IRange;
}
export interface DefinitionLinkDto {
export interface IDefinitionLinkDto {
originSelectionRange?: IRange;
uri: UriComponents;
range: IRange;
targetSelectionRange?: IRange;
}
export interface WorkspaceSymbolDto extends IdObject {
export interface IWorkspaceSymbolDto extends IdObject {
name: string;
containerName?: string;
kind: modes.SymbolKind;
location: LocationDto;
location: ILocationDto;
}
export interface WorkspaceSymbolsDto extends IdObject {
symbols: WorkspaceSymbolDto[];
export interface IWorkspaceSymbolsDto extends IdObject {
symbols: IWorkspaceSymbolDto[];
}
export interface ResourceFileEditDto {
export interface IResourceFileEditDto {
oldUri?: UriComponents;
newUri?: UriComponents;
options?: {
@@ -1005,76 +999,76 @@ export interface ResourceFileEditDto {
};
}
export interface ResourceTextEditDto {
export interface IResourceTextEditDto {
resource: UriComponents;
modelVersionId?: number;
edits: modes.TextEdit[];
}
export interface WorkspaceEditDto {
edits: Array<ResourceFileEditDto | ResourceTextEditDto>;
export interface IWorkspaceEditDto {
edits: Array<IResourceFileEditDto | IResourceTextEditDto>;
// todo@joh reject should go into rename
rejectReason?: string;
}
export function reviveWorkspaceEditDto(data: WorkspaceEditDto | undefined): modes.WorkspaceEdit {
export function reviveWorkspaceEditDto(data: IWorkspaceEditDto | undefined): modes.WorkspaceEdit {
if (data && data.edits) {
for (const edit of data.edits) {
if (typeof (<ResourceTextEditDto>edit).resource === 'object') {
(<ResourceTextEditDto>edit).resource = URI.revive((<ResourceTextEditDto>edit).resource);
if (typeof (<IResourceTextEditDto>edit).resource === 'object') {
(<IResourceTextEditDto>edit).resource = URI.revive((<IResourceTextEditDto>edit).resource);
} else {
(<ResourceFileEditDto>edit).newUri = URI.revive((<ResourceFileEditDto>edit).newUri);
(<ResourceFileEditDto>edit).oldUri = URI.revive((<ResourceFileEditDto>edit).oldUri);
(<IResourceFileEditDto>edit).newUri = URI.revive((<IResourceFileEditDto>edit).newUri);
(<IResourceFileEditDto>edit).oldUri = URI.revive((<IResourceFileEditDto>edit).oldUri);
}
}
}
return <modes.WorkspaceEdit>data;
}
export type CommandDto = ObjectIdentifier & modes.Command;
export type ICommandDto = ObjectIdentifier & modes.Command;
export interface CodeActionDto {
export interface ICodeActionDto {
title: string;
edit?: WorkspaceEditDto;
edit?: IWorkspaceEditDto;
diagnostics?: IMarkerData[];
command?: CommandDto;
command?: ICommandDto;
kind?: string;
isPreferred?: boolean;
}
export interface CodeActionListDto {
export interface ICodeActionListDto {
cacheId: number;
actions: ReadonlyArray<CodeActionDto>;
actions: ReadonlyArray<ICodeActionDto>;
}
export type CacheId = number;
export type ChainedCacheId = [CacheId, CacheId];
export interface LinksListDto {
export interface ILinksListDto {
id?: CacheId;
links: LinkDto[];
links: ILinkDto[];
}
export interface LinkDto {
export interface ILinkDto {
cacheId?: ChainedCacheId;
range: IRange;
url?: string | UriComponents;
tooltip?: string;
}
export interface CodeLensListDto {
export interface ICodeLensListDto {
cacheId?: number;
lenses: CodeLensDto[];
lenses: ICodeLensDto[];
}
export interface CodeLensDto {
export interface ICodeLensDto {
cacheId?: ChainedCacheId;
range: IRange;
command?: CommandDto;
command?: ICommandDto;
}
export interface CallHierarchyDto {
export interface ICallHierarchyDto {
_id: number;
kind: modes.SymbolKind;
name: string;
@@ -1086,40 +1080,40 @@ export interface CallHierarchyDto {
export interface ExtHostLanguageFeaturesShape {
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensListDto | undefined>;
$resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<ICodeLensListDto | undefined>;
$resolveCodeLens(handle: number, symbol: ICodeLensDto, token: CancellationToken): Promise<ICodeLensDto | undefined>;
$releaseCodeLenses(handle: number, id: number): void;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<DefinitionLinkDto[]>;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
$provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
$provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<IDefinitionLinkDto[]>;
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined>;
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined>;
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<LocationDto[] | undefined>;
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined>;
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<ILocationDto[] | undefined>;
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
$releaseCodeActions(handle: number, cacheId: number): void;
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined>;
$provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise<WorkspaceSymbolsDto>;
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined>;
$provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise<IWorkspaceSymbolsDto>;
$resolveWorkspaceSymbol(handle: number, symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise<IWorkspaceSymbolDto | undefined>;
$releaseWorkspaceSymbols(handle: number, id: number): void;
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined>;
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<IWorkspaceEditDto | undefined>;
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation | undefined>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<SuggestDataDto | undefined>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<ISuggestResultDto | undefined>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<ISuggestDataDto | undefined>;
$releaseCompletionItems(handle: number, id: number): void;
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<SignatureHelpDto | undefined>;
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<ISignatureHelpDto | undefined>;
$releaseSignatureHelp(handle: number, id: number): void;
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<LinksListDto | undefined>;
$resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<LinkDto | undefined>;
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<ILinksListDto | undefined>;
$resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<ILinkDto | undefined>;
$releaseDocumentLinks(handle: number, id: number): void;
$provideDocumentColors(handle: number, resource: UriComponents, token: CancellationToken): Promise<IRawColorInfo[]>;
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[] | undefined>;
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined>;
$provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]>;
$provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<CallHierarchyDto | undefined>;
$resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[CallHierarchyDto, modes.Location[]][]>;
$provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<ICallHierarchyDto | undefined>;
$resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[ICallHierarchyDto, modes.Location[]][]>;
}
export interface ExtHostQuickOpenShape {
@@ -1133,7 +1127,7 @@ export interface ExtHostQuickOpenShape {
$onDidHide(sessionId: number): void;
}
export interface ShellLaunchConfigDto {
export interface IShellLaunchConfigDto {
name?: string;
executable?: string;
args?: string[] | string;
@@ -1161,12 +1155,13 @@ export interface ExtHostTerminalServiceShape {
$acceptTerminalOpened(id: number, name: string): void;
$acceptActiveTerminalChanged(id: number | null): void;
$acceptTerminalProcessId(id: number, processId: number): void;
/** @deprecated */
$acceptTerminalProcessData(id: number, data: string): void;
$acceptTerminalRendererInput(id: number, data: string): void;
$acceptTerminalProcessData2(id: number, data: string): void;
$acceptTerminalTitleChange(id: number, name: string): void;
$acceptTerminalDimensions(id: number, cols: number, rows: number): void;
$acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void;
$spawnExtHostProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
$spawnExtHostProcess(id: number, shellLaunchConfig: IShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
$startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void;
$acceptProcessInput(id: number, data: string): void;
$acceptProcessResize(id: number, cols: number, rows: number): void;
@@ -1176,7 +1171,7 @@ export interface ExtHostTerminalServiceShape {
$acceptProcessRequestLatency(id: number): number;
$acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
$requestAvailableShells(): Promise<IShellDefinitionDto[]>;
$requestDefaultShellAndArgs(): Promise<IShellAndArgsDto>;
$requestDefaultShellAndArgs(useAutomationShell: boolean): Promise<IShellAndArgsDto>;
}
export interface ExtHostSCMShape {
@@ -1254,8 +1249,8 @@ export interface ExtHostDebugServiceShape {
$startDASession(handle: number, session: IDebugSessionDto): Promise<void>;
$stopDASession(handle: number): Promise<void>;
$sendDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): void;
$resolveDebugConfiguration(handle: number, folder: UriComponents | undefined, debugConfiguration: IConfig): Promise<IConfig | null | undefined>;
$provideDebugConfigurations(handle: number, folder: UriComponents | undefined): Promise<IConfig[]>;
$resolveDebugConfiguration(handle: number, folder: UriComponents | undefined, debugConfiguration: IConfig, token: CancellationToken): Promise<IConfig | null | undefined>;
$provideDebugConfigurations(handle: number, folder: UriComponents | undefined, token: CancellationToken): Promise<IConfig[]>;
$legacyDebugAdapterExecutable(handle: number, folderUri: UriComponents | undefined): Promise<IAdapterDescriptor>; // TODO@AW legacy
$provideDebugAdapter(handle: number, session: IDebugSessionDto): Promise<IAdapterDescriptor>;
$acceptDebugSessionStarted(session: IDebugSessionDto): void;
@@ -1360,7 +1355,6 @@ export const ExtHostContext = {
ExtHostDocumentSaveParticipant: createExtId<ExtHostDocumentSaveParticipantShape>('ExtHostDocumentSaveParticipant'),
ExtHostEditors: createExtId<ExtHostEditorsShape>('ExtHostEditors'),
ExtHostTreeViews: createExtId<ExtHostTreeViewsShape>('ExtHostTreeViews'),
ExtHostDownloadService: createExtId<ExtHostDownloadServiceShape>('ExtHostDownloadService'),
ExtHostFileSystem: createExtId<ExtHostFileSystemShape>('ExtHostFileSystem'),
ExtHostFileSystemEventService: createExtId<ExtHostFileSystemEventServiceShape>('ExtHostFileSystemEventService'),
ExtHostLanguageFeatures: createExtId<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),

View File

@@ -8,7 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as types from 'vs/workbench/api/common/extHostTypes';
import { IRawColorInfo, WorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { IRawColorInfo, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { ISingleEditOperation } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import * as search from 'vs/workbench/contrib/search/common/search';
@@ -135,7 +135,7 @@ export class ExtHostApiCommands {
description: 'Execute code action provider.',
args: [
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
{ name: 'range', description: 'Range in a text document', constraint: types.Range },
{ name: 'rangeOrSelection', description: 'Range in a text document. Some refactoring provider requires Selection object.', constraint: types.Range },
{ name: 'kind', description: '(optional) Code action kind to return code actions for', constraint: (value: any) => !value || typeof value.value === 'string' },
],
returns: 'A promise that resolves to an array of Command-instances.'
@@ -362,7 +362,7 @@ export class ExtHostApiCommands {
position: position && typeConverters.Position.from(position),
newName
};
return this._commands.executeCommand<WorkspaceEditDto>('_executeDocumentRenameProvider', args).then(value => {
return this._commands.executeCommand<IWorkspaceEditDto>('_executeDocumentRenameProvider', args).then(value => {
if (!value) {
return undefined;
}
@@ -470,20 +470,22 @@ export class ExtHostApiCommands {
return res;
}
detail: string;
range: vscode.Range;
selectionRange: vscode.Range;
children: vscode.DocumentSymbol[];
containerName: string;
detail!: string;
range!: vscode.Range;
selectionRange!: vscode.Range;
children!: vscode.DocumentSymbol[];
containerName!: string;
}
return value.map(MergedInfo.to);
});
}
private _executeCodeActionProvider(resource: URI, range: types.Range, kind?: string): Promise<(vscode.CodeAction | vscode.Command | undefined)[] | undefined> {
private _executeCodeActionProvider(resource: URI, rangeOrSelection: types.Range | types.Selection, kind?: string): Promise<(vscode.CodeAction | vscode.Command | undefined)[] | undefined> {
const args = {
resource,
range: typeConverters.Range.from(range),
rangeOrSelection: types.Selection.isSelection(rangeOrSelection)
? typeConverters.Selection.from(rangeOrSelection)
: typeConverters.Range.from(rangeOrSelection),
kind
};
return this._commands.executeCommand<CustomCodeAction[]>('_executeCodeActionProvider', args)
@@ -504,6 +506,7 @@ export class ExtHostApiCommands {
if (codeAction.command) {
ret.command = this._commands.converter.fromInternal(codeAction.command);
}
ret.isPreferred = codeAction.isPreferred;
return ret;
}
}));

View File

@@ -63,7 +63,7 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
private readonly _uuid = generateUuid();
private _html: string = '';
private _options: vscode.WebviewOptions;
private _options: vscode.WebviewOptions = Object.create(null);
toWebviewResource(resource: vscode.Uri): vscode.Uri {
return toWebviewResource(that._initData, this._uuid, resource);

View File

@@ -8,7 +8,7 @@ import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters';
import { cloneAndChange } from 'vs/base/common/objects';
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, IMainContext, CommandDto } from './extHost.protocol';
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, ICommandDto } from './extHost.protocol';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import * as modes from 'vs/editor/common/modes';
import * as vscode from 'vscode';
@@ -19,6 +19,8 @@ import { Position } from 'vs/editor/common/core/position';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
interface CommandHandler {
callback: Function;
@@ -32,6 +34,8 @@ export interface ArgumentProcessor {
export class ExtHostCommands implements ExtHostCommandsShape {
readonly _serviceBrand: any;
private readonly _onDidExecuteCommand: Emitter<vscode.CommandExecutionEvent>;
readonly onDidExecuteCommand: Event<vscode.CommandExecutionEvent>;
@@ -42,10 +46,10 @@ export class ExtHostCommands implements ExtHostCommandsShape {
private readonly _argumentProcessors: ArgumentProcessor[];
constructor(
mainContext: IMainContext,
logService: ILogService
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@ILogService logService: ILogService
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadCommands);
this._proxy = extHostRpc.getProxy(MainContext.MainThreadCommands);
this._onDidExecuteCommand = new Emitter<vscode.CommandExecutionEvent>({
onFirstListenerDidAdd: () => this._proxy.$registerCommandListener(),
onLastListenerRemove: () => this._proxy.$unregisterCommandListener(),
@@ -228,13 +232,13 @@ export class CommandsConverter {
this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this);
}
toInternal(command: vscode.Command | undefined, disposables: DisposableStore): CommandDto | undefined {
toInternal(command: vscode.Command | undefined, disposables: DisposableStore): ICommandDto | undefined {
if (!command) {
return undefined;
}
const result: CommandDto = {
const result: ICommandDto = {
$ident: undefined,
id: command.command,
title: command.title,
@@ -282,3 +286,6 @@ export class CommandsConverter {
}
}
export interface IExtHostCommands extends ExtHostCommands { }
export const IExtHostCommands = createDecorator<IExtHostCommands>('IExtHostCommands');

View File

@@ -253,13 +253,13 @@ export class ExtHostCommentThread implements vscode.CommentThread {
return this._range;
}
private _label: string;
private _label: string | undefined;
get label(): string {
get label(): string | undefined {
return this._label;
}
set label(label: string) {
set label(label: string | undefined) {
this._label = label;
this._onDidUpdateCommentThread.fire();
}

View File

@@ -7,8 +7,8 @@ import { mixin, deepClone } from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import * as vscode from 'vscode';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData, MainContext } from './extHost.protocol';
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
import { Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
@@ -18,6 +18,8 @@ import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/confi
import { isObject } from 'vs/base/common/types';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { Barrier } from 'vs/base/common/async';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
function lookUp(tree: any, key: string) {
if (key) {
@@ -40,13 +42,18 @@ type ConfigurationInspect<T> = {
export class ExtHostConfiguration implements ExtHostConfigurationShape {
readonly _serviceBrand: any;
private readonly _proxy: MainThreadConfigurationShape;
private readonly _extHostWorkspace: ExtHostWorkspace;
private readonly _barrier: Barrier;
private _actual: ExtHostConfigProvider | null;
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace) {
this._proxy = proxy;
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadConfiguration);
this._extHostWorkspace = extHostWorkspace;
this._barrier = new Barrier();
this._actual = null;
@@ -274,3 +281,6 @@ export class ExtHostConfigProvider {
return new ConfigurationModel(model.contents, model.keys, model.overrides).freeze();
}
}
export const IExtHostConfiguration = createDecorator<IExtHostConfiguration>('IExtHostConfiguration');
export interface IExtHostConfiguration extends ExtHostConfiguration { }

View File

@@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { ExtHostDebugServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import * as vscode from 'vscode';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IExtHostDebugService = createDecorator<IExtHostDebugService>('IExtHostDebugService');
export interface IExtHostDebugService extends ExtHostDebugServiceShape {
readonly _serviceBrand: any;
onDidStartDebugSession: Event<vscode.DebugSession>;
onDidTerminateDebugSession: Event<vscode.DebugSession>;
onDidChangeActiveDebugSession: Event<vscode.DebugSession | undefined>;
activeDebugSession: vscode.DebugSession | undefined;
activeDebugConsole: vscode.DebugConsole;
onDidReceiveDebugSessionCustomEvent: Event<vscode.DebugSessionCustomEvent>;
onDidChangeBreakpoints: Event<vscode.BreakpointsChangeEvent>;
breakpoints: vscode.Breakpoint[];
addBreakpoints(breakpoints0: vscode.Breakpoint[]): Promise<void>;
removeBreakpoints(breakpoints0: vscode.Breakpoint[]): Promise<void>;
startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession): Promise<boolean>;
registerDebugConfigurationProvider(type: string, provider: vscode.DebugConfigurationProvider): vscode.Disposable;
registerDebugAdapterDescriptorFactory(extension: IExtensionDescription, type: string, factory: vscode.DebugAdapterDescriptorFactory): vscode.Disposable;
registerDebugAdapterTrackerFactory(type: string, factory: vscode.DebugAdapterTrackerFactory): vscode.Disposable;
}

View File

@@ -5,26 +5,31 @@
import * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol';
import { MainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol';
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { asArray } from 'vs/base/common/arrays';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
interface ProviderData {
provider: vscode.DecorationProvider;
extensionId: ExtensionIdentifier;
}
export class ExtHostDecorations implements ExtHostDecorationsShape {
export class ExtHostDecorations implements IExtHostDecorations {
private static _handlePool = 0;
readonly _serviceBrand: undefined;
private readonly _provider = new Map<number, ProviderData>();
private readonly _proxy: MainThreadDecorationsShape;
constructor(mainContext: IMainContext) {
this._proxy = mainContext.getProxy(MainContext.MainThreadDecorations);
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadDecorations);
}
registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable {
@@ -70,3 +75,6 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
});
}
}
export const IExtHostDecorations = createDecorator<IExtHostDecorations>('IExtHostDecorations');
export interface IExtHostDecorations extends ExtHostDecorations, ExtHostDecorationsShape { }

View File

@@ -50,7 +50,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
}
if (this._documentsAndEditors.getDocument(uri)) {
this.$provideTextDocumentContent(handle, uri).then(value => {
if (!value) {
if (!value && typeof value !== 'string') {
return;
}

View File

@@ -26,7 +26,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
private _proxy: MainThreadDocumentsShape;
private _languageId: string;
private _isDirty: boolean;
private _document: vscode.TextDocument;
private _document?: vscode.TextDocument;
private _textLines: vscode.TextLine[] = [];
private _isDisposed: boolean = false;

View File

@@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event';
import { URI, UriComponents } from 'vs/base/common/uri';
import { sequence } from 'vs/base/common/async';
import { illegalState } from 'vs/base/common/errors';
import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, ResourceTextEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IResourceTextEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { TextEdit } from 'vs/workbench/api/common/extHostTypes';
import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
@@ -142,7 +142,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
}).then(values => {
const resourceEdit: ResourceTextEditDto = {
const resourceEdit: IResourceTextEditDto = {
resource: document.uri,
edits: []
};
@@ -153,7 +153,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
resourceEdit.edits.push({
range: range && Range.from(range),
text: newText,
eol: EndOfLine.from(newEol)
eol: newEol && EndOfLine.from(newEol)
});
}
}

View File

@@ -7,17 +7,21 @@ import * as assert from 'vs/base/common/assert';
import { Emitter, Event } from 'vs/base/common/event';
import { dispose } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape {
readonly _serviceBrand: any;
private _disposables: Disposable[] = [];
private _activeEditorId: string | null;
private _activeEditorId: string | null = null;
private readonly _editors = new Map<string, ExtHostTextEditor>();
private readonly _documents = new Map<string, ExtHostDocumentData>();
@@ -33,7 +37,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
readonly onDidChangeActiveTextEditor: Event<ExtHostTextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
constructor(
private readonly _mainContext: IMainContext,
@IExtHostRpcService private readonly _extHostRpc: IExtHostRpcService,
) { }
dispose() {
@@ -64,7 +68,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
assert.ok(!this._documents.has(resource.toString()), `document '${resource} already exists!'`);
const documentData = new ExtHostDocumentData(
this._mainContext.getProxy(MainContext.MainThreadDocuments),
this._extHostRpc.getProxy(MainContext.MainThreadDocuments),
resource,
data.lines,
data.EOL,
@@ -95,7 +99,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
const documentData = this._documents.get(resource.toString())!;
const editor = new ExtHostTextEditor(
this._mainContext.getProxy(MainContext.MainThreadTextEditors),
this._extHostRpc.getProxy(MainContext.MainThreadTextEditors),
data.id,
documentData,
data.selections.map(typeConverters.Selection.to),
@@ -159,3 +163,6 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
return result;
}
}
export interface IExtHostDocumentsAndEditors extends ExtHostDocumentsAndEditors { }
export const IExtHostDocumentsAndEditors = createDecorator<IExtHostDocumentsAndEditors>('IExtHostDocumentsAndEditors');

View File

@@ -0,0 +1,779 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import * as path from 'vs/base/common/path';
import { originalFSPath } from 'vs/base/common/resources';
import { Barrier } from 'vs/base/common/async';
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';
import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
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, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
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 { Schemas } from 'vs/base/common/network';
import { VSBuffer } from 'vs/base/common/buffer';
import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento';
import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes';
import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
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 const IHostUtils = createDecorator<IHostUtils>('IHostUtils');
export interface IHostUtils {
_serviceBrand: undefined;
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 abstract class AbstractExtHostExtensionService implements ExtHostExtensionServiceShape {
readonly _serviceBrand: any;
private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000;
protected readonly _hostUtils: IHostUtils;
protected readonly _initData: IInitData;
protected readonly _extHostContext: IExtHostRpcService;
protected readonly _instaService: IInstantiationService;
protected readonly _extHostWorkspace: ExtHostWorkspace;
protected readonly _extHostConfiguration: ExtHostConfiguration;
protected readonly _extHostLogService: ExtHostLogService;
protected readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape;
protected readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape;
protected readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape;
private readonly _almostReadyToRunExtensions: Barrier;
private readonly _readyToStartExtensionHost: Barrier;
private readonly _readyToRunExtensions: Barrier;
protected readonly _registry: ExtensionDescriptionRegistry;
private readonly _storage: ExtHostStorage;
private readonly _storagePath: IExtensionStoragePaths;
private readonly _activator: ExtensionsActivator;
private _extensionPathIndex: Promise<TernarySearchTree<IExtensionDescription>> | null;
private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; };
private _started: boolean;
private readonly _disposables: DisposableStore;
constructor(
@IInstantiationService instaService: IInstantiationService,
@IHostUtils hostUtils: IHostUtils,
@IExtHostRpcService extHostContext: IExtHostRpcService,
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace,
@IExtHostConfiguration extHostConfiguration: IExtHostConfiguration,
@ILogService extHostLogService: ExtHostLogService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IExtensionStoragePaths storagePath: IExtensionStoragePaths
) {
this._hostUtils = hostUtils;
this._extHostContext = extHostContext;
this._initData = initData;
this._extHostWorkspace = extHostWorkspace;
this._extHostConfiguration = extHostConfiguration;
this._extHostLogService = extHostLogService;
this._disposables = new DisposableStore();
this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace);
this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry);
this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService);
this._almostReadyToRunExtensions = new Barrier();
this._readyToStartExtensionHost = new Barrier();
this._readyToRunExtensions = new Barrier();
this._registry = new ExtensionDescriptionRegistry(this._initData.extensions);
this._storage = new ExtHostStorage(this._extHostContext);
this._storagePath = storagePath;
this._instaService = instaService.createChild(new ServiceCollection(
[IExtHostStorage, this._storage]
));
const hostExtensions = new Set<string>();
this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId)));
this._activator = new ExtensionsActivator(this._registry, this._initData.resolvedExtensions, this._initData.hostExtensions, {
onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => {
this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error);
},
actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<ActivatedExtension> => {
if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) {
const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null);
await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent);
return new HostExtension();
}
const extensionDescription = this._registry.getExtensionDescription(extensionId)!;
return this._activateExtension(extensionDescription, reason);
}
});
this._extensionPathIndex = null;
this._resolvers = Object.create(null);
this._started = false;
}
public async initialize(): Promise<void> {
try {
await this._beforeAlmostReadyToRunExtensions();
this._almostReadyToRunExtensions.open();
await this._extHostWorkspace.waitForInitializeCall();
this._readyToStartExtensionHost.open();
if (this._initData.autoStart) {
this._startExtensionHost();
}
} catch (err) {
errors.onUnexpectedError(err);
}
}
protected abstract _beforeAlmostReadyToRunExtensions(): Promise<void>;
public async deactivateAll(): Promise<void> {
let allPromises: Promise<void>[] = [];
try {
const allExtensions = this._registry.getAllExtensionDescriptions();
const allExtensionsIds = allExtensions.map(ext => ext.identifier);
const activatedExtensions = allExtensionsIds.filter(id => this.isActivated(id));
allPromises = activatedExtensions.map((extensionId) => {
return this._deactivate(extensionId);
});
} catch (err) {
// TODO: write to log once we have one
}
await allPromises;
}
public isActivated(extensionId: ExtensionIdentifier): boolean {
if (this._readyToRunExtensions.isOpen()) {
return this._activator.isActivated(extensionId);
}
return false;
}
private _activateByEvent(activationEvent: string, startup: boolean): Promise<void> {
const reason = new ExtensionActivatedByEvent(startup, activationEvent);
return this._activator.activateByEvent(activationEvent, reason);
}
private _activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<void> {
return this._activator.activateById(extensionId, reason);
}
public activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<void> {
return this._activateById(extensionId, reason).then(() => {
const extension = this._activator.getActivatedExtension(extensionId);
if (extension.activationFailed) {
// activation failed => bubble up the error as the promise result
return Promise.reject(extension.activationFailedError);
}
return undefined;
});
}
public getExtensionRegistry(): Promise<ExtensionDescriptionRegistry> {
return this._readyToRunExtensions.wait().then(_ => this._registry);
}
public getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined {
if (this._readyToRunExtensions.isOpen()) {
return this._activator.getActivatedExtension(extensionId).exports;
} else {
return null;
}
}
// create trie to enable fast 'filename -> extension id' look up
public getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>> {
if (!this._extensionPathIndex) {
const tree = TernarySearchTree.forPaths<IExtensionDescription>();
const extensions = this._registry.getAllExtensionDescriptions().map(ext => {
if (!ext.main) {
return undefined;
}
return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext));
});
this._extensionPathIndex = Promise.all(extensions).then(() => tree);
}
return this._extensionPathIndex;
}
private _deactivate(extensionId: ExtensionIdentifier): Promise<void> {
let result = Promise.resolve(undefined);
if (!this._readyToRunExtensions.isOpen()) {
return result;
}
if (!this._activator.isActivated(extensionId)) {
return result;
}
const extension = this._activator.getActivatedExtension(extensionId);
if (!extension) {
return result;
}
// call deactivate if available
try {
if (typeof extension.module.deactivate === 'function') {
result = Promise.resolve(extension.module.deactivate()).then(undefined, (err) => {
// TODO: Do something with err if this is not the shutdown case
return Promise.resolve(undefined);
});
}
} catch (err) {
// TODO: Do something with err if this is not the shutdown case
}
// clean up subscriptions
try {
dispose(extension.subscriptions);
} catch (err) {
// TODO: Do something with err if this is not the shutdown case
}
return result;
}
// --- impl
private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier);
return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => {
const activationTimes = activatedExtension.activationTimes;
const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null);
this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent);
this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes);
return activatedExtension;
}, (err) => {
this._logExtensionActivationTimes(extensionDescription, reason, 'failure');
throw err;
});
}
private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) {
const event = getTelemetryActivationEvent(extensionDescription, reason);
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
});
}
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
const event = getTelemetryActivationEvent(extensionDescription, reason);
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));
}
this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`);
const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup);
return Promise.all<any>([
this._loadCommonJSModule(extensionDescription.main, activationTimesBuilder),
this._loadExtensionContext(extensionDescription)
]).then(values => {
return AbstractExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, <IExtensionModule>values[0], <IExtensionContext>values[1], activationTimesBuilder);
});
}
protected abstract _loadCommonJSModule<T>(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T>;
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);
this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`);
return Promise.all([
globalState.whenReady,
workspaceState.whenReady,
this._storagePath.whenReady
]).then(() => {
const that = this;
return Object.freeze(<IExtensionContext>{
globalState,
workspaceState,
subscriptions: [],
get extensionPath() { return extensionDescription.extensionLocation.fsPath; },
storagePath: this._storagePath.workspaceValue(extensionDescription),
globalStoragePath: this._storagePath.globalValue(extensionDescription),
asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); },
logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier),
executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local,
});
});
}
private static _callActivate(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<ActivatedExtension> {
// Make sure the extension's surface is not undefined
extensionModule = extensionModule || {
activate: undefined,
deactivate: undefined
};
return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => {
return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions);
});
}
private static _callActivateOptional(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<IExtensionAPI> {
if (typeof extensionModule.activate === 'function') {
try {
activationTimesBuilder.activateCallStart();
logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`);
const activateResult: Promise<IExtensionAPI> = extensionModule.activate.apply(global, [context]);
activationTimesBuilder.activateCallStop();
activationTimesBuilder.activateResolveStart();
return Promise.resolve(activateResult).then((value) => {
activationTimesBuilder.activateResolveStop();
return value;
});
} catch (err) {
return Promise.reject(err);
}
} else {
// No activate found => the module is the extension's exports
return Promise.resolve<IExtensionAPI>(extensionModule);
}
}
// -- eager activation
// Handle "eager" activation extensions
private _handleEagerExtensions(): Promise<void> {
this._activateByEvent('*', true).then(undefined, (err) => {
console.error(err);
});
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(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(folders, desc);
})
).then(() => { });
}
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[] = [];
for (const activationEvent of activationEvents) {
if (/^workspaceContains:/.test(activationEvent)) {
const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length);
if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) {
globPatterns.push(fileNameOrGlob);
} else {
fileNames.push(fileNameOrGlob);
}
}
}
if (fileNames.length === 0 && globPatterns.length === 0) {
return Promise.resolve(undefined);
}
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(folders: ReadonlyArray<vscode.WorkspaceFolder>, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
// find exact path
for (const { uri } of folders) {
if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) {
// the file was found
return (
this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${fileName}`))
.then(undefined, err => console.error(err))
);
}
}
return undefined;
}
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) {
return Promise.resolve(undefined);
}
const tokenSource = new CancellationTokenSource();
const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token);
const timer = setTimeout(async () => {
tokenSource.cancel();
this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContainsTimeout:${globPatterns.join(',')}`))
.then(undefined, err => console.error(err));
}, AbstractExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT);
let exists: boolean = false;
try {
exists = await searchP;
} catch (err) {
if (!errors.isPromiseCanceledError(err)) {
console.error(err);
}
}
tokenSource.dispose();
clearTimeout(timer);
if (exists) {
// a file was found matching one of the glob patterns
return (
this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`))
.then(undefined, err => console.error(err))
);
}
return Promise.resolve(undefined);
}
private _handleExtensionTests(): Promise<void> {
return this._doHandleExtensionTests().then(undefined, error => {
console.error(error); // ensure any error message makes it onto the console
return Promise.reject(error);
});
}
private async _doHandleExtensionTests(): Promise<void> {
const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment;
if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) {
return Promise.resolve(undefined);
}
const extensionTestsPath = originalFSPath(extensionTestsLocationURI);
// Require the test runner via node require from the provided path
let testRunner: ITestRunner | INewTestRunner | undefined;
let requireError: Error | undefined;
try {
testRunner = await this._loadCommonJSModule(extensionTestsPath, new ExtensionActivationTimesBuilder(false));
} catch (error) {
requireError = error;
}
// Execute the runner if it follows the old `run` spec
if (testRunner && typeof testRunner.run === 'function') {
return new Promise<void>((c, e) => {
const oldTestRunnerCallback = (error: Error, failures: number | undefined) => {
if (error) {
e(error.toString());
} else {
c(undefined);
}
// 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);
});
}
});
}
// Otherwise make sure to shutdown anyway even in case of an error
else {
this._gracefulExit(1 /* ERROR */);
}
return Promise.reject(new Error(requireError ? requireError.toString() : nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath)));
}
private _gracefulExit(code: number): void {
// to give the PH process a chance to flush any outstanding console
// 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.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) {
this._mainThreadExtensionsProxy.$onExtensionHostExit(code);
return;
}
this._hostUtils.exit(code);
}, 500);
}
private _startExtensionHost(): Promise<void> {
if (this._started) {
throw new Error(`Extension host is already started!`);
}
this._started = true;
return this._readyToStartExtensionHost.wait()
.then(() => this._readyToRunExtensions.open())
.then(() => this._handleEagerExtensions())
.then(() => this._handleExtensionTests())
.then(() => {
this._extHostLogService.info(`eager extensions activated`);
});
}
// -- called by extensions
public registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable {
this._resolvers[authorityPrefix] = resolver;
return toDisposable(() => {
delete this._resolvers[authorityPrefix];
});
}
// -- called by main thread
public async $resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise<IResolveAuthorityResult> {
const authorityPlusIndex = remoteAuthority.indexOf('+');
if (authorityPlusIndex === -1) {
throw new Error(`Not an authority that can be resolved!`);
}
const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex);
await this._almostReadyToRunExtensions.wait();
await this._activateByEvent(`onResolveRemoteAuthority:${authorityPrefix}`, false);
const resolver = this._resolvers[authorityPrefix];
if (!resolver) {
throw new Error(`No remote extension installed to resolve ${authorityPrefix}.`);
}
try {
const result = await resolver.resolve(remoteAuthority, { resolveAttempt });
// Split merged API result into separate authority/options
const authority: ResolvedAuthority = {
authority: remoteAuthority,
host: result.host,
port: result.port
};
const options: ResolvedOptions = {
extensionHostEnv: result.extensionHostEnv
};
return {
type: 'ok',
value: {
authority,
options
}
};
} catch (err) {
if (err instanceof RemoteAuthorityResolverError) {
return {
type: 'error',
error: {
code: err._code,
message: err._message,
detail: err._detail
}
};
}
throw err;
}
}
public $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void> {
this._registry.keepOnly(enabledExtensionIds);
return this._startExtensionHost();
}
public $activateByEvent(activationEvent: string): Promise<void> {
return (
this._readyToRunExtensions.wait()
.then(_ => this._activateByEvent(activationEvent, false))
);
}
public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<boolean> {
await this._readyToRunExtensions.wait();
if (!this._registry.getExtensionDescription(extensionId)) {
// unknown extension => ignore
return false;
}
await this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent));
return true;
}
public async $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void> {
toAdd.forEach((extension) => (<any>extension).extensionLocation = URI.revive(extension.extensionLocation));
const trie = await this.getExtensionPathIndex();
await Promise.all(toRemove.map(async (extensionId) => {
const extensionDescription = this._registry.getExtensionDescription(extensionId);
if (!extensionDescription) {
return;
}
const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath);
trie.delete(URI.file(realpathValue).fsPath);
}));
await Promise.all(toAdd.map(async (extensionDescription) => {
const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath);
trie.set(URI.file(realpathValue).fsPath, extensionDescription);
}));
this._registry.deltaExtensions(toAdd, toRemove);
return Promise.resolve(undefined);
}
public async $test_latency(n: number): Promise<number> {
return n;
}
public async $test_up(b: VSBuffer): Promise<number> {
return b.byteLength;
}
public async $test_down(size: number): Promise<VSBuffer> {
let buff = VSBuffer.alloc(size);
let value = Math.random() % 256;
for (let i = 0; i < size; i++) {
buff.writeUInt8(value, i);
}
return buff;
}
public abstract async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void>;
}
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' :
'';
const event = {
id: extensionDescription.identifier.value,
name: extensionDescription.name,
extensionVersion: extensionDescription.version,
publisherDisplayName: extensionDescription.publisher,
activationEvents: extensionDescription.activationEvents ? extensionDescription.activationEvents.join(',') : null,
isBuiltin: extensionDescription.isBuiltin,
reason: reasonStr
};
return event;
}
export const IExtHostExtensionService = createDecorator<IExtHostExtensionService>('IExtHostExtensionService');
export interface IExtHostExtensionService extends AbstractExtHostExtensionService {
_serviceBrand: any;
initialize(): Promise<void>;
isActivated(extensionId: ExtensionIdentifier): boolean;
activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<void>;
deactivateAll(): Promise<void>;
getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined;
getExtensionRegistry(): Promise<ExtensionDescriptionRegistry>;
getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>>;
registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable;
}

View File

@@ -155,7 +155,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
private readonly _usedSchemes = new Set<string>();
private readonly _watches = new Map<number, IDisposable>();
private _linkProviderRegistration: IDisposable;
private _linkProviderRegistration?: IDisposable;
private _handlePool: number = 0;
readonly fileSystem: vscode.FileSystem;

View File

@@ -9,7 +9,7 @@ import { IRelativePattern, parse } from 'vs/base/common/glob';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import * as vscode from 'vscode';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, ResourceFileEditDto, ResourceTextEditDto, MainThreadTextEditorsShape } from './extHost.protocol';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, IResourceFileEditDto, IResourceTextEditDto, MainThreadTextEditorsShape } from './extHost.protocol';
import * as typeConverter from './extHostTypeConverters';
import { Disposable, WorkspaceEdit } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
@@ -169,7 +169,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
}
// flatten all WorkspaceEdits collected via waitUntil-call
// and apply them in one go.
const allEdits = new Array<Array<ResourceFileEditDto | ResourceTextEditDto>>();
const allEdits = new Array<Array<IResourceFileEditDto | IResourceTextEditDto>>();
for (let edit of edits) {
if (edit) { // sparse array
let { edits } = typeConverter.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors);

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IInitData } from './extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IExtHostInitDataService = createDecorator<IExtHostInitDataService>('IExtHostInitDataService');
export interface IExtHostInitDataService extends Readonly<IInitData> {
_serviceBrand: undefined;
}

View File

@@ -14,7 +14,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics';
import { asPromise } from 'vs/base/common/async';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, SuggestDataDto, LinksListDto, ChainedCacheId, CodeLensListDto, CodeActionListDto, SignatureHelpDto, SignatureHelpContextDto } from './extHost.protocol';
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, IRawColorInfo, IMainContext, IdObject, IRegExpDto, IIndentationRuleDto, IOnEnterRuleDto, ILanguageConfigurationDto, IWorkspaceSymbolDto, ISuggestResultDto, IWorkspaceSymbolsDto, ICodeActionDto, IDocumentFilterDto, IWorkspaceEditDto, ISignatureHelpProviderMetadataDto, ILinkDto, ICodeLensDto, ISuggestDataDto, ILinksListDto, ChainedCacheId, ICodeLensListDto, ICodeActionListDto, ISignatureHelpDto, ISignatureHelpContextDto } from './extHost.protocol';
import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position';
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
@@ -111,7 +111,7 @@ class CodeLensAdapter {
private readonly _provider: vscode.CodeLensProvider
) { }
provideCodeLenses(resource: URI, token: CancellationToken): Promise<CodeLensListDto | undefined> {
provideCodeLenses(resource: URI, token: CancellationToken): Promise<ICodeLensListDto | undefined> {
const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideCodeLenses(doc, token)).then(lenses => {
@@ -124,7 +124,7 @@ class CodeLensAdapter {
const disposables = new DisposableStore();
this._disposables.set(cacheId, disposables);
const result: CodeLensListDto = {
const result: ICodeLensListDto = {
cacheId,
lenses: [],
};
@@ -141,7 +141,7 @@ class CodeLensAdapter {
});
}
resolveCodeLens(symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
resolveCodeLens(symbol: ICodeLensDto, token: CancellationToken): Promise<ICodeLensDto | undefined> {
const lens = symbol.cacheId && this._cache.get(...symbol.cacheId);
if (!lens) {
@@ -308,7 +308,7 @@ class ReferenceAdapter {
}
}
export interface CustomCodeAction extends CodeActionDto {
export interface CustomCodeAction extends ICodeActionDto {
_isSynthetic?: boolean;
}
@@ -327,7 +327,7 @@ class CodeActionAdapter {
private readonly _extensionId: ExtensionIdentifier
) { }
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined> {
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined> {
const doc = this._documents.getDocument(resource);
const ran = Selection.isISelection(rangeOrSelection)
@@ -391,7 +391,7 @@ class CodeActionAdapter {
}
}
return <CodeActionListDto>{ cacheId, actions };
return <ICodeActionListDto>{ cacheId, actions };
});
}
@@ -480,8 +480,8 @@ class NavigateTypeAdapter {
this._provider = provider;
}
provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<WorkspaceSymbolsDto> {
const result: WorkspaceSymbolsDto = IdObject.mixin({ symbols: [] });
provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<IWorkspaceSymbolsDto> {
const result: IWorkspaceSymbolsDto = IdObject.mixin({ symbols: [] });
return asPromise(() => this._provider.provideWorkspaceSymbols(search, token)).then(value => {
if (isNonEmptyArray(value)) {
for (const item of value) {
@@ -506,7 +506,7 @@ class NavigateTypeAdapter {
});
}
resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined> {
resolveWorkspaceSymbol(symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise<IWorkspaceSymbolDto | undefined> {
if (typeof this._provider.resolveWorkspaceSymbol !== 'function') {
return Promise.resolve(symbol);
@@ -543,7 +543,7 @@ class RenameAdapter {
private readonly _provider: vscode.RenameProvider
) { }
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined> {
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<IWorkspaceEditDto | undefined> {
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
@@ -556,10 +556,10 @@ class RenameAdapter {
}, err => {
const rejectReason = RenameAdapter._asMessage(err);
if (rejectReason) {
return <WorkspaceEditDto>{ rejectReason, edits: undefined! };
return <IWorkspaceEditDto>{ rejectReason, edits: undefined! };
} else {
// generic error
return Promise.reject<WorkspaceEditDto>(err);
return Promise.reject<IWorkspaceEditDto>(err);
}
});
}
@@ -633,7 +633,7 @@ class SuggestAdapter {
this._provider = provider;
}
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined> {
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<ISuggestResultDto | undefined> {
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
@@ -662,7 +662,7 @@ class SuggestAdapter {
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos))
.with({ end: pos });
const result: SuggestResultDto = {
const result: ISuggestResultDto = {
x: pid,
b: [],
a: typeConvert.Range.from(wordRangeBeforePos),
@@ -682,7 +682,7 @@ class SuggestAdapter {
});
}
resolveCompletionItem(_resource: URI, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<SuggestDataDto | undefined> {
resolveCompletionItem(_resource: URI, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<ISuggestDataDto | undefined> {
if (typeof this._provider.resolveCompletionItem !== 'function') {
return Promise.resolve(undefined);
@@ -710,7 +710,7 @@ class SuggestAdapter {
this._cache.delete(id);
}
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId): SuggestDataDto | undefined {
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId): ISuggestDataDto | undefined {
if (typeof item.label !== 'string' || item.label.length === 0) {
console.warn('INVALID text edit -> must have at least a label');
return undefined;
@@ -721,7 +721,7 @@ class SuggestAdapter {
throw Error('DisposableStore is missing...');
}
const result: SuggestDataDto = {
const result: ISuggestDataDto = {
//
x: id,
//
@@ -777,7 +777,7 @@ class SignatureHelpAdapter {
private readonly _provider: vscode.SignatureHelpProvider,
) { }
provideSignatureHelp(resource: URI, position: IPosition, context: SignatureHelpContextDto, token: CancellationToken): Promise<SignatureHelpDto | undefined> {
provideSignatureHelp(resource: URI, position: IPosition, context: ISignatureHelpContextDto, token: CancellationToken): Promise<ISignatureHelpDto | undefined> {
const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
const vscodeContext = this.reviveContext(context);
@@ -791,7 +791,7 @@ class SignatureHelpAdapter {
});
}
private reviveContext(context: SignatureHelpContextDto): vscode.SignatureHelpContext {
private reviveContext(context: ISignatureHelpContextDto): vscode.SignatureHelpContext {
let activeSignatureHelp: vscode.SignatureHelp | undefined = undefined;
if (context.activeSignatureHelp) {
const revivedSignatureHelp = typeConvert.SignatureHelp.to(context.activeSignatureHelp);
@@ -855,7 +855,7 @@ class LinkProviderAdapter {
private readonly _provider: vscode.DocumentLinkProvider
) { }
provideLinks(resource: URI, token: CancellationToken): Promise<LinksListDto | undefined> {
provideLinks(resource: URI, token: CancellationToken): Promise<ILinksListDto | undefined> {
const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentLinks(doc, token)).then(links => {
@@ -877,9 +877,9 @@ class LinkProviderAdapter {
} else {
// cache links for future resolving
const pid = this._cache.add(links);
const result: LinksListDto = { links: [], id: pid };
const result: ILinksListDto = { links: [], id: pid };
for (let i = 0; i < links.length; i++) {
const dto: LinkDto = typeConvert.DocumentLink.from(links[i]);
const dto: ILinkDto = typeConvert.DocumentLink.from(links[i]);
dto.cacheId = [pid, i];
result.links.push(dto);
}
@@ -888,7 +888,7 @@ class LinkProviderAdapter {
});
}
resolveLink(id: ChainedCacheId, token: CancellationToken): Promise<LinkDto | undefined> {
resolveLink(id: ChainedCacheId, token: CancellationToken): Promise<ILinkDto | undefined> {
if (typeof this._provider.resolveDocumentLink !== 'function') {
return Promise.resolve(undefined);
}
@@ -1103,11 +1103,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
this._logService = logService;
}
private _transformDocumentSelector(selector: vscode.DocumentSelector): Array<ISerializedDocumentFilter> {
private _transformDocumentSelector(selector: vscode.DocumentSelector): Array<IDocumentFilterDto> {
return coalesce(asArray(selector).map(sel => this._doTransformDocumentSelector(sel)));
}
private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter | undefined {
private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): IDocumentFilterDto | undefined {
if (typeof selector === 'string') {
return {
$serialized: true,
@@ -1215,11 +1215,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return result;
}
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensListDto | undefined> {
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<ICodeLensListDto | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.provideCodeLenses(URI.revive(resource), token), undefined);
}
$resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
$resolveCodeLens(handle: number, symbol: ICodeLensDto, token: CancellationToken): Promise<ICodeLensDto | undefined> {
return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(symbol, token), undefined);
}
@@ -1314,7 +1314,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
}
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionListDto | undefined> {
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined> {
return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(URI.revive(resource), rangeOrSelection, context, token), undefined);
}
@@ -1362,11 +1362,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise<WorkspaceSymbolsDto> {
$provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise<IWorkspaceSymbolsDto> {
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search, token), { symbols: [] });
}
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined> {
$resolveWorkspaceSymbol(handle: number, symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise<IWorkspaceSymbolDto | undefined> {
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol, token), undefined);
}
@@ -1382,7 +1382,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined> {
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<IWorkspaceEditDto | undefined> {
return this._withAdapter(handle, RenameAdapter, adapter => adapter.provideRenameEdits(URI.revive(resource), position, newName, token), undefined);
}
@@ -1398,11 +1398,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto | undefined> {
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<ISuggestResultDto | undefined> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(URI.revive(resource), position, context, token), undefined);
}
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<SuggestDataDto | undefined> {
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise<ISuggestDataDto | undefined> {
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.resolveCompletionItem(URI.revive(resource), position, id, token), undefined);
}
@@ -1413,7 +1413,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
// --- parameter hints
registerSignatureHelpProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, metadataOrTriggerChars: string[] | vscode.SignatureHelpProviderMetadata): vscode.Disposable {
const metadata: ISerializedSignatureHelpProviderMetadata | undefined = Array.isArray(metadataOrTriggerChars)
const metadata: ISignatureHelpProviderMetadataDto | undefined = Array.isArray(metadataOrTriggerChars)
? { triggerCharacters: metadataOrTriggerChars, retriggerCharacters: [] }
: metadataOrTriggerChars;
@@ -1422,7 +1422,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: SignatureHelpContextDto, token: CancellationToken): Promise<SignatureHelpDto | undefined> {
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: ISignatureHelpContextDto, token: CancellationToken): Promise<ISignatureHelpDto | undefined> {
return this._withAdapter(handle, SignatureHelpAdapter, adapter => adapter.provideSignatureHelp(URI.revive(resource), position, context, token), undefined);
}
@@ -1438,11 +1438,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._createDisposable(handle);
}
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<LinksListDto | undefined> {
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<ILinksListDto | undefined> {
return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.provideLinks(URI.revive(resource), token), undefined);
}
$resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<LinkDto | undefined> {
$resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise<ILinkDto | undefined> {
return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.resolveLink(id, token), undefined);
}
@@ -1504,14 +1504,14 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
// --- configuration
private static _serializeRegExp(regExp: RegExp): ISerializedRegExp {
private static _serializeRegExp(regExp: RegExp): IRegExpDto {
return {
pattern: regExp.source,
flags: regExpFlags(regExp),
};
}
private static _serializeIndentationRule(indentationRule: vscode.IndentationRule): ISerializedIndentationRule {
private static _serializeIndentationRule(indentationRule: vscode.IndentationRule): IIndentationRuleDto {
return {
decreaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.decreaseIndentPattern),
increaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.increaseIndentPattern),
@@ -1520,7 +1520,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
};
}
private static _serializeOnEnterRule(onEnterRule: vscode.OnEnterRule): ISerializedOnEnterRule {
private static _serializeOnEnterRule(onEnterRule: vscode.OnEnterRule): IOnEnterRuleDto {
return {
beforeText: ExtHostLanguageFeatures._serializeRegExp(onEnterRule.beforeText),
afterText: onEnterRule.afterText ? ExtHostLanguageFeatures._serializeRegExp(onEnterRule.afterText) : undefined,
@@ -1529,7 +1529,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
};
}
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] {
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): IOnEnterRuleDto[] {
return onEnterRules.map(ExtHostLanguageFeatures._serializeOnEnterRule);
}
@@ -1549,7 +1549,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
}
const handle = this._nextHandle();
const serializedConfiguration: ISerializedLanguageConfiguration = {
const serializedConfiguration: ILanguageConfigurationDto = {
comments: configuration.comments,
brackets: configuration.brackets,
wordPattern: configuration.wordPattern ? ExtHostLanguageFeatures._serializeRegExp(configuration.wordPattern) : undefined,

View File

@@ -14,7 +14,7 @@ export class ExtensionMemento implements IExtensionMemento {
private readonly _storage: ExtHostStorage;
private readonly _init: Promise<ExtensionMemento>;
private _value: { [n: string]: any; };
private _value?: { [n: string]: any; };
private readonly _storageListener: IDisposable;
constructor(id: string, global: boolean, storage: ExtHostStorage) {
@@ -41,7 +41,7 @@ export class ExtensionMemento implements IExtensionMemento {
get<T>(key: string): T | undefined;
get<T>(key: string, defaultValue: T): T;
get<T>(key: string, defaultValue?: T): T {
let value = this._value[key];
let value = this._value![key];
if (typeof value === 'undefined') {
value = defaultValue;
}
@@ -49,8 +49,8 @@ export class ExtensionMemento implements IExtensionMemento {
}
update(key: string, value: any): Promise<void> {
this._value[key] = value;
return this._storage.setValue(this._shared, this._id, this._value);
this._value![key] = value;
return this._storage.setValue(this._shared, this._id, this._value!);
}
dispose(): void {

View File

@@ -3,12 +3,14 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MainContext, MainThreadOutputServiceShape, IMainContext, ExtHostOutputServiceShape } from './extHost.protocol';
import { MainContext, MainThreadOutputServiceShape, ExtHostOutputServiceShape } from './extHost.protocol';
import * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel {
@@ -27,6 +29,7 @@ export abstract class AbstractExtHostOutputChannel extends Disposable implements
this._name = name;
this._proxy = proxy;
this._id = proxy.$register(this.name, log, file);
this._disposed = false;
this._offset = 0;
}
@@ -105,38 +108,50 @@ class ExtHostLogFileOutputChannel extends AbstractExtHostOutputChannel {
}
}
export interface IOutputChannelFactory {
createOutputChannel(name: string, logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise<AbstractExtHostOutputChannel>;
}
export class LazyOutputChannel implements vscode.OutputChannel {
export const PushOutputChannelFactory = new class implements IOutputChannelFactory {
async createOutputChannel(name: string, _logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise<AbstractExtHostOutputChannel> {
return new ExtHostPushOutputChannel(name, proxy);
constructor(
readonly name: string,
private readonly _channel: Promise<AbstractExtHostOutputChannel>
) { }
append(value: string): void {
this._channel.then(channel => channel.append(value));
}
};
appendLine(value: string): void {
this._channel.then(channel => channel.appendLine(value));
}
clear(): void {
this._channel.then(channel => channel.clear());
}
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
this._channel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
}
hide(): void {
this._channel.then(channel => channel.hide());
}
dispose(): void {
this._channel.then(channel => channel.dispose());
}
}
export class ExtHostOutputService implements ExtHostOutputServiceShape {
private readonly _factory: IOutputChannelFactory;
private readonly _logsLocation: URI;
private readonly _proxy: MainThreadOutputServiceShape;
private readonly _channels: Map<string, AbstractExtHostOutputChannel> = new Map<string, AbstractExtHostOutputChannel>();
private _visibleChannelDisposable: IDisposable;
readonly _serviceBrand: any;
constructor(factory: IOutputChannelFactory, logsLocation: URI, mainContext: IMainContext) {
this._factory = factory;
this._logsLocation = logsLocation;
this._proxy = mainContext.getProxy(MainContext.MainThreadOutputService);
protected readonly _proxy: MainThreadOutputServiceShape;
protected readonly _channels: Map<string, AbstractExtHostOutputChannel> = new Map<string, AbstractExtHostOutputChannel>();
protected readonly _visibleChannelDisposable = new MutableDisposable();
constructor(@IExtHostRpcService extHostRpc: IExtHostRpcService) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadOutputService);
}
$setVisibleChannel(channelId: string): void {
if (this._visibleChannelDisposable) {
this._visibleChannelDisposable = dispose(this._visibleChannelDisposable);
}
if (channelId) {
const channel = this._channels.get(channelId);
if (channel) {
this._visibleChannelDisposable = channel.onDidAppend(() => channel.update());
this._visibleChannelDisposable.value = channel.onDidAppend(() => channel.update());
}
}
}
@@ -145,33 +160,8 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
name = name.trim();
if (!name) {
throw new Error('illegal argument `name`. must not be falsy');
} else {
const extHostOutputChannel = this._factory.createOutputChannel(name, this._logsLocation, this._proxy);
extHostOutputChannel.then(channel => channel._id.then(id => this._channels.set(id, channel)));
return {
get name(): string {
return name;
},
append(value: string): void {
extHostOutputChannel.then(channel => channel.append(value));
},
appendLine(value: string): void {
extHostOutputChannel.then(channel => channel.appendLine(value));
},
clear(): void {
extHostOutputChannel.then(channel => channel.clear());
},
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
extHostOutputChannel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
},
hide(): void {
extHostOutputChannel.then(channel => channel.hide());
},
dispose(): void {
extHostOutputChannel.then(channel => channel.dispose());
}
};
}
return new ExtHostPushOutputChannel(name, this._proxy);
}
createOutputChannelFromLogFile(name: string, file: URI): vscode.OutputChannel {
@@ -185,3 +175,6 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
return new ExtHostLogFileOutputChannel(name, file, this._proxy);
}
}
export interface IExtHostOutputService extends ExtHostOutputService { }
export const IExtHostOutputService = createDecorator<IExtHostOutputService>('IExtHostOutputService');

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ProxyIdentifier, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IExtHostRpcService = createDecorator<IExtHostRpcService>('IExtHostRpcService');
export interface IExtHostRpcService extends IRPCProtocol {
_serviceBrand: any;
}
export class ExtHostRpcService implements IExtHostRpcService {
readonly _serviceBrand: any;
readonly getProxy: <T>(identifier: ProxyIdentifier<T>) => T;
readonly set: <T, R extends T> (identifier: ProxyIdentifier<T>, instance: R) => R;
readonly assertRegistered: (identifiers: ProxyIdentifier<any>[]) => void;
constructor(rpcProtocol: IRPCProtocol) {
this.getProxy = rpcProtocol.getProxy.bind(rpcProtocol);
this.set = rpcProtocol.set.bind(rpcProtocol);
this.assertRegistered = rpcProtocol.assertRegistered.bind(rpcProtocol);
}
}

View File

@@ -9,7 +9,7 @@ import { debounce } from 'vs/base/common/decorators';
import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
import { asPromise } from 'vs/base/common/async';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, CommandDto } from './extHost.protocol';
import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, ICommandDto } from './extHost.protocol';
import { sortedDiff } from 'vs/base/common/arrays';
import { comparePaths } from 'vs/base/common/comparers';
import * as vscode from 'vscode';
@@ -445,7 +445,7 @@ class ExtHostSourceControl implements vscode.SourceControl {
this._statusBarCommands = statusBarCommands;
const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c, this._statusBarDisposables.value!)) as CommandDto[];
const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c, this._statusBarDisposables.value!)) as ICommandDto[];
this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal });
}

View File

@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import { ExtHostSearchShape } from '../common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExtHostSearch extends ExtHostSearchShape {
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable;
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable;
}
export const IExtHostSearch = createDecorator<IExtHostSearch>('IExtHostSearch');

View File

@@ -3,8 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MainContext, MainThreadStorageShape, IMainContext, ExtHostStorageShape } from './extHost.protocol';
import { MainContext, MainThreadStorageShape, ExtHostStorageShape } from './extHost.protocol';
import { Emitter } from 'vs/base/common/event';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IStorageChangeEvent {
shared: boolean;
@@ -14,12 +16,14 @@ export interface IStorageChangeEvent {
export class ExtHostStorage implements ExtHostStorageShape {
readonly _serviceBrand: any;
private _proxy: MainThreadStorageShape;
private _onDidChangeStorage = new Emitter<IStorageChangeEvent>();
readonly onDidChangeStorage = this._onDidChangeStorage.event;
constructor(mainContext: IMainContext) {
constructor(mainContext: IExtHostRpcService) {
this._proxy = mainContext.getProxy(MainContext.MainThreadStorage);
}
@@ -35,3 +39,6 @@ export class ExtHostStorage implements ExtHostStorageShape {
this._onDidChangeStorage.fire({ shared, key, value });
}
}
export interface IExtHostStorage extends ExtHostStorage { }
export const IExtHostStorage = createDecorator<IExtHostStorage>('IExtHostStorage');

View File

@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IExtensionStoragePaths = createDecorator<IExtensionStoragePaths>('IExtensionStoragePaths');
export interface IExtensionStoragePaths {
_serviceBrand: any;
whenReady: Promise<any>;
workspaceValue(extension: IExtensionDescription): string | undefined;
globalValue(extension: IExtensionDescription): string;
}

View File

@@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { ExtHostTaskShape } from 'vs/workbench/api/common/extHost.protocol';
import * as vscode from 'vscode';
import { TaskSystemInfoDTO } from '../common/shared/tasks';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExtHostTask extends ExtHostTaskShape {
readonly _serviceBrand: any;
taskExecutions: vscode.TaskExecution[];
onDidStartTask: Event<vscode.TaskStartEvent>;
onDidEndTask: Event<vscode.TaskEndEvent>;
onDidStartTaskProcess: Event<vscode.TaskProcessStartEvent>;
onDidEndTaskProcess: Event<vscode.TaskProcessEndEvent>;
registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable;
registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void;
fetchTasks(filter?: vscode.TaskFilter): Promise<vscode.Task[]>;
executeTask(extension: IExtensionDescription, task: vscode.Task): Promise<vscode.TaskExecution>;
terminateTask(execution: vscode.TaskExecution): Promise<void>;
}
export const IExtHostTask = createDecorator<IExtHostTask>('IExtHostTask');

View File

@@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Event } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape {
_serviceBrand: any;
activeTerminal: vscode.Terminal | undefined;
terminals: vscode.Terminal[];
onDidCloseTerminal: Event<vscode.Terminal>;
onDidOpenTerminal: Event<vscode.Terminal>;
onDidChangeActiveTerminal: Event<vscode.Terminal | undefined>;
onDidChangeTerminalDimensions: Event<vscode.TerminalDimensionsChangeEvent>;
onDidWriteTerminalData: Event<vscode.TerminalDataWriteEvent>;
createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal;
createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal;
createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal;
attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void;
getDefaultShell(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string;
}
export const IExtHostTerminalService = createDecorator<IExtHostTerminalService>('IExtHostTerminalService');

View File

@@ -151,11 +151,11 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
private _proxy: MainThreadTextEditorsShape;
private _id: string;
private _tabSize: number;
private _indentSize: number;
private _insertSpaces: boolean;
private _cursorStyle: TextEditorCursorStyle;
private _lineNumbers: TextEditorLineNumbersStyle;
private _tabSize!: number;
private _indentSize!: number;
private _insertSpaces!: boolean;
private _cursorStyle!: TextEditorCursorStyle;
private _lineNumbers!: TextEditorLineNumbersStyle;
constructor(proxy: MainThreadTextEditorsShape, id: string, source: IResolvedTextEditorConfiguration) {
this._proxy = proxy;

View File

@@ -13,7 +13,7 @@ import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.proto
import { ITreeItem, TreeViewItemHandleArg, ITreeItemLabel, IRevealOptions } from 'vs/workbench/common/views';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { asPromise } from 'vs/base/common/async';
import { TreeItemCollapsibleState, ThemeIcon, MarkdownString } from 'vs/workbench/api/common/extHostTypes';
import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/common/extHostTypes';
import { isUndefinedOrNull, isString } from 'vs/base/common/types';
import { equals, coalesce } from 'vs/base/common/arrays';
import { ILogService } from 'vs/platform/log/common/log';
@@ -84,7 +84,10 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
get visible() { return treeView.visible; },
get onDidChangeVisibility() { return treeView.onDidChangeVisibility; },
get message() { return treeView.message; },
set message(message: string | MarkdownString) { checkProposedApiEnabled(extension); treeView.message = message; },
set message(message: string) {
checkProposedApiEnabled(extension);
treeView.message = message;
},
reveal: (element: T, options?: IRevealOptions): Promise<void> => {
return treeView.reveal(element, options);
},
@@ -182,6 +185,7 @@ export class ExtHostTreeView<T> extends Disposable {
private _onDidChangeData: Emitter<TreeData<T>> = this._register(new Emitter<TreeData<T>>());
private refreshPromise: Promise<void> = Promise.resolve();
private refreshQueue: Promise<void> = Promise.resolve();
constructor(private viewId: string, options: vscode.TreeViewOptions<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) {
super();
@@ -214,9 +218,11 @@ export class ExtHostTreeView<T> extends Disposable {
return result;
}, 200)(({ message, elements }) => {
if (elements.length) {
const _promiseCallback = promiseCallback;
refreshingPromise = null;
this.refresh(elements).then(() => _promiseCallback());
this.refreshQueue = this.refreshQueue.then(() => {
const _promiseCallback = promiseCallback;
refreshingPromise = null;
return this.refresh(elements).then(() => _promiseCallback());
});
}
if (message) {
this.proxy.$setMessage(this.viewId, this._message);
@@ -255,12 +261,12 @@ export class ExtHostTreeView<T> extends Disposable {
.then(treeNode => this.proxy.$reveal(this.viewId, treeNode.item, parentChain.map(p => p.item), { select, focus, expand })), error => this.logService.error(error));
}
private _message: string | MarkdownString;
get message(): string | MarkdownString {
private _message: string = '';
get message(): string {
return this._message;
}
set message(message: string | MarkdownString) {
set message(message: string) {
this._message = message;
this._onDidChangeData.fire({ message: true, element: false });
}
@@ -583,9 +589,9 @@ export class ExtHostTreeView<T> extends Disposable {
if (node) {
if (node.children) {
for (const child of node.children) {
const childEleement = this.elements.get(child.item.handle);
if (childEleement) {
this.clear(childEleement);
const childElement = this.elements.get(child.item.handle);
if (childElement) {
this.clear(childElement);
}
}
}
@@ -601,9 +607,9 @@ export class ExtHostTreeView<T> extends Disposable {
if (node) {
if (node.children) {
for (const child of node.children) {
const childEleement = this.elements.get(child.item.handle);
if (childEleement) {
this.clear(childEleement);
const childElement = this.elements.get(child.item.handle);
if (childElement) {
this.clear(childElement);
}
}
}

View File

@@ -19,7 +19,7 @@ import { IRange } from 'vs/editor/common/core/range';
import { ISelection } from 'vs/editor/common/core/selection';
import * as htmlContent from 'vs/base/common/htmlContent';
import * as languageSelector from 'vs/editor/common/modes/languageSelector';
import { WorkspaceEditDto, ResourceTextEditDto, ResourceFileEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { IWorkspaceEditDto, IResourceTextEditDto, IResourceFileEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { MarkerSeverity, IRelatedInformation, IMarkerData, MarkerTag } from 'vs/platform/markers/common/markers';
import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
@@ -442,7 +442,7 @@ export namespace TextEdit {
export function from(edit: vscode.TextEdit): modes.TextEdit {
return <modes.TextEdit>{
text: edit.newText,
eol: EndOfLine.from(edit.newEol),
eol: edit.newEol && EndOfLine.from(edit.newEol),
range: Range.from(edit.range)
};
}
@@ -455,8 +455,8 @@ export namespace TextEdit {
}
export namespace WorkspaceEdit {
export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors): WorkspaceEditDto {
const result: WorkspaceEditDto = {
export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors): IWorkspaceEditDto {
const result: IWorkspaceEditDto = {
edits: []
};
for (const entry of (value as types.WorkspaceEdit)._allEntries()) {
@@ -464,28 +464,28 @@ export namespace WorkspaceEdit {
if (Array.isArray(uriOrEdits)) {
// text edits
const doc = documents && uri ? documents.getDocument(uri) : undefined;
result.edits.push(<ResourceTextEditDto>{ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) });
result.edits.push(<IResourceTextEditDto>{ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) });
} else {
// resource edits
result.edits.push(<ResourceFileEditDto>{ oldUri: uri, newUri: uriOrEdits, options: entry[2] });
result.edits.push(<IResourceFileEditDto>{ oldUri: uri, newUri: uriOrEdits, options: entry[2] });
}
}
return result;
}
export function to(value: WorkspaceEditDto) {
export function to(value: IWorkspaceEditDto) {
const result = new types.WorkspaceEdit();
for (const edit of value.edits) {
if (Array.isArray((<ResourceTextEditDto>edit).edits)) {
if (Array.isArray((<IResourceTextEditDto>edit).edits)) {
result.set(
URI.revive((<ResourceTextEditDto>edit).resource),
<types.TextEdit[]>(<ResourceTextEditDto>edit).edits.map(TextEdit.to)
URI.revive((<IResourceTextEditDto>edit).resource),
<types.TextEdit[]>(<IResourceTextEditDto>edit).edits.map(TextEdit.to)
);
} else {
result.renameFile(
URI.revive((<ResourceFileEditDto>edit).oldUri!),
URI.revive((<ResourceFileEditDto>edit).newUri!),
(<ResourceFileEditDto>edit).options
URI.revive((<IResourceFileEditDto>edit).oldUri!),
URI.revive((<IResourceFileEditDto>edit).newUri!),
(<IResourceFileEditDto>edit).options
);
}
}

View File

@@ -514,7 +514,7 @@ export class TextEdit {
protected _range: Range;
protected _newText: string | null;
protected _newEol: EndOfLine;
protected _newEol?: EndOfLine;
get range(): Range {
return this._range;
@@ -538,11 +538,11 @@ export class TextEdit {
this._newText = value;
}
get newEol(): EndOfLine {
get newEol(): EndOfLine | undefined {
return this._newEol;
}
set newEol(value: EndOfLine) {
set newEol(value: EndOfLine | undefined) {
if (value && typeof value !== 'number') {
throw illegalArgument('newEol');
}
@@ -550,7 +550,7 @@ export class TextEdit {
}
constructor(range: Range, newText: string | null) {
this.range = range;
this._range = range;
this._newText = newText;
}
@@ -798,7 +798,7 @@ export class Location {
}
uri: URI;
range: Range;
range!: Range;
constructor(uri: URI, rangeOrPosition: Range | Position) {
this.uri = uri;
@@ -861,10 +861,10 @@ export class Diagnostic {
range: Range;
message: string;
source: string;
code: string | number;
severity: DiagnosticSeverity;
relatedInformation: DiagnosticRelatedInformation[];
source?: string;
code?: string | number;
relatedInformation?: DiagnosticRelatedInformation[];
tags?: DiagnosticTag[];
constructor(range: Range, message: string, severity: DiagnosticSeverity = DiagnosticSeverity.Error) {
@@ -989,7 +989,7 @@ export class SymbolInformation {
}
name: string;
location: Location;
location!: Location;
kind: SymbolKind;
containerName: string | undefined;
@@ -1075,6 +1075,8 @@ export class CodeAction {
kind?: CodeActionKind;
isPreferred?: boolean;
constructor(title: string, kind?: CodeActionKind) {
this.title = title;
this.kind = kind;
@@ -1253,8 +1255,8 @@ export class SignatureInformation {
export class SignatureHelp {
signatures: SignatureInformation[];
activeSignature: number;
activeParameter: number;
activeSignature: number = 0;
activeParameter: number = 0;
constructor() {
this.signatures = [];
@@ -1310,19 +1312,19 @@ export enum CompletionItemKind {
export class CompletionItem implements vscode.CompletionItem {
label: string;
kind: CompletionItemKind | undefined;
kind?: CompletionItemKind;
detail?: string;
documentation?: string | MarkdownString;
sortText?: string;
filterText?: string;
preselect?: boolean;
insertText: string | SnippetString;
insertText?: string | SnippetString;
keepWhitespace?: boolean;
range: Range;
range?: Range;
commitCharacters?: string[];
textEdit: TextEdit;
additionalTextEdits: TextEdit[];
command: vscode.Command;
textEdit?: TextEdit;
additionalTextEdits?: TextEdit[];
command?: vscode.Command;
constructor(label: string, kind?: CompletionItemKind) {
this.label = label;
@@ -1753,26 +1755,6 @@ export enum TaskScope {
Workspace = 2
}
export class CustomExecution implements vscode.CustomExecution {
private _callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number>;
constructor(callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number>) {
this._callback = callback;
}
public computeId(): string {
return 'customExecution' + generateUuid();
}
public set callback(value: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number>) {
this._callback = value;
}
public get callback(): (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number> {
return this._callback;
}
}
export class CustomExecution2 implements vscode.CustomExecution2 {
private _callback: () => Thenable<vscode.Pseudoterminal>;
constructor(callback: () => Thenable<vscode.Pseudoterminal>) {
@@ -1804,7 +1786,7 @@ export class Task implements vscode.Task2 {
private _definition: vscode.TaskDefinition;
private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder | undefined;
private _name: string;
private _execution: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined;
private _execution: ProcessExecution | ShellExecution | CustomExecution2 | undefined;
private _problemMatchers: string[];
private _hasDefinedMatchers: boolean;
private _isBackground: boolean;
@@ -1813,8 +1795,8 @@ export class Task implements vscode.Task2 {
private _presentationOptions: vscode.TaskPresentationOptions;
private _runOptions: vscode.RunOptions;
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2, problemMatchers?: string | string[]);
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2, problemMatchers?: string | string[]);
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution2, problemMatchers?: string | string[]);
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution2, problemMatchers?: string | string[]);
constructor(definition: vscode.TaskDefinition, arg2: string | (vscode.TaskScope.Global | vscode.TaskScope.Workspace) | vscode.WorkspaceFolder, arg3: any, arg4?: any, arg5?: any, arg6?: any) {
this.definition = definition;
let problemMatchers: string | string[];
@@ -1879,7 +1861,7 @@ export class Task implements vscode.Task2 {
type: Task.ShellType,
id: this._execution.computeId()
};
} else if (this._execution instanceof CustomExecution) {
} else if (this._execution instanceof CustomExecution2) {
this._definition = {
type: Task.ExtensionCallbackType,
id: this._execution.computeId()
@@ -1926,18 +1908,18 @@ export class Task implements vscode.Task2 {
}
get execution(): ProcessExecution | ShellExecution | undefined {
return ((this._execution instanceof CustomExecution) || (this._execution instanceof CustomExecution2)) ? undefined : this._execution;
return (this._execution instanceof CustomExecution2) ? undefined : this._execution;
}
set execution(value: ProcessExecution | ShellExecution | undefined) {
this.execution2 = value;
}
get execution2(): ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined {
get execution2(): ProcessExecution | ShellExecution | CustomExecution2 | undefined {
return this._execution;
}
set execution2(value: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined) {
set execution2(value: ProcessExecution | ShellExecution | CustomExecution2 | undefined) {
if (value === null) {
value = undefined;
}

View File

@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IURITransformer } from 'vs/base/common/uriIpc';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { URI, UriComponents } from 'vs/base/common/uri';
export interface IURITransformerService extends IURITransformer {
_serviceBrand: any;
}
export const IURITransformerService = createDecorator<IURITransformerService>('IURITransformerService');
export class URITransformerService implements IURITransformerService {
_serviceBrand: any;
transformIncoming: (uri: UriComponents) => UriComponents;
transformOutgoing: (uri: UriComponents) => UriComponents;
transformOutgoingURI: (uri: URI) => URI;
transformOutgoingScheme: (scheme: string) => string;
constructor(delegate: IURITransformer | null) {
if (!delegate) {
this.transformIncoming = arg => arg;
this.transformOutgoing = arg => arg;
this.transformOutgoingURI = arg => arg;
this.transformOutgoingScheme = arg => arg;
} else {
this.transformIncoming = delegate.transformIncoming.bind(delegate);
this.transformOutgoing = delegate.transformOutgoing.bind(delegate);
this.transformOutgoingURI = delegate.transformOutgoingURI.bind(delegate);
this.transformOutgoingScheme = delegate.transformOutgoingScheme.bind(delegate);
}
}
}

View File

@@ -20,11 +20,14 @@ import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspa
import { Range, RelativePattern } from 'vs/workbench/api/common/extHostTypes';
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import * as vscode from 'vscode';
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext, IStaticWorkspaceData } from './extHost.protocol';
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, MainContext } from './extHost.protocol';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Barrier } from 'vs/base/common/async';
import { Schemas } from 'vs/base/common/network';
import { withUndefinedAsNull } from 'vs/base/common/types';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
export interface IExtHostWorkspaceProvider {
getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise<vscode.WorkspaceFolder | undefined>;
@@ -153,6 +156,8 @@ class ExtHostWorkspaceImpl extends Workspace {
export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspaceProvider {
readonly _serviceBrand: any;
private readonly _onDidChangeWorkspace = new Emitter<vscode.WorkspaceFoldersChangeEvent>();
readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event;
@@ -169,21 +174,21 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
private readonly _activeSearchCallbacks: ((match: IRawFileMatch2) => any)[] = [];
constructor(
mainContext: IMainContext,
logService: ILogService,
requestIdProvider: Counter,
data?: IStaticWorkspaceData
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@ILogService logService: ILogService,
) {
this._logService = logService;
this._requestIdProvider = requestIdProvider;
this._requestIdProvider = new Counter();
this._barrier = new Barrier();
this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace);
this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService);
this._proxy = extHostRpc.getProxy(MainContext.MainThreadWorkspace);
this._messageService = extHostRpc.getProxy(MainContext.MainThreadMessageService);
const data = initData.workspace;
this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, [], data.configuration ? URI.revive(data.configuration) : null, !!data.isUntitled) : undefined;
}
$initializeWorkspace(data: IWorkspaceData): void {
$initializeWorkspace(data: IWorkspaceData | null): void {
this.$acceptWorkspaceData(data);
this._barrier.open();
}
@@ -289,7 +294,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
this._unconfirmedWorkspace = undefined;
// show error to user
this._messageService.$showMessage(Severity.Error, localize('updateerror', "Extension '{0}' failed to update workspace folders: {1}", extName, error), { extension }, []);
this._messageService.$showMessage(Severity.Error, localize('updateerror', "Extension '{0}' failed to update workspace folders: {1}", extName, error.toString()), { extension }, []);
});
}
@@ -390,7 +395,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
}
}
$acceptWorkspaceData(data: IWorkspaceData): void {
$acceptWorkspaceData(data: IWorkspaceData | null): void {
const { workspace, added, removed } = ExtHostWorkspaceImpl.toExtHostWorkspace(data, this._confirmedWorkspace, this._unconfirmedWorkspace);
@@ -546,3 +551,6 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
return this._proxy.$resolveProxy(url);
}
}
export const IExtHostWorkspace = createDecorator<IExtHostWorkspace>('IExtHostWorkspace');
export interface IExtHostWorkspace extends ExtHostWorkspace, ExtHostWorkspaceShape, IExtHostWorkspaceProvider { }

View File

@@ -66,10 +66,6 @@ export interface ShellExecutionDTO {
options?: ShellExecutionOptionsDTO;
}
export interface CustomExecutionDTO {
customExecution: 'customExecution';
}
export interface CustomExecution2DTO {
customExecution: 'customExecution2';
}
@@ -88,7 +84,7 @@ export interface TaskHandleDTO {
export interface TaskDTO {
_id: string;
name?: string;
execution: ProcessExecutionDTO | ShellExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined;
execution: ProcessExecutionDTO | ShellExecutionDTO | CustomExecution2DTO | undefined;
definition: TaskDefinitionDTO;
isBackground?: boolean;
source: TaskSourceDTO;
@@ -129,4 +125,4 @@ export interface TaskSystemInfoDTO {
scheme: string;
authority: string;
platform: string;
}
}