Merge branch 'master' into cleanup_ext_host_terminals

This commit is contained in:
Daniel Imms
2019-11-17 12:29:21 -08:00
committed by GitHub
613 changed files with 11843 additions and 7794 deletions

View File

@@ -446,7 +446,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
private registerPanel(commentsPanelAlreadyConstructed: boolean) {
if (!commentsPanelAlreadyConstructed) {
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(new PanelDescriptor(
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor.create(
CommentsPanel,
COMMENTS_PANEL_ID,
COMMENTS_PANEL_TITLE,

View File

@@ -33,11 +33,11 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
private static _convertOpenOptions(options: MainThreadDialogOpenOptions): IOpenDialogOptions {
const result: IOpenDialogOptions = {
openLabel: options.openLabel,
openLabel: options.openLabel || undefined,
canSelectFiles: options.canSelectFiles || (!options.canSelectFiles && !options.canSelectFolders),
canSelectFolders: options.canSelectFolders,
canSelectMany: options.canSelectMany,
defaultUri: URI.revive(options.defaultUri)
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined
};
if (options.filters) {
result.filters = [];
@@ -48,8 +48,8 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
private static _convertSaveOptions(options: MainThreadDialogSaveOptions): ISaveDialogOptions {
const result: ISaveDialogOptions = {
defaultUri: URI.revive(options.defaultUri),
saveLabel: options.saveLabel
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined,
saveLabel: options.saveLabel || undefined
};
if (options.filters) {
result.filters = [];

View File

@@ -233,7 +233,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
initialValue,
useResourcePath: Boolean(resource && resource.path)
}).then(model => {
const resource = model.getResource();
const resource = model.resource;
if (!this._modelIsSynced.has(resource.toString())) {
throw new Error(`expected URI ${resource.toString()} to have come to LIFE`);

View File

@@ -52,10 +52,10 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
$stat(uri: UriComponents): Promise<IStat> {
return this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }).then(stat => {
return {
ctime: 0,
ctime: stat.ctime,
mtime: stat.mtime,
size: stat.size,
type: MainThreadFileSystem._getFileType(stat)
type: MainThreadFileSystem._asFileType(stat)
};
}).catch(MainThreadFileSystem._handleError);
}
@@ -67,12 +67,22 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
err.name = FileSystemProviderErrorCode.FileNotADirectory;
throw err;
}
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._getFileType(child)] as [string, FileType]);
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._asFileType(child)] as [string, FileType]);
}).catch(MainThreadFileSystem._handleError);
}
private static _getFileType(stat: IFileStat): FileType {
return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0);
private static _asFileType(stat: IFileStat): FileType {
let res = 0;
if (stat.isFile) {
res += FileType.File;
} else if (stat.isDirectory) {
res += FileType.Directory;
}
if (stat.isSymbolicLink) {
res += FileType.SymbolicLink;
}
return res;
}
$readFile(uri: UriComponents): Promise<VSBuffer> {

View File

@@ -30,7 +30,8 @@ import { ILogService } from 'vs/platform/log/common/log';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ISaveParticipant, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { ISaveParticipant, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../common/extHost.protocol';
export interface ICodeActionsOnSaveOptions {
@@ -51,7 +52,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO);
}
}
@@ -113,7 +114,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant {
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doInsertFinalNewLine(model.textEditorModel);
}
}
@@ -147,7 +148,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO);
}
}
@@ -257,7 +258,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
const model = editorModel.textEditorModel;
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() };
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.resource };
const setting = this._configurationService.getValue<ICodeActionsOnSaveOptions>('editor.codeActionsOnSave', settingsOverrides);
if (!setting) {
return undefined;
@@ -282,6 +283,10 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
return undefined;
}
const excludedActions = Object.keys(setting)
.filter(x => setting[x] === false)
.map(x => new CodeActionKind(x));
const tokenSource = new CancellationTokenSource();
const timeout = this._configurationService.getValue<number>('editor.codeActionsOnSaveTimeout', settingsOverrides);
@@ -292,15 +297,15 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
tokenSource.cancel();
reject(localize('codeActionsOnSave.didTimeout', "Aborted codeActionsOnSave after {0}ms", timeout));
}, timeout)),
this.applyOnSaveActions(model, codeActionsOnSave, tokenSource.token)
this.applyOnSaveActions(model, codeActionsOnSave, excludedActions, tokenSource.token)
]).finally(() => {
tokenSource.cancel();
});
}
private async applyOnSaveActions(model: ITextModel, codeActionsOnSave: CodeActionKind[], token: CancellationToken): Promise<void> {
private async applyOnSaveActions(model: ITextModel, codeActionsOnSave: readonly CodeActionKind[], excludes: readonly CodeActionKind[], token: CancellationToken): Promise<void> {
for (const codeActionKind of codeActionsOnSave) {
const actionsToRun = await this.getActionsToRun(model, codeActionKind, token);
const actionsToRun = await this.getActionsToRun(model, codeActionKind, excludes, token);
try {
await this.applyCodeActions(actionsToRun.actions);
} catch {
@@ -317,10 +322,10 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
}
}
private getActionsToRun(model: ITextModel, codeActionKind: CodeActionKind, token: CancellationToken) {
private getActionsToRun(model: ITextModel, codeActionKind: CodeActionKind, excludes: readonly CodeActionKind[], token: CancellationToken) {
return getCodeActions(model, model.getFullModelRange(), {
type: 'auto',
filter: { kind: codeActionKind, includeSourceActions: true },
filter: { include: codeActionKind, excludes: excludes, includeSourceActions: true },
}, token);
}
}
@@ -343,7 +348,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant {
return new Promise<any>((resolve, reject) => {
setTimeout(() => reject(localize('timeout.onWillSave', "Aborted onWillSaveTextDocument-event after 1750ms")), 1750);
this._proxy.$participateInSave(editorModel.getResource(), env.reason).then(values => {
this._proxy.$participateInSave(editorModel.resource, env.reason).then(values => {
if (!values.every(success => success)) {
return Promise.reject(new Error('listener failed'));
}

View File

@@ -12,6 +12,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { isUndefinedOrNull, isNumber } from 'vs/base/common/types';
import { Registry } from 'vs/platform/registry/common/platform';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
@extHostNamedCustomer(MainContext.MainThreadTreeViews)
export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape {
@@ -23,13 +24,16 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
extHostContext: IExtHostContext,
@IViewsService private readonly viewsService: IViewsService,
@INotificationService private readonly notificationService: INotificationService,
@IExtensionService private readonly extensionService: IExtensionService
@IExtensionService private readonly extensionService: IExtensionService,
@ILogService private readonly logService: ILogService
) {
super();
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews);
}
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void {
this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options);
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
this._dataProviders.set(treeViewId, dataProvider);
@@ -49,6 +53,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void> {
this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, item, parentChain, options);
return this.viewsService.openView(treeViewId, options.focus)
.then(() => {
const viewer = this.getTreeView(treeViewId);
@@ -60,6 +66,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$refresh(treeViewId: string, itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeItem }): Promise<void> {
this.logService.trace('MainThreadTreeViews#$refresh', treeViewId, itemsToRefreshByHandle);
const viewer = this.getTreeView(treeViewId);
const dataProvider = this._dataProviders.get(treeViewId);
if (viewer && dataProvider) {
@@ -70,6 +78,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$setMessage(treeViewId: string, message: string): void {
this.logService.trace('MainThreadTreeViews#$setMessage', treeViewId, message);
const viewer = this.getTreeView(treeViewId);
if (viewer) {
viewer.message = message;
@@ -77,6 +87,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$setTitle(treeViewId: string, title: string): void {
this.logService.trace('MainThreadTreeViews#$setTitle', treeViewId, title);
const viewer = this.getTreeView(treeViewId);
if (viewer) {
viewer.title = title;

View File

@@ -20,6 +20,7 @@ import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } fr
import { IEditorInput } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { CustomFileEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
import { ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
import { WebviewExtensionDescription } from 'vs/workbench/contrib/webview/browser/webview';
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
@@ -27,7 +28,6 @@ import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { extHostNamedCustomer } from '../common/extHostCustomers';
import { CustomEditorModel } from 'vs/workbench/contrib/customEditor/browser/customEditorModel';
/**
* Bi-directional map between webview handles and inputs.
@@ -95,11 +95,11 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
private readonly _webviewInputs = new WebviewInputStore();
private readonly _revivers = new Map<string, IDisposable>();
private readonly _editorProviders = new Map<string, IDisposable>();
private readonly _models = new Map<string, CustomEditorModel>();
constructor(
context: extHostProtocol.IExtHostContext,
@IExtensionService extensionService: IExtensionService,
@ICustomEditorService private readonly _customEditorService: ICustomEditorService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IEditorService private readonly _editorService: IEditorService,
@IOpenerService private readonly _openerService: IOpenerService,
@@ -271,18 +271,20 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
webviewInput.webview.options = options;
webviewInput.webview.extension = extension;
const model = new CustomEditorModel();
webviewInput.setModel(model);
this._models.set(handle, model);
webviewInput.onDispose(() => {
this._models.delete(handle);
});
const model = await this._customEditorService.models.loadOrCreate(webviewInput.getResource(), webviewInput.viewType);
model.onUndo(edit => {
this._proxy.$undoEdits(handle, [edit]);
});
model.onRedo(edit => {
this._proxy.$redoEdits(handle, [edit]);
});
webviewInput.onDispose(() => {
this._customEditorService.models.disposeModel(model);
});
try {
await this._proxy.$resolveWebviewEditor(
webviewInput.getResource(),
@@ -316,7 +318,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
throw new Error('Webview is not a webview editor');
}
const model = this._models.get(handle);
const model = this._customEditorService.models.get(webview.getResource(), webview.viewType);
if (!model) {
throw new Error('Could not find model for webview editor');
}

View File

@@ -42,9 +42,17 @@ export class MainThreadWindow implements MainThreadWindowShape {
return Promise.resolve(this.hostService.hasFocus);
}
async $openUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<boolean> {
async $openUri(uriComponents: UriComponents, uriString: string | undefined, options: IOpenUriOptions): Promise<boolean> {
const uri = URI.from(uriComponents);
return this.openerService.open(uri, { openExternal: true, allowTunneling: options.allowTunneling });
let target: URI | string;
if (uriString && URI.parse(uriString).toString() === uri.toString()) {
// called with string and no transformation happened -> keep string
target = uriString;
} else {
// called with URI or transformed -> use uri
target = uri;
}
return this.openerService.open(target, { openExternal: true, allowTunneling: options.allowTunneling });
}
async $asExternalUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<UriComponents> {

View File

@@ -15,7 +15,7 @@ import { IFileMatch, IPatternInfo, ISearchProgressItem, ISearchService } from 'v
import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape, IWorkspaceData, ITextSearchComplete } from '../common/extHost.protocol';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@@ -37,7 +37,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
extHostContext: IExtHostContext,
@ISearchService private readonly _searchService: ISearchService,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService,
@ITextFileService private readonly _textFileService: ITextFileService,
@IEditorService private readonly _editorService: IEditorService,
@IWorkspaceEditingService private readonly _workspaceEditingService: IWorkspaceEditingService,
@INotificationService private readonly _notificationService: INotificationService,
@IRequestService private readonly _requestService: IRequestService,
@@ -212,9 +212,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
// --- save & edit resources ---
$saveAll(includeUntitled?: boolean): Promise<boolean> {
return this._textFileService.saveAll(includeUntitled).then(result => {
return result.results.every(each => each.success === true);
});
return this._editorService.saveAll({ includeUntitled });
}
$resolveProxy(url: string): Promise<string | undefined> {

View File

@@ -335,7 +335,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
super(id, `${id}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
}
}
const viewletDescriptor = new ViewletDescriptor(
const viewletDescriptor = ViewletDescriptor.create(
CustomViewlet,
id,
title,
@@ -359,7 +359,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
}
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(
new SyncActionDescriptor(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", title)),
SyncActionDescriptor.create(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", title)),
`View: Show ${title}`,
localize('view', "View")
);

View File

@@ -105,7 +105,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
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, extHostWorkspace));
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService));
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));
@@ -113,7 +113,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
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 extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol, extHostLogService));
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));
@@ -130,7 +130,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// Other instances
const extHostClipboard = new ExtHostClipboard(rpcProtocol);
const extHostMessageService = new ExtHostMessageService(rpcProtocol);
const extHostMessageService = new ExtHostMessageService(rpcProtocol, extHostLogService);
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments);
@@ -149,7 +149,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
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`);
extHostLogService.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`);
done = true;
}
}
@@ -180,20 +180,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
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.');
extHostLogService.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);
callback.apply(thisArg, [activeTextEditor, edit, ...args]);
}).then((result) => {
if (!result) {
console.warn('Edits from command ' + id + ' were not applied.');
extHostLogService.warn('Edits from command ' + id + ' were not applied.');
}
}, (err) => {
console.warn('An error occurred while running command ' + id, err);
extHostLogService.warn('An error occurred while running command ' + id, err);
});
});
},
@@ -202,7 +201,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
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.');
extHostLogService.warn('Cannot execute ' + id + ' because there is no active text editor.');
return undefined;
}
@@ -778,7 +777,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
if (!parentSessionOrOptions || (typeof parentSessionOrOptions === 'object' && 'configuration' in parentSessionOrOptions)) {
return extHostDebugService.startDebugging(folder, nameOrConfig, { parentSession: parentSessionOrOptions });
}
checkProposedApiEnabled(extension);
return extHostDebugService.startDebugging(folder, nameOrConfig, parentSessionOrOptions || {});
},
addBreakpoints(breakpoints: vscode.Breakpoint[]) {
@@ -786,6 +784,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
},
removeBreakpoints(breakpoints: vscode.Breakpoint[]) {
return extHostDebugService.removeBreakpoints(breakpoints);
},
asDebugSourceUri(source: vscode.DebugSource, session?: vscode.DebugSession): vscode.Uri {
checkProposedApiEnabled(extension);
return extHostDebugService.asDebugSourceUri(source, session);
}
};

View File

@@ -45,7 +45,7 @@ import { ITerminalDimensions, IShellLaunchConfig } from 'vs/workbench/contrib/te
import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import * as search from 'vs/workbench/services/search/common/search';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator';
export interface IEnvironment {
@@ -590,6 +590,7 @@ export interface ExtHostWebviewsShape {
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$undoEdits(handle: WebviewPanelHandle, edits: string[]): void;
$redoEdits(handle: WebviewPanelHandle, edits: string[]): void;
}
export interface MainThreadUrlsShape extends IDisposable {
@@ -759,7 +760,7 @@ export interface IOpenUriOptions {
export interface MainThreadWindowShape extends IDisposable {
$getWindowVisibility(): Promise<boolean>;
$openUri(uri: UriComponents, options: IOpenUriOptions): Promise<boolean>;
$openUri(uri: UriComponents, uriString: string | undefined, options: IOpenUriOptions): Promise<boolean>;
$asExternalUri(uri: UriComponents, options: IOpenUriOptions): Promise<UriComponents>;
}

View File

@@ -20,6 +20,7 @@ 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';
import { ILogService } from 'vs/platform/log/common/log';
function lookUp(tree: any, key: string) {
if (key) {
@@ -45,16 +46,19 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
readonly _serviceBrand: undefined;
private readonly _proxy: MainThreadConfigurationShape;
private readonly _logService: ILogService;
private readonly _extHostWorkspace: ExtHostWorkspace;
private readonly _barrier: Barrier;
private _actual: ExtHostConfigProvider | null;
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace,
@ILogService logService: ILogService,
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadConfiguration);
this._extHostWorkspace = extHostWorkspace;
this._logService = logService;
this._barrier = new Barrier();
this._actual = null;
}
@@ -64,7 +68,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
}
$initializeConfiguration(data: IConfigurationInitData): void {
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data);
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data, this._logService);
this._barrier.open();
}
@@ -80,9 +84,11 @@ export class ExtHostConfigProvider {
private readonly _extHostWorkspace: ExtHostWorkspace;
private _configurationScopes: Map<string, ConfigurationScope | undefined>;
private _configuration: Configuration;
private _logService: ILogService;
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) {
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData, logService: ILogService) {
this._proxy = proxy;
this._logService = logService;
this._extHostWorkspace = extHostWorkspace;
this._configuration = ExtHostConfigProvider.parse(data);
this._configurationScopes = this._toMap(data.configurationScopes);
@@ -236,13 +242,13 @@ export class ExtHostConfigProvider {
const extensionIdText = extensionId ? `[${extensionId.value}] ` : '';
if (ConfigurationScope.RESOURCE === scope) {
if (resource === undefined) {
console.warn(`${extensionIdText}Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${key}', provide the URI of a resource or 'null' for any resource.`);
this._logService.warn(`${extensionIdText}Accessing a resource scoped configuration without providing a resource is not expected. To get the effective value for '${key}', provide the URI of a resource or 'null' for any resource.`);
}
return;
}
if (ConfigurationScope.WINDOW === scope) {
if (resource) {
console.warn(`${extensionIdText}Accessing a window scoped configuration for a resource is not expected. To associate '${key}' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.`);
this._logService.warn(`${extensionIdText}Accessing a window scoped configuration for a resource is not expected. To associate '${key}' to a resource, define its scope to 'resource' in configuration contributions in 'package.json'.`);
}
return;
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
import { IConstructorSignature1, BrandedService } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
@@ -13,12 +13,12 @@ export type IExtHostNamedCustomer<T extends IDisposable> = [ProxyIdentifier<T>,
export type IExtHostCustomerCtor<T extends IDisposable> = IConstructorSignature1<IExtHostContext, T>;
export function extHostNamedCustomer<T extends IDisposable>(id: ProxyIdentifier<T>) {
return function (ctor: IExtHostCustomerCtor<T>): void {
return function <Services extends BrandedService[]>(ctor: { new(context: IExtHostContext, ...services: Services): T }): void {
ExtHostCustomersRegistryImpl.INSTANCE.registerNamedCustomer(id, ctor);
};
}
export function extHostCustomer<T extends IDisposable>(ctor: IExtHostCustomerCtor<T>): void {
export function extHostCustomer<T extends IDisposable, Services extends BrandedService[]>(ctor: { new(context: IExtHostContext, ...services: Services): T }): void {
ExtHostCustomersRegistryImpl.INSTANCE.registerCustomer(ctor);
}

View File

@@ -30,5 +30,6 @@ export interface IExtHostDebugService extends ExtHostDebugServiceShape {
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;
asDebugSourceUri(source: vscode.DebugSource, session?: vscode.DebugSession): vscode.Uri;
}

View File

@@ -12,6 +12,7 @@ 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';
import { ILogService } from 'vs/platform/log/common/log';
interface ProviderData {
provider: vscode.DecorationProvider;
@@ -28,6 +29,7 @@ export class ExtHostDecorations implements IExtHostDecorations {
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@ILogService private readonly _logService: ILogService,
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadDecorations);
}
@@ -66,10 +68,10 @@ export class ExtHostDecorations implements IExtHostDecorations {
Decoration.validate(data);
result[id] = <DecorationData>[data.priority, data.bubble, data.title, data.letter, data.color];
} catch (e) {
console.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`);
this._logService.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`);
}
}, err => {
console.error(err);
this._logService.error(err);
});
})).then(() => {

View File

@@ -13,6 +13,7 @@ import * as converter from './extHostTypeConverters';
import { mergeSort } from 'vs/base/common/arrays';
import { Event, Emitter } from 'vs/base/common/event';
import { keys } from 'vs/base/common/map';
import { ILogService } from 'vs/platform/log/common/log';
export class DiagnosticCollection implements vscode.DiagnosticCollection {
@@ -253,7 +254,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
readonly onDidChangeDiagnostics: Event<vscode.DiagnosticChangeEvent> = Event.map(Event.debounce(this._onDidChangeDiagnostics.event, ExtHostDiagnostics._debouncer, 50), ExtHostDiagnostics._mapper);
constructor(mainContext: IMainContext) {
constructor(mainContext: IMainContext, @ILogService private readonly _logService: ILogService) {
this._proxy = mainContext.getProxy(MainContext.MainThreadDiagnostics);
}
@@ -266,7 +267,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
} else if (!_collections.has(name)) {
owner = name;
} else {
console.warn(`DiagnosticCollection with name '${name}' does already exist.`);
this._logService.warn(`DiagnosticCollection with name '${name}' does already exist.`);
do {
owner = name + ExtHostDiagnostics._idPool++;
} while (_collections.has(owner));

View File

@@ -239,8 +239,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
} else if (regExpLeadsToEndlessLoop(regexp)) {
// use default when custom-regexp is bad
console.warn(`[getWordRangeAtPosition]: ignoring custom regexp '${regexp.source}' because it matches the empty string.`);
regexp = getWordDefinitionFor(this._languageId);
throw new Error(`[getWordRangeAtPosition]: ignoring custom regexp '${regexp.source}' because it matches the empty string.`);
}
const wordAtText = getWordAtText(

View File

@@ -11,7 +11,7 @@ import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IResou
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';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import * as vscode from 'vscode';
import { LinkedList } from 'vs/base/common/linkedList';
import { ILogService } from 'vs/platform/log/common/log';

View File

@@ -474,11 +474,11 @@ class NavigateTypeAdapter {
private readonly _symbolCache = new Map<number, vscode.SymbolInformation>();
private readonly _resultCache = new Map<number, [number, number]>();
private readonly _provider: vscode.WorkspaceSymbolProvider;
constructor(provider: vscode.WorkspaceSymbolProvider) {
this._provider = provider;
}
constructor(
private readonly _provider: vscode.WorkspaceSymbolProvider,
private readonly _logService: ILogService
) { }
provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceSymbolsDto> {
const result: extHostProtocol.IWorkspaceSymbolsDto = extHostProtocol.IdObject.mixin({ symbols: [] });
@@ -490,7 +490,7 @@ class NavigateTypeAdapter {
continue;
}
if (!item.name) {
console.warn('INVALID SymbolInformation, lacks name', item);
this._logService.warn('INVALID SymbolInformation, lacks name', item);
continue;
}
const symbol = extHostProtocol.IdObject.mixin(typeConvert.WorkspaceSymbol.from(item));
@@ -538,7 +538,8 @@ class RenameAdapter {
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _provider: vscode.RenameProvider
private readonly _provider: vscode.RenameProvider,
private readonly _logService: ILogService
) { }
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | undefined> {
@@ -587,7 +588,7 @@ class RenameAdapter {
return undefined;
}
if (range.start.line > pos.line || range.end.line < pos.line) {
console.warn('INVALID rename location: position line must be within range start/end lines');
this._logService.warn('INVALID rename location: position line must be within range start/end lines');
return undefined;
}
return { range: typeConvert.Range.from(range), text };
@@ -618,18 +619,15 @@ class SuggestAdapter {
return typeof provider.resolveCompletionItem === 'function';
}
private _documents: ExtHostDocuments;
private _commands: CommandsConverter;
private _provider: vscode.CompletionItemProvider;
private _cache = new Cache<vscode.CompletionItem>('CompletionItem');
private _disposables = new Map<number, DisposableStore>();
constructor(documents: ExtHostDocuments, commands: CommandsConverter, provider: vscode.CompletionItemProvider) {
this._documents = documents;
this._commands = commands;
this._provider = provider;
}
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _commands: CommandsConverter,
private readonly _provider: vscode.CompletionItemProvider,
private readonly _logService: ILogService
) { }
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<extHostProtocol.ISuggestResultDto | undefined> {
@@ -712,7 +710,7 @@ class SuggestAdapter {
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: extHostProtocol.ChainedCacheId): extHostProtocol.ISuggestDataDto | undefined {
if (typeof item.label !== 'string' || item.label.length === 0) {
console.warn('INVALID text edit -> must have at least a label');
this._logService.warn('INVALID text edit -> must have at least a label');
return undefined;
}
@@ -764,7 +762,7 @@ class SuggestAdapter {
if (range) {
if (Range.isRange(range)) {
if (!SuggestAdapter._isValidRangeForCompletion(range, position)) {
console.trace('INVALID range -> must be single line and on the same line');
this._logService.trace('INVALID range -> must be single line and on the same line');
return undefined;
}
result[extHostProtocol.ISuggestDataDtoField.range] = typeConvert.Range.from(range);
@@ -776,7 +774,7 @@ class SuggestAdapter {
|| !range.inserting.start.isEqual(range.replacing.start)
|| !range.replacing.contains(range.inserting)
) {
console.trace('INVALID range -> must be single line, on the same line, insert range must be a prefix of replace range');
this._logService.trace('INVALID range -> must be single line, on the same line, insert range must be a prefix of replace range');
return undefined;
}
result[extHostProtocol.ISuggestDataDtoField.range] = {
@@ -992,7 +990,8 @@ class SelectionRangeAdapter {
constructor(
private readonly _documents: ExtHostDocuments,
private readonly _provider: vscode.SelectionRangeProvider
private readonly _provider: vscode.SelectionRangeProvider,
private readonly _logService: ILogService
) { }
provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]> {
@@ -1004,7 +1003,7 @@ class SelectionRangeAdapter {
return [];
}
if (allProviderRanges.length !== positions.length) {
console.warn('BAD selection ranges, provider must return ranges for each position');
this._logService.warn('BAD selection ranges, provider must return ranges for each position');
return [];
}
@@ -1413,7 +1412,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
// --- navigate types
registerWorkspaceSymbolProvider(extension: IExtensionDescription, provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
const handle = this._addNewAdapter(new NavigateTypeAdapter(provider), extension);
const handle = this._addNewAdapter(new NavigateTypeAdapter(provider, this._logService), extension);
this._proxy.$registerNavigateTypeSupport(handle);
return this._createDisposable(handle);
}
@@ -1433,7 +1432,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
// --- rename
registerRenameProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
const handle = this._addNewAdapter(new RenameAdapter(this._documents, provider), extension);
const handle = this._addNewAdapter(new RenameAdapter(this._documents, provider, this._logService), extension);
this._proxy.$registerRenameSupport(handle, this._transformDocumentSelector(selector), RenameAdapter.supportsResolving(provider));
return this._createDisposable(handle);
}
@@ -1449,7 +1448,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
// --- suggestion
registerCompletionItemProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider), extension);
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider, this._logService), extension);
this._proxy.$registerSuggestSupport(handle, this._transformDocumentSelector(selector), triggerCharacters, SuggestAdapter.supportsResolving(provider), extension.identifier);
return this._createDisposable(handle);
}
@@ -1533,7 +1532,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
// --- smart select
registerSelectionRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable {
const handle = this._addNewAdapter(new SelectionRangeAdapter(this._documents, provider), extension);
const handle = this._addNewAdapter(new SelectionRangeAdapter(this._documents, provider, this._logService), extension);
this._proxy.$registerSelectionRangeProvider(handle, this._transformDocumentSelector(selector));
return this._createDisposable(handle);
}

View File

@@ -7,6 +7,7 @@ import Severity from 'vs/base/common/severity';
import * as vscode from 'vscode';
import { MainContext, MainThreadMessageServiceShape, MainThreadMessageOptions, IMainContext } from './extHost.protocol';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
function isMessageItem(item: any): item is vscode.MessageItem {
return item && item.title;
@@ -16,7 +17,10 @@ export class ExtHostMessageService {
private _proxy: MainThreadMessageServiceShape;
constructor(mainContext: IMainContext) {
constructor(
mainContext: IMainContext,
@ILogService private readonly _logService: ILogService
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadMessageService);
}
@@ -45,7 +49,7 @@ export class ExtHostMessageService {
let { title, isCloseAffordance } = command;
commands.push({ title, isCloseAffordance: !!isCloseAffordance, handle });
} else {
console.warn('Invalid message item:', command);
this._logService.warn('Invalid message item:', command);
}
}

View File

@@ -18,6 +18,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
import { platform } from 'vs/base/common/process';
import { ILogService } from 'vs/platform/log/common/log';
interface LoadFunction {
@@ -41,7 +42,8 @@ export abstract class RequireInterceptor {
@IInstantiationService private readonly _instaService: IInstantiationService,
@IExtHostConfiguration private readonly _extHostConfiguration: IExtHostConfiguration,
@IExtHostExtensionService private readonly _extHostExtensionService: IExtHostExtensionService,
@IExtHostInitDataService private readonly _initData: IExtHostInitDataService
@IExtHostInitDataService private readonly _initData: IExtHostInitDataService,
@ILogService private readonly _logService: ILogService,
) {
this._factories = new Map<string, INodeModuleFactory>();
this._alternatives = [];
@@ -54,7 +56,7 @@ export abstract class RequireInterceptor {
const configProvider = await this._extHostConfiguration.getConfigProvider();
const extensionPaths = await this._extHostExtensionService.getExtensionPathIndex();
this.register(new VSCodeNodeModuleFactory(this._apiFactory, extensionPaths, this._extensionRegistry, configProvider));
this.register(new VSCodeNodeModuleFactory(this._apiFactory, extensionPaths, this._extensionRegistry, configProvider, this._logService));
this.register(this._instaService.createInstance(KeytarNodeModuleFactory));
if (this._initData.remote.isRemote) {
this.register(this._instaService.createInstance(OpenNodeModuleFactory, extensionPaths, this._initData.environment.appUriScheme));
@@ -91,7 +93,8 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
private readonly _apiFactory: IExtensionApiFactory,
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
private readonly _extensionRegistry: ExtensionDescriptionRegistry,
private readonly _configProvider: ExtHostConfigProvider
private readonly _configProvider: ExtHostConfigProvider,
private readonly _logService: ILogService,
) {
}
@@ -112,7 +115,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
if (!this._defaultApiImpl) {
let extensionPathsPretty = '';
this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
console.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`);
this._logService.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`);
this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider);
}
return this._defaultApiImpl;
@@ -242,9 +245,9 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
return this.callOriginal(target, options);
}
if (uri.scheme === 'http' || uri.scheme === 'https') {
return mainThreadWindow.$openUri(uri, { allowTunneling: true });
return mainThreadWindow.$openUri(uri, target, { allowTunneling: true });
} else if (uri.scheme === 'mailto' || uri.scheme === this._appUriScheme) {
return mainThreadWindow.$openUri(uri, {});
return mainThreadWindow.$openUri(uri, target, {});
}
return this.callOriginal(target, options);
};

View File

@@ -180,8 +180,7 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
}
if (fn && typeof fn !== 'function') {
console.warn('Invalid SCM input box validation function');
return;
throw new Error(`[${this._extension.identifier.value}]: Invalid SCM input box validation function`);
}
this._validateInput = fn;

View File

@@ -3,10 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import { ExtHostSearchShape } from '../common/extHost.protocol';
import { ExtHostSearchShape, MainThreadSearchShape, MainContext } from '../common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { ILogService } from 'vs/platform/log/common/log';
import { IRawFileQuery, ISearchCompleteStats, IFileQuery, IRawTextQuery, IRawQuery, ITextQuery, IFolderQuery } from 'vs/workbench/services/search/common/search';
import { URI, UriComponents } from 'vs/base/common/uri';
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
export interface IExtHostSearch extends ExtHostSearchShape {
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable;
@@ -14,3 +21,111 @@ export interface IExtHostSearch extends ExtHostSearchShape {
}
export const IExtHostSearch = createDecorator<IExtHostSearch>('IExtHostSearch');
export class ExtHostSearch implements ExtHostSearchShape {
protected readonly _proxy: MainThreadSearchShape = this.extHostRpc.getProxy(MainContext.MainThreadSearch);
protected _handlePool: number = 0;
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
private readonly _textSearchUsedSchemes = new Set<string>();
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
private readonly _fileSearchUsedSchemes = new Set<string>();
private readonly _fileSearchManager = new FileSearchManager();
constructor(
@IExtHostRpcService private extHostRpc: IExtHostRpcService,
@IURITransformerService protected _uriTransformer: IURITransformerService,
@ILogService protected _logService: ILogService
) { }
protected _transformScheme(scheme: string): string {
return this._uriTransformer.transformOutgoingScheme(scheme);
}
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
if (this._textSearchUsedSchemes.has(scheme)) {
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
}
this._textSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._textSearchProvider.set(handle, provider);
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._textSearchUsedSchemes.delete(scheme);
this._textSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
if (this._fileSearchUsedSchemes.has(scheme)) {
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
}
this._fileSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._fileSearchProvider.set(handle, provider);
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._fileSearchUsedSchemes.delete(scheme);
this._fileSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const query = reviveQuery(rawQuery);
const provider = this._fileSearchProvider.get(handle);
if (provider) {
return this._fileSearchManager.fileSearch(query, provider, batch => {
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
}, token);
} else {
throw new Error('unknown provider: ' + handle);
}
}
$clearCache(cacheKey: string): Promise<void> {
this._fileSearchManager.clearCache(cacheKey);
return Promise.resolve(undefined);
}
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const provider = this._textSearchProvider.get(handle);
if (!provider || !provider.provideTextSearchResults) {
throw new Error(`Unknown provider ${handle}`);
}
const query = reviveQuery(rawQuery);
const engine = this.createTextSearchManager(query, provider);
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
}
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
return new TextSearchManager(query, provider, {
readdir: resource => Promise.resolve([]), // TODO@rob implement
toCanonicalName: encoding => encoding
});
}
}
export function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
return {
...<any>rawQuery, // TODO@rob ???
...{
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
}
};
}
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
return {
...rawFolderQuery,
folder: URI.revive(rawFolderQuery.folder)
};
}

View File

@@ -24,6 +24,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Schemas } from 'vs/base/common/network';
import * as Platform from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
export interface IExtHostTask extends ExtHostTaskShape {
@@ -374,6 +375,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
protected readonly _editorService: IExtHostDocumentsAndEditors;
protected readonly _configurationService: IExtHostConfiguration;
protected readonly _terminalService: IExtHostTerminalService;
protected readonly _logService: ILogService;
protected _handleCounter: number;
protected _handlers: Map<number, HandlerData>;
protected _taskExecutions: Map<string, TaskExecutionImpl>;
@@ -393,7 +395,8 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadTask);
this._workspaceProvider = workspaceService;
@@ -406,6 +409,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
this._providedCustomExecutions2 = new Map<string, types.CustomExecution>();
this._notProvidedCustomExecutions = new Set<string>();
this._activeCustomExecutions2 = new Map<string, types.CustomExecution>();
this._logService = logService;
}
public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable {
@@ -661,9 +665,10 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
if (initData.remote.isRemote && initData.remote.authority) {
this.registerTaskSystem(Schemas.vscodeRemote, {
scheme: Schemas.vscodeRemote,
@@ -696,7 +701,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
if (value) {
for (let task of value) {
if (!task.definition || !validTypes[task.definition.type]) {
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
}
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);
@@ -707,7 +712,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
// is invoked, we have to be able to map it back to our data.
taskIdPromises.push(this.addCustomExecution(taskDTO, task, true));
} else {
console.warn('Only custom execution tasks supported.');
this._logService.warn('Only custom execution tasks supported.');
}
}
}
@@ -721,7 +726,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
return resolvedTaskDTO;
} else {
console.warn('Only custom execution tasks supported.');
this._logService.warn('Only custom execution tasks supported.');
}
return undefined;
}

View File

@@ -198,7 +198,13 @@ class ExtHostTreeView<T> extends Disposable {
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) {
constructor(
private viewId: string, options: vscode.TreeViewOptions<T>,
private proxy: MainThreadTreeViewsShape,
private commands: CommandsConverter,
private logService: ILogService,
private extension: IExtensionDescription
) {
super();
if (extension.contributes && extension.contributes.views) {
for (const location in extension.contributes.views) {
@@ -250,7 +256,7 @@ class ExtHostTreeView<T> extends Disposable {
getChildren(parentHandle: TreeItemHandle | Root): Promise<ITreeItem[]> {
const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : undefined;
if (parentHandle && !parentElement) {
console.error(`No tree item with id \'${parentHandle}\' found.`);
this.logService.error(`No tree item with id \'${parentHandle}\' found.`);
return Promise.resolve([]);
}

View File

@@ -13,7 +13,7 @@ import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/mode
import * as vscode from 'vscode';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress';
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { SaveReason } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { IPosition } from 'vs/editor/common/core/position';
import * as editorRange from 'vs/editor/common/core/range';
import { ISelection } from 'vs/editor/common/core/selection';
@@ -31,7 +31,6 @@ import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
export interface PositionLike {
line: number;
character: number;

View File

@@ -740,6 +740,18 @@ export class SnippetString {
return this;
}
appendChoice(values: string[], number: number = this._tabstop++): SnippetString {
const value = SnippetString._escape(values.toString());
this.value += '${';
this.value += number;
this.value += '|';
this.value += value;
this.value += '|}';
return this;
}
appendVariable(name: string, defaultValue?: string | ((snippet: SnippetString) => any)): SnippetString {
if (typeof defaultValue === 'function') {
@@ -1143,8 +1155,8 @@ export class SelectionRange {
export class CallHierarchyItem {
_sessionId: string;
_itemId: string;
_sessionId?: string;
_itemId?: string;
kind: SymbolKind;
name: string;

View File

@@ -5,10 +5,12 @@
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { assertIsDefined } from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
@@ -34,6 +36,7 @@ export class ExtHostWebview implements vscode.Webview {
private readonly _initData: WebviewInitData,
private readonly _workspace: IExtHostWorkspace | undefined,
private readonly _extension: IExtensionDescription,
private readonly _logService: ILogService,
) { }
public dispose() {
@@ -62,7 +65,7 @@ export class ExtHostWebview implements vscode.Webview {
if (this._initData.isExtensionDevelopmentDebug && !this._hasCalledAsWebviewUri) {
if (/(["'])vscode-resource:([^\s'"]+?)(["'])/i.test(value)) {
this._hasCalledAsWebviewUri = true;
console.warn(`${this._extension.identifier.value} created a webview that appears to use the vscode-resource scheme directly. Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
this._logService.warn(`${this._extension.identifier.value} created a webview that appears to use the vscode-resource scheme directly. Please migrate to use the 'webview.asWebviewUri' api instead: https://aka.ms/vscode-webview-use-aswebviewuri`);
}
}
this._proxy.$setHtml(this._handle, value);
@@ -113,7 +116,8 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa
readonly _onDidChangeViewStateEmitter = this._register(new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>());
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = this._onDidChangeViewStateEmitter.event;
_capabilities: vscode.WebviewEditorCapabilities;
public _capabilities?: vscode.WebviewEditorCapabilities;
constructor(
handle: WebviewPanelHandle,
@@ -245,7 +249,11 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa
}
_undoEdits(edits: string[]): void {
this._capabilities.editingCapability?.undoEdits(edits);
assertIsDefined(this._capabilities).editingCapability?.undoEdits(edits);
}
_redoEdits(edits: string[]): void {
assertIsDefined(this._capabilities).editingCapability?.applyEdits(edits);
}
private assertNotDisposed() {
@@ -270,6 +278,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
mainContext: IMainContext,
private readonly initData: WebviewInitData,
private readonly workspace: IExtHostWorkspace | undefined,
private readonly _logService: ILogService,
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadWebviews);
}
@@ -290,7 +299,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
const handle = ExtHostWebviews.newHandle();
this._proxy.$createWebviewPanel({ id: extension.identifier, location: extension.extensionLocation }, handle, viewType, title, webviewShowOptions, convertWebviewOptions(extension, this.workspace, options));
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension);
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
const panel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, viewColumn, options, webview);
this._webviewPanels.set(handle, panel);
return panel;
@@ -347,7 +356,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
_handle: WebviewPanelHandle,
extensionId: string
): void {
console.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
this._logService.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
}
public $onDidChangeWebviewPanelViewStates(newStates: WebviewPanelViewStateData): void {
@@ -407,7 +416,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
const { serializer, extension } = entry;
const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.initData, this.workspace, extension);
const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
const revivedPanel = new ExtHostWebviewEditor(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(webviewHandle, revivedPanel);
await serializer.deserializeWebviewPanel(revivedPanel, state);
@@ -427,7 +436,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
const { provider, extension } = entry;
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension);
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService);
const revivedPanel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(handle, revivedPanel);
const capabilities = await provider.resolveWebviewEditor({ resource: URI.revive(resource) }, revivedPanel);
@@ -442,6 +451,14 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
panel._undoEdits(edits);
}
$redoEdits(handle: WebviewPanelHandle, edits: string[]): void {
const panel = this.getWebviewPanel(handle);
if (!panel) {
return;
}
panel._redoEdits(edits);
}
private getWebviewPanel(handle: WebviewPanelHandle): ExtHostWebviewEditor | undefined {
return this._webviewPanels.get(handle);
}

View File

@@ -39,7 +39,9 @@ export class ExtHostWindow implements ExtHostWindowShape {
}
openUri(stringOrUri: string | URI, options: IOpenUriOptions): Promise<boolean> {
let uriAsString: string | undefined;
if (typeof stringOrUri === 'string') {
uriAsString = stringOrUri;
try {
stringOrUri = URI.parse(stringOrUri);
} catch (e) {
@@ -51,7 +53,7 @@ export class ExtHostWindow implements ExtHostWindowShape {
} else if (stringOrUri.scheme === Schemas.command) {
return Promise.reject(`Invalid scheme '${stringOrUri.scheme}'`);
}
return this._proxy.$openUri(stringOrUri, options);
return this._proxy.$openUri(stringOrUri, uriAsString, options);
}
async asExternalUri(uri: URI, options: IOpenUriOptions): Promise<URI> {

View File

@@ -18,7 +18,7 @@ import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
@@ -38,7 +38,7 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors);
registerSingleton(IExtHostTerminalService, ExtHostTerminalService);
registerSingleton(IExtHostTask, ExtHostTask);
registerSingleton(IExtHostDebugService, ExtHostDebugService);
registerSingleton(IExtHostSearch, ExtHostSearch);
registerSingleton(IExtHostSearch, NativeExtHostSearch);
registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths);
registerSingleton(IExtHostExtensionService, ExtHostExtensionService);
registerSingleton(IExtHostStorage, ExtHostStorage);

View File

@@ -38,6 +38,7 @@ import { ISignService } from 'vs/platform/sign/common/sign';
import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { withNullAsUndefined } from 'vs/base/common/types';
export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugServiceShape {
@@ -114,7 +115,7 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
this._onDidStartDebugSession = new Emitter<vscode.DebugSession>();
this._onDidTerminateDebugSession = new Emitter<vscode.DebugSession>();
this._onDidChangeActiveDebugSession = new Emitter<vscode.DebugSession>();
this._onDidChangeActiveDebugSession = new Emitter<vscode.DebugSession | undefined>();
this._onDidReceiveDebugSessionCustomEvent = new Emitter<vscode.DebugSessionCustomEvent>();
this._debugServiceProxy = extHostRpcService.getProxy(MainContext.MainThreadDebugService);
@@ -138,6 +139,32 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
});
}
public asDebugSourceUri(src: vscode.DebugSource, session?: vscode.DebugSession): URI {
const source = <any>src;
if (typeof source.sourceReference === 'number') {
// src can be retrieved via DAP's "source" request
let debug = `debug:${encodeURIComponent(source.path || '')}`;
let sep = '?';
if (session) {
debug += `${sep}session=${encodeURIComponent(session.id)}`;
sep = '&';
}
debug += `${sep}ref=${source.sourceReference}`;
return URI.parse(debug);
} else if (source.path) {
// src is just a local file path
return URI.file(source.path);
} else {
throw new Error(`cannot create uri from DAP 'source' object; properties 'path' and 'sourceReference' are both missing.`);
}
}
private registerAllDebugTypes(extensionRegistry: ExtensionDescriptionRegistry) {
const debugTypes: string[] = [];
@@ -485,11 +512,11 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
}
this._debugServiceProxy.$acceptDAError(debugAdapterHandle, err.name, err.message, err.stack);
});
debugAdapter.onExit((code: number) => {
debugAdapter.onExit((code: number | null) => {
if (tracker && tracker.onExit) {
tracker.onExit(code, undefined);
tracker.onExit(withNullAsUndefined(code), undefined);
}
this._debugServiceProxy.$acceptDAExit(debugAdapterHandle, code, undefined);
this._debugServiceProxy.$acceptDAExit(debugAdapterHandle, withNullAsUndefined(code), undefined);
});
if (tracker && tracker.onWillStartSession) {

View File

@@ -3,47 +3,37 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { ILogService } from 'vs/platform/log/common/log';
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search';
import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager';
import { IFileQuery, IRawFileQuery, ISearchCompleteStats, isSerializedFileMatch, ISerializedSearchProgressItem, ITextQuery } from 'vs/workbench/services/search/common/search';
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider';
import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
import * as vscode from 'vscode';
import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ExtHostSearch, reviveQuery } from 'vs/workbench/api/common/extHostSearch';
import { Schemas } from 'vs/base/common/network';
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
export class ExtHostSearch implements ExtHostSearchShape {
export class NativeExtHostSearch extends ExtHostSearch {
private readonly _proxy: MainThreadSearchShape;
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
private readonly _textSearchUsedSchemes = new Set<string>();
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
private readonly _fileSearchUsedSchemes = new Set<string>();
private _handlePool: number = 0;
protected _pfs: typeof pfs = pfs; // allow extending for tests
private _internalFileSearchHandle: number = -1;
private _internalFileSearchProvider: SearchService | null = null;
private _fileSearchManager: FileSearchManager;
protected _pfs: typeof pfs = pfs; // allow extending for tests
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IURITransformerService private _uriTransformer: IURITransformerService,
@ILogService private _logService: ILogService,
@IURITransformerService _uriTransformer: IURITransformerService,
@ILogService _logService: ILogService,
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch);
this._fileSearchManager = new FileSearchManager();
super(extHostRpc, _uriTransformer, _logService);
if (initData.remote.isRemote && initData.remote.authority) {
this._registerEHSearchProviders();
@@ -52,8 +42,8 @@ export class ExtHostSearch implements ExtHostSearchShape {
private _registerEHSearchProviders(): void {
const outputChannel = new OutputChannel(this._logService);
this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel));
this.registerInternalFileSearchProvider('file', new SearchService());
this.registerTextSearchProvider(Schemas.file, new RipgrepSearchProvider(outputChannel));
this.registerInternalFileSearchProvider(Schemas.file, new SearchService());
}
private registerInternalFileSearchProvider(scheme: string, provider: SearchService): IDisposable {
@@ -67,59 +57,16 @@ export class ExtHostSearch implements ExtHostSearchShape {
});
}
private _transformScheme(scheme: string): string {
return this._uriTransformer.transformOutgoingScheme(scheme);
}
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
if (this._textSearchUsedSchemes.has(scheme)) {
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
}
this._textSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._textSearchProvider.set(handle, provider);
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._textSearchUsedSchemes.delete(scheme);
this._textSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
if (this._fileSearchUsedSchemes.has(scheme)) {
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
}
this._fileSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._fileSearchProvider.set(handle, provider);
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._fileSearchUsedSchemes.delete(scheme);
this._fileSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const query = reviveQuery(rawQuery);
if (handle === this._internalFileSearchHandle) {
return this.doInternalFileSearch(handle, session, query, token);
} else {
const provider = this._fileSearchProvider.get(handle);
if (provider) {
return this._fileSearchManager.fileSearch(query, provider, batch => {
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
}, token);
} else {
throw new Error('unknown provider: ' + handle);
}
}
return super.$provideFileSearchResults(handle, session, rawQuery, token);
}
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const onResult = (ev: ISerializedSearchProgressItem) => {
if (isSerializedFileMatch(ev)) {
ev = [ev];
@@ -147,37 +94,11 @@ export class ExtHostSearch implements ExtHostSearchShape {
this._internalFileSearchProvider.clearCache(cacheKey);
}
this._fileSearchManager.clearCache(cacheKey);
return Promise.resolve(undefined);
return super.$clearCache(cacheKey);
}
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
const provider = this._textSearchProvider.get(handle);
if (!provider || !provider.provideTextSearchResults) {
throw new Error(`Unknown provider ${handle}`);
}
const query = reviveQuery(rawQuery);
const engine = new TextSearchManager(query, provider, this._pfs);
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
return new NativeTextSearchManager(query, provider);
}
}
function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
return {
...<any>rawQuery, // TODO
...{
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
}
};
}
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
return {
...rawFolderQuery,
folder: URI.revive(rawFolderQuery.folder)
};
}

View File

@@ -11,6 +11,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { withNullAsUndefined } from 'vs/base/common/types';
import { ILogService } from 'vs/platform/log/common/log';
export class ExtensionStoragePaths implements IExtensionStoragePaths {
@@ -22,7 +23,10 @@ export class ExtensionStoragePaths implements IExtensionStoragePaths {
readonly whenReady: Promise<string | undefined>;
private _value?: string;
constructor(@IExtHostInitDataService initData: IExtHostInitDataService) {
constructor(
@IExtHostInitDataService initData: IExtHostInitDataService,
@ILogService private readonly _logService: ILogService,
) {
this._workspace = withNullAsUndefined(initData.workspace);
this._environment = initData.environment;
this.whenReady = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value);
@@ -69,7 +73,7 @@ export class ExtensionStoragePaths implements IExtensionStoragePaths {
return storagePath;
} catch (e) {
console.error(e);
this._logService.error(e);
return undefined;
}
}

View File

@@ -22,6 +22,7 @@ import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerData } from 'vs/workbench/api/common/extHostTask';
import { Schemas } from 'vs/base/common/network';
import { ILogService } from 'vs/platform/log/common/log';
export class ExtHostTask extends ExtHostTaskBase {
private _variableResolver: ExtHostVariableResolverService | undefined;
@@ -32,9 +33,10 @@ export class ExtHostTask extends ExtHostTaskBase {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
if (initData.remote.isRemote && initData.remote.authority) {
this.registerTaskSystem(Schemas.vscodeRemote, {
scheme: Schemas.vscodeRemote,
@@ -71,7 +73,7 @@ export class ExtHostTask extends ExtHostTaskBase {
if (value) {
for (let task of value) {
if (!task.definition || !validTypes[task.definition.type]) {
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
}
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);