mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-30 05:21:08 +01:00
Merge with master
This commit is contained in:
@@ -58,7 +58,7 @@ import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExtHostUrls } from 'vs/workbench/api/node/extHostUrls';
|
||||
import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview';
|
||||
import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { IExtensionDescription, throwProposedApiError, checkProposedApiEnabled, nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
|
||||
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry';
|
||||
@@ -66,7 +66,7 @@ import * as vscode from 'vscode';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
|
||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): typeof vscode;
|
||||
}
|
||||
|
||||
function proposedApiFunction<T>(extension: IExtensionDescription, fn: T): T {
|
||||
@@ -142,7 +142,7 @@ export function createApiFactory(
|
||||
// Register API-ish commands
|
||||
ExtHostApiCommands.register(extHostCommands);
|
||||
|
||||
return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode {
|
||||
return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, 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
|
||||
@@ -219,7 +219,7 @@ export function createApiFactory(
|
||||
});
|
||||
},
|
||||
registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => {
|
||||
return extHostCommands.registerCommand(true, id, async (...args: any[]) => {
|
||||
return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
|
||||
let activeTextEditor = extHostEditors.getActiveTextEditor();
|
||||
if (!activeTextEditor) {
|
||||
console.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
@@ -242,9 +242,9 @@ export function createApiFactory(
|
||||
const env: typeof vscode.env = Object.freeze({
|
||||
get machineId() { return initData.telemetryInfo.machineId; },
|
||||
get sessionId() { return initData.telemetryInfo.sessionId; },
|
||||
get language() { return platform.language; },
|
||||
get language() { return platform.language!; },
|
||||
get appName() { return product.nameLong; },
|
||||
get appRoot() { return initData.environment.appRoot.fsPath; },
|
||||
get appRoot() { return initData.environment.appRoot!.fsPath; },
|
||||
get logLevel() {
|
||||
checkProposedApiEnabled(extension);
|
||||
return typeConverters.LogLevel.to(extHostLogService.getLevel());
|
||||
@@ -263,8 +263,8 @@ export function createApiFactory(
|
||||
|
||||
// namespace: extensions
|
||||
const extensions: typeof vscode.extensions = {
|
||||
getExtension(extensionId: string): Extension<any> {
|
||||
let desc = extensionRegistry.getExtensionDescription(extensionId);
|
||||
getExtension(extensionId: string): Extension<any> | undefined {
|
||||
const desc = extensionRegistry.getExtensionDescription(extensionId);
|
||||
if (desc) {
|
||||
return new Extension(extensionService, desc);
|
||||
}
|
||||
@@ -443,7 +443,7 @@ export function createApiFactory(
|
||||
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);
|
||||
return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token);
|
||||
},
|
||||
showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) {
|
||||
return extHostQuickOpen.showWorkspaceFolderPick(options);
|
||||
@@ -511,34 +511,34 @@ export function createApiFactory(
|
||||
// namespace: workspace
|
||||
const workspace: typeof vscode.workspace = {
|
||||
get rootPath() {
|
||||
return extHostWorkspace.getPath();
|
||||
return workspaceProvider.getPath();
|
||||
},
|
||||
set rootPath(value) {
|
||||
throw errors.readonly();
|
||||
},
|
||||
getWorkspaceFolder(resource) {
|
||||
return extHostWorkspace.getWorkspaceFolder(resource);
|
||||
return workspaceProvider.getWorkspaceFolder(resource);
|
||||
},
|
||||
get workspaceFolders() {
|
||||
return extHostWorkspace.getWorkspaceFolders();
|
||||
return workspaceProvider.getWorkspaceFolders();
|
||||
},
|
||||
get name() {
|
||||
return extHostWorkspace.name;
|
||||
return workspaceProvider.name;
|
||||
},
|
||||
set name(value) {
|
||||
throw errors.readonly();
|
||||
},
|
||||
updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => {
|
||||
return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd);
|
||||
return workspaceProvider.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd);
|
||||
},
|
||||
onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) {
|
||||
return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables);
|
||||
return workspaceProvider.onDidChangeWorkspace(listener, thisArgs, disposables);
|
||||
},
|
||||
asRelativePath: (pathOrUri, includeWorkspace) => {
|
||||
return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace);
|
||||
return workspaceProvider.getRelativePath(pathOrUri, includeWorkspace);
|
||||
},
|
||||
findFiles: (include, exclude, maxResults?, token?) => {
|
||||
return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token);
|
||||
return workspaceProvider.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token);
|
||||
},
|
||||
findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback, callbackOrToken?, token?: vscode.CancellationToken) => {
|
||||
let options: vscode.FindTextInFilesOptions;
|
||||
@@ -553,10 +553,10 @@ export function createApiFactory(
|
||||
token = callbackOrToken;
|
||||
}
|
||||
|
||||
return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token);
|
||||
return workspaceProvider.findTextInFiles(query, options || {}, callback, extension.identifier, token);
|
||||
},
|
||||
saveAll: (includeUntitled?) => {
|
||||
return extHostWorkspace.saveAll(includeUntitled);
|
||||
return workspaceProvider.saveAll(includeUntitled);
|
||||
},
|
||||
applyEdit(edit: vscode.WorkspaceEdit): Thenable<boolean> {
|
||||
return extHostEditors.applyWorkspaceEdit(edit);
|
||||
@@ -774,7 +774,7 @@ export function createApiFactory(
|
||||
DocumentSymbol: extHostTypes.DocumentSymbol,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
EventEmitter: Emitter,
|
||||
ExtensionCallbackExecution: extHostTypes.ExtensionCallbackExecution,
|
||||
CustomTaskExecution: extHostTypes.CustomTaskExecution,
|
||||
FileChangeType: extHostTypes.FileChangeType,
|
||||
FileSystemError: extHostTypes.FileSystemError,
|
||||
FileType: files.FileType,
|
||||
@@ -809,7 +809,7 @@ export function createApiFactory(
|
||||
SymbolInformation: extHostTypes.SymbolInformation,
|
||||
SymbolKind: extHostTypes.SymbolKind,
|
||||
Task: extHostTypes.Task,
|
||||
TaskWithExtensionCallback: extHostTypes.Task,
|
||||
TaskWithCustomTaskExecution: extHostTypes.Task,
|
||||
TaskGroup: extHostTypes.TaskGroup,
|
||||
TaskPanelKind: extHostTypes.TaskPanelKind,
|
||||
TaskRevealKind: extHostTypes.TaskRevealKind,
|
||||
@@ -852,7 +852,7 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
|
||||
public id: string;
|
||||
public extensionPath: string;
|
||||
public packageJSON: any;
|
||||
public packageJSON: IExtensionDescription;
|
||||
|
||||
constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) {
|
||||
this._extensionService = extensionService;
|
||||
@@ -867,6 +867,9 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
}
|
||||
|
||||
get exports(): T {
|
||||
if (this.packageJSON.api === 'none') {
|
||||
return undefined;
|
||||
}
|
||||
return <T>this._extensionService.getExtensionExports(this._identifier);
|
||||
}
|
||||
|
||||
@@ -875,11 +878,11 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, configProvider));
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, workspaceProvider, configProvider));
|
||||
}
|
||||
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): void {
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): void {
|
||||
|
||||
// each extension is meant to get its own api implementation
|
||||
const extApiImpl = new Map<string, typeof vscode>();
|
||||
@@ -897,7 +900,7 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchT
|
||||
if (ext) {
|
||||
let apiImpl = extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier));
|
||||
if (!apiImpl) {
|
||||
apiImpl = factory(ext, extensionRegistry, configProvider);
|
||||
apiImpl = factory(ext, extensionRegistry, workspaceProvider, configProvider);
|
||||
extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl);
|
||||
}
|
||||
return apiImpl;
|
||||
@@ -908,7 +911,7 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchT
|
||||
let extensionPathsPretty = '';
|
||||
extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`);
|
||||
console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}. These are the extension path mappings: \n${extensionPathsPretty}`);
|
||||
defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, configProvider);
|
||||
defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, workspaceProvider, configProvider);
|
||||
}
|
||||
return defaultApiImpl;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ import { ResourceLabelFormatter } from 'vs/platform/label/common/label';
|
||||
import { LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { IPickOptions, IQuickInputButton, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IPatternInfo, IRawFileMatch2, IRawQuery, IRawTextQuery, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { IPatternInfo, IRawFileMatch2, IRawQuery, IRawTextQuery, ISearchCompleteStats } from 'vs/workbench/services/search/common/search';
|
||||
import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
@@ -48,26 +48,30 @@ import { IRemoteConsoleLog } from 'vs/base/node/console';
|
||||
|
||||
export interface IEnvironment {
|
||||
isExtensionDevelopmentDebug: boolean;
|
||||
appRoot: URI;
|
||||
appSettingsHome: URI;
|
||||
extensionDevelopmentLocationURI: URI;
|
||||
extensionTestsPath: string;
|
||||
appRoot?: URI;
|
||||
appSettingsHome?: URI;
|
||||
extensionDevelopmentLocationURI?: URI;
|
||||
extensionTestsPath?: string;
|
||||
globalStorageHome: URI;
|
||||
}
|
||||
|
||||
export interface IWorkspaceData {
|
||||
export interface IStaticWorkspaceData {
|
||||
id: string;
|
||||
name: string;
|
||||
folders: { uri: UriComponents, name: string, index: number }[];
|
||||
configuration?: UriComponents;
|
||||
}
|
||||
|
||||
export interface IWorkspaceData extends IStaticWorkspaceData {
|
||||
folders: { uri: UriComponents, name: string, index: number }[];
|
||||
}
|
||||
|
||||
export interface IInitData {
|
||||
commit: string;
|
||||
commit?: string;
|
||||
parentPid: number;
|
||||
environment: IEnvironment;
|
||||
workspace: IWorkspaceData;
|
||||
workspace?: IStaticWorkspaceData;
|
||||
resolvedExtensions: ExtensionIdentifier[];
|
||||
hostExtensions: ExtensionIdentifier[];
|
||||
extensions: IExtensionDescription[];
|
||||
telemetryInfo: ITelemetryInfo;
|
||||
logLevel: LogLevel;
|
||||
@@ -147,14 +151,14 @@ export interface MainThreadDialogSaveOptions {
|
||||
}
|
||||
|
||||
export interface MainThreadDiaglogsShape extends IDisposable {
|
||||
$showOpenDialog(options: MainThreadDialogOpenOptions): Promise<UriComponents[]>;
|
||||
$showSaveDialog(options: MainThreadDialogSaveOptions): Promise<UriComponents>;
|
||||
$showOpenDialog(options: MainThreadDialogOpenOptions): Promise<UriComponents[] | undefined>;
|
||||
$showSaveDialog(options: MainThreadDialogSaveOptions): Promise<UriComponents | undefined>;
|
||||
}
|
||||
|
||||
export interface MainThreadDecorationsShape extends IDisposable {
|
||||
$registerDecorationProvider(handle: number, label: string): void;
|
||||
$unregisterDecorationProvider(handle: number): void;
|
||||
$onDidChange(handle: number, resources: UriComponents[]): void;
|
||||
$onDidChange(handle: number, resources: UriComponents[] | null): void;
|
||||
}
|
||||
|
||||
export interface MainThreadDocumentContentProvidersShape extends IDisposable {
|
||||
@@ -294,7 +298,7 @@ export interface ISerializedSignatureHelpProviderMetadata {
|
||||
export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
$unregister(handle: number): void;
|
||||
$registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void;
|
||||
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number): void;
|
||||
$registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void;
|
||||
$emitCodeLensEvent(eventHandle: number, event?: any): void;
|
||||
$registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
|
||||
$registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void;
|
||||
@@ -329,17 +333,17 @@ export interface MainThreadMessageOptions {
|
||||
}
|
||||
|
||||
export interface MainThreadMessageServiceShape extends IDisposable {
|
||||
$showMessage(severity: Severity, message: string, options: MainThreadMessageOptions, commands: { title: string; isCloseAffordance: boolean; handle: number; }[]): Promise<number>;
|
||||
$showMessage(severity: Severity, message: string, options: MainThreadMessageOptions, commands: { title: string; isCloseAffordance: boolean; handle: number; }[]): Promise<number | undefined>;
|
||||
}
|
||||
|
||||
export interface MainThreadOutputServiceShape extends IDisposable {
|
||||
$register(label: string, log: boolean, file?: UriComponents): Promise<string>;
|
||||
$append(channelId: string, value: string): Promise<void>;
|
||||
$update(channelId: string): Promise<void>;
|
||||
$clear(channelId: string, till: number): Promise<void>;
|
||||
$reveal(channelId: string, preserveFocus: boolean): Promise<void>;
|
||||
$close(channelId: string): Promise<void>;
|
||||
$dispose(channelId: string): Promise<void>;
|
||||
$append(channelId: string, value: string): Promise<void> | undefined;
|
||||
$update(channelId: string): Promise<void> | undefined;
|
||||
$clear(channelId: string, till: number): Promise<void> | undefined;
|
||||
$reveal(channelId: string, preserveFocus: boolean): Promise<void> | undefined;
|
||||
$close(channelId: string): Promise<void> | undefined;
|
||||
$dispose(channelId: string): Promise<void> | undefined;
|
||||
}
|
||||
|
||||
export interface MainThreadProgressShape extends IDisposable {
|
||||
@@ -440,7 +444,7 @@ export interface TransferInputBox extends BaseTransferQuickInput {
|
||||
}
|
||||
|
||||
export interface MainThreadQuickOpenShape extends IDisposable {
|
||||
$show(instance: number, options: IPickOptions<TransferQuickPickItems>, token: CancellationToken): Promise<number | number[]>;
|
||||
$show(instance: number, options: IPickOptions<TransferQuickPickItems>, token: CancellationToken): Promise<number | number[] | undefined>;
|
||||
$setItems(instance: number, items: TransferQuickPickItems[]): Promise<void>;
|
||||
$setError(instance: number, error: Error): Promise<void>;
|
||||
$input(options: vscode.InputBoxOptions, validateInput: boolean, token: CancellationToken): Promise<string>;
|
||||
@@ -506,7 +510,7 @@ export interface ExtHostUrlsShape {
|
||||
}
|
||||
|
||||
export interface MainThreadWorkspaceShape extends IDisposable {
|
||||
$startFileSearch(includePattern: string, includeFolder: URI, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise<UriComponents[]> | undefined;
|
||||
$startFileSearch(includePattern: string | undefined, includeFolder: URI | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise<UriComponents[] | undefined>;
|
||||
$startTextSearch(query: IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise<vscode.TextSearchComplete>;
|
||||
$checkExists(includes: string[], token: CancellationToken): Promise<boolean>;
|
||||
$saveAll(includeUntitled?: boolean): Promise<boolean>;
|
||||
@@ -549,6 +553,7 @@ export interface MainThreadTaskShape extends IDisposable {
|
||||
|
||||
export interface MainThreadExtensionServiceShape extends IDisposable {
|
||||
$localShowMessage(severity: Severity, msg: string): void;
|
||||
$activateExtension(extensionId: ExtensionIdentifier, activationEvent: string): Promise<void>;
|
||||
$onWillActivateExtension(extensionId: ExtensionIdentifier): void;
|
||||
$onDidActivateExtension(extensionId: ExtensionIdentifier, startup: boolean, codeLoadingTime: number, activateCallTime: number, activateResolvedTime: number, activationEvent: string): void;
|
||||
$onExtensionActivationFailed(extensionId: ExtensionIdentifier): void;
|
||||
@@ -653,7 +658,7 @@ export interface ExtHostDiagnosticsShape {
|
||||
}
|
||||
|
||||
export interface ExtHostDocumentContentProvidersShape {
|
||||
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string>;
|
||||
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string | null | undefined>;
|
||||
}
|
||||
|
||||
export interface IModelAddedData {
|
||||
@@ -721,6 +726,7 @@ export interface ExtHostTreeViewsShape {
|
||||
}
|
||||
|
||||
export interface ExtHostWorkspaceShape {
|
||||
$initializeWorkspace(workspace: IWorkspaceData | null): void;
|
||||
$acceptWorkspaceData(workspace: IWorkspaceData | null): void;
|
||||
$handleTextSearchResult(result: IRawFileMatch2, requestId: number): void;
|
||||
}
|
||||
@@ -752,7 +758,7 @@ export interface ExtHostExtensionServiceShape {
|
||||
$resolveAuthority(remoteAuthority: string): Promise<ResolvedAuthority>;
|
||||
$startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void>;
|
||||
$activateByEvent(activationEvent: string): Promise<void>;
|
||||
$activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<void>;
|
||||
$activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<boolean>;
|
||||
|
||||
$deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise<void>;
|
||||
|
||||
@@ -883,38 +889,42 @@ export interface CodeActionDto {
|
||||
|
||||
export type LinkDto = ObjectIdentifier & modes.ILink;
|
||||
|
||||
export type CodeLensDto = ObjectIdentifier & modes.ICodeLensSymbol;
|
||||
export interface CodeLensDto extends ObjectIdentifier {
|
||||
range: IRange;
|
||||
id?: string;
|
||||
command?: CommandDto;
|
||||
}
|
||||
|
||||
export interface ExtHostLanguageFeaturesShape {
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[]>;
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
|
||||
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensDto[]>;
|
||||
$resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto>;
|
||||
$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[]>;
|
||||
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover>;
|
||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[]>;
|
||||
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<LocationDto[]>;
|
||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[]>;
|
||||
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]>;
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]>;
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]>;
|
||||
$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<CodeActionDto[] | undefined>;
|
||||
$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>;
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined>;
|
||||
$releaseWorkspaceSymbols(handle: number, id: number): void;
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto>;
|
||||
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation>;
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | 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>;
|
||||
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise<modes.CompletionItem>;
|
||||
$releaseCompletionItems(handle: number, id: number): void;
|
||||
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp>;
|
||||
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<LinkDto[]>;
|
||||
$resolveDocumentLink(handle: number, link: LinkDto, token: CancellationToken): Promise<LinkDto>;
|
||||
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp | undefined>;
|
||||
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<LinkDto[] | undefined>;
|
||||
$resolveDocumentLink(handle: number, link: LinkDto, token: CancellationToken): Promise<LinkDto | undefined>;
|
||||
$provideDocumentColors(handle: number, resource: UriComponents, token: CancellationToken): Promise<IRawColorInfo[]>;
|
||||
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[]>;
|
||||
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[]>;
|
||||
$provideSelectionRanges(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.SelectionRange[]>;
|
||||
$provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]>;
|
||||
}
|
||||
|
||||
export interface ExtHostQuickOpenShape {
|
||||
@@ -933,7 +943,7 @@ export interface ShellLaunchConfigDto {
|
||||
executable?: string;
|
||||
args?: string[] | string;
|
||||
cwd?: string | URI;
|
||||
env?: { [key: string]: string };
|
||||
env?: { [key: string]: string | null };
|
||||
}
|
||||
|
||||
export interface ExtHostTerminalServiceShape {
|
||||
@@ -954,7 +964,7 @@ export interface ExtHostTerminalServiceShape {
|
||||
}
|
||||
|
||||
export interface ExtHostSCMShape {
|
||||
$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents>;
|
||||
$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents | null>;
|
||||
$onInputBoxValueChange(sourceControlHandle: number, value: string): void;
|
||||
$executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): Promise<void>;
|
||||
$validateInput(sourceControlHandle: number, value: string, cursorPosition: number): Promise<[string, number] | undefined>;
|
||||
@@ -1033,7 +1043,7 @@ export interface ExtHostDebugServiceShape {
|
||||
$provideDebugAdapter(handle: number, session: IDebugSessionDto): Promise<IAdapterDescriptor>;
|
||||
$acceptDebugSessionStarted(session: IDebugSessionDto): void;
|
||||
$acceptDebugSessionTerminated(session: IDebugSessionDto): void;
|
||||
$acceptDebugSessionActiveChanged(session: IDebugSessionDto): void;
|
||||
$acceptDebugSessionActiveChanged(session: IDebugSessionDto | undefined): void;
|
||||
$acceptDebugSessionCustomEvent(session: IDebugSessionDto, event: any): void;
|
||||
$acceptBreakpointsDelta(delta: IBreakpointsDeltaDto): void;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures';
|
||||
import { ICommandsExecutor, PreviewHTMLAPICommand, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand } from './apiCommands';
|
||||
import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { isFalsyOrEmpty, isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
|
||||
export class ExtHostApiCommands {
|
||||
|
||||
@@ -199,7 +199,7 @@ export class ExtHostApiCommands {
|
||||
description: 'Execute selection range provider.',
|
||||
args: [
|
||||
{ name: 'uri', description: 'Uri of a text document', constraint: URI },
|
||||
{ name: 'position', description: 'Position in a text document', constraint: types.Position }
|
||||
{ name: 'positions', description: 'Positions in a text document', constraint: a => Array.isArray(a) }
|
||||
],
|
||||
returns: 'A promise that resolves to an array of ranges.'
|
||||
});
|
||||
@@ -420,16 +420,15 @@ export class ExtHostApiCommands {
|
||||
});
|
||||
}
|
||||
|
||||
private _executeSelectionRangeProvider(resource: URI, position: types.Position): Promise<vscode.SelectionRange[]> {
|
||||
private _executeSelectionRangeProvider(resource: URI, positions: types.Position[]): Promise<vscode.SelectionRange[][]> {
|
||||
let pos = positions.map(typeConverters.Position.from);
|
||||
const args = {
|
||||
resource,
|
||||
position: position && typeConverters.Position.from(position)
|
||||
position: pos[0],
|
||||
positions: pos
|
||||
};
|
||||
return this._commands.executeCommand<modes.SelectionRange[]>('_executeSelectionRangeProvider', args).then(result => {
|
||||
if (isNonEmptyArray(result)) {
|
||||
return result.map(typeConverters.SelectionRange.to);
|
||||
}
|
||||
return [];
|
||||
return this._commands.executeCommand<modes.SelectionRange[][]>('_executeSelectionRangeProvider', args).then(result => {
|
||||
return result.map(oneResult => oneResult.map(typeConverters.SelectionRange.to));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,11 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
private _executeContributedCommand<T>(id: string, args: any[]): Promise<T> {
|
||||
let { callback, thisArg, description } = this._commands.get(id);
|
||||
const command = this._commands.get(id);
|
||||
if (!command) {
|
||||
throw new Error('Unknown command');
|
||||
}
|
||||
let { callback, thisArg, description } = command;
|
||||
if (description) {
|
||||
for (let i = 0; i < description.args.length; i++) {
|
||||
try {
|
||||
@@ -207,7 +211,7 @@ export class CommandsConverter {
|
||||
this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this);
|
||||
}
|
||||
|
||||
toInternal(command: vscode.Command): CommandDto {
|
||||
toInternal(command: vscode.Command | undefined): CommandDto | undefined {
|
||||
|
||||
if (!command) {
|
||||
return undefined;
|
||||
@@ -237,7 +241,7 @@ export class CommandsConverter {
|
||||
return result;
|
||||
}
|
||||
|
||||
fromInternal(command: modes.Command): vscode.Command {
|
||||
fromInternal(command: modes.Command | undefined): vscode.Command | undefined {
|
||||
|
||||
if (!command) {
|
||||
return undefined;
|
||||
@@ -258,7 +262,7 @@ export class CommandsConverter {
|
||||
|
||||
private _executeConvertedCommand<R>(...args: any[]): Promise<R> {
|
||||
const actualCmd = this._heap.get<vscode.Command>(args[0]);
|
||||
return this._commands.executeCommand(actualCmd.command, ...actualCmd.arguments);
|
||||
return this._commands.executeCommand(actualCmd.command, ...(actualCmd.arguments || []));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,107 +111,68 @@ export class ExtHostComments implements ExtHostCommentsShape {
|
||||
}
|
||||
|
||||
$editComment(handle: number, uri: UriComponents, comment: modes.Comment, text: string): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.editComment(data.document, convertFromComment(comment), text, CancellationToken.None);
|
||||
return handlerData.provider.editComment(document, convertFromComment(comment), text, CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
$deleteComment(handle: number, uri: UriComponents, comment: modes.Comment): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.deleteComment(data.document, convertFromComment(comment), CancellationToken.None);
|
||||
return handlerData.provider.deleteComment(document, convertFromComment(comment), CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
$startDraft(handle: number, uri: UriComponents): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.startDraft(data.document, CancellationToken.None);
|
||||
return handlerData.provider.startDraft(document, CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
$deleteDraft(handle: number, uri: UriComponents): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.deleteDraft(data.document, CancellationToken.None);
|
||||
return handlerData.provider.deleteDraft(document, CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
$finishDraft(handle: number, uri: UriComponents): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.finishDraft(data.document, CancellationToken.None);
|
||||
return handlerData.provider.finishDraft(document, CancellationToken.None);
|
||||
});
|
||||
}
|
||||
|
||||
$addReaction(handle: number, uri: UriComponents, comment: modes.Comment, reaction: modes.CommentReaction): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.addReaction(data.document, convertFromComment(comment), reaction);
|
||||
return handlerData.provider.addReaction(document, convertFromComment(comment), reaction);
|
||||
});
|
||||
}
|
||||
|
||||
$deleteReaction(handle: number, uri: UriComponents, comment: modes.Comment, reaction: modes.CommentReaction): Promise<void> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.deleteReaction(data.document, convertFromComment(comment), reaction);
|
||||
return handlerData.provider.deleteReaction(document, convertFromComment(comment), reaction);
|
||||
});
|
||||
}
|
||||
|
||||
$provideDocumentComments(handle: number, uri: UriComponents): Promise<modes.CommentInfo> {
|
||||
const data = this._documents.getDocumentData(URI.revive(uri));
|
||||
if (!data || !data.document) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
const document = this._documents.getDocument(URI.revive(uri));
|
||||
const handlerData = this._documentProviders.get(handle);
|
||||
return asPromise(() => {
|
||||
return handlerData.provider.provideDocumentComments(data.document, CancellationToken.None);
|
||||
return handlerData.provider.provideDocumentComments(document, CancellationToken.None);
|
||||
}).then(commentInfo => commentInfo ? convertCommentInfo(handle, handlerData.extensionId, handlerData.provider, commentInfo, this._commandsConverter) : null);
|
||||
}
|
||||
|
||||
@@ -297,6 +258,9 @@ function convertToComment(provider: vscode.DocumentCommentProvider | vscode.Work
|
||||
const canEdit = !!(provider as vscode.DocumentCommentProvider).editComment && vscodeComment.canEdit;
|
||||
const canDelete = !!(provider as vscode.DocumentCommentProvider).deleteComment && vscodeComment.canDelete;
|
||||
const iconPath = vscodeComment.userIconPath ? vscodeComment.userIconPath.toString() : vscodeComment.gravatar;
|
||||
const providerCanDeleteReaction = !!(provider as vscode.DocumentCommentProvider).deleteReaction;
|
||||
const providerCanAddReaction = !!(provider as vscode.DocumentCommentProvider).addReaction;
|
||||
|
||||
return {
|
||||
commentId: vscodeComment.commentId,
|
||||
body: extHostTypeConverter.MarkdownString.from(vscodeComment.body),
|
||||
@@ -306,6 +270,12 @@ function convertToComment(provider: vscode.DocumentCommentProvider | vscode.Work
|
||||
canDelete: canDelete,
|
||||
command: vscodeComment.command ? commandsConverter.toInternal(vscodeComment.command) : null,
|
||||
isDraft: vscodeComment.isDraft,
|
||||
commentReactions: vscodeComment.commentReactions
|
||||
commentReactions: vscodeComment.commentReactions.map(reaction => {
|
||||
return {
|
||||
label: reaction.label,
|
||||
hasReacted: reaction.hasReacted,
|
||||
canEdit: (reaction.hasReacted && providerCanDeleteReaction) || (!reaction.hasReacted && providerCanAddReaction)
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ 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/node/extHostWorkspace';
|
||||
import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol';
|
||||
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
|
||||
import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -57,8 +57,10 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
}
|
||||
|
||||
$initializeConfiguration(data: IConfigurationInitData): void {
|
||||
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data);
|
||||
this._barrier.open();
|
||||
this._extHostWorkspace.getWorkspaceProvider().then(workspaceProvider => {
|
||||
this._actual = new ExtHostConfigProvider(this._proxy, workspaceProvider, data);
|
||||
this._barrier.open();
|
||||
});
|
||||
}
|
||||
|
||||
$acceptConfigurationChanged(data: IConfigurationInitData, eventData: IWorkspaceConfigurationChangeEventData): void {
|
||||
@@ -70,11 +72,11 @@ export class ExtHostConfigProvider {
|
||||
|
||||
private readonly _onDidChangeConfiguration = new Emitter<vscode.ConfigurationChangeEvent>();
|
||||
private readonly _proxy: MainThreadConfigurationShape;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspaceProvider;
|
||||
private _configurationScopes: { [key: string]: ConfigurationScope };
|
||||
private _configuration: Configuration;
|
||||
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) {
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspaceProvider, data: IConfigurationInitData) {
|
||||
this._proxy = proxy;
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._configuration = ExtHostConfigProvider.parse(data);
|
||||
|
||||
@@ -16,15 +16,15 @@ import {
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExecutableDebugAdapter, SocketDebugAdapter, AbstractDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { ITerminalSettings, IDebuggerContribution, IConfig, IDebugAdapter, IDebugAdapterServer, IDebugAdapterExecutable, IAdapterDescriptor } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { getTerminalLauncher, hasChildProcesses, prepareCommand } from 'vs/workbench/contrib/debug/node/terminals';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/node/variableResolver';
|
||||
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver';
|
||||
import { ExtHostConfiguration, ExtHostConfigProvider } from './extHostConfiguration';
|
||||
import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
import { convertToVSCPaths, convertToDAPaths, isDebuggerMainContribution } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
@@ -128,8 +128,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
const debuggers = <IDebuggerContribution[]>ed.contributes['debuggers'];
|
||||
if (debuggers && debuggers.length > 0) {
|
||||
for (const dbg of debuggers) {
|
||||
// only debugger contributions with a label, program, or runtime attribute are considered a "defining" debugger contribution
|
||||
if (dbg.type && (dbg.label || dbg.program || dbg.runtime)) {
|
||||
if (isDebuggerMainContribution(dbg)) {
|
||||
debugTypes.push(dbg.type);
|
||||
if (dbg.adapterExecutableCommand) {
|
||||
this._aexCommands.set(dbg.type, dbg.adapterExecutableCommand);
|
||||
@@ -360,12 +359,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
}
|
||||
|
||||
public async $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): Promise<IConfig> {
|
||||
const configProvider = await this._configurationService.getConfigProvider();
|
||||
const [workspaceProvider, configProvider] = await Promise.all([this._workspaceService.getWorkspaceProvider(), this._configurationService.getConfigProvider()]);
|
||||
if (!this._variableResolver) {
|
||||
this._variableResolver = new ExtHostVariableResolverService(this._workspaceService, this._editorsService, configProvider);
|
||||
this._variableResolver = new ExtHostVariableResolverService(workspaceProvider, this._editorsService, configProvider);
|
||||
}
|
||||
let ws: IWorkspaceFolder;
|
||||
const folder = this.getFolder(folderUri);
|
||||
const folder = this.getFolder(folderUri, workspaceProvider);
|
||||
if (folder) {
|
||||
ws = {
|
||||
uri: folder.uri,
|
||||
@@ -379,10 +378,11 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
return this._variableResolver.resolveAny(ws, config);
|
||||
}
|
||||
|
||||
public $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise<void> {
|
||||
public async $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const mythis = this;
|
||||
|
||||
const session = this.getSession(sessionDto);
|
||||
const session = this.getSession(sessionDto, workspaceProvider);
|
||||
return this.getAdapterDescriptor(this.getAdapterFactoryByType(session.type), session).then(x => {
|
||||
|
||||
const adapter = this.convertToDto(x);
|
||||
@@ -546,7 +546,8 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
this.fireBreakpointChanges(a, r, c);
|
||||
}
|
||||
|
||||
public $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<vscode.DebugConfiguration[]> {
|
||||
public async $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<vscode.DebugConfiguration[]> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let provider = this.getConfigProviderByHandle(configProviderHandle);
|
||||
if (!provider) {
|
||||
return Promise.reject(new Error('no handler found'));
|
||||
@@ -554,10 +555,11 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
if (!provider.provideDebugConfigurations) {
|
||||
return Promise.reject(new Error('handler has no method provideDebugConfigurations'));
|
||||
}
|
||||
return asPromise(() => provider.provideDebugConfigurations(this.getFolder(folderUri), CancellationToken.None));
|
||||
return asPromise(() => provider.provideDebugConfigurations(this.getFolder(folderUri, workspaceProvider), CancellationToken.None));
|
||||
}
|
||||
|
||||
public $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise<vscode.DebugConfiguration> {
|
||||
public async $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise<vscode.DebugConfiguration> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let provider = this.getConfigProviderByHandle(configProviderHandle);
|
||||
if (!provider) {
|
||||
return Promise.reject(new Error('no handler found'));
|
||||
@@ -565,11 +567,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
if (!provider.resolveDebugConfiguration) {
|
||||
return Promise.reject(new Error('handler has no method resolveDebugConfiguration'));
|
||||
}
|
||||
return asPromise(() => provider.resolveDebugConfiguration(this.getFolder(folderUri), debugConfiguration, CancellationToken.None));
|
||||
return asPromise(() => provider.resolveDebugConfiguration(this.getFolder(folderUri, workspaceProvider), debugConfiguration, CancellationToken.None));
|
||||
}
|
||||
|
||||
// TODO@AW legacy
|
||||
public $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<IAdapterDescriptor> {
|
||||
public async $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<IAdapterDescriptor> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let provider = this.getConfigProviderByHandle(configProviderHandle);
|
||||
if (!provider) {
|
||||
return Promise.reject(new Error('no handler found'));
|
||||
@@ -577,41 +580,42 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
if (!provider.debugAdapterExecutable) {
|
||||
return Promise.reject(new Error('handler has no method debugAdapterExecutable'));
|
||||
}
|
||||
return asPromise(() => provider.debugAdapterExecutable(this.getFolder(folderUri), CancellationToken.None)).then(x => this.convertToDto(x));
|
||||
return asPromise(() => provider.debugAdapterExecutable(this.getFolder(folderUri, workspaceProvider), CancellationToken.None)).then(x => this.convertToDto(x));
|
||||
}
|
||||
|
||||
public $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise<IAdapterDescriptor> {
|
||||
public async $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise<IAdapterDescriptor> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let adapterProvider = this.getAdapterProviderByHandle(adapterProviderHandle);
|
||||
if (!adapterProvider) {
|
||||
return Promise.reject(new Error('no handler found'));
|
||||
}
|
||||
return this.getAdapterDescriptor(adapterProvider, this.getSession(sessionDto)).then(x => this.convertToDto(x));
|
||||
return this.getAdapterDescriptor(adapterProvider, this.getSession(sessionDto, workspaceProvider)).then(x => this.convertToDto(x));
|
||||
}
|
||||
|
||||
public $acceptDebugSessionStarted(sessionDto: IDebugSessionDto): void {
|
||||
|
||||
this._onDidStartDebugSession.fire(this.getSession(sessionDto));
|
||||
public async $acceptDebugSessionStarted(sessionDto: IDebugSessionDto): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
this._onDidStartDebugSession.fire(this.getSession(sessionDto, workspaceProvider));
|
||||
}
|
||||
|
||||
public $acceptDebugSessionTerminated(sessionDto: IDebugSessionDto): void {
|
||||
|
||||
const session = this.getSession(sessionDto);
|
||||
public async $acceptDebugSessionTerminated(sessionDto: IDebugSessionDto): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const session = this.getSession(sessionDto, workspaceProvider);
|
||||
if (session) {
|
||||
this._onDidTerminateDebugSession.fire(session);
|
||||
this._debugSessions.delete(session.id);
|
||||
}
|
||||
}
|
||||
|
||||
public $acceptDebugSessionActiveChanged(sessionDto: IDebugSessionDto): void {
|
||||
|
||||
this._activeDebugSession = sessionDto ? this.getSession(sessionDto) : undefined;
|
||||
public async $acceptDebugSessionActiveChanged(sessionDto: IDebugSessionDto | undefined): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
this._activeDebugSession = sessionDto ? this.getSession(sessionDto, workspaceProvider) : undefined;
|
||||
this._onDidChangeActiveDebugSession.fire(this._activeDebugSession);
|
||||
}
|
||||
|
||||
public $acceptDebugSessionCustomEvent(sessionDto: IDebugSessionDto, event: any): void {
|
||||
|
||||
public async $acceptDebugSessionCustomEvent(sessionDto: IDebugSessionDto, event: any): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const ee: vscode.DebugSessionCustomEvent = {
|
||||
session: this.getSession(sessionDto),
|
||||
session: this.getSession(sessionDto, workspaceProvider),
|
||||
event: event.event,
|
||||
body: event.body
|
||||
};
|
||||
@@ -776,12 +780,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
}
|
||||
}
|
||||
|
||||
private getSession(dto: IDebugSessionDto): ExtHostDebugSession {
|
||||
private getSession(dto: IDebugSessionDto, workspaceProvider: ExtHostWorkspaceProvider): ExtHostDebugSession {
|
||||
if (dto) {
|
||||
if (typeof dto === 'string') {
|
||||
return this._debugSessions.get(dto);
|
||||
} else {
|
||||
const debugSession = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, this.getFolder(dto.folderUri), dto.configuration);
|
||||
const debugSession = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, this.getFolder(dto.folderUri, workspaceProvider), dto.configuration);
|
||||
this._debugSessions.set(debugSession.id, debugSession);
|
||||
return debugSession;
|
||||
}
|
||||
@@ -789,10 +793,10 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getFolder(_folderUri: UriComponents | undefined): vscode.WorkspaceFolder | undefined {
|
||||
private getFolder(_folderUri: UriComponents | undefined, workspaceProvider: ExtHostWorkspaceProvider): vscode.WorkspaceFolder | undefined {
|
||||
if (_folderUri) {
|
||||
const folderURI = URI.revive(_folderUri);
|
||||
return this._workspaceService.resolveWorkspaceFolder(folderURI);
|
||||
return workspaceProvider.resolveWorkspaceFolder(folderURI);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -853,7 +857,7 @@ export class ExtHostDebugConsole implements vscode.DebugConsole {
|
||||
|
||||
export class ExtHostVariableResolverService extends AbstractVariableResolverService {
|
||||
|
||||
constructor(workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) {
|
||||
constructor(workspaceService: ExtHostWorkspaceProvider, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) {
|
||||
super({
|
||||
getFolderUri: (folderName: string): URI => {
|
||||
const folders = workspaceService.getWorkspaceFolders();
|
||||
|
||||
@@ -46,16 +46,20 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
|
||||
const result: DecorationReply = Object.create(null);
|
||||
return Promise.all(requests.map(request => {
|
||||
const { handle, uri, id } = request;
|
||||
if (!this._provider.has(handle)) {
|
||||
const entry = this._provider.get(handle);
|
||||
if (!entry) {
|
||||
// might have been unregistered in the meantime
|
||||
return undefined;
|
||||
}
|
||||
const { provider, extensionId } = this._provider.get(handle);
|
||||
const { provider, extensionId } = entry;
|
||||
return Promise.resolve(provider.provideDecoration(URI.revive(uri), token)).then(data => {
|
||||
if (data && data.letter && data.letter.length !== 1) {
|
||||
console.warn(`INVALID decoration from extension '${extensionId.value}'. The 'letter' must be set and be one character, not '${data.letter}'.`);
|
||||
}
|
||||
result[id] = data && <DecorationData>[data.priority, data.bubble, data.title, data.letter, data.color, data.source];
|
||||
if (data) {
|
||||
result[id] = <DecorationData>[data.priority, data.bubble, data.title, data.letter, data.color, data.source];
|
||||
|
||||
}
|
||||
}, err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
// the actual implementation for #set
|
||||
|
||||
this._checkDisposed();
|
||||
let toSync: vscode.Uri[];
|
||||
let toSync: vscode.Uri[] = [];
|
||||
let hasChanged = true;
|
||||
|
||||
if (first instanceof URI) {
|
||||
@@ -81,7 +81,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
||||
} else if (Array.isArray(first)) {
|
||||
// update many rows
|
||||
toSync = [];
|
||||
let lastUri: vscode.Uri;
|
||||
let lastUri: vscode.Uri | undefined;
|
||||
|
||||
// ensure stable-sort
|
||||
mergeSort(first, DiagnosticCollection._compareIndexedTuplesByUri);
|
||||
@@ -255,7 +255,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadDiagnostics);
|
||||
}
|
||||
|
||||
createDiagnosticCollection(name: string): vscode.DiagnosticCollection {
|
||||
createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
|
||||
let { _collections, _proxy, _onDidChangeDiagnostics } = this;
|
||||
let owner: string;
|
||||
if (!name) {
|
||||
@@ -272,7 +272,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
|
||||
const result = new class extends DiagnosticCollection {
|
||||
constructor() {
|
||||
super(name, owner, ExtHostDiagnostics._maxDiagnosticsPerFile, _proxy, _onDidChangeDiagnostics);
|
||||
super(name!, owner, ExtHostDiagnostics._maxDiagnosticsPerFile, _proxy, _onDidChangeDiagnostics);
|
||||
_collections.set(owner, this);
|
||||
}
|
||||
dispose() {
|
||||
@@ -286,6 +286,7 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape {
|
||||
|
||||
getDiagnostics(resource: vscode.Uri): vscode.Diagnostic[];
|
||||
getDiagnostics(): [vscode.Uri, vscode.Diagnostic[]][];
|
||||
getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][];
|
||||
getDiagnostics(resource?: vscode.Uri): vscode.Diagnostic[] | [vscode.Uri, vscode.Diagnostic[]][] {
|
||||
if (resource) {
|
||||
return this._getDiagnostics(resource);
|
||||
|
||||
@@ -15,15 +15,15 @@ export class ExtHostDialogs {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadDialogs);
|
||||
}
|
||||
|
||||
showOpenDialog(options: vscode.OpenDialogOptions): Promise<URI[]> {
|
||||
showOpenDialog(options: vscode.OpenDialogOptions): Promise<URI[] | undefined> {
|
||||
return this._proxy.$showOpenDialog(options).then(filepaths => {
|
||||
return filepaths && filepaths.map(URI.revive);
|
||||
return filepaths ? filepaths.map(URI.revive) : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
showSaveDialog(options: vscode.SaveDialogOptions): Promise<URI> {
|
||||
showSaveDialog(options: vscode.SaveDialogOptions): Promise<URI | undefined> {
|
||||
return this._proxy.$showSaveDialog(options).then(filepath => {
|
||||
return filepath && URI.revive(filepath);
|
||||
return filepath ? URI.revive(filepath) : undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
|
||||
this._documentContentProviders.set(handle, provider);
|
||||
this._proxy.$registerTextContentProvider(handle, scheme);
|
||||
|
||||
let subscription: IDisposable;
|
||||
let subscription: IDisposable | undefined;
|
||||
if (typeof provider.onDidChange === 'function') {
|
||||
subscription = provider.onDidChange(uri => {
|
||||
if (uri.scheme !== scheme) {
|
||||
@@ -54,6 +54,9 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
|
||||
}
|
||||
if (this._documentsAndEditors.getDocument(uri.toString())) {
|
||||
this.$provideTextDocumentContent(handle, uri).then(value => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const document = this._documentsAndEditors.getDocument(uri.toString());
|
||||
if (!document) {
|
||||
@@ -84,7 +87,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro
|
||||
});
|
||||
}
|
||||
|
||||
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string> {
|
||||
$provideTextDocumentContent(handle: number, uri: UriComponents): Promise<string | null | undefined> {
|
||||
const provider = this._documentContentProviders.get(handle);
|
||||
if (!provider) {
|
||||
return Promise.reject(new Error(`unsupported uri-scheme: ${uri.scheme}`));
|
||||
|
||||
@@ -14,10 +14,10 @@ import { EndOfLine, Position, Range } from 'vs/workbench/api/node/extHostTypes';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
const _modeId2WordDefinition = new Map<string, RegExp>();
|
||||
export function setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void {
|
||||
export function setWordDefinitionFor(modeId: string, wordDefinition: RegExp | undefined): void {
|
||||
_modeId2WordDefinition.set(modeId, wordDefinition);
|
||||
}
|
||||
export function getWordDefinitionFor(modeId: string): RegExp {
|
||||
export function getWordDefinitionFor(modeId: string): RegExp | undefined {
|
||||
return _modeId2WordDefinition.get(modeId);
|
||||
}
|
||||
|
||||
@@ -131,14 +131,14 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
|
||||
private _lineAt(lineOrPosition: number | vscode.Position): vscode.TextLine {
|
||||
|
||||
let line: number;
|
||||
let line: number | undefined;
|
||||
if (lineOrPosition instanceof Position) {
|
||||
line = lineOrPosition.line;
|
||||
} else if (typeof lineOrPosition === 'number') {
|
||||
line = lineOrPosition;
|
||||
}
|
||||
|
||||
if (line < 0 || line >= this._lines.length) {
|
||||
if (typeof line !== 'number' || line < 0 || line >= this._lines.length) {
|
||||
throw new Error('Illegal value for `line`');
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
if (!result || result.lineNumber !== line || result.text !== this._lines[line]) {
|
||||
|
||||
const text = this._lines[line];
|
||||
const firstNonWhitespaceCharacterIndex = /^(\s*)/.exec(text)[1].length;
|
||||
const firstNonWhitespaceCharacterIndex = /^(\s*)/.exec(text)![1].length;
|
||||
const range = new Range(line, 0, line, text.length);
|
||||
const rangeIncludingLineBreak = line < this._lines.length - 1
|
||||
? new Range(line, 0, line + 1, 0)
|
||||
@@ -170,7 +170,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
private _offsetAt(position: vscode.Position): number {
|
||||
position = this._validatePosition(position);
|
||||
this._ensureLineStarts();
|
||||
return this._lineStarts.getAccumulatedValue(position.line - 1) + position.character;
|
||||
return this._lineStarts!.getAccumulatedValue(position.line - 1) + position.character;
|
||||
}
|
||||
|
||||
private _positionAt(offset: number): vscode.Position {
|
||||
@@ -178,7 +178,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
offset = Math.max(0, offset);
|
||||
|
||||
this._ensureLineStarts();
|
||||
let out = this._lineStarts.getIndexOf(offset);
|
||||
let out = this._lineStarts!.getIndexOf(offset);
|
||||
|
||||
let lineLength = this._lines[out.index].length;
|
||||
|
||||
@@ -238,7 +238,7 @@ export class ExtHostDocumentData extends MirrorTextModel {
|
||||
return new Position(line, character);
|
||||
}
|
||||
|
||||
private _getWordRangeAtPosition(_position: vscode.Position, regexp?: RegExp): vscode.Range {
|
||||
private _getWordRangeAtPosition(_position: vscode.Position, regexp?: RegExp): vscode.Range | undefined {
|
||||
let position = this._validatePosition(_position);
|
||||
|
||||
if (!regexp) {
|
||||
|
||||
@@ -72,7 +72,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
|
||||
private _deliverEventAsyncAndBlameBadListeners([listener, thisArg, extension]: Listener, stubEvent: vscode.TextDocumentWillSaveEvent): Promise<any> {
|
||||
const errors = this._badListeners.get(listener);
|
||||
if (errors > this._thresholds.errors) {
|
||||
if (typeof errors === 'number' && errors > this._thresholds.errors) {
|
||||
// bad listener - ignore
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
|
||||
const errors = this._badListeners.get(listener);
|
||||
this._badListeners.set(listener, !errors ? 1 : errors + 1);
|
||||
|
||||
if (errors > this._thresholds.errors) {
|
||||
if (typeof errors === 'number' && errors > this._thresholds.errors) {
|
||||
this._logService.info(`onWillSaveTextDocument-listener from extension '${extension.identifier.value}' will now be IGNORED because of timeouts and/or errors`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
return this._documentsAndEditors.allDocuments();
|
||||
}
|
||||
|
||||
public getDocumentData(resource: vscode.Uri): ExtHostDocumentData {
|
||||
public getDocumentData(resource: vscode.Uri): ExtHostDocumentData | undefined {
|
||||
if (!resource) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -67,6 +67,14 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getDocument(resource: vscode.Uri): vscode.TextDocument {
|
||||
const data = this.getDocumentData(resource);
|
||||
if (!data || !data.document) {
|
||||
throw new Error('Unable to retrieve document from URI');
|
||||
}
|
||||
return data.document;
|
||||
}
|
||||
|
||||
public ensureDocumentData(uri: URI): Promise<ExtHostDocumentData> {
|
||||
|
||||
let cached = this._documentsAndEditors.getDocument(uri.toString());
|
||||
@@ -143,7 +151,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
});
|
||||
}
|
||||
|
||||
public setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void {
|
||||
public setWordDefinitionFor(modeId: string, wordDefinition: RegExp | undefined): void {
|
||||
setWordDefinitionFor(modeId, wordDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
const id = uri.toString();
|
||||
const data = this._documents.get(id);
|
||||
this._documents.delete(id);
|
||||
removedDocuments.push(data);
|
||||
if (data) {
|
||||
removedDocuments.push(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +81,9 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
for (const id of delta.removedEditors) {
|
||||
const editor = this._editors.get(id);
|
||||
this._editors.delete(id);
|
||||
removedEditors.push(editor);
|
||||
if (editor) {
|
||||
removedEditors.push(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +101,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
data.selections.map(typeConverters.Selection.to),
|
||||
data.options,
|
||||
data.visibleRanges.map(typeConverters.Range.to),
|
||||
typeConverters.ViewColumn.to(data.editorPosition)
|
||||
typeof data.editorPosition === 'number' ? typeConverters.ViewColumn.to(data.editorPosition) : undefined
|
||||
);
|
||||
this._editors.set(data.id, editor);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
@@ -161,6 +160,12 @@ export class EmptyExtension extends ActivatedExtension {
|
||||
}
|
||||
}
|
||||
|
||||
export class HostExtension extends ActivatedExtension {
|
||||
constructor() {
|
||||
super(false, null, ExtensionActivationTimes.NONE, { activate: undefined, deactivate: undefined }, undefined, []);
|
||||
}
|
||||
}
|
||||
|
||||
export class FailedExtension extends ActivatedExtension {
|
||||
constructor(activationError: Error) {
|
||||
super(true, activationError, ExtensionActivationTimes.NONE, { activate: undefined, deactivate: undefined }, undefined, []);
|
||||
@@ -170,7 +175,7 @@ export class FailedExtension extends ActivatedExtension {
|
||||
export interface IExtensionsActivatorHost {
|
||||
showMessage(severity: Severity, message: string): void;
|
||||
|
||||
actualActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension>;
|
||||
actualActivateExtension(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<ActivatedExtension>;
|
||||
}
|
||||
|
||||
export class ExtensionActivatedByEvent {
|
||||
@@ -192,6 +197,7 @@ export class ExtensionsActivator {
|
||||
|
||||
private readonly _registry: ExtensionDescriptionRegistry;
|
||||
private readonly _resolvedExtensionsSet: Set<string>;
|
||||
private readonly _hostExtensionsMap: Map<string, ExtensionIdentifier>;
|
||||
private readonly _host: IExtensionsActivatorHost;
|
||||
private readonly _activatingExtensions: Map<string, Promise<void>>;
|
||||
private readonly _activatedExtensions: Map<string, ActivatedExtension>;
|
||||
@@ -200,10 +206,12 @@ export class ExtensionsActivator {
|
||||
*/
|
||||
private readonly _alreadyActivatedEvents: { [activationEvent: string]: boolean; };
|
||||
|
||||
constructor(registry: ExtensionDescriptionRegistry, resolvedExtensions: ExtensionIdentifier[], host: IExtensionsActivatorHost) {
|
||||
constructor(registry: ExtensionDescriptionRegistry, resolvedExtensions: ExtensionIdentifier[], hostExtensions: ExtensionIdentifier[], host: IExtensionsActivatorHost) {
|
||||
this._registry = registry;
|
||||
this._resolvedExtensionsSet = new Set<string>();
|
||||
resolvedExtensions.forEach((extensionId) => this._resolvedExtensionsSet.add(ExtensionIdentifier.toKey(extensionId)));
|
||||
this._hostExtensionsMap = new Map<string, ExtensionIdentifier>();
|
||||
hostExtensions.forEach((extensionId) => this._hostExtensionsMap.set(ExtensionIdentifier.toKey(extensionId), extensionId));
|
||||
this._host = host;
|
||||
this._activatingExtensions = new Map<string, Promise<void>>();
|
||||
this._activatedExtensions = new Map<string, ActivatedExtension>();
|
||||
@@ -231,7 +239,7 @@ export class ExtensionsActivator {
|
||||
return NO_OP_VOID_PROMISE;
|
||||
}
|
||||
let activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent);
|
||||
return this._activateExtensions(activateExtensions, reason, 0).then(() => {
|
||||
return this._activateExtensions(activateExtensions.map(e => e.identifier), reason).then(() => {
|
||||
this._alreadyActivatedEvents[activationEvent] = true;
|
||||
});
|
||||
}
|
||||
@@ -242,14 +250,20 @@ export class ExtensionsActivator {
|
||||
throw new Error('Extension `' + extensionId + '` is not known');
|
||||
}
|
||||
|
||||
return this._activateExtensions([desc], reason, 0);
|
||||
return this._activateExtensions([desc.identifier], reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle semantics related to dependencies for `currentExtension`.
|
||||
* semantics: `redExtensions` must wait for `greenExtensions`.
|
||||
*/
|
||||
private _handleActivateRequest(currentExtension: IExtensionDescription, greenExtensions: { [id: string]: IExtensionDescription; }, redExtensions: IExtensionDescription[]): void {
|
||||
private _handleActivateRequest(currentExtensionId: ExtensionIdentifier, greenExtensions: { [id: string]: ExtensionIdentifier; }, redExtensions: ExtensionIdentifier[]): void {
|
||||
if (this._hostExtensionsMap.has(ExtensionIdentifier.toKey(currentExtensionId))) {
|
||||
greenExtensions[ExtensionIdentifier.toKey(currentExtensionId)] = currentExtensionId;
|
||||
return;
|
||||
}
|
||||
|
||||
const currentExtension = this._registry.getExtensionDescription(currentExtensionId)!;
|
||||
let depIds = (typeof currentExtension.extensionDependencies === 'undefined' ? [] : currentExtension.extensionDependencies);
|
||||
let currentExtensionGetsGreenLight = true;
|
||||
|
||||
@@ -261,72 +275,71 @@ export class ExtensionsActivator {
|
||||
continue;
|
||||
}
|
||||
|
||||
const depDesc = this._registry.getExtensionDescription(depId);
|
||||
const dep = this._activatedExtensions.get(ExtensionIdentifier.toKey(depId));
|
||||
if (dep && !dep.activationFailed) {
|
||||
// the dependency is already activated OK
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!depDesc) {
|
||||
// Error condition 1: unknown dependency
|
||||
this._host.showMessage(Severity.Error, nls.localize('unknownDep', "Cannot activate extension '{0}' because it depends on extension '{1}', which is not installed or disabled. Please install or enable '{1}' and reload the window.", currentExtension.displayName || currentExtension.identifier.value, depId));
|
||||
const error = new Error(`Unknown dependency '${depId}'`);
|
||||
if (dep && dep.activationFailed) {
|
||||
// Error condition 2: a dependency has already failed activation
|
||||
this._host.showMessage(Severity.Error, nls.localize('failedDep1', "Cannot activate extension '{0}' because it depends on extension '{1}', which failed to activate.", currentExtension.displayName || currentExtension.identifier.value, depId));
|
||||
const error = new Error(`Dependency ${depId} failed to activate`);
|
||||
(<any>error).detail = dep.activationFailedError;
|
||||
this._activatedExtensions.set(ExtensionIdentifier.toKey(currentExtension.identifier), new FailedExtension(error));
|
||||
return;
|
||||
}
|
||||
|
||||
const dep = this._activatedExtensions.get(ExtensionIdentifier.toKey(depId));
|
||||
if (dep) {
|
||||
if (dep.activationFailed) {
|
||||
// Error condition 2: a dependency has already failed activation
|
||||
this._host.showMessage(Severity.Error, nls.localize('failedDep1', "Cannot activate extension '{0}' because it depends on extension '{1}', which failed to activate.", currentExtension.displayName || currentExtension.identifier.value, depId));
|
||||
const error = new Error(`Dependency ${depId} failed to activate`);
|
||||
(<any>error).detail = dep.activationFailedError;
|
||||
this._activatedExtensions.set(ExtensionIdentifier.toKey(currentExtension.identifier), new FailedExtension(error));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (this._hostExtensionsMap.has(ExtensionIdentifier.toKey(depId))) {
|
||||
// must first wait for the dependency to activate
|
||||
currentExtensionGetsGreenLight = false;
|
||||
greenExtensions[ExtensionIdentifier.toKey(depId)] = depDesc;
|
||||
greenExtensions[ExtensionIdentifier.toKey(depId)] = this._hostExtensionsMap.get(ExtensionIdentifier.toKey(depId))!;
|
||||
continue;
|
||||
}
|
||||
|
||||
const depDesc = this._registry.getExtensionDescription(depId);
|
||||
if (depDesc) {
|
||||
// must first wait for the dependency to activate
|
||||
currentExtensionGetsGreenLight = false;
|
||||
greenExtensions[ExtensionIdentifier.toKey(depId)] = depDesc.identifier;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Error condition 1: unknown dependency
|
||||
this._host.showMessage(Severity.Error, nls.localize('unknownDep', "Cannot activate extension '{0}' because it depends on extension '{1}', which is not installed or disabled. Please install or enable '{1}' and reload the window.", currentExtension.displayName || currentExtension.identifier.value, depId));
|
||||
const error = new Error(`Unknown dependency '${depId}'`);
|
||||
this._activatedExtensions.set(ExtensionIdentifier.toKey(currentExtension.identifier), new FailedExtension(error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentExtensionGetsGreenLight) {
|
||||
greenExtensions[ExtensionIdentifier.toKey(currentExtension.identifier)] = currentExtension;
|
||||
greenExtensions[ExtensionIdentifier.toKey(currentExtension.identifier)] = currentExtensionId;
|
||||
} else {
|
||||
redExtensions.push(currentExtension);
|
||||
redExtensions.push(currentExtensionId);
|
||||
}
|
||||
}
|
||||
|
||||
private _activateExtensions(extensionDescriptions: IExtensionDescription[], reason: ExtensionActivationReason, recursionLevel: number): Promise<void> {
|
||||
// console.log(recursionLevel, '_activateExtensions: ', extensionDescriptions.map(p => p.id));
|
||||
if (extensionDescriptions.length === 0) {
|
||||
private _activateExtensions(extensionIds: ExtensionIdentifier[], reason: ExtensionActivationReason): Promise<void> {
|
||||
// console.log('_activateExtensions: ', extensionIds.map(p => p.value));
|
||||
if (extensionIds.length === 0) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
extensionDescriptions = extensionDescriptions.filter((p) => !this._activatedExtensions.has(ExtensionIdentifier.toKey(p.identifier)));
|
||||
if (extensionDescriptions.length === 0) {
|
||||
extensionIds = extensionIds.filter((p) => !this._activatedExtensions.has(ExtensionIdentifier.toKey(p)));
|
||||
if (extensionIds.length === 0) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
if (recursionLevel > 10) {
|
||||
// More than 10 dependencies deep => most likely a dependency loop
|
||||
for (let i = 0, len = extensionDescriptions.length; i < len; i++) {
|
||||
// Error condition 3: dependency loop
|
||||
this._host.showMessage(Severity.Error, nls.localize('failedDep2', "Extension '{0}' failed to activate. Reason: more than 10 levels of dependencies (most likely a dependency loop).", extensionDescriptions[i].identifier.value));
|
||||
const error = new Error('More than 10 levels of dependencies (most likely a dependency loop)');
|
||||
this._activatedExtensions.set(ExtensionIdentifier.toKey(extensionDescriptions[i].identifier), new FailedExtension(error));
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
let greenMap: { [id: string]: ExtensionIdentifier; } = Object.create(null),
|
||||
red: ExtensionIdentifier[] = [];
|
||||
|
||||
let greenMap: { [id: string]: IExtensionDescription; } = Object.create(null),
|
||||
red: IExtensionDescription[] = [];
|
||||
|
||||
for (let i = 0, len = extensionDescriptions.length; i < len; i++) {
|
||||
this._handleActivateRequest(extensionDescriptions[i], greenMap, red);
|
||||
for (let i = 0, len = extensionIds.length; i < len; i++) {
|
||||
this._handleActivateRequest(extensionIds[i], greenMap, red);
|
||||
}
|
||||
|
||||
// Make sure no red is also green
|
||||
for (let i = 0, len = red.length; i < len; i++) {
|
||||
const redExtensionKey = ExtensionIdentifier.toKey(red[i].identifier);
|
||||
const redExtensionKey = ExtensionIdentifier.toKey(red[i]);
|
||||
if (greenMap[redExtensionKey]) {
|
||||
delete greenMap[redExtensionKey];
|
||||
}
|
||||
@@ -342,13 +355,13 @@ export class ExtensionsActivator {
|
||||
return Promise.all(green.map((p) => this._activateExtension(p, reason))).then(_ => undefined);
|
||||
}
|
||||
|
||||
return this._activateExtensions(green, reason, recursionLevel + 1).then(_ => {
|
||||
return this._activateExtensions(red, reason, recursionLevel + 1);
|
||||
return this._activateExtensions(green, reason).then(_ => {
|
||||
return this._activateExtensions(red, reason);
|
||||
});
|
||||
}
|
||||
|
||||
private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<void> {
|
||||
const extensionKey = ExtensionIdentifier.toKey(extensionDescription.identifier);
|
||||
private _activateExtension(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<void> {
|
||||
const extensionKey = ExtensionIdentifier.toKey(extensionId);
|
||||
|
||||
if (this._activatedExtensions.has(extensionKey)) {
|
||||
return Promise.resolve(undefined);
|
||||
@@ -359,9 +372,9 @@ export class ExtensionsActivator {
|
||||
return currentlyActivatingExtension;
|
||||
}
|
||||
|
||||
const newlyActivatingExtension = this._host.actualActivateExtension(extensionDescription, reason).then(undefined, (err) => {
|
||||
this._host.showMessage(Severity.Error, nls.localize('activationError', "Activating extension '{0}' failed: {1}.", extensionDescription.identifier.value, err.message));
|
||||
console.error('Activating extension `' + extensionDescription.identifier.value + '` failed: ', err.message);
|
||||
const newlyActivatingExtension = this._host.actualActivateExtension(extensionId, reason).then(undefined, (err) => {
|
||||
this._host.showMessage(Severity.Error, nls.localize('activationError', "Activating extension '{0}' failed: {1}.", extensionId.value, err.message));
|
||||
console.error('Activating extension `' + extensionId.value + '` failed: ', err.message);
|
||||
console.log('Here is the error stack: ', err.stack);
|
||||
// Treat the extension as being empty
|
||||
return new FailedExtension(err);
|
||||
|
||||
@@ -13,12 +13,12 @@ import { URI } from 'vs/base/common/uri';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { createApiFactory, initializeExtensionApi, IExtensionApiFactory } from 'vs/workbench/api/node/extHost.api.impl';
|
||||
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, IWorkspaceData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IStaticWorkspaceData } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionMemento, IExtensionModule } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionMemento, IExtensionModule, HostExtension } from 'vs/workbench/api/node/extHostExtensionActivator';
|
||||
import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
|
||||
import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry';
|
||||
import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver';
|
||||
@@ -26,6 +26,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
class ExtensionMemento implements IExtensionMemento {
|
||||
|
||||
@@ -80,13 +81,13 @@ class ExtensionMemento implements IExtensionMemento {
|
||||
|
||||
class ExtensionStoragePath {
|
||||
|
||||
private readonly _workspace: IWorkspaceData;
|
||||
private readonly _workspace?: IStaticWorkspaceData;
|
||||
private readonly _environment: IEnvironment;
|
||||
|
||||
private readonly _ready: Promise<string>;
|
||||
private _value: string;
|
||||
private readonly _ready: Promise<string | undefined>;
|
||||
private _value?: string;
|
||||
|
||||
constructor(workspace: IWorkspaceData, environment: IEnvironment) {
|
||||
constructor(workspace: IStaticWorkspaceData | undefined, environment: IEnvironment) {
|
||||
this._workspace = workspace;
|
||||
this._environment = environment;
|
||||
this._ready = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value);
|
||||
@@ -96,7 +97,7 @@ class ExtensionStoragePath {
|
||||
return this._ready;
|
||||
}
|
||||
|
||||
workspaceValue(extension: IExtensionDescription): string {
|
||||
workspaceValue(extension: IExtensionDescription): string | undefined {
|
||||
if (this._value) {
|
||||
return path.join(this._value, extension.identifier.value);
|
||||
}
|
||||
@@ -107,7 +108,7 @@ class ExtensionStoragePath {
|
||||
return path.join(this._environment.globalStorageHome.fsPath, extension.identifier.value.toLowerCase());
|
||||
}
|
||||
|
||||
private async _getOrCreateWorkspaceStoragePath(): Promise<string> {
|
||||
private async _getOrCreateWorkspaceStoragePath(): Promise<string | undefined> {
|
||||
if (!this._workspace) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
@@ -192,7 +193,11 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
this._registry = new ExtensionDescriptionRegistry(initData.extensions);
|
||||
this._storage = new ExtHostStorage(this._extHostContext);
|
||||
this._storagePath = new ExtensionStoragePath(initData.workspace, initData.environment);
|
||||
this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, {
|
||||
|
||||
const hostExtensions = new Set<string>();
|
||||
initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId)));
|
||||
|
||||
this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, initData.hostExtensions, {
|
||||
showMessage: (severity: Severity, message: string): void => {
|
||||
this._mainThreadExtensionsProxy.$localShowMessage(severity, message);
|
||||
|
||||
@@ -208,7 +213,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
},
|
||||
|
||||
actualActivateExtension: (extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> => {
|
||||
actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<ActivatedExtension> => {
|
||||
if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) {
|
||||
let 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);
|
||||
}
|
||||
});
|
||||
@@ -229,9 +240,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
private async _initialize(): Promise<void> {
|
||||
try {
|
||||
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
||||
await initializeExtensionApi(this, this._extensionApiFactory, this._registry, configProvider);
|
||||
const workspaceProvider = await this._extHostWorkspace.getWorkspaceProvider();
|
||||
await initializeExtensionApi(this, this._extensionApiFactory, this._registry, workspaceProvider, configProvider);
|
||||
// Do this when extension service exists, but extensions are not being activated yet.
|
||||
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy);
|
||||
await connectProxyResolver(workspaceProvider, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy);
|
||||
this._barrier.open();
|
||||
} catch (err) {
|
||||
errors.onUnexpectedError(err);
|
||||
@@ -473,15 +485,15 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
// -- eager activation
|
||||
|
||||
// Handle "eager" activation extensions
|
||||
private _handleEagerExtensions(): Promise<void> {
|
||||
private _handleEagerExtensions(workspaceProvider: ExtHostWorkspaceProvider): Promise<void> {
|
||||
this._activateByEvent('*', true).then(undefined, (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
return this._handleWorkspaceContainsEagerExtensions(this._initData.workspace);
|
||||
return this._handleWorkspaceContainsEagerExtensions(workspaceProvider.workspace);
|
||||
}
|
||||
|
||||
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspaceData): Promise<void> {
|
||||
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace | undefined): Promise<void> {
|
||||
if (!workspace || workspace.folders.length === 0) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
@@ -493,7 +505,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
).then(() => { });
|
||||
}
|
||||
|
||||
private _handleWorkspaceContainsEagerExtension(workspace: IWorkspaceData, desc: IExtensionDescription): Promise<void> {
|
||||
private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise<void> {
|
||||
const activationEvents = desc.activationEvents;
|
||||
if (!activationEvents) {
|
||||
return Promise.resolve(undefined);
|
||||
@@ -523,7 +535,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
return Promise.all([fileNamePromise, globPatternPromise]).then(() => { });
|
||||
}
|
||||
|
||||
private async _activateIfFileName(workspace: IWorkspaceData, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
|
||||
private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
|
||||
|
||||
// find exact path
|
||||
for (const { uri } of workspace.folders) {
|
||||
@@ -555,7 +567,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
.then(undefined, err => console.error(err));
|
||||
}, ExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT);
|
||||
|
||||
let exists: boolean;
|
||||
let exists: boolean = false;
|
||||
try {
|
||||
exists = await searchP;
|
||||
} catch (err) {
|
||||
@@ -596,8 +608,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
}
|
||||
|
||||
// Require the test runner via node require from the provided path
|
||||
let testRunner: ITestRunner;
|
||||
let requireError: Error;
|
||||
let testRunner: ITestRunner | undefined;
|
||||
let requireError: Error | undefined;
|
||||
try {
|
||||
testRunner = <any>require.__$__nodeRequire(this._initData.environment.extensionTestsPath);
|
||||
} catch (error) {
|
||||
@@ -607,7 +619,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
// Execute the runner if it follows our spec
|
||||
if (testRunner && typeof testRunner.run === 'function') {
|
||||
return new Promise<void>((c, e) => {
|
||||
testRunner.run(this._initData.environment.extensionTestsPath, (error, failures) => {
|
||||
testRunner!.run(this._initData.environment.extensionTestsPath, (error, failures) => {
|
||||
if (error) {
|
||||
e(error.toString());
|
||||
} else {
|
||||
@@ -641,7 +653,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
this._started = true;
|
||||
|
||||
return this._barrier.wait()
|
||||
.then(() => this._handleEagerExtensions())
|
||||
.then(() => this._extHostWorkspace.getWorkspaceProvider())
|
||||
.then(workspaceProvider => this._handleEagerExtensions(workspaceProvider))
|
||||
.then(() => this._handleExtensionTests())
|
||||
.then(() => {
|
||||
this._extHostLogService.info(`eager extensions activated`);
|
||||
@@ -666,11 +679,14 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
);
|
||||
}
|
||||
|
||||
public $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<void> {
|
||||
return (
|
||||
this._barrier.wait()
|
||||
.then(_ => this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent)))
|
||||
);
|
||||
public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise<boolean> {
|
||||
await this._barrier.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> {
|
||||
|
||||
@@ -39,12 +39,12 @@ class DocumentSymbolAdapter {
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideDocumentSymbols(resource: URI, token: CancellationToken): Promise<modes.DocumentSymbol[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
provideDocumentSymbols(resource: URI, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
return asPromise(() => this._provider.provideDocumentSymbols(doc, token)).then(value => {
|
||||
if (isFalsyOrEmpty(value)) {
|
||||
return undefined;
|
||||
} else if (value[0] instanceof DocumentSymbol) {
|
||||
} else if (value![0] instanceof DocumentSymbol) {
|
||||
return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
|
||||
} else {
|
||||
return DocumentSymbolAdapter._asDocumentSymbolTree(<SymbolInformation[]>value);
|
||||
@@ -105,7 +105,7 @@ class CodeLensAdapter {
|
||||
) { }
|
||||
|
||||
provideCodeLenses(resource: URI, token: CancellationToken): Promise<CodeLensDto[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
|
||||
return asPromise(() => this._provider.provideCodeLenses(doc, token)).then(lenses => {
|
||||
let result: CodeLensDto[] = [];
|
||||
@@ -122,18 +122,18 @@ class CodeLensAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
resolveCodeLens(resource: URI, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto> {
|
||||
resolveCodeLens(resource: URI, symbol: CodeLensDto, token: CancellationToken): Promise<CodeLensDto | undefined> {
|
||||
|
||||
const lens = this._heapService.get<vscode.CodeLens>(ObjectIdentifier.of(symbol));
|
||||
if (!lens) {
|
||||
return undefined;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
let resolve: Promise<vscode.CodeLens>;
|
||||
let resolve: Promise<vscode.CodeLens | undefined | null>;
|
||||
if (typeof this._provider.resolveCodeLens !== 'function' || lens.isResolved) {
|
||||
resolve = Promise.resolve(lens);
|
||||
} else {
|
||||
resolve = asPromise(() => this._provider.resolveCodeLens(lens, token));
|
||||
resolve = asPromise(() => this._provider.resolveCodeLens!(lens, token));
|
||||
}
|
||||
|
||||
return resolve.then(newLens => {
|
||||
@@ -150,7 +150,7 @@ function convertToLocationLinks(value: vscode.Definition): modes.LocationLink[]
|
||||
} else if (value) {
|
||||
return [typeConvert.DefinitionLink.from(value)];
|
||||
}
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
|
||||
class DefinitionAdapter {
|
||||
@@ -161,7 +161,7 @@ class DefinitionAdapter {
|
||||
) { }
|
||||
|
||||
provideDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
return asPromise(() => this._provider.provideDefinition(doc, pos, token)).then(convertToLocationLinks);
|
||||
}
|
||||
@@ -175,7 +175,7 @@ class DeclarationAdapter {
|
||||
) { }
|
||||
|
||||
provideDeclaration(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
return asPromise(() => this._provider.provideDeclaration(doc, pos, token)).then(convertToLocationLinks);
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class ImplementationAdapter {
|
||||
) { }
|
||||
|
||||
provideImplementation(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
return asPromise(() => this._provider.provideImplementation(doc, pos, token)).then(convertToLocationLinks);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ class TypeDefinitionAdapter {
|
||||
) { }
|
||||
|
||||
provideTypeDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
return asPromise(() => this._provider.provideTypeDefinition(doc, pos, token)).then(convertToLocationLinks);
|
||||
}
|
||||
@@ -216,9 +216,9 @@ class HoverAdapter {
|
||||
private readonly _provider: vscode.HoverProvider,
|
||||
) { }
|
||||
|
||||
public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.Hover> {
|
||||
public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined> {
|
||||
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.provideHover(doc, pos, token)).then(value => {
|
||||
@@ -244,9 +244,9 @@ class DocumentHighlightAdapter {
|
||||
private readonly _provider: vscode.DocumentHighlightProvider
|
||||
) { }
|
||||
|
||||
provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[]> {
|
||||
provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined> {
|
||||
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.provideDocumentHighlights(doc, pos, token)).then(value => {
|
||||
@@ -265,8 +265,8 @@ class ReferenceAdapter {
|
||||
private readonly _provider: vscode.ReferenceProvider
|
||||
) { }
|
||||
|
||||
provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<modes.Location[]> {
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<modes.Location[] | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.provideReferences(doc, pos, context, token)).then(value => {
|
||||
@@ -294,9 +294,9 @@ class CodeActionAdapter {
|
||||
private readonly _extensionId: ExtensionIdentifier
|
||||
) { }
|
||||
|
||||
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[]> {
|
||||
provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[] | undefined> {
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const ran = Selection.isISelection(rangeOrSelection)
|
||||
? <vscode.Selection>typeConvert.Selection.to(rangeOrSelection)
|
||||
: <vscode.Range>typeConvert.Range.to(rangeOrSelection);
|
||||
@@ -317,7 +317,7 @@ class CodeActionAdapter {
|
||||
};
|
||||
|
||||
return asPromise(() => this._provider.provideCodeActions(doc, ran, codeActionContext, token)).then(commandsOrActions => {
|
||||
if (isFalsyOrEmpty(commandsOrActions)) {
|
||||
if (!isNonEmptyArray(commandsOrActions)) {
|
||||
return undefined;
|
||||
}
|
||||
const result: CustomCodeAction[] = [];
|
||||
@@ -369,9 +369,9 @@ class DocumentFormattingAdapter {
|
||||
private readonly _provider: vscode.DocumentFormattingEditProvider
|
||||
) { }
|
||||
|
||||
provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
|
||||
const { document } = this._documents.getDocumentData(resource);
|
||||
const document = this._documents.getDocument(resource);
|
||||
|
||||
return asPromise(() => this._provider.provideDocumentFormattingEdits(document, <any>options, token)).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
@@ -389,9 +389,9 @@ class RangeFormattingAdapter {
|
||||
private readonly _provider: vscode.DocumentRangeFormattingEditProvider
|
||||
) { }
|
||||
|
||||
provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
|
||||
const { document } = this._documents.getDocumentData(resource);
|
||||
const document = this._documents.getDocument(resource);
|
||||
const ran = typeConvert.Range.to(range);
|
||||
|
||||
return asPromise(() => this._provider.provideDocumentRangeFormattingEdits(document, ran, <any>options, token)).then(value => {
|
||||
@@ -412,9 +412,9 @@ class OnTypeFormattingAdapter {
|
||||
|
||||
autoFormatTriggerCharacters: string[] = []; // not here
|
||||
|
||||
provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
|
||||
const { document } = this._documents.getDocumentData(resource);
|
||||
const document = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.provideOnTypeFormattingEdits(document, pos, ch, <any>options, token)).then(value => {
|
||||
@@ -450,7 +450,7 @@ class NavigateTypeAdapter {
|
||||
continue;
|
||||
}
|
||||
const symbol = IdObject.mixin(typeConvert.WorkspaceSymbol.from(item));
|
||||
this._symbolCache[symbol._id] = item;
|
||||
this._symbolCache[symbol._id!] = item;
|
||||
result.symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
@@ -462,19 +462,19 @@ class NavigateTypeAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto> {
|
||||
resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined> {
|
||||
|
||||
if (typeof this._provider.resolveWorkspaceSymbol !== 'function') {
|
||||
return Promise.resolve(symbol);
|
||||
}
|
||||
|
||||
const item = this._symbolCache[symbol._id];
|
||||
const item = this._symbolCache[symbol._id!];
|
||||
if (item) {
|
||||
return asPromise(() => this._provider.resolveWorkspaceSymbol(item, token)).then(value => {
|
||||
return asPromise(() => this._provider.resolveWorkspaceSymbol!(item, token)).then(value => {
|
||||
return value && mixin(symbol, typeConvert.WorkspaceSymbol.from(value), true);
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
releaseWorkspaceSymbols(id: number): any {
|
||||
@@ -499,9 +499,9 @@ class RenameAdapter {
|
||||
private readonly _provider: vscode.RenameProvider
|
||||
) { }
|
||||
|
||||
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto> {
|
||||
provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined> {
|
||||
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.provideRenameEdits(doc, pos, newName, token)).then(value => {
|
||||
@@ -512,7 +512,7 @@ class RenameAdapter {
|
||||
}, err => {
|
||||
let rejectReason = RenameAdapter._asMessage(err);
|
||||
if (rejectReason) {
|
||||
return <WorkspaceEditDto>{ rejectReason, edits: undefined };
|
||||
return <WorkspaceEditDto>{ rejectReason, edits: undefined! };
|
||||
} else {
|
||||
// generic error
|
||||
return Promise.reject<WorkspaceEditDto>(err);
|
||||
@@ -520,17 +520,17 @@ class RenameAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation & modes.Rejection> {
|
||||
resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<(modes.RenameLocation & modes.Rejection) | undefined> {
|
||||
if (typeof this._provider.prepareRename !== 'function') {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
let doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
let pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise(() => this._provider.prepareRename(doc, pos, token)).then(rangeOrLocation => {
|
||||
|
||||
let range: vscode.Range;
|
||||
let range: vscode.Range | undefined;
|
||||
let text: string;
|
||||
if (Range.isRange(rangeOrLocation)) {
|
||||
range = rangeOrLocation;
|
||||
@@ -552,14 +552,14 @@ class RenameAdapter {
|
||||
}, err => {
|
||||
let rejectReason = RenameAdapter._asMessage(err);
|
||||
if (rejectReason) {
|
||||
return <modes.RenameLocation & modes.Rejection>{ rejectReason, range: undefined, text: undefined };
|
||||
return <modes.RenameLocation & modes.Rejection>{ rejectReason, range: undefined!, text: undefined! };
|
||||
} else {
|
||||
return Promise.reject<any>(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static _asMessage(err: any): string {
|
||||
private static _asMessage(err: any): string | undefined {
|
||||
if (typeof err === 'string') {
|
||||
return err;
|
||||
} else if (err instanceof Error && typeof err.message === 'string') {
|
||||
@@ -591,7 +591,7 @@ class SuggestAdapter {
|
||||
|
||||
provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise<SuggestResultDto> {
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
|
||||
return asPromise<vscode.CompletionItem[] | vscode.CompletionList>(
|
||||
@@ -643,18 +643,18 @@ class SuggestAdapter {
|
||||
}
|
||||
|
||||
const { _parentId, _id } = (<SuggestionDto>suggestion);
|
||||
const item = this._cache.has(_parentId) && this._cache.get(_parentId)[_id];
|
||||
const item = this._cache.has(_parentId) ? this._cache.get(_parentId)![_id] : undefined;
|
||||
if (!item) {
|
||||
return Promise.resolve(suggestion);
|
||||
}
|
||||
|
||||
return asPromise(() => this._provider.resolveCompletionItem(item, token)).then(resolvedItem => {
|
||||
return asPromise(() => this._provider.resolveCompletionItem!(item, token)).then(resolvedItem => {
|
||||
|
||||
if (!resolvedItem) {
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos)).with({ end: pos });
|
||||
const newSuggestion = this._convertCompletionItem(resolvedItem, pos, wordRangeBeforePos, _id, _parentId);
|
||||
@@ -670,7 +670,7 @@ class SuggestAdapter {
|
||||
this._cache.delete(id);
|
||||
}
|
||||
|
||||
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): SuggestionDto {
|
||||
private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, defaultRange: vscode.Range, _id: number, _parentId: number): SuggestionDto | undefined {
|
||||
if (typeof item.label !== 'string' || item.label.length === 0) {
|
||||
console.warn('INVALID text edit -> must have at least a label');
|
||||
return undefined;
|
||||
@@ -684,7 +684,7 @@ class SuggestAdapter {
|
||||
label: item.label,
|
||||
kind: typeConvert.CompletionItemKind.from(item.kind),
|
||||
detail: item.detail,
|
||||
documentation: typeConvert.MarkdownString.fromStrict(item.documentation),
|
||||
documentation: typeof item.documentation === 'undefined' ? undefined : typeConvert.MarkdownString.fromStrict(item.documentation),
|
||||
filterText: item.filterText,
|
||||
sortText: item.sortText,
|
||||
preselect: item.preselect,
|
||||
@@ -740,8 +740,8 @@ class SignatureHelpAdapter {
|
||||
private readonly _heap: ExtHostHeapService,
|
||||
) { }
|
||||
|
||||
provideSignatureHelp(resource: URI, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
provideSignatureHelp(resource: URI, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
const vscodeContext = this.reviveContext(context);
|
||||
|
||||
@@ -779,8 +779,8 @@ class LinkProviderAdapter {
|
||||
private readonly _provider: vscode.DocumentLinkProvider
|
||||
) { }
|
||||
|
||||
provideLinks(resource: URI, token: CancellationToken): Promise<LinkDto[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
provideLinks(resource: URI, token: CancellationToken): Promise<LinkDto[] | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
|
||||
return asPromise(() => this._provider.provideDocumentLinks(doc, token)).then(links => {
|
||||
if (!Array.isArray(links)) {
|
||||
@@ -796,18 +796,18 @@ class LinkProviderAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
resolveLink(link: LinkDto, token: CancellationToken): Promise<LinkDto> {
|
||||
resolveLink(link: LinkDto, token: CancellationToken): Promise<LinkDto | undefined> {
|
||||
if (typeof this._provider.resolveDocumentLink !== 'function') {
|
||||
return undefined;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
const id = ObjectIdentifier.of(link);
|
||||
const item = this._heapService.get<vscode.DocumentLink>(id);
|
||||
if (!item) {
|
||||
return undefined;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
return asPromise(() => this._provider.resolveDocumentLink(item, token)).then(value => {
|
||||
return asPromise(() => this._provider.resolveDocumentLink!(item, token)).then(value => {
|
||||
if (value) {
|
||||
return typeConvert.DocumentLink.from(value);
|
||||
}
|
||||
@@ -824,7 +824,7 @@ class ColorProviderAdapter {
|
||||
) { }
|
||||
|
||||
provideColors(resource: URI, token: CancellationToken): Promise<IRawColorInfo[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const doc = this._documents.getDocument(resource);
|
||||
return asPromise(() => this._provider.provideDocumentColors(doc, token)).then(colors => {
|
||||
if (!Array.isArray(colors)) {
|
||||
return [];
|
||||
@@ -841,11 +841,14 @@ class ColorProviderAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
provideColorPresentations(resource: URI, raw: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[]> {
|
||||
const document = this._documents.getDocumentData(resource).document;
|
||||
provideColorPresentations(resource: URI, raw: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[] | undefined> {
|
||||
const document = this._documents.getDocument(resource);
|
||||
const range = typeConvert.Range.to(raw.range);
|
||||
const color = typeConvert.Color.to(raw.color);
|
||||
return asPromise(() => this._provider.provideColorPresentations(color, { document, range }, token)).then(value => {
|
||||
if (!Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
return value.map(typeConvert.ColorPresentation.from);
|
||||
});
|
||||
}
|
||||
@@ -858,8 +861,8 @@ class FoldingProviderAdapter {
|
||||
private _provider: vscode.FoldingRangeProvider
|
||||
) { }
|
||||
|
||||
provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[]> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined> {
|
||||
const doc = this._documents.getDocument(resource);
|
||||
return asPromise(() => this._provider.provideFoldingRanges(doc, context, token)).then(ranges => {
|
||||
if (!Array.isArray(ranges)) {
|
||||
return undefined;
|
||||
@@ -876,23 +879,35 @@ class SelectionRangeAdapter {
|
||||
private readonly _provider: vscode.SelectionRangeProvider
|
||||
) { }
|
||||
|
||||
provideSelectionRanges(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.SelectionRange[]> {
|
||||
provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]> {
|
||||
const { document } = this._documents.getDocumentData(resource);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
return asPromise(() => this._provider.provideSelectionRanges(document, pos, token)).then(selectionRanges => {
|
||||
if (isFalsyOrEmpty(selectionRanges)) {
|
||||
return undefined;
|
||||
const positions = pos.map(typeConvert.Position.to);
|
||||
|
||||
return asPromise(() => this._provider.provideSelectionRanges(document, positions, token)).then(allProviderRanges => {
|
||||
if (isFalsyOrEmpty(allProviderRanges)) {
|
||||
return [];
|
||||
}
|
||||
let result: modes.SelectionRange[] = [];
|
||||
let last: vscode.Position | vscode.Range = pos;
|
||||
for (const sel of selectionRanges) {
|
||||
if (!sel.range.contains(last)) {
|
||||
throw new Error('INVALID selection range, must contain the previous range');
|
||||
if (allProviderRanges.length !== positions.length) {
|
||||
console.warn('BAD selection ranges, provider must return ranges for each position');
|
||||
return [];
|
||||
}
|
||||
|
||||
let allResults: modes.SelectionRange[][] = [];
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
const oneResult: modes.SelectionRange[] = [];
|
||||
allResults.push(oneResult);
|
||||
|
||||
const oneProviderRanges = allProviderRanges[i];
|
||||
let last: vscode.Position | vscode.Range = positions[i];
|
||||
for (const selectionRange of oneProviderRanges) {
|
||||
if (!selectionRange.range.contains(last)) {
|
||||
throw new Error('INVALID selection range, must contain the previous range');
|
||||
}
|
||||
oneResult.push(typeConvert.SelectionRange.from(selectionRange));
|
||||
last = selectionRange.range;
|
||||
}
|
||||
result.push(typeConvert.SelectionRange.from(sel));
|
||||
last = sel.range;
|
||||
}
|
||||
return result;
|
||||
return allResults;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -918,7 +933,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
private static _handlePool: number = 0;
|
||||
|
||||
private readonly _schemeTransformer: ISchemeTransformer;
|
||||
private readonly _schemeTransformer: ISchemeTransformer | null;
|
||||
private _proxy: MainThreadLanguageFeaturesShape;
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: ExtHostCommands;
|
||||
@@ -929,7 +944,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
schemeTransformer: ISchemeTransformer,
|
||||
schemeTransformer: ISchemeTransformer | null,
|
||||
documents: ExtHostDocuments,
|
||||
commands: ExtHostCommands,
|
||||
heapMonitor: ExtHostHeapService,
|
||||
@@ -953,7 +968,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return [this._doTransformDocumentSelector(selector)];
|
||||
}
|
||||
|
||||
private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter {
|
||||
private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter | undefined {
|
||||
if (typeof selector === 'string') {
|
||||
return {
|
||||
$serialized: true,
|
||||
@@ -993,7 +1008,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
}
|
||||
|
||||
private _withAdapter<A, R>(handle: number, ctor: { new(...args: any[]): A }, callback: (adapter: A) => Promise<R>): Promise<R> {
|
||||
let data = this._adapter.get(handle);
|
||||
const data = this._adapter.get(handle);
|
||||
if (!data) {
|
||||
return Promise.reject(new Error('no adapter found'));
|
||||
}
|
||||
|
||||
if (data.adapter instanceof ctor) {
|
||||
let t1: number;
|
||||
if (data.extension) {
|
||||
@@ -1001,11 +1020,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
this._logService.trace(`[${data.extension.identifier.value}] INVOKE provider '${(ctor as any).name}'`);
|
||||
}
|
||||
let p = callback(data.adapter);
|
||||
if (data.extension) {
|
||||
const extension = data.extension;
|
||||
if (extension) {
|
||||
Promise.resolve(p).then(
|
||||
() => this._logService.trace(`[${data.extension.identifier.value}] provider DONE after ${Date.now() - t1}ms`),
|
||||
() => this._logService.trace(`[${extension.identifier.value}] provider DONE after ${Date.now() - t1}ms`),
|
||||
err => {
|
||||
this._logService.error(`[${data.extension.identifier.value}] provider FAILED`);
|
||||
this._logService.error(`[${extension.identifier.value}] provider FAILED`);
|
||||
this._logService.error(err);
|
||||
}
|
||||
);
|
||||
@@ -1034,7 +1054,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[]> {
|
||||
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined> {
|
||||
return this._withAdapter(handle, DocumentSymbolAdapter, adapter => adapter.provideDocumentSymbols(URI.revive(resource), token));
|
||||
}
|
||||
|
||||
@@ -1049,7 +1069,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
let result = this._createDisposable(handle);
|
||||
|
||||
if (eventHandle !== undefined) {
|
||||
const subscription = provider.onDidChangeCodeLenses(_ => this._proxy.$emitCodeLensEvent(eventHandle));
|
||||
const subscription = provider.onDidChangeCodeLenses!(_ => this._proxy.$emitCodeLensEvent(eventHandle));
|
||||
result = Disposable.from(result, subscription);
|
||||
}
|
||||
|
||||
@@ -1114,7 +1134,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover> {
|
||||
$provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined> {
|
||||
return this._withAdapter(handle, HoverAdapter, adapter => adapter.provideHover(URI.revive(resource), position, token));
|
||||
}
|
||||
|
||||
@@ -1126,7 +1146,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[]> {
|
||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined> {
|
||||
return this._withAdapter(handle, DocumentHighlightAdapter, adapter => adapter.provideDocumentHighlights(URI.revive(resource), position, token));
|
||||
}
|
||||
|
||||
@@ -1138,7 +1158,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<modes.Location[]> {
|
||||
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<modes.Location[] | undefined> {
|
||||
return this._withAdapter(handle, ReferenceAdapter, adapter => adapter.provideReferences(URI.revive(resource), position, context, token));
|
||||
}
|
||||
|
||||
@@ -1146,12 +1166,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
|
||||
registerCodeActionProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider, this._logService, extension.identifier), extension);
|
||||
this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), metadata && metadata.providedCodeActionKinds ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined);
|
||||
this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), (metadata && metadata.providedCodeActionKinds) ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
|
||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[]> {
|
||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<CodeActionDto[] | undefined> {
|
||||
return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(URI.revive(resource), rangeOrSelection, context, token));
|
||||
}
|
||||
|
||||
@@ -1163,7 +1183,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
$provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
return this._withAdapter(handle, DocumentFormattingAdapter, adapter => adapter.provideDocumentFormattingEdits(URI.revive(resource), options, token));
|
||||
}
|
||||
|
||||
@@ -1173,7 +1193,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
$provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
return this._withAdapter(handle, RangeFormattingAdapter, adapter => adapter.provideDocumentRangeFormattingEdits(URI.revive(resource), range, options, token));
|
||||
}
|
||||
|
||||
@@ -1183,7 +1203,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[]> {
|
||||
$provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
|
||||
return this._withAdapter(handle, OnTypeFormattingAdapter, adapter => adapter.provideOnTypeFormattingEdits(URI.revive(resource), position, ch, options, token));
|
||||
}
|
||||
|
||||
@@ -1199,7 +1219,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search, token));
|
||||
}
|
||||
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto> {
|
||||
$resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise<WorkspaceSymbolDto | undefined> {
|
||||
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol, token));
|
||||
}
|
||||
|
||||
@@ -1215,11 +1235,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto> {
|
||||
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise<WorkspaceEditDto | undefined> {
|
||||
return this._withAdapter(handle, RenameAdapter, adapter => adapter.provideRenameEdits(URI.revive(resource), position, newName, token));
|
||||
}
|
||||
|
||||
$resolveRenameLocation(handle: number, resource: URI, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation> {
|
||||
$resolveRenameLocation(handle: number, resource: URI, position: IPosition, token: CancellationToken): Promise<modes.RenameLocation | undefined> {
|
||||
return this._withAdapter(handle, RenameAdapter, adapter => adapter.resolveRenameLocation(URI.revive(resource), position, token));
|
||||
}
|
||||
|
||||
@@ -1245,8 +1265,8 @@ 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 = Array.isArray(metadataOrTriggerChars)
|
||||
registerSignatureHelpProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, metadataOrTriggerChars: string[] | vscode.SignatureHelpProviderMetadata): vscode.Disposable {
|
||||
const metadata: ISerializedSignatureHelpProviderMetadata | undefined = Array.isArray(metadataOrTriggerChars)
|
||||
? { triggerCharacters: metadataOrTriggerChars, retriggerCharacters: [] }
|
||||
: metadataOrTriggerChars;
|
||||
|
||||
@@ -1255,7 +1275,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp> {
|
||||
$provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise<modes.SignatureHelp | undefined> {
|
||||
return this._withAdapter(handle, SignatureHelpAdapter, adapter => adapter.provideSignatureHelp(URI.revive(resource), position, context, token));
|
||||
}
|
||||
|
||||
@@ -1267,11 +1287,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.ILink[]> {
|
||||
$provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.ILink[] | undefined> {
|
||||
return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.provideLinks(URI.revive(resource), token));
|
||||
}
|
||||
|
||||
$resolveDocumentLink(handle: number, link: modes.ILink, token: CancellationToken): Promise<modes.ILink> {
|
||||
$resolveDocumentLink(handle: number, link: modes.ILink, token: CancellationToken): Promise<modes.ILink | undefined> {
|
||||
return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.resolveLink(link, token));
|
||||
}
|
||||
|
||||
@@ -1307,8 +1327,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideSelectionRanges(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<modes.SelectionRange[]> {
|
||||
return this._withAdapter(handle, SelectionRangeAdapter, adapter => adapter.provideSelectionRanges(URI.revive(resource), position, token));
|
||||
$provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]> {
|
||||
return this._withAdapter(handle, SelectionRangeAdapter, adapter => adapter.provideSelectionRanges(URI.revive(resource), positions, token));
|
||||
}
|
||||
|
||||
// --- configuration
|
||||
@@ -1350,7 +1370,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
};
|
||||
}
|
||||
|
||||
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] {
|
||||
private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] | undefined | null {
|
||||
if (typeof onEnterRules === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1372,7 +1392,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
||||
if (wordPattern) {
|
||||
this._documents.setWordDefinitionFor(languageId, wordPattern);
|
||||
} else {
|
||||
this._documents.setWordDefinitionFor(languageId, null);
|
||||
this._documents.setWordDefinitionFor(languageId, undefined);
|
||||
}
|
||||
|
||||
const handle = this._nextHandle();
|
||||
|
||||
@@ -24,9 +24,10 @@ export class ExtHostLanguages {
|
||||
return this._proxy.$getLanguages();
|
||||
}
|
||||
|
||||
changeLanguage(uri: vscode.Uri, languageId: string): Promise<vscode.TextDocument> {
|
||||
changeLanguage(uri: vscode.Uri, languageId: string): Promise<vscode.TextDocument | undefined> {
|
||||
return this._proxy.$changeLanguage(uri, languageId).then(() => {
|
||||
return this._documents.getDocumentData(uri).document;
|
||||
const data = this._documents.getDocumentData(uri);
|
||||
return data ? data.document : undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { MainContext, MainThreadOutputServiceShape, IMainContext, ExtHostOutputS
|
||||
import * as vscode from 'vscode';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { posix } from 'path';
|
||||
import { OutputAppender } from 'vs/platform/output/node/outputAppender';
|
||||
import { OutputAppender } from 'vs/workbench/contrib/output/node/outputAppender';
|
||||
import { toLocalISOString } from 'vs/base/common/date';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
|
||||
@@ -27,11 +27,11 @@ export class ExtHostProgress implements ExtHostProgressShape {
|
||||
const { title, location, cancellable } = options;
|
||||
const source = localize('extensionSource', "{0} (Extension)", extension.displayName || extension.name);
|
||||
this._proxy.$startProgress(handle, { location: ProgressLocation.from(location), title, source, cancellable });
|
||||
return this._withProgress(handle, task, cancellable);
|
||||
return this._withProgress(handle, task, !!cancellable);
|
||||
}
|
||||
|
||||
private _withProgress<R>(handle: number, task: (progress: Progress<IProgressStep>, token: CancellationToken) => Thenable<R>, cancellable: boolean): Thenable<R> {
|
||||
let source: CancellationTokenSource;
|
||||
let source: CancellationTokenSource | undefined;
|
||||
if (cancellable) {
|
||||
source = new CancellationTokenSource();
|
||||
this._mapHandleToCancellationSource.set(handle, source);
|
||||
@@ -48,7 +48,7 @@ export class ExtHostProgress implements ExtHostProgressShape {
|
||||
let p: Thenable<R>;
|
||||
|
||||
try {
|
||||
p = task(new ProgressCallback(this._proxy, handle), cancellable ? source.token : CancellationToken.None);
|
||||
p = task(new ProgressCallback(this._proxy, handle), cancellable && source ? source.token : CancellationToken.None);
|
||||
} catch (err) {
|
||||
progressEnd(handle);
|
||||
throw err;
|
||||
|
||||
@@ -164,7 +164,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this._workspace.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0];
|
||||
return this._workspace.getWorkspaceProvider().then(workspaceProvider => workspaceProvider.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { compareItemsByScore, IItemAccessor, prepareQuery, ScorerCache } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { ICachedSearchStats, IFileIndexProviderStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchCompleteStats } from 'vs/platform/search/common/search';
|
||||
import { ICachedSearchStats, IFileIndexProviderStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, ISearchCompleteStats } from 'vs/workbench/services/search/common/search';
|
||||
import { IDirectoryEntry, IDirectoryTree, IInternalFileMatch } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/node/search';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
@@ -8,7 +8,7 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery } from 'vs/platform/search/common/search';
|
||||
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery } from 'vs/workbench/services/search/common/search';
|
||||
import { FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex';
|
||||
import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
|
||||
@@ -35,12 +35,12 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
private _handlePool: number = 0;
|
||||
|
||||
private _internalFileSearchHandle: number;
|
||||
private _internalFileSearchProvider: SearchService;
|
||||
private _internalFileSearchProvider: SearchService | null;
|
||||
|
||||
private _fileSearchManager: FileSearchManager;
|
||||
private _fileIndexSearchManager: FileIndexSearchManager;
|
||||
|
||||
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer, private _logService: ILogService, private _extfs = extfs) {
|
||||
constructor(mainContext: IMainContext, private _schemeTransformer: ISchemeTransformer | null, private _logService: ILogService, private _extfs = extfs) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadSearch);
|
||||
this._fileSearchManager = new FileSearchManager();
|
||||
this._fileIndexSearchManager = new FileIndexSearchManager();
|
||||
@@ -124,6 +124,10 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
}, token);
|
||||
} else {
|
||||
const indexProvider = this._fileIndexProvider.get(handle);
|
||||
if (!indexProvider) {
|
||||
throw new Error('unknown provider: ' + handle);
|
||||
}
|
||||
|
||||
return this._fileIndexSearchManager.fileSearch(query, indexProvider, batch => {
|
||||
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
|
||||
}, token);
|
||||
@@ -147,7 +151,11 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
}
|
||||
};
|
||||
|
||||
return this._internalFileSearchProvider.doFileSearch(rawQuery, onResult, token);
|
||||
if (!this._internalFileSearchProvider) {
|
||||
throw new Error('No internal file search handler');
|
||||
}
|
||||
|
||||
return <Promise<ISearchCompleteStats>>this._internalFileSearchProvider.doFileSearch(rawQuery, onResult, token);
|
||||
}
|
||||
|
||||
$clearCache(cacheKey: string): Promise<void> {
|
||||
@@ -163,8 +171,8 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
|
||||
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const provider = this._textSearchProvider.get(handle);
|
||||
if (!provider.provideTextSearchResults) {
|
||||
return Promise.resolve(undefined);
|
||||
if (!provider || !provider.provideTextSearchResults) {
|
||||
throw new Error(`Unknown provider ${handle}`);
|
||||
}
|
||||
|
||||
const query = reviveQuery(rawQuery);
|
||||
|
||||
@@ -16,13 +16,13 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e
|
||||
import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import * as vscode from 'vscode';
|
||||
import {
|
||||
TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO,
|
||||
ProcessExecutionOptionsDTO, ProcessExecutionDTO,
|
||||
ShellExecutionOptionsDTO, ShellExecutionDTO,
|
||||
ExtensionCallbackExecutionDTO,
|
||||
CustomTaskExecutionDTO,
|
||||
TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, TaskSetDTO
|
||||
} from '../shared/tasks';
|
||||
import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
@@ -79,7 +79,7 @@ namespace ProcessExecutionOptionsDTO {
|
||||
}
|
||||
|
||||
namespace ProcessExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | ExtensionCallbackExecutionDTO): value is ProcessExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomTaskExecutionDTO): value is ProcessExecutionDTO {
|
||||
let candidate = value as ProcessExecutionDTO;
|
||||
return candidate && !!candidate.process;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace ShellExecutionOptionsDTO {
|
||||
}
|
||||
|
||||
namespace ShellExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | ExtensionCallbackExecutionDTO): value is ShellExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomTaskExecutionDTO): value is ShellExecutionDTO {
|
||||
let candidate = value as ShellExecutionDTO;
|
||||
return candidate && (!!candidate.commandLine || !!candidate.command);
|
||||
}
|
||||
@@ -153,15 +153,15 @@ namespace ShellExecutionDTO {
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExtensionCallbackExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | ExtensionCallbackExecutionDTO): value is ExtensionCallbackExecutionDTO {
|
||||
let candidate = value as ExtensionCallbackExecutionDTO;
|
||||
return candidate && candidate.extensionCallback === 'extensionCallback';
|
||||
namespace CustomTaskExecutionDTO {
|
||||
export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomTaskExecutionDTO): value is CustomTaskExecutionDTO {
|
||||
let candidate = value as CustomTaskExecutionDTO;
|
||||
return candidate && candidate.customTaskExecution === 'customTaskExecution';
|
||||
}
|
||||
|
||||
export function from(value: vscode.ExtensionCallbackExecution): ExtensionCallbackExecutionDTO {
|
||||
export function from(value: vscode.CustomTaskExecution): CustomTaskExecutionDTO {
|
||||
return {
|
||||
extensionCallback: 'extensionCallback'
|
||||
customTaskExecution: 'customTaskExecution'
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -199,13 +199,13 @@ namespace TaskDTO {
|
||||
if (value === undefined || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
let execution: ShellExecutionDTO | ProcessExecutionDTO | ExtensionCallbackExecutionDTO;
|
||||
let execution: ShellExecutionDTO | ProcessExecutionDTO | CustomTaskExecutionDTO;
|
||||
if (value.execution instanceof types.ProcessExecution) {
|
||||
execution = ProcessExecutionDTO.from(value.execution);
|
||||
} else if (value.execution instanceof types.ShellExecution) {
|
||||
execution = ShellExecutionDTO.from(value.execution);
|
||||
} else if ((<vscode.TaskWithExtensionCallback>value).executionWithExtensionCallback && (<vscode.TaskWithExtensionCallback>value).executionWithExtensionCallback instanceof types.ExtensionCallbackExecution) {
|
||||
execution = ExtensionCallbackExecutionDTO.from(<types.ExtensionCallbackExecution>(<vscode.TaskWithExtensionCallback>value).executionWithExtensionCallback);
|
||||
} else if ((<vscode.TaskWithCustomTaskExecution>value).executionWithExtensionCallback && (<vscode.TaskWithCustomTaskExecution>value).executionWithExtensionCallback instanceof types.CustomTaskExecution) {
|
||||
execution = CustomTaskExecutionDTO.from(<types.CustomTaskExecution>(<vscode.TaskWithCustomTaskExecution>value).executionWithExtensionCallback);
|
||||
}
|
||||
|
||||
let definition: TaskDefinitionDTO = TaskDefinitionDTO.from(value.definition);
|
||||
@@ -243,7 +243,7 @@ namespace TaskDTO {
|
||||
};
|
||||
return result;
|
||||
}
|
||||
export function to(value: TaskDTO, workspace: ExtHostWorkspace): types.Task {
|
||||
export function to(value: TaskDTO, workspace: ExtHostWorkspaceProvider): types.Task {
|
||||
if (value === undefined || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -320,8 +320,8 @@ class TaskExecutionImpl implements vscode.TaskExecution {
|
||||
}
|
||||
|
||||
namespace TaskExecutionDTO {
|
||||
export function to(value: TaskExecutionDTO, tasks: ExtHostTask): vscode.TaskExecution {
|
||||
return new TaskExecutionImpl(tasks, value.id, TaskDTO.to(value.task, tasks.extHostWorkspace));
|
||||
export function to(value: TaskExecutionDTO, tasks: ExtHostTask, workspaceProvider: ExtHostWorkspaceProvider): vscode.TaskExecution {
|
||||
return new TaskExecutionImpl(tasks, value.id, TaskDTO.to(value.task, workspaceProvider));
|
||||
}
|
||||
export function from(value: vscode.TaskExecution): TaskExecutionDTO {
|
||||
return {
|
||||
@@ -344,7 +344,7 @@ class ExtensionCallbackExecutionData implements IDisposable {
|
||||
private terminalId?: number;
|
||||
|
||||
constructor(
|
||||
private readonly callbackData: vscode.ExtensionCallbackExecution,
|
||||
private readonly callbackData: vscode.CustomTaskExecution,
|
||||
private readonly terminalService: ExtHostTerminalService) {
|
||||
}
|
||||
|
||||
@@ -449,10 +449,6 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
this._activeExtensionCallbacks = new Map<string, ExtensionCallbackExecutionData>();
|
||||
}
|
||||
|
||||
public get extHostWorkspace(): ExtHostWorkspace {
|
||||
return this._workspaceService;
|
||||
}
|
||||
|
||||
public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable {
|
||||
if (!provider) {
|
||||
return new types.Disposable(() => { });
|
||||
@@ -471,10 +467,11 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
}
|
||||
|
||||
public fetchTasks(filter?: vscode.TaskFilter): Promise<vscode.Task[]> {
|
||||
return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then((values) => {
|
||||
return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then(async (values) => {
|
||||
let result: vscode.Task[] = [];
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
for (let value of values) {
|
||||
let task = TaskDTO.to(value, this._workspaceService);
|
||||
let task = TaskDTO.to(value, workspaceProvider);
|
||||
if (task) {
|
||||
result.push(task);
|
||||
}
|
||||
@@ -483,17 +480,18 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public executeTask(extension: IExtensionDescription, task: vscode.Task): Promise<vscode.TaskExecution> {
|
||||
public async executeTask(extension: IExtensionDescription, task: vscode.Task): Promise<vscode.TaskExecution> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let tTask = (task as types.Task);
|
||||
// We have a preserved ID. So the task didn't change.
|
||||
if (tTask._id !== undefined) {
|
||||
return this._proxy.$executeTask(TaskHandleDTO.from(tTask)).then(value => this.getTaskExecution(value, task));
|
||||
return this._proxy.$executeTask(TaskHandleDTO.from(tTask)).then(value => this.getTaskExecution(value, workspaceProvider, task));
|
||||
} else {
|
||||
let dto = TaskDTO.from(task, extension);
|
||||
if (dto === undefined) {
|
||||
return Promise.reject(new Error('Task is not valid'));
|
||||
}
|
||||
return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, task));
|
||||
return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, workspaceProvider, task));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +512,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._onDidExecuteTask.event;
|
||||
}
|
||||
|
||||
public $onDidStartTask(execution: TaskExecutionDTO, terminalId: number): void {
|
||||
public async $onDidStartTask(execution: TaskExecutionDTO, terminalId: number): Promise<void> {
|
||||
// Once a terminal is spun up for the extension callback task execution
|
||||
// this event will be fired.
|
||||
// At that point, we need to actually start the callback, but
|
||||
@@ -534,8 +532,9 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
extensionCallback.startCallback(terminalId);
|
||||
}
|
||||
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
this._onDidExecuteTask.fire({
|
||||
execution: this.getTaskExecution(execution)
|
||||
execution: this.getTaskExecution(execution, workspaceProvider)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -543,8 +542,9 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._onDidTerminateTask.event;
|
||||
}
|
||||
|
||||
public $OnDidEndTask(execution: TaskExecutionDTO): void {
|
||||
const _execution = this.getTaskExecution(execution);
|
||||
public async $OnDidEndTask(execution: TaskExecutionDTO): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const _execution = this.getTaskExecution(execution, workspaceProvider);
|
||||
this._taskExecutions.delete(execution.id);
|
||||
this.extensionCallbackTaskComplete(execution);
|
||||
this._onDidTerminateTask.fire({
|
||||
@@ -556,8 +556,9 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._onDidTaskProcessStarted.event;
|
||||
}
|
||||
|
||||
public $onDidStartTaskProcess(value: TaskProcessStartedDTO): void {
|
||||
const execution = this.getTaskExecution(value.id);
|
||||
public async $onDidStartTaskProcess(value: TaskProcessStartedDTO): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const execution = this.getTaskExecution(value.id, workspaceProvider);
|
||||
if (execution) {
|
||||
this._onDidTaskProcessStarted.fire({
|
||||
execution: execution,
|
||||
@@ -570,8 +571,9 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._onDidTaskProcessEnded.event;
|
||||
}
|
||||
|
||||
public $onDidEndTaskProcess(value: TaskProcessEndedDTO): void {
|
||||
const execution = this.getTaskExecution(value.id);
|
||||
public async $onDidEndTaskProcess(value: TaskProcessEndedDTO): Promise<void> {
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
const execution = this.getTaskExecution(value.id, workspaceProvider);
|
||||
if (execution) {
|
||||
this._onDidTaskProcessEnded.fire({
|
||||
execution: execution,
|
||||
@@ -610,11 +612,11 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
const taskDTO: TaskDTO = TaskDTO.from(task, handler.extension);
|
||||
taskDTOs.push(taskDTO);
|
||||
|
||||
if (ExtensionCallbackExecutionDTO.is(taskDTO.execution)) {
|
||||
if (CustomTaskExecutionDTO.is(taskDTO.execution)) {
|
||||
taskIdPromises.push(new Promise((resolve) => {
|
||||
// The ID is calculated on the main thread task side, so, let's call into it here.
|
||||
this._proxy.$createTaskId(taskDTO).then((taskId) => {
|
||||
this._providedExtensionCallbacks.set(taskId, new ExtensionCallbackExecutionData(<vscode.ExtensionCallbackExecution>(<vscode.TaskWithExtensionCallback>task).executionWithExtensionCallback, this._terminalService));
|
||||
this._providedExtensionCallbacks.set(taskId, new ExtensionCallbackExecutionData(<vscode.CustomTaskExecution>(<vscode.TaskWithCustomTaskExecution>task).executionWithExtensionCallback, this._terminalService));
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
@@ -638,13 +640,14 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
|
||||
public async $resolveVariables(uriComponents: UriComponents, toResolve: { process?: { name: string; cwd?: string; path?: string }, variables: string[] }): Promise<{ process?: string, variables: { [key: string]: string; } }> {
|
||||
const configProvider = await this._configurationService.getConfigProvider();
|
||||
const workspaceProvider = await this._workspaceService.getWorkspaceProvider();
|
||||
let uri: URI = URI.revive(uriComponents);
|
||||
let result = {
|
||||
process: undefined as string,
|
||||
variables: Object.create(null)
|
||||
};
|
||||
let workspaceFolder = this._workspaceService.resolveWorkspaceFolder(uri);
|
||||
let resolver = new ExtHostVariableResolverService(this._workspaceService, this._editorService, configProvider);
|
||||
let workspaceFolder = workspaceProvider.resolveWorkspaceFolder(uri);
|
||||
let resolver = new ExtHostVariableResolverService(workspaceProvider, this._editorService, configProvider);
|
||||
let ws: IWorkspaceFolder = {
|
||||
uri: workspaceFolder.uri,
|
||||
name: workspaceFolder.name,
|
||||
@@ -677,7 +680,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
return this._handleCounter++;
|
||||
}
|
||||
|
||||
private getTaskExecution(execution: TaskExecutionDTO | string, task?: vscode.Task): TaskExecutionImpl {
|
||||
private getTaskExecution(execution: TaskExecutionDTO | string, workspaceProvider: ExtHostWorkspaceProvider, task?: vscode.Task): TaskExecutionImpl {
|
||||
if (typeof execution === 'string') {
|
||||
return this._taskExecutions.get(execution);
|
||||
}
|
||||
@@ -686,7 +689,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._workspaceService));
|
||||
result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, workspaceProvider));
|
||||
this._taskExecutions.set(execution.id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostTerminalRenderer extends BaseExtHostTerminal implements vscode.TerminalRenderer, vscode.AnsiRenderer {
|
||||
export class ExtHostTerminalRenderer extends BaseExtHostTerminal implements vscode.TerminalRenderer {
|
||||
public get name(): string { return this._name; }
|
||||
public set name(newName: string) {
|
||||
this._name = newName;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { ExtHostEditorsShape, IEditorPropertiesChangeData, IMainContext, ITextDocumentShowOptions, ITextEditorPositionData, MainContext, MainThreadTextEditorsShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { ExtHostTextEditor, TextEditorDecorationType } from 'vs/workbench/api/node/extHostTextEditor';
|
||||
@@ -42,7 +43,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => this._onDidChangeActiveTextEditor.fire(e));
|
||||
}
|
||||
|
||||
getActiveTextEditor(): ExtHostTextEditor {
|
||||
getActiveTextEditor(): ExtHostTextEditor | undefined {
|
||||
return this._extHostDocumentsAndEditors.activeEditor();
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
textEditor._acceptSelections(selections);
|
||||
}
|
||||
if (data.visibleRanges) {
|
||||
const visibleRanges = data.visibleRanges.map(TypeConverters.Range.to);
|
||||
const visibleRanges = arrays.coalesce(data.visibleRanges.map(TypeConverters.Range.to));
|
||||
textEditor._acceptVisibleRanges(visibleRanges);
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
});
|
||||
}
|
||||
if (data.visibleRanges) {
|
||||
const visibleRanges = data.visibleRanges.map(TypeConverters.Range.to);
|
||||
const visibleRanges = arrays.coalesce(data.visibleRanges.map(TypeConverters.Range.to));
|
||||
this._onDidChangeTextEditorVisibleRanges.fire({
|
||||
textEditor,
|
||||
visibleRanges
|
||||
|
||||
@@ -28,6 +28,7 @@ import * as marked from 'vs/base/common/marked/marked';
|
||||
import { parse } from 'vs/base/common/marshalling';
|
||||
import { cloneAndChange } from 'vs/base/common/objects';
|
||||
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
export interface PositionLike {
|
||||
line: number;
|
||||
@@ -64,7 +65,10 @@ export namespace Selection {
|
||||
}
|
||||
export namespace Range {
|
||||
|
||||
export function from(range: RangeLike): IRange {
|
||||
export function from(range: undefined): undefined;
|
||||
export function from(range: RangeLike): IRange;
|
||||
export function from(range: RangeLike | undefined): IRange | undefined;
|
||||
export function from(range: RangeLike | undefined): IRange | undefined {
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -77,7 +81,10 @@ export namespace Range {
|
||||
};
|
||||
}
|
||||
|
||||
export function to(range: IRange): types.Range {
|
||||
export function to(range: undefined): types.Range;
|
||||
export function to(range: IRange): types.Range;
|
||||
export function to(range: IRange | undefined): types.Range | undefined;
|
||||
export function to(range: IRange | undefined): types.Range | undefined {
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -96,7 +103,7 @@ export namespace Position {
|
||||
}
|
||||
|
||||
export namespace DiagnosticTag {
|
||||
export function from(value: vscode.DiagnosticTag): MarkerTag {
|
||||
export function from(value: vscode.DiagnosticTag): MarkerTag | undefined {
|
||||
switch (value) {
|
||||
case types.DiagnosticTag.Unnecessary:
|
||||
return MarkerTag.Unnecessary;
|
||||
@@ -114,7 +121,7 @@ export namespace Diagnostic {
|
||||
code: isString(value.code) || isNumber(value.code) ? String(value.code) : undefined,
|
||||
severity: DiagnosticSeverity.from(value.severity),
|
||||
relatedInformation: value.relatedInformation && value.relatedInformation.map(DiagnosticRelatedInformation.from),
|
||||
tags: Array.isArray(value.tags) ? value.tags.map(DiagnosticTag.from) : undefined,
|
||||
tags: Array.isArray(value.tags) ? coalesce(value.tags.map(DiagnosticTag.from)) : undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -175,12 +182,12 @@ export namespace ViewColumn {
|
||||
return ACTIVE_GROUP; // default is always the active group
|
||||
}
|
||||
|
||||
export function to(position?: EditorViewColumn): vscode.ViewColumn {
|
||||
export function to(position: EditorViewColumn): vscode.ViewColumn {
|
||||
if (typeof position === 'number' && position >= 0) {
|
||||
return position + 1; // adjust to index (ViewColumn.ONE => 1)
|
||||
}
|
||||
|
||||
return undefined;
|
||||
throw new Error(`invalid 'EditorViewColumn'`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,13 +233,15 @@ export namespace MarkdownString {
|
||||
}
|
||||
|
||||
// extract uris into a separate object
|
||||
res.uris = Object.create(null);
|
||||
const resUris: { [href: string]: UriComponents } = Object.create(null);
|
||||
res.uris = resUris;
|
||||
|
||||
let renderer = new marked.Renderer();
|
||||
renderer.image = renderer.link = (href: string): string => {
|
||||
try {
|
||||
let uri = URI.parse(href, true);
|
||||
uri = uri.with({ query: _uriMassage(uri.query, res.uris) });
|
||||
res.uris[href] = uri;
|
||||
uri = uri.with({ query: _uriMassage(uri.query, resUris) });
|
||||
resUris[href] = uri;
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
@@ -284,10 +293,12 @@ export namespace MarkdownString {
|
||||
|
||||
export function fromRangeOrRangeWithMessage(ranges: vscode.Range[] | vscode.DecorationOptions[]): IDecorationOptions[] {
|
||||
if (isDecorationOptionsArr(ranges)) {
|
||||
return ranges.map(r => {
|
||||
return ranges.map((r): IDecorationOptions => {
|
||||
return {
|
||||
range: Range.from(r.range),
|
||||
hoverMessage: Array.isArray(r.hoverMessage) ? MarkdownString.fromMany(r.hoverMessage) : r.hoverMessage && MarkdownString.from(r.hoverMessage),
|
||||
hoverMessage: Array.isArray(r.hoverMessage)
|
||||
? MarkdownString.fromMany(r.hoverMessage)
|
||||
: (r.hoverMessage ? MarkdownString.from(r.hoverMessage) : undefined),
|
||||
renderOptions: <any> /* URI vs Uri */r.renderOptions
|
||||
};
|
||||
});
|
||||
@@ -318,7 +329,7 @@ export namespace ThemableDecorationAttachmentRenderOptions {
|
||||
}
|
||||
return {
|
||||
contentText: options.contentText,
|
||||
contentIconPath: pathOrURIToURI(options.contentIconPath),
|
||||
contentIconPath: options.contentIconPath ? pathOrURIToURI(options.contentIconPath) : undefined,
|
||||
border: options.border,
|
||||
borderColor: <string | types.ThemeColor>options.borderColor,
|
||||
fontStyle: options.fontStyle,
|
||||
@@ -357,11 +368,11 @@ export namespace ThemableDecorationRenderOptions {
|
||||
color: <string | types.ThemeColor>options.color,
|
||||
opacity: options.opacity,
|
||||
letterSpacing: options.letterSpacing,
|
||||
gutterIconPath: pathOrURIToURI(options.gutterIconPath),
|
||||
gutterIconPath: options.gutterIconPath ? pathOrURIToURI(options.gutterIconPath) : undefined,
|
||||
gutterIconSize: options.gutterIconSize,
|
||||
overviewRulerColor: <string | types.ThemeColor>options.overviewRulerColor,
|
||||
before: ThemableDecorationAttachmentRenderOptions.from(options.before),
|
||||
after: ThemableDecorationAttachmentRenderOptions.from(options.after),
|
||||
before: options.before ? ThemableDecorationAttachmentRenderOptions.from(options.before) : undefined,
|
||||
after: options.after ? ThemableDecorationAttachmentRenderOptions.from(options.after) : undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -388,10 +399,10 @@ export namespace DecorationRenderOptions {
|
||||
export function from(options: vscode.DecorationRenderOptions): IDecorationRenderOptions {
|
||||
return {
|
||||
isWholeLine: options.isWholeLine,
|
||||
rangeBehavior: DecorationRangeBehavior.from(options.rangeBehavior),
|
||||
rangeBehavior: options.rangeBehavior ? DecorationRangeBehavior.from(options.rangeBehavior) : undefined,
|
||||
overviewRulerLane: options.overviewRulerLane,
|
||||
light: ThemableDecorationRenderOptions.from(options.light),
|
||||
dark: ThemableDecorationRenderOptions.from(options.dark),
|
||||
light: options.light ? ThemableDecorationRenderOptions.from(options.light) : undefined,
|
||||
dark: options.dark ? ThemableDecorationRenderOptions.from(options.dark) : undefined,
|
||||
|
||||
backgroundColor: <string | types.ThemeColor>options.backgroundColor,
|
||||
outline: options.outline,
|
||||
@@ -411,11 +422,11 @@ export namespace DecorationRenderOptions {
|
||||
color: <string | types.ThemeColor>options.color,
|
||||
opacity: options.opacity,
|
||||
letterSpacing: options.letterSpacing,
|
||||
gutterIconPath: pathOrURIToURI(options.gutterIconPath),
|
||||
gutterIconPath: options.gutterIconPath ? pathOrURIToURI(options.gutterIconPath) : undefined,
|
||||
gutterIconSize: options.gutterIconSize,
|
||||
overviewRulerColor: <string | types.ThemeColor>options.overviewRulerColor,
|
||||
before: ThemableDecorationAttachmentRenderOptions.from(options.before),
|
||||
after: ThemableDecorationAttachmentRenderOptions.from(options.after),
|
||||
before: options.before ? ThemableDecorationAttachmentRenderOptions.from(options.before) : undefined,
|
||||
after: options.after ? ThemableDecorationAttachmentRenderOptions.from(options.after) : undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -432,7 +443,7 @@ export namespace TextEdit {
|
||||
|
||||
export function to(edit: modes.TextEdit): types.TextEdit {
|
||||
const result = new types.TextEdit(Range.to(edit.range), edit.text);
|
||||
result.newEol = EndOfLine.to(edit.eol);
|
||||
result.newEol = (typeof edit.eol === 'undefined' ? undefined : EndOfLine.to(edit.eol))!;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -446,7 +457,7 @@ export namespace WorkspaceEdit {
|
||||
const [uri, uriOrEdits] = entry;
|
||||
if (Array.isArray(uriOrEdits)) {
|
||||
// text edits
|
||||
const doc = documents ? documents.getDocument(uri.toString()) : undefined;
|
||||
const doc = documents && uri ? documents.getDocument(uri.toString()) : undefined;
|
||||
result.edits.push(<ResourceTextEditDto>{ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) });
|
||||
} else {
|
||||
// resource edits
|
||||
@@ -648,7 +659,7 @@ export namespace CompletionContext {
|
||||
|
||||
export namespace CompletionItemKind {
|
||||
|
||||
export function from(kind: types.CompletionItemKind): modes.CompletionItemKind {
|
||||
export function from(kind: types.CompletionItemKind | undefined): modes.CompletionItemKind {
|
||||
switch (kind) {
|
||||
case types.CompletionItemKind.Method: return modes.CompletionItemKind.Method;
|
||||
case types.CompletionItemKind.Function: return modes.CompletionItemKind.Function;
|
||||
@@ -724,9 +735,9 @@ export namespace CompletionItem {
|
||||
result.preselect = suggestion.preselect;
|
||||
result.commitCharacters = suggestion.commitCharacters;
|
||||
result.range = Range.to(suggestion.range);
|
||||
result.keepWhitespace = Boolean(suggestion.insertTextRules & modes.CompletionItemInsertTextRule.KeepWhitespace);
|
||||
result.keepWhitespace = typeof suggestion.insertTextRules === 'undefined' ? false : Boolean(suggestion.insertTextRules & modes.CompletionItemInsertTextRule.KeepWhitespace);
|
||||
// 'inserText'-logic
|
||||
if (suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) {
|
||||
if (typeof suggestion.insertTextRules !== 'undefined' && suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) {
|
||||
result.insertText = new types.SnippetString(suggestion.insertText);
|
||||
} else {
|
||||
result.insertText = suggestion.insertText;
|
||||
@@ -742,7 +753,7 @@ export namespace ParameterInformation {
|
||||
export function from(info: types.ParameterInformation): modes.ParameterInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: MarkdownString.fromStrict(info.documentation)
|
||||
documentation: info.documentation ? MarkdownString.fromStrict(info.documentation) : undefined
|
||||
};
|
||||
}
|
||||
export function to(info: modes.ParameterInformation): types.ParameterInformation {
|
||||
@@ -758,7 +769,7 @@ export namespace SignatureInformation {
|
||||
export function from(info: types.SignatureInformation): modes.SignatureInformation {
|
||||
return {
|
||||
label: info.label,
|
||||
documentation: MarkdownString.fromStrict(info.documentation),
|
||||
documentation: info.documentation ? MarkdownString.fromStrict(info.documentation) : undefined,
|
||||
parameters: info.parameters && info.parameters.map(ParameterInformation.from)
|
||||
};
|
||||
}
|
||||
@@ -801,7 +812,7 @@ export namespace DocumentLink {
|
||||
}
|
||||
|
||||
export function to(link: modes.ILink): vscode.DocumentLink {
|
||||
return new types.DocumentLink(Range.to(link.range), link.url && URI.parse(link.url));
|
||||
return new types.DocumentLink(Range.to(link.range), link.url ? URI.parse(link.url) : undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,7 +888,7 @@ export namespace TextDocumentSaveReason {
|
||||
|
||||
export namespace EndOfLine {
|
||||
|
||||
export function from(eol: vscode.EndOfLine): EndOfLineSequence {
|
||||
export function from(eol: vscode.EndOfLine): EndOfLineSequence | undefined {
|
||||
if (eol === types.EndOfLine.CRLF) {
|
||||
return EndOfLineSequence.CRLF;
|
||||
} else if (eol === types.EndOfLine.LF) {
|
||||
@@ -886,7 +897,7 @@ export namespace EndOfLine {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function to(eol: EndOfLineSequence): vscode.EndOfLine {
|
||||
export function to(eol: EndOfLineSequence): vscode.EndOfLine | undefined {
|
||||
if (eol === EndOfLineSequence.CRLF) {
|
||||
return types.EndOfLine.CRLF;
|
||||
} else if (eol === EndOfLineSequence.LF) {
|
||||
@@ -903,7 +914,7 @@ export namespace ProgressLocation {
|
||||
case types.ProgressLocation.Window: return MainProgressLocation.Window;
|
||||
case types.ProgressLocation.Notification: return MainProgressLocation.Notification;
|
||||
}
|
||||
return undefined;
|
||||
throw new Error(`Unknown 'ProgressLocation'`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +946,7 @@ export namespace FoldingRangeKind {
|
||||
|
||||
export namespace TextEditorOptions {
|
||||
|
||||
export function from(options?: vscode.TextDocumentShowOptions): ITextEditorOptions {
|
||||
export function from(options?: vscode.TextDocumentShowOptions): ITextEditorOptions | undefined {
|
||||
if (options) {
|
||||
return {
|
||||
pinned: typeof options.preview === 'boolean' ? !options.preview : undefined,
|
||||
@@ -975,7 +986,10 @@ export namespace GlobPattern {
|
||||
|
||||
export namespace LanguageSelector {
|
||||
|
||||
export function from(selector: vscode.DocumentSelector): languageSelector.LanguageSelector {
|
||||
export function from(selector: undefined): undefined;
|
||||
export function from(selector: vscode.DocumentSelector): languageSelector.LanguageSelector;
|
||||
export function from(selector: vscode.DocumentSelector | undefined): languageSelector.LanguageSelector | undefined;
|
||||
export function from(selector: vscode.DocumentSelector | undefined): languageSelector.LanguageSelector | undefined {
|
||||
if (!selector) {
|
||||
return undefined;
|
||||
} else if (Array.isArray(selector)) {
|
||||
@@ -986,7 +1000,7 @@ export namespace LanguageSelector {
|
||||
return <languageSelector.LanguageFilter>{
|
||||
language: selector.language,
|
||||
scheme: selector.scheme,
|
||||
pattern: GlobPattern.from(selector.pattern),
|
||||
pattern: typeof selector.pattern === 'undefined' ? undefined : GlobPattern.from(selector.pattern),
|
||||
exclusive: selector.exclusive
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,6 +16,18 @@ import { generateUuid } from 'vs/base/common/uuid';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
|
||||
function es5ClassCompat(target: Function): any {
|
||||
///@ts-ignore
|
||||
function _() { return Reflect.construct(target, arguments, this.constructor); }
|
||||
Object.defineProperty(_, 'name', Object.getOwnPropertyDescriptor(target, 'name')!);
|
||||
///@ts-ignore
|
||||
Object.setPrototypeOf(_, target);
|
||||
///@ts-ignore
|
||||
Object.setPrototypeOf(_.prototype, target.prototype);
|
||||
return _;
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Disposable {
|
||||
|
||||
static from(...inDisposables: { dispose(): any }[]): Disposable {
|
||||
@@ -46,6 +58,7 @@ export class Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Position {
|
||||
|
||||
static Min(...positions: Position[]): Position {
|
||||
@@ -217,6 +230,7 @@ export class Position {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Range {
|
||||
|
||||
static isRange(thing: any): thing is vscode.Range {
|
||||
@@ -351,6 +365,7 @@ export class Range {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Selection extends Range {
|
||||
|
||||
static isSelection(thing: any): thing is Selection {
|
||||
@@ -421,6 +436,7 @@ export enum EndOfLine {
|
||||
CRLF = 2
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class TextEdit {
|
||||
|
||||
static isTextEdit(thing: any): thing is TextEdit {
|
||||
@@ -524,6 +540,7 @@ export interface IFileTextEdit {
|
||||
edit: TextEdit;
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class WorkspaceEdit implements vscode.WorkspaceEdit {
|
||||
|
||||
private _edits = new Array<IFileOperation | IFileTextEdit>();
|
||||
@@ -627,6 +644,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SnippetString {
|
||||
|
||||
static isSnippetString(thing: any): thing is SnippetString {
|
||||
@@ -720,6 +738,7 @@ export enum DiagnosticSeverity {
|
||||
Error = 0
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Location {
|
||||
|
||||
static isLocation(thing: any): thing is Location {
|
||||
@@ -758,6 +777,7 @@ export class Location {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DiagnosticRelatedInformation {
|
||||
|
||||
static is(thing: any): thing is DiagnosticRelatedInformation {
|
||||
@@ -791,6 +811,7 @@ export class DiagnosticRelatedInformation {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Diagnostic {
|
||||
|
||||
range: Range;
|
||||
@@ -835,6 +856,7 @@ export class Diagnostic {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Hover {
|
||||
|
||||
public contents: vscode.MarkdownString[] | vscode.MarkedString[];
|
||||
@@ -864,6 +886,7 @@ export enum DocumentHighlightKind {
|
||||
Write = 2
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DocumentHighlight {
|
||||
|
||||
range: Range;
|
||||
@@ -911,6 +934,7 @@ export enum SymbolKind {
|
||||
TypeParameter = 25
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SymbolInformation {
|
||||
|
||||
static validate(candidate: SymbolInformation): void {
|
||||
@@ -924,9 +948,9 @@ export class SymbolInformation {
|
||||
kind: SymbolKind;
|
||||
containerName: string | undefined;
|
||||
|
||||
constructor(name: string, kind: SymbolKind, containerName: string, location: Location);
|
||||
constructor(name: string, kind: SymbolKind, containerName: string | undefined, location: Location);
|
||||
constructor(name: string, kind: SymbolKind, range: Range, uri?: URI, containerName?: string);
|
||||
constructor(name: string, kind: SymbolKind, rangeOrContainer: string | Range, locationOrUri?: Location | URI, containerName?: string) {
|
||||
constructor(name: string, kind: SymbolKind, rangeOrContainer: string | undefined | Range, locationOrUri?: Location | URI, containerName?: string) {
|
||||
this.name = name;
|
||||
this.kind = kind;
|
||||
this.containerName = containerName;
|
||||
@@ -954,6 +978,7 @@ export class SymbolInformation {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DocumentSymbol {
|
||||
|
||||
static validate(candidate: DocumentSymbol): void {
|
||||
@@ -993,6 +1018,7 @@ export enum CodeActionTrigger {
|
||||
Manual = 2,
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class CodeAction {
|
||||
title: string;
|
||||
|
||||
@@ -1011,6 +1037,7 @@ export class CodeAction {
|
||||
}
|
||||
|
||||
|
||||
@es5ClassCompat
|
||||
export class CodeActionKind {
|
||||
private static readonly sep = '.';
|
||||
|
||||
@@ -1041,6 +1068,7 @@ export class CodeActionKind {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SelectionRangeKind {
|
||||
|
||||
private static readonly _sep = '.';
|
||||
@@ -1060,6 +1088,7 @@ export class SelectionRangeKind {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SelectionRange {
|
||||
|
||||
kind: SelectionRangeKind;
|
||||
@@ -1072,6 +1101,7 @@ export class SelectionRange {
|
||||
}
|
||||
|
||||
|
||||
@es5ClassCompat
|
||||
export class CodeLens {
|
||||
|
||||
range: Range;
|
||||
@@ -1088,6 +1118,7 @@ export class CodeLens {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class MarkdownString {
|
||||
|
||||
value: string;
|
||||
@@ -1118,6 +1149,7 @@ export class MarkdownString {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class ParameterInformation {
|
||||
|
||||
label: string | [number, number];
|
||||
@@ -1129,6 +1161,7 @@ export class ParameterInformation {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SignatureInformation {
|
||||
|
||||
label: string;
|
||||
@@ -1142,6 +1175,7 @@ export class SignatureInformation {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SignatureHelp {
|
||||
|
||||
signatures: SignatureInformation[];
|
||||
@@ -1166,8 +1200,8 @@ export enum CompletionTriggerKind {
|
||||
}
|
||||
|
||||
export interface CompletionContext {
|
||||
triggerKind: CompletionTriggerKind;
|
||||
triggerCharacter: string;
|
||||
readonly triggerKind: CompletionTriggerKind;
|
||||
readonly triggerCharacter?: string;
|
||||
}
|
||||
|
||||
export enum CompletionItemKind {
|
||||
@@ -1198,19 +1232,20 @@ export enum CompletionItemKind {
|
||||
TypeParameter = 24
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class CompletionItem implements vscode.CompletionItem {
|
||||
|
||||
label: string;
|
||||
kind: CompletionItemKind | undefined;
|
||||
detail: string;
|
||||
documentation: string | MarkdownString;
|
||||
sortText: string;
|
||||
filterText: string;
|
||||
preselect: boolean;
|
||||
detail?: string;
|
||||
documentation?: string | MarkdownString;
|
||||
sortText?: string;
|
||||
filterText?: string;
|
||||
preselect?: boolean;
|
||||
insertText: string | SnippetString;
|
||||
keepWhitespace?: boolean;
|
||||
range: Range;
|
||||
commitCharacters: string[];
|
||||
commitCharacters?: string[];
|
||||
textEdit: TextEdit;
|
||||
additionalTextEdits: TextEdit[];
|
||||
command: vscode.Command;
|
||||
@@ -1235,6 +1270,7 @@ export class CompletionItem implements vscode.CompletionItem {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class CompletionList {
|
||||
|
||||
isIncomplete?: boolean;
|
||||
@@ -1314,7 +1350,7 @@ export enum DecorationRangeBehavior {
|
||||
}
|
||||
|
||||
export namespace TextEditorSelectionChangeKind {
|
||||
export function fromValue(s: string) {
|
||||
export function fromValue(s: string | undefined) {
|
||||
switch (s) {
|
||||
case 'keyboard': return TextEditorSelectionChangeKind.Keyboard;
|
||||
case 'mouse': return TextEditorSelectionChangeKind.Mouse;
|
||||
@@ -1324,13 +1360,14 @@ export namespace TextEditorSelectionChangeKind {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DocumentLink {
|
||||
|
||||
range: Range;
|
||||
|
||||
target: URI;
|
||||
target?: URI;
|
||||
|
||||
constructor(range: Range, target: URI) {
|
||||
constructor(range: Range, target: URI | undefined) {
|
||||
if (target && !(target instanceof URI)) {
|
||||
throw illegalArgument('target');
|
||||
}
|
||||
@@ -1342,6 +1379,7 @@ export class DocumentLink {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Color {
|
||||
readonly red: number;
|
||||
readonly green: number;
|
||||
@@ -1358,6 +1396,7 @@ export class Color {
|
||||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
|
||||
@es5ClassCompat
|
||||
export class ColorInformation {
|
||||
range: Range;
|
||||
|
||||
@@ -1375,6 +1414,7 @@ export class ColorInformation {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class ColorPresentation {
|
||||
label: string;
|
||||
textEdit?: TextEdit;
|
||||
@@ -1416,6 +1456,7 @@ export enum TaskPanelKind {
|
||||
New = 3
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class TaskGroup implements vscode.TaskGroup {
|
||||
|
||||
private _id: string;
|
||||
@@ -1458,6 +1499,7 @@ export class TaskGroup implements vscode.TaskGroup {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class ProcessExecution implements vscode.ProcessExecution {
|
||||
|
||||
private _process: string;
|
||||
@@ -1530,6 +1572,7 @@ export class ProcessExecution implements vscode.ProcessExecution {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class ShellExecution implements vscode.ShellExecution {
|
||||
|
||||
private _commandLine: string;
|
||||
@@ -1626,32 +1669,33 @@ export enum TaskScope {
|
||||
Workspace = 2
|
||||
}
|
||||
|
||||
export class ExtensionCallbackExecution implements vscode.ExtensionCallbackExecution {
|
||||
private _callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<void>;
|
||||
export class CustomTaskExecution implements vscode.CustomTaskExecution {
|
||||
private _callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number | undefined>;
|
||||
|
||||
constructor(callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<void>) {
|
||||
constructor(callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number | undefined>) {
|
||||
this._callback = callback;
|
||||
}
|
||||
|
||||
public computeId(): string {
|
||||
const hash = crypto.createHash('md5');
|
||||
hash.update('extensionCallback');
|
||||
hash.update('customTaskExecution');
|
||||
hash.update(generateUuid());
|
||||
return hash.digest('hex');
|
||||
}
|
||||
|
||||
public set callback(value: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<void>) {
|
||||
public set callback(value: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number | undefined>) {
|
||||
this._callback = value;
|
||||
}
|
||||
|
||||
public get callback(): (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<void> {
|
||||
public get callback(): (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable<number | undefined> {
|
||||
return this._callback;
|
||||
}
|
||||
}
|
||||
|
||||
export class Task implements vscode.TaskWithExtensionCallback {
|
||||
@es5ClassCompat
|
||||
export class Task implements vscode.TaskWithCustomTaskExecution {
|
||||
|
||||
private static ExtensionCallbackType: string = 'extensionCallback';
|
||||
private static ExtensionCallbackType: string = 'customTaskExecution';
|
||||
private static ProcessType: string = 'process';
|
||||
private static ShellType: string = 'shell';
|
||||
private static EmptyType: string = '$empty';
|
||||
@@ -1661,7 +1705,7 @@ export class Task implements vscode.TaskWithExtensionCallback {
|
||||
private _definition: vscode.TaskDefinition;
|
||||
private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder | undefined;
|
||||
private _name: string;
|
||||
private _execution: ProcessExecution | ShellExecution | ExtensionCallbackExecution | undefined;
|
||||
private _execution: ProcessExecution | ShellExecution | CustomTaskExecution | undefined;
|
||||
private _problemMatchers: string[];
|
||||
private _hasDefinedMatchers: boolean;
|
||||
private _isBackground: boolean;
|
||||
@@ -1670,8 +1714,8 @@ export class Task implements vscode.TaskWithExtensionCallback {
|
||||
private _presentationOptions: vscode.TaskPresentationOptions;
|
||||
private _runOptions: vscode.RunOptions;
|
||||
|
||||
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | ExtensionCallbackExecution, problemMatchers?: string | string[]);
|
||||
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | ExtensionCallbackExecution, problemMatchers?: string | string[]);
|
||||
constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomTaskExecution, problemMatchers?: string | string[]);
|
||||
constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomTaskExecution, 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[];
|
||||
@@ -1736,7 +1780,7 @@ export class Task implements vscode.TaskWithExtensionCallback {
|
||||
type: Task.ShellType,
|
||||
id: this._execution.computeId()
|
||||
};
|
||||
} else if (this._execution instanceof ExtensionCallbackExecution) {
|
||||
} else if (this._execution instanceof CustomTaskExecution) {
|
||||
this._definition = {
|
||||
type: Task.ExtensionCallbackType,
|
||||
id: this._execution.computeId()
|
||||
@@ -1783,18 +1827,18 @@ export class Task implements vscode.TaskWithExtensionCallback {
|
||||
}
|
||||
|
||||
get execution(): ProcessExecution | ShellExecution | undefined {
|
||||
return (this._execution instanceof ExtensionCallbackExecution) ? undefined : this._execution;
|
||||
return (this._execution instanceof CustomTaskExecution) ? undefined : this._execution;
|
||||
}
|
||||
|
||||
set execution(value: ProcessExecution | ShellExecution | undefined) {
|
||||
this.executionWithExtensionCallback = value;
|
||||
}
|
||||
|
||||
get executionWithExtensionCallback(): ProcessExecution | ShellExecution | ExtensionCallbackExecution | undefined {
|
||||
get executionWithExtensionCallback(): ProcessExecution | ShellExecution | CustomTaskExecution | undefined {
|
||||
return this._execution;
|
||||
}
|
||||
|
||||
set executionWithExtensionCallback(value: ProcessExecution | ShellExecution | ExtensionCallbackExecution | undefined) {
|
||||
set executionWithExtensionCallback(value: ProcessExecution | ShellExecution | CustomTaskExecution | undefined) {
|
||||
if (value === null) {
|
||||
value = undefined;
|
||||
}
|
||||
@@ -1895,6 +1939,7 @@ export enum ProgressLocation {
|
||||
Notification = 15
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class TreeItem {
|
||||
|
||||
label?: string | vscode.TreeItemLabel;
|
||||
@@ -1934,6 +1979,7 @@ export class ThemeIcon {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class ThemeColor {
|
||||
id: string;
|
||||
constructor(id: string) {
|
||||
@@ -1949,6 +1995,7 @@ export enum ConfigurationTarget {
|
||||
WorkspaceFolder = 3
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class RelativePattern implements IRelativePattern {
|
||||
base: string;
|
||||
baseFolder?: URI;
|
||||
@@ -1981,6 +2028,7 @@ export class RelativePattern implements IRelativePattern {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class Breakpoint {
|
||||
|
||||
private _id: string | undefined;
|
||||
@@ -2011,6 +2059,7 @@ export class Breakpoint {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class SourceBreakpoint extends Breakpoint {
|
||||
readonly location: Location;
|
||||
|
||||
@@ -2023,6 +2072,7 @@ export class SourceBreakpoint extends Breakpoint {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class FunctionBreakpoint extends Breakpoint {
|
||||
readonly functionName: string;
|
||||
|
||||
@@ -2035,6 +2085,7 @@ export class FunctionBreakpoint extends Breakpoint {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable {
|
||||
readonly command: string;
|
||||
readonly args: string[];
|
||||
@@ -2047,6 +2098,7 @@ export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DebugAdapterServer implements vscode.DebugAdapterServer {
|
||||
readonly port: number;
|
||||
readonly host?: string;
|
||||
@@ -2058,6 +2110,7 @@ export class DebugAdapterServer implements vscode.DebugAdapterServer {
|
||||
}
|
||||
|
||||
/*
|
||||
@es5ClassCompat
|
||||
export class DebugAdapterImplementation implements vscode.DebugAdapterImplementation {
|
||||
readonly implementation: any;
|
||||
|
||||
@@ -2085,6 +2138,7 @@ export enum FileChangeType {
|
||||
Deleted = 3,
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class FileSystemError extends Error {
|
||||
|
||||
static FileExists(messageOrUri?: string | URI): FileSystemError {
|
||||
@@ -2127,6 +2181,7 @@ export class FileSystemError extends Error {
|
||||
|
||||
//#region folding api
|
||||
|
||||
@es5ClassCompat
|
||||
export class FoldingRange {
|
||||
|
||||
start: number;
|
||||
@@ -2162,6 +2217,7 @@ export enum CommentThreadCollapsibleState {
|
||||
Expanded = 1
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class QuickInputButtons {
|
||||
|
||||
static readonly Back: vscode.QuickInputButton = { iconPath: 'back.svg' };
|
||||
|
||||
@@ -333,7 +333,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
||||
}
|
||||
|
||||
const webview = new ExtHostWebview(webviewHandle, this._proxy, options);
|
||||
const revivedPanel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeConverters.ViewColumn.to(position), options, webview);
|
||||
const revivedPanel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeof position === 'number' ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
|
||||
this._webviewPanels.set(webviewHandle, revivedPanel);
|
||||
return Promise.resolve(serializer.deserializeWebviewPanel(revivedPanel, state));
|
||||
}
|
||||
|
||||
@@ -17,14 +17,15 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IRawFileMatch2, resultIsMatch } from 'vs/platform/search/common/search';
|
||||
import { IRawFileMatch2, resultIsMatch } from 'vs/workbench/services/search/common/search';
|
||||
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { Range, RelativePattern } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtHostWorkspaceShape, IMainContext, IWorkspaceData, MainContext, MainThreadMessageServiceShape, MainThreadWorkspaceShape } from './extHost.protocol';
|
||||
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext } from './extHost.protocol';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
|
||||
function isFolderEqual(folderA: URI, folderB: URI): boolean {
|
||||
return isEqual(folderA, folderB, !isLinux);
|
||||
@@ -56,7 +57,7 @@ interface MutableWorkspaceFolder extends vscode.WorkspaceFolder {
|
||||
|
||||
class ExtHostWorkspaceImpl extends Workspace {
|
||||
|
||||
static toExtHostWorkspace(data: IWorkspaceData, previousConfirmedWorkspace?: ExtHostWorkspaceImpl, previousUnconfirmedWorkspace?: ExtHostWorkspaceImpl): { workspace: ExtHostWorkspaceImpl, added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[] } {
|
||||
static toExtHostWorkspace(data: IWorkspaceData, previousConfirmedWorkspace?: ExtHostWorkspaceImpl, previousUnconfirmedWorkspace?: ExtHostWorkspaceImpl): { workspace: ExtHostWorkspaceImpl | null, added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[] } {
|
||||
if (!data) {
|
||||
return { workspace: null, added: [], removed: [] };
|
||||
}
|
||||
@@ -68,7 +69,7 @@ class ExtHostWorkspaceImpl extends Workspace {
|
||||
// data and update their properties. It could be that an extension stored them
|
||||
// for later use and we want to keep them "live" if they are still present.
|
||||
const oldWorkspace = previousConfirmedWorkspace;
|
||||
if (oldWorkspace) {
|
||||
if (previousConfirmedWorkspace) {
|
||||
folders.forEach((folderData, index) => {
|
||||
const folderUri = URI.revive(folderData.uri);
|
||||
const existingFolder = ExtHostWorkspaceImpl._findFolder(previousUnconfirmedWorkspace || previousConfirmedWorkspace, folderUri);
|
||||
@@ -95,7 +96,7 @@ class ExtHostWorkspaceImpl extends Workspace {
|
||||
return { workspace, added, removed };
|
||||
}
|
||||
|
||||
private static _findFolder(workspace: ExtHostWorkspaceImpl, folderUriToFind: URI): MutableWorkspaceFolder {
|
||||
private static _findFolder(workspace: ExtHostWorkspaceImpl, folderUriToFind: URI): MutableWorkspaceFolder | undefined {
|
||||
for (let i = 0; i < workspace.folders.length; i++) {
|
||||
const folder = workspace.workspaceFolders[i];
|
||||
if (isFolderEqual(folder.uri, folderUriToFind)) {
|
||||
@@ -127,28 +128,70 @@ class ExtHostWorkspaceImpl extends Workspace {
|
||||
return this._workspaceFolders.slice(0);
|
||||
}
|
||||
|
||||
getWorkspaceFolder(uri: URI, resolveParent?: boolean): vscode.WorkspaceFolder {
|
||||
getWorkspaceFolder(uri: URI, resolveParent?: boolean): vscode.WorkspaceFolder | undefined {
|
||||
if (resolveParent && this._structure.get(uri.toString())) {
|
||||
// `uri` is a workspace folder so we check for its parent
|
||||
uri = dirname(uri);
|
||||
uri = dirname(uri)!;
|
||||
}
|
||||
return this._structure.findSubstr(uri.toString());
|
||||
}
|
||||
|
||||
resolveWorkspaceFolder(uri: URI): vscode.WorkspaceFolder {
|
||||
resolveWorkspaceFolder(uri: URI): vscode.WorkspaceFolder | undefined {
|
||||
return this._structure.get(uri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
|
||||
private readonly _mainContext: IMainContext;
|
||||
private readonly _logService: ILogService;
|
||||
private readonly _requestIdProvider: Counter;
|
||||
private readonly _barrier: Barrier;
|
||||
private _actual: ExtHostWorkspaceProvider | null;
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
logService: ILogService,
|
||||
requestIdProvider: Counter
|
||||
) {
|
||||
this._mainContext = mainContext;
|
||||
this._logService = logService;
|
||||
this._requestIdProvider = requestIdProvider;
|
||||
this._barrier = new Barrier();
|
||||
this._actual = null;
|
||||
}
|
||||
|
||||
public getWorkspaceProvider(): Promise<ExtHostWorkspaceProvider> {
|
||||
return this._barrier.wait().then(_ => this._actual!);
|
||||
}
|
||||
|
||||
$initializeWorkspace(data: IWorkspaceData): void {
|
||||
this._actual = new ExtHostWorkspaceProvider(this._mainContext, data, this._logService, this._requestIdProvider);
|
||||
this._barrier.open();
|
||||
}
|
||||
|
||||
$acceptWorkspaceData(workspace: IWorkspaceData): void {
|
||||
if (this._actual) {
|
||||
this._actual.$acceptWorkspaceData(workspace);
|
||||
}
|
||||
}
|
||||
|
||||
$handleTextSearchResult(result: IRawFileMatch2, requestId: number): void {
|
||||
if (this._actual) {
|
||||
this._actual.$handleTextSearchResult(result, requestId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
export class ExtHostWorkspaceProvider {
|
||||
|
||||
private readonly _onDidChangeWorkspace = new Emitter<vscode.WorkspaceFoldersChangeEvent>();
|
||||
|
||||
private _confirmedWorkspace?: ExtHostWorkspaceImpl;
|
||||
private _unconfirmedWorkspace?: ExtHostWorkspaceImpl;
|
||||
|
||||
private readonly _proxy: MainThreadWorkspaceShape;
|
||||
|
||||
private _confirmedWorkspace: ExtHostWorkspaceImpl;
|
||||
private _unconfirmedWorkspace: ExtHostWorkspaceImpl;
|
||||
|
||||
private _messageService: MainThreadMessageServiceShape;
|
||||
private readonly _messageService: MainThreadMessageServiceShape;
|
||||
|
||||
readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event;
|
||||
|
||||
@@ -162,24 +205,24 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace);
|
||||
this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService);
|
||||
this._confirmedWorkspace = ExtHostWorkspaceImpl.toExtHostWorkspace(data).workspace;
|
||||
this._confirmedWorkspace = ExtHostWorkspaceImpl.toExtHostWorkspace(data).workspace || undefined;
|
||||
}
|
||||
|
||||
// --- workspace ---
|
||||
|
||||
get workspace(): Workspace {
|
||||
get workspace(): Workspace | undefined {
|
||||
return this._actualWorkspace;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
get name(): string | undefined {
|
||||
return this._actualWorkspace ? this._actualWorkspace.name : undefined;
|
||||
}
|
||||
|
||||
private get _actualWorkspace(): ExtHostWorkspaceImpl {
|
||||
private get _actualWorkspace(): ExtHostWorkspaceImpl | undefined {
|
||||
return this._unconfirmedWorkspace || this._confirmedWorkspace;
|
||||
}
|
||||
|
||||
getWorkspaceFolders(): vscode.WorkspaceFolder[] {
|
||||
getWorkspaceFolders(): vscode.WorkspaceFolder[] | undefined {
|
||||
if (!this._actualWorkspace) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -215,7 +258,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
|
||||
// Simulate the updateWorkspaceFolders method on our data to do more validation
|
||||
const newWorkspaceFolders = currentWorkspaceFolders.slice(0);
|
||||
newWorkspaceFolders.splice(index, deleteCount, ...validatedDistinctWorkspaceFoldersToAdd.map(f => ({ uri: f.uri, name: f.name || basenameOrAuthority(f.uri), index: undefined })));
|
||||
newWorkspaceFolders.splice(index, deleteCount, ...validatedDistinctWorkspaceFoldersToAdd.map(f => ({ uri: f.uri, name: f.name || basenameOrAuthority(f.uri), index: undefined! /* fixed later */ })));
|
||||
|
||||
for (let i = 0; i < newWorkspaceFolders.length; i++) {
|
||||
const folder = newWorkspaceFolders[i];
|
||||
@@ -250,21 +293,21 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
return true;
|
||||
}
|
||||
|
||||
getWorkspaceFolder(uri: vscode.Uri, resolveParent?: boolean): vscode.WorkspaceFolder {
|
||||
getWorkspaceFolder(uri: vscode.Uri, resolveParent?: boolean): vscode.WorkspaceFolder | undefined {
|
||||
if (!this._actualWorkspace) {
|
||||
return undefined;
|
||||
}
|
||||
return this._actualWorkspace.getWorkspaceFolder(uri, resolveParent);
|
||||
}
|
||||
|
||||
resolveWorkspaceFolder(uri: vscode.Uri): vscode.WorkspaceFolder {
|
||||
resolveWorkspaceFolder(uri: vscode.Uri): vscode.WorkspaceFolder | undefined {
|
||||
if (!this._actualWorkspace) {
|
||||
return undefined;
|
||||
}
|
||||
return this._actualWorkspace.resolveWorkspaceFolder(uri);
|
||||
}
|
||||
|
||||
getPath(): string {
|
||||
getPath(): string | undefined {
|
||||
|
||||
// this is legacy from the days before having
|
||||
// multi-root and we keep it only alive if there
|
||||
@@ -281,9 +324,9 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
return folders[0].uri.fsPath;
|
||||
}
|
||||
|
||||
getRelativePath(pathOrUri: string | vscode.Uri, includeWorkspace?: boolean): string {
|
||||
getRelativePath(pathOrUri: string | vscode.Uri, includeWorkspace?: boolean): string | undefined {
|
||||
|
||||
let path: string;
|
||||
let path: string | undefined;
|
||||
if (typeof pathOrUri === 'string') {
|
||||
path = pathOrUri;
|
||||
} else if (typeof pathOrUri !== 'undefined') {
|
||||
@@ -303,7 +346,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
return path;
|
||||
}
|
||||
|
||||
if (typeof includeWorkspace === 'undefined') {
|
||||
if (typeof includeWorkspace === 'undefined' && this._actualWorkspace) {
|
||||
includeWorkspace = this._actualWorkspace.folders.length > 1;
|
||||
}
|
||||
|
||||
@@ -324,7 +367,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
name: this._actualWorkspace.name,
|
||||
configuration: this._actualWorkspace.configuration,
|
||||
folders
|
||||
} as IWorkspaceData, this._actualWorkspace).workspace;
|
||||
} as IWorkspaceData, this._actualWorkspace).workspace || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +377,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
|
||||
// Update our workspace object. We have a confirmed workspace, so we drop our
|
||||
// unconfirmed workspace.
|
||||
this._confirmedWorkspace = workspace;
|
||||
this._confirmedWorkspace = workspace || undefined;
|
||||
this._unconfirmedWorkspace = undefined;
|
||||
|
||||
// Events
|
||||
@@ -349,8 +392,8 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
findFiles(include: string | RelativePattern, exclude: vscode.GlobPattern, maxResults: number, extensionId: ExtensionIdentifier, token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.Uri[]> {
|
||||
this._logService.trace(`extHostWorkspace#findFiles: fileSearch, extension: ${extensionId.value}, entryPoint: findFiles`);
|
||||
|
||||
let includePattern: string;
|
||||
let includeFolder: URI;
|
||||
let includePattern: string | undefined;
|
||||
let includeFolder: URI | undefined;
|
||||
if (include) {
|
||||
if (typeof include === 'string') {
|
||||
includePattern = include;
|
||||
@@ -362,7 +405,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
}
|
||||
}
|
||||
|
||||
let excludePatternOrDisregardExcludes: string | false;
|
||||
let excludePatternOrDisregardExcludes: string | false = false;
|
||||
if (exclude === null) {
|
||||
excludePatternOrDisregardExcludes = false;
|
||||
} else if (exclude) {
|
||||
@@ -381,7 +424,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
.then(data => Array.isArray(data) ? data.map(URI.revive) : []);
|
||||
}
|
||||
|
||||
findTextInFiles(query: vscode.TextSearchQuery, options: vscode.FindTextInFilesOptions, callback: (result: vscode.TextSearchResult) => void, extensionId: ExtensionIdentifier, token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.TextSearchComplete> {
|
||||
findTextInFiles(query: vscode.TextSearchQuery, options: vscode.FindTextInFilesOptions, callback: (result: vscode.TextSearchResult) => void, extensionId: ExtensionIdentifier, token: vscode.CancellationToken = CancellationToken.None): Promise<vscode.TextSearchComplete | undefined> {
|
||||
this._logService.trace(`extHostWorkspace#findTextInFiles: textSearch, extension: ${extensionId.value}, entryPoint: findTextInFiles`);
|
||||
|
||||
const requestId = this._requestIdProvider.getNext();
|
||||
@@ -413,7 +456,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
beforeContext: options.beforeContext,
|
||||
|
||||
includePattern: options.include && globPatternToString(options.include),
|
||||
excludePattern: options.exclude && globPatternToString(options.exclude)
|
||||
excludePattern: options.exclude ? globPatternToString(options.exclude) : undefined
|
||||
};
|
||||
|
||||
let isCanceled = false;
|
||||
@@ -424,7 +467,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
}
|
||||
|
||||
const uri = URI.revive(p.resource);
|
||||
p.results.forEach(result => {
|
||||
p.results!.forEach(result => {
|
||||
if (resultIsMatch(result)) {
|
||||
callback(<vscode.TextSearchMatch>{
|
||||
uri,
|
||||
@@ -471,7 +514,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
return this._proxy.$saveAll(includeUntitled);
|
||||
}
|
||||
|
||||
resolveProxy(url: string): Promise<string> {
|
||||
resolveProxy(url: string): Promise<string | undefined> {
|
||||
return this._proxy.$resolveProxy(url);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user