diff --git a/extensions/git/package.json b/extensions/git/package.json index 2a92f71671228d4812112de1554a0700b0f136ce..9cee78f096b5696f9d7f3202570a38f97a0c359b 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1139,11 +1139,6 @@ "when": "scmProvider == git && scmResourceGroup == workingTree", "group": "2_view" }, - { - "command": "git.openChange", - "when": "scmProvider == git && scmResourceGroup == workingTree", - "group": "navigation" - }, { "command": "git.openChange", "when": "scmProvider == git && scmResourceGroup == untracked", diff --git a/package.json b/package.json index 5baee5dd59c8c04ec14f16eed3c6c37d7605c18a..9595c9037ee6d04f3c40cf1d5c04c049103e32d4 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,8 @@ "@types/node": "^10.12.12", "@types/semver": "^5.5.0", "@types/sinon": "^1.16.36", + "@types/yauzl": "^2.9.1", + "@types/yazl": "^2.4.2", "@types/webpack": "^4.4.10", "@types/winreg": "^1.2.30", "ansi-colors": "^3.2.3", diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index aa0af48b342b88aa74f80f88297a6bc06620c1a2..a6430a44ccb82112224abba696297e2daa99c5d1 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -14,7 +14,6 @@ }, "include": [ "typings/require.d.ts", - "typings/require-monaco.d.ts", "typings/thenable.d.ts", "typings/es6-promise.d.ts", "typings/lib.es2018.promise.d.ts", diff --git a/src/typings/require.d.ts b/src/typings/require.d.ts index 0d8aa16d726343659a1cabbd2b039daff8dd3110..733da26c9adfb2f25d6403c41ebcf9026214f74a 100644 --- a/src/typings/require.d.ts +++ b/src/typings/require.d.ts @@ -48,3 +48,5 @@ interface NodeRequire { __$__nodeRequire(moduleName: string): T; getStats(): ReadonlyArray; } + +declare var require: NodeRequire; diff --git a/src/typings/yauzl.d.ts b/src/typings/yauzl.d.ts deleted file mode 100644 index 39ef2ad9488e2460719e22da7d653e1bc334d558..0000000000000000000000000000000000000000 --- a/src/typings/yauzl.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'yauzl' { - - import { EventEmitter } from 'events'; - import { Readable } from 'stream'; - - export class Entry { - fileName: string; - extraFields: { id: number; data: Buffer; }[]; - comment: string; - versionMadeBy: number; - versionNeededToExtract: number; - generalPurposeBitFlag: number; - compressionMethod: number; - lastModFileTime: number; - lastModFileDate: number; - crc32: number; - compressedSize: number; - uncompressedSize: number; - fileNameLength: number; - extraFieldLength: number; - fileCommentLength: number; - internalFileAttributes: number; - externalFileAttributes: number; - relativeOffsetOfLocalHeader: number; - getLastModDate(): Date; - } - - export class ZipFile extends EventEmitter { - readEntry(): void; - openReadStream(entry: Entry, callback: (err?: Error, stream?: Readable) => void): void; - close(): void; - isOpen: boolean; - entryCount: number; - comment: string; - } - - export interface IOptions { - autoClose?: boolean; - lazyEntries?: boolean; - } - - export function open(path: string, callback: (err?: Error, zipfile?: ZipFile) => void): void; - export function open(path: string, options: IOptions | undefined, callback: (err?: Error, zipfile?: ZipFile) => void): void; -} \ No newline at end of file diff --git a/src/typings/yazl.d.ts b/src/typings/yazl.d.ts deleted file mode 100644 index 5644d092913ef480ce72314190383627ef9e1a41..0000000000000000000000000000000000000000 --- a/src/typings/yazl.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'yazl' { - import * as stream from 'stream'; - - class ZipFile { - outputStream: stream.Stream; - addBuffer(buffer: Buffer, path: string): void; - addFile(localPath: string, path: string): void; - end(): void; - } -} \ No newline at end of file diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 49acc994b208f3eb011193b431c5eb9842fe9dbf..dc83adc86f408f19f83670f3b7da62e0aab8162d 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -14,7 +14,7 @@ height: 100%; position: absolute; top: 0; - left: 18px; + left: 16px; pointer-events: none; } diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index eaa6fa36ff81f2411a49a599d864ccaf08714802..93ebb6ad6075690868b810e8feaf09eae760de66 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -163,7 +163,7 @@ function extractZip(zipfile: ZipFile, targetPath: string, options: IOptions, tok function openZip(zipFile: string, lazy: boolean = false): Promise { return new Promise((resolve, reject) => { - _openZip(zipFile, lazy ? { lazyEntries: true } : undefined, (error?: Error, zipfile?: ZipFile) => { + _openZip(zipFile, lazy ? { lazyEntries: true } : undefined!, (error?: Error, zipfile?: ZipFile) => { if (error) { reject(toExtractError(error)); } else { diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index bbec87911f9c032a9ff306b5db2f2f5c9089a0ee..c00e6162bcb2ef0a537b065dbaf00abb7a71e503 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -498,39 +498,35 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha this._registrations.set(handle, callh.CallHierarchyProviderRegistry.register(selector, { prepareCallHierarchy: async (document, position, token) => { - const result = await this._proxy.$prepareCallHierarchy(handle, document.uri, position, token); - if (!result) { + const item = await this._proxy.$prepareCallHierarchy(handle, document.uri, position, token); + if (!item) { return undefined; } return { - dispose: () => this._proxy.$releaseCallHierarchy(handle, result.sessionId), - root: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(result.root) + dispose: () => this._proxy.$releaseCallHierarchy(handle, item._sessionId), + root: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item) }; }, provideOutgoingCalls: async (item, token) => { - const outgoing = await this._proxy.$provideCallHierarchyOutgoingCalls(handle, item.id, token); + const outgoing = await this._proxy.$provideCallHierarchyOutgoingCalls(handle, item._sessionId, item._itemId, token); if (!outgoing) { return outgoing; } - return outgoing.map(([item, fromRanges]): callh.OutgoingCall => { - return { - to: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), - fromRanges - }; + outgoing.forEach(value => { + value.to = MainThreadLanguageFeatures._reviveCallHierarchyItemDto(value.to); }); + return outgoing; }, provideIncomingCalls: async (item, token) => { - const incoming = await this._proxy.$provideCallHierarchyIncomingCalls(handle, item.id, token); + const incoming = await this._proxy.$provideCallHierarchyIncomingCalls(handle, item._sessionId, item._itemId, token); if (!incoming) { return incoming; } - return incoming.map(([item, fromRanges]): callh.IncomingCall => { - return { - from: MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item), - fromRanges - }; + incoming.forEach(value => { + value.from = MainThreadLanguageFeatures._reviveCallHierarchyItemDto(value.from); }); + return incoming; } })); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 6c6364cf730770765eab544cf2626676a39d1806..63da5a6a6b2053aec586395522ef63d17c4b7e35 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -71,7 +71,7 @@ export interface IStaticWorkspaceData { } export interface IWorkspaceData extends IStaticWorkspaceData { - folders: { uri: UriComponents, name: string, index: number }[]; + folders: { uri: UriComponents, name: string, index: number; }[]; } export interface IInitData { @@ -97,7 +97,7 @@ export interface IConfigurationInitData extends IConfigurationData { export interface IWorkspaceConfigurationChangeEventData { changedConfiguration: IConfigurationModel; - changedConfigurationByResource: { [folder: string]: IConfigurationModel }; + changedConfigurationByResource: { [folder: string]: IConfigurationModel; }; } export interface IExtHostContext extends IRPCProtocol { @@ -136,7 +136,7 @@ export type CommentThreadChanges = Partial<{ label: string, contextValue: string, comments: modes.Comment[], - collapseState: modes.CommentThreadCollapsibleState + collapseState: modes.CommentThreadCollapsibleState; }>; export interface MainThreadCommentsShape extends IDisposable { @@ -165,13 +165,13 @@ export interface MainThreadDialogOpenOptions { canSelectFiles?: boolean; canSelectFolders?: boolean; canSelectMany?: boolean; - filters?: { [name: string]: string[] }; + filters?: { [name: string]: string[]; }; } export interface MainThreadDialogSaveOptions { defaultUri?: UriComponents; saveLabel?: string; - filters?: { [name: string]: string[] }; + filters?: { [name: string]: string[]; }; } export interface MainThreadDiaglogsShape extends IDisposable { @@ -254,8 +254,8 @@ export interface MainThreadTextEditorsShape extends IDisposable { } export interface MainThreadTreeViewsShape extends IDisposable { - $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void; - $refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise; + $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean; }): void; + $refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem; }): Promise; $reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise; $setMessage(treeViewId: string, message: string): void; $setTitle(treeViewId: string, title: string): void; @@ -278,7 +278,7 @@ export interface MainThreadKeytarShape extends IDisposable { $setPassword(service: string, account: string, password: string): Promise; $deletePassword(service: string, account: string): Promise; $findPassword(service: string): Promise; - $findCredentials(service: string): Promise>; + $findCredentials(service: string): Promise>; } export interface IRegExpDto { @@ -321,7 +321,7 @@ export interface ILanguageConfigurationDto { }; } -export type GlobPattern = string | { base: string; pattern: string }; +export type GlobPattern = string | { base: string; pattern: string; }; export interface IDocumentFilterDto { $serialized: true; @@ -400,7 +400,7 @@ export interface TerminalLaunchConfig { shellPath?: string; shellArgs?: string[] | string; cwd?: string | UriComponents; - env?: { [key: string]: string | null }; + env?: { [key: string]: string | null; }; waitOnExit?: boolean; strictEnv?: boolean; hideFromUser?: boolean; @@ -408,7 +408,7 @@ export interface TerminalLaunchConfig { } export interface MainThreadTerminalServiceShape extends IDisposable { - $createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string }>; + $createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string; }>; $dispose(terminalId: number): void; $hide(terminalId: number): void; $sendText(terminalId: number, text: string, addNewLine: boolean): void; @@ -558,7 +558,7 @@ export interface MainThreadWebviewsShape extends IDisposable { $disposeWebview(handle: WebviewPanelHandle): void; $reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void; $setTitle(handle: WebviewPanelHandle, value: string): void; - $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents } | undefined): void; + $setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void; $setHtml(handle: WebviewPanelHandle, value: string): void; $setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void; @@ -593,7 +593,7 @@ export interface MainThreadUrlsShape extends IDisposable { $registerUriHandler(handle: number, extensionId: ExtensionIdentifier): Promise; $unregisterUriHandler(handle: number): Promise; $createAppUri(uri: UriComponents): Promise; - $proposedCreateAppUri(extensionId: ExtensionIdentifier, options?: { payload?: Partial }): Promise; + $proposedCreateAppUri(extensionId: ExtensionIdentifier, options?: { payload?: Partial; }): Promise; } export interface ExtHostUrlsShape { @@ -609,7 +609,7 @@ export interface MainThreadWorkspaceShape extends IDisposable { $startTextSearch(query: search.IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise; $checkExists(folders: UriComponents[], includes: string[], token: CancellationToken): Promise; $saveAll(includeUntitled?: boolean): Promise; - $updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string }[]): Promise; + $updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents, name?: string; }[]): Promise; $resolveProxy(url: string): Promise; } @@ -764,7 +764,7 @@ export interface MainThreadWindowShape extends IDisposable { export interface ExtHostCommandsShape { $executeContributedCommand(id: string, ...args: any[]): Promise; - $getContributedCommandHandlerDescriptions(): Promise<{ [id: string]: string | ICommandHandlerDescription }>; + $getContributedCommandHandlerDescriptions(): Promise<{ [id: string]: string | ICommandHandlerDescription; }>; } export interface ExtHostConfigurationShape { @@ -898,7 +898,7 @@ export interface ExtHostExtensionServiceShape { $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise; $activateByEvent(activationEvent: string): Promise; $activate(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise; - $setRemoteEnvironment(env: { [key: string]: string | null }): Promise; + $setRemoteEnvironment(env: { [key: string]: string | null; }): Promise; $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise; @@ -978,7 +978,7 @@ export interface ISuggestDataDto { [ISuggestDataDtoField.preselect]?: boolean; [ISuggestDataDtoField.insertText]?: string; [ISuggestDataDtoField.insertTextRules]?: modes.CompletionItemInsertTextRule; - [ISuggestDataDtoField.range]?: IRange | { insert: IRange, replace: IRange }; + [ISuggestDataDtoField.range]?: IRange | { insert: IRange, replace: IRange; }; [ISuggestDataDtoField.commitCharacters]?: string[]; [ISuggestDataDtoField.additionalTextEdits]?: ISingleEditOperation[]; [ISuggestDataDtoField.command]?: modes.Command; @@ -989,7 +989,7 @@ export interface ISuggestDataDto { export interface ISuggestResultDto { x?: number; - a: { insert: IRange, replace: IRange }; + a: { insert: IRange, replace: IRange; }; b: ISuggestDataDto[]; c?: boolean; } @@ -1112,7 +1112,8 @@ export interface ICodeLensDto { } export interface ICallHierarchyItemDto { - id: string; + _sessionId: string; + _itemId: string; kind: modes.SymbolKind; name: string; detail?: string; @@ -1121,6 +1122,16 @@ export interface ICallHierarchyItemDto { selectionRange: IRange; } +export interface IIncomingCallDto { + from: ICallHierarchyItemDto; + fromRanges: IRange[]; +} + +export interface IOutgoingCallDto { + fromRanges: IRange[]; + to: ICallHierarchyItemDto; +} + export interface ExtHostLanguageFeaturesShape { $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise; $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise; @@ -1155,9 +1166,9 @@ export interface ExtHostLanguageFeaturesShape { $provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise; $provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise; $provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise; - $prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: ICallHierarchyItemDto } | undefined>; - $provideCallHierarchyIncomingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[ICallHierarchyItemDto, IRange[]][] | undefined>; - $provideCallHierarchyOutgoingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[ICallHierarchyItemDto, IRange[]][] | undefined>; + $prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideCallHierarchyIncomingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise; + $provideCallHierarchyOutgoingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise; $releaseCallHierarchy(handle: number, sessionId: string): void; } @@ -1177,7 +1188,7 @@ export interface IShellLaunchConfigDto { executable?: string; args?: string[] | string; cwd?: string | UriComponents; - env?: { [key: string]: string | null }; + env?: { [key: string]: string | null; }; } export interface IShellDefinitionDto { @@ -1232,8 +1243,8 @@ export interface ExtHostTaskShape { $onDidStartTaskProcess(value: tasks.TaskProcessStartedDTO): void; $onDidEndTaskProcess(value: tasks.TaskProcessEndedDTO): void; $OnDidEndTask(execution: tasks.TaskExecutionDTO): void; - $resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string }, variables: string[] }): Promise<{ process?: string; variables: { [key: string]: string } }>; - $getDefaultShellAndArgs(): Thenable<{ shell: string, args: string[] | string | undefined }>; + $resolveVariables(workspaceFolder: UriComponents, toResolve: { process?: { name: string; cwd?: string; }, variables: string[]; }): Promise<{ process?: string; variables: { [key: string]: string; }; }>; + $getDefaultShellAndArgs(): Thenable<{ shell: string, args: string[] | string | undefined; }>; $jsonTasksSupported(): Thenable; } @@ -1321,7 +1332,7 @@ export interface DecorationRequest { } export type DecorationData = [number, boolean, string, string, ThemeColor]; -export type DecorationReply = { [id: number]: DecorationData }; +export type DecorationReply = { [id: number]: DecorationData; }; export interface ExtHostDecorationsShape { $provideDecorations(requests: DecorationRequest[], token: CancellationToken): Promise; diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index e0ae9e2f5f95a46a4573d6c0cdcb4e68943c815e..67e9ba8669e219ce3634ed21b1d5c1ee698dce8a 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as types from 'vs/workbench/api/common/extHostTypes'; -import { IRawColorInfo, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { IRawColorInfo, IWorkspaceEditDto, ICallHierarchyItemDto, IIncomingCallDto, IOutgoingCallDto } from 'vs/workbench/api/common/extHost.protocol'; import { ISingleEditOperation } from 'vs/editor/common/model'; import * as modes from 'vs/editor/common/modes'; import * as search from 'vs/workbench/contrib/search/common/search'; @@ -19,10 +19,97 @@ import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { IRange } from 'vs/editor/common/core/range'; +import { IPosition } from 'vs/editor/common/core/position'; + +//#region --- NEW world + +export class ApiCommandArgument { + + static readonly Uri = new ApiCommandArgument('uri', 'Uri of a text document', v => URI.isUri(v), v => v); + static readonly Position = new ApiCommandArgument('position', 'A position in a text document', v => types.Position.isPosition(v), typeConverters.Position.from); + + static readonly CallHierarchyItem = new ApiCommandArgument('item', 'A call hierarchy item', v => v instanceof types.CallHierarchyItem, typeConverters.CallHierarchyItem.to); + + constructor( + readonly name: string, + readonly description: string, + readonly validate: (v: V) => boolean, + readonly convert: (v: V) => O + ) { } +} + +export class ApiCommandResult { + + constructor( + readonly description: string, + readonly convert: (v: V) => O + ) { } +} + +export class ApiCommand { + + constructor( + readonly id: string, + readonly internalId: string, + readonly description: string, + readonly args: ApiCommandArgument[], + readonly result: ApiCommandResult + ) { } + + register(commands: ExtHostCommands): IDisposable { + + return commands.registerCommand(false, this.id, async (...apiArgs) => { + + const internalArgs = this.args.map((arg, i) => { + if (!arg.validate(apiArgs[i])) { + throw new Error(`Invalid argument '${arg.name}' when running '${this.id}', receieved: ${apiArgs[i]}`); + } + return arg.convert(apiArgs[i]); + }); + + const internalResult = await commands.executeCommand(this.internalId, ...internalArgs); + return this.result.convert(internalResult); + }, undefined, this._getCommandHandlerDesc()); + } + + private _getCommandHandlerDesc(): ICommandHandlerDescription { + return { + description: this.description, + args: this.args, + returns: this.result.description + }; + } +} + + +const newCommands: ApiCommand[] = [ + new ApiCommand( + 'vscode.prepareCallHierarchy', '_executePrepareCallHierarchy', 'Prepare call hierarchy at a position inside a document', + [ApiCommandArgument.Uri, ApiCommandArgument.Position], + new ApiCommandResult('A CallHierarchyItem or undefined', v => typeConverters.CallHierarchyItem.to(v)) + ), + new ApiCommand( + 'vscode.provideIncomingCalls', '_executeProvideIncomingCalls', 'Compute incoming calls for an item', + [ApiCommandArgument.CallHierarchyItem], + new ApiCommandResult('A CallHierarchyItem or undefined', v => v.map(typeConverters.CallHierarchyIncomingCall.to)) + ), + new ApiCommand( + 'vscode.provideOutgoingCalls', '_executeProvideOutgoingCalls', 'Compute outgoing calls for an item', + [ApiCommandArgument.CallHierarchyItem], + new ApiCommandResult('A CallHierarchyItem or undefined', v => v.map(typeConverters.CallHierarchyOutgoingCall.to)) + ), +]; + + +//#endregion + + +//#region OLD world export class ExtHostApiCommands { static register(commands: ExtHostCommands) { + newCommands.forEach(command => command.register(commands)); return new ExtHostApiCommands(commands).registerCommands(); } @@ -433,7 +520,7 @@ export class ExtHostApiCommands { }); } - private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range }): Promise { + private _executeColorPresentationProvider(color: types.Color, context: { uri: URI, range: types.Range; }): Promise { const args = { resource: context.uri, color: typeConverters.Color.from(color), diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index acb80872268a51888dd7076d51b65f7c62bc830c..ee4043d7860bdbe9469fc0dd600490b848f04921 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -26,6 +26,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { DisposableStore, dispose } from 'vs/base/common/lifecycle'; +import { IdGenerator } from 'vs/base/common/idGenerator'; // --- adapter @@ -751,7 +752,7 @@ class SuggestAdapter { } // 'overwrite[Before|After]'-logic - let range: vscode.Range | { inserting: vscode.Range, replacing: vscode.Range } | undefined; + let range: vscode.Range | { inserting: vscode.Range, replacing: vscode.Range; } | undefined; if (item.textEdit) { range = item.textEdit.range; } else if (item.range) { @@ -1034,15 +1035,15 @@ class SelectionRangeAdapter { class CallHierarchyAdapter { - private _idPool: number = 0; - private readonly _cache = new Map(); + private readonly _idPool = new IdGenerator(''); + private readonly _cache = new Map>(); constructor( private readonly _documents: ExtHostDocuments, private readonly _provider: vscode.CallHierarchyProvider ) { } - async prepareSession(uri: URI, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: extHostProtocol.ICallHierarchyItemDto } | undefined> { + async prepareSession(uri: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(uri); const pos = typeConvert.Position.to(position); @@ -1050,13 +1051,14 @@ class CallHierarchyAdapter { if (!item) { return undefined; } - const sessionId = String.fromCharCode(this._idPool++); - this._cache.set(sessionId, []); - return { sessionId, root: this._cacheAndConvertItem(sessionId, item) }; + const sessionId = this._idPool.nextId(); + + this._cache.set(sessionId, new Map()); + return this._cacheAndConvertItem(sessionId, item); } - async provideCallsTo(itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> { - const item = this._itemFromCache(itemId); + async provideCallsTo(sessionId: string, itemId: string, token: CancellationToken): Promise { + const item = this._itemFromCache(sessionId, itemId); if (!item) { throw new Error('missing call hierarchy item'); } @@ -1064,11 +1066,16 @@ class CallHierarchyAdapter { if (!calls) { return undefined; } - return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[this._cacheAndConvertItem(itemId, call.from), call.fromRanges.map(typeConvert.Range.from)])); + return calls.map(call => { + return { + from: this._cacheAndConvertItem(sessionId, call.from), + fromRanges: call.fromRanges.map(r => typeConvert.Range.from(r)) + }; + }); } - async provideCallsFrom(itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> { - const item = this._itemFromCache(itemId); + async provideCallsFrom(sessionId: string, itemId: string, token: CancellationToken): Promise { + const item = this._itemFromCache(sessionId, itemId); if (!item) { throw new Error('missing call hierarchy item'); } @@ -1076,7 +1083,12 @@ class CallHierarchyAdapter { if (!calls) { return undefined; } - return calls.map(call => (<[extHostProtocol.ICallHierarchyItemDto, IRange[]]>[this._cacheAndConvertItem(itemId, call.to), call.fromRanges.map(typeConvert.Range.from)])); + return calls.map(call => { + return { + to: this._cacheAndConvertItem(sessionId, call.to), + fromRanges: call.fromRanges.map(r => typeConvert.Range.from(r)) + }; + }); } releaseSession(sessionId: string): void { @@ -1085,9 +1097,10 @@ class CallHierarchyAdapter { private _cacheAndConvertItem(itemOrSessionId: string, item: vscode.CallHierarchyItem): extHostProtocol.ICallHierarchyItemDto { const sessionId = itemOrSessionId.charAt(0); - const array = this._cache.get(sessionId)!; + const map = this._cache.get(sessionId)!; const dto: extHostProtocol.ICallHierarchyItemDto = { - id: sessionId + String.fromCharCode(array.length), + _sessionId: sessionId, + _itemId: map.size.toString(36), name: item.name, detail: item.detail, kind: typeConvert.SymbolKind.from(item.kind), @@ -1095,17 +1108,13 @@ class CallHierarchyAdapter { range: typeConvert.Range.from(item.range), selectionRange: typeConvert.Range.from(item.selectionRange), }; - array.push(item); + map.set(dto._itemId, item); return dto; } - private _itemFromCache(itemId: string): vscode.CallHierarchyItem | undefined { - const sessionId = itemId.charAt(0); - const array = this._cache.get(sessionId); - if (!array) { - return undefined; - } - return array[itemId.charCodeAt(1)]; + private _itemFromCache(sessionId: string, itemId: string): vscode.CallHierarchyItem | undefined { + const map = this._cache.get(sessionId); + return map && map.get(itemId); } } @@ -1193,7 +1202,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF return ExtHostLanguageFeatures._handlePool++; } - private _withAdapter(handle: number, ctor: { new(...args: any[]): A }, callback: (adapter: A, extension: IExtensionDescription | undefined) => Promise, fallbackValue: R): Promise { + private _withAdapter(handle: number, ctor: { new(...args: any[]): A; }, callback: (adapter: A, extension: IExtensionDescription | undefined) => Promise, fallbackValue: R): Promise { const data = this._adapter.get(handle); if (!data) { return Promise.resolve(fallbackValue); @@ -1541,16 +1550,16 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF return this._createDisposable(handle); } - $prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<{ sessionId: string, root: extHostProtocol.ICallHierarchyItemDto } | undefined> { + $prepareCallHierarchy(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise { return this._withAdapter(handle, CallHierarchyAdapter, adapter => Promise.resolve(adapter.prepareSession(URI.revive(resource), position, token)), undefined); } - $provideCallHierarchyIncomingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> { - return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsTo(itemId, token), undefined); + $provideCallHierarchyIncomingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise { + return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsTo(sessionId, itemId, token), undefined); } - $provideCallHierarchyOutgoingCalls(handle: number, itemId: string, token: CancellationToken): Promise<[extHostProtocol.ICallHierarchyItemDto, IRange[]][] | undefined> { - return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsFrom(itemId, token), undefined); + $provideCallHierarchyOutgoingCalls(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise { + return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallsFrom(sessionId, itemId, token), undefined); } $releaseCallHierarchy(handle: number, sessionId: string): void { diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index ea12d55450eeafcac87bf4fda55d13bf660a474b..a0671a6e51ef627fb1f11b464d739c86f750d564 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -255,7 +255,7 @@ export namespace MarkdownString { } // extract uris into a separate object - const resUris: { [href: string]: UriComponents } = Object.create(null); + const resUris: { [href: string]: UriComponents; } = Object.create(null); res.uris = resUris; const collectUri = (href: string): string => { @@ -277,7 +277,7 @@ export namespace MarkdownString { return res; } - function _uriMassage(part: string, bucket: { [n: string]: UriComponents }): string { + function _uriMassage(part: string, bucket: { [n: string]: UriComponents; }): string { if (!part) { return part; } @@ -513,7 +513,7 @@ export namespace WorkspaceEdit { export namespace SymbolKind { - const _fromMapping: { [kind: number]: modes.SymbolKind } = Object.create(null); + const _fromMapping: { [kind: number]: modes.SymbolKind; } = Object.create(null); _fromMapping[types.SymbolKind.File] = modes.SymbolKind.File; _fromMapping[types.SymbolKind.Module] = modes.SymbolKind.Module; _fromMapping[types.SymbolKind.Namespace] = modes.SymbolKind.Namespace; @@ -627,8 +627,8 @@ export namespace DocumentSymbol { export namespace CallHierarchyItem { - export function to(item: extHostProtocol.ICallHierarchyItemDto): vscode.CallHierarchyItem { - return new types.CallHierarchyItem( + export function to(item: extHostProtocol.ICallHierarchyItemDto): types.CallHierarchyItem { + const result = new types.CallHierarchyItem( SymbolKind.to(item.kind), item.name, item.detail || '', @@ -636,6 +636,31 @@ export namespace CallHierarchyItem { Range.to(item.range), Range.to(item.selectionRange) ); + + result._sessionId = item._sessionId; + result._itemId = item._itemId; + + return result; + } +} + +export namespace CallHierarchyIncomingCall { + + export function to(item: extHostProtocol.IIncomingCallDto): types.CallHierarchyIncomingCall { + return new types.CallHierarchyIncomingCall( + CallHierarchyItem.to(item.from), + item.fromRanges.map(r => Range.to(r)) + ); + } +} + +export namespace CallHierarchyOutgoingCall { + + export function to(item: extHostProtocol.IOutgoingCallDto): types.CallHierarchyOutgoingCall { + return new types.CallHierarchyOutgoingCall( + CallHierarchyItem.to(item.to), + item.fromRanges.map(r => Range.to(r)) + ); } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ff4afdb3f049748dfc4583a96927404155b1f13e..158fe11fda7e77262e5e6dbfed26d54487b7329a 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -29,8 +29,8 @@ function es5ClassCompat(target: Function): any { @es5ClassCompat export class Disposable { - static from(...inDisposables: { dispose(): any }[]): Disposable { - let disposables: ReadonlyArray<{ dispose(): any }> | undefined = inDisposables; + static from(...inDisposables: { dispose(): any; }[]): Disposable { + let disposables: ReadonlyArray<{ dispose(): any; }> | undefined = inDisposables; return new Disposable(function () { if (disposables) { for (const disposable of disposables) { @@ -333,9 +333,9 @@ export class Range { return this._start.line === this._end.line; } - with(change: { start?: Position, end?: Position }): Range; + with(change: { start?: Position, end?: Position; }): Range; with(start?: Position, end?: Position): Range; - with(startOrChange: Position | undefined | { start?: Position, end?: Position }, end: Position = this.end): Range { + with(startOrChange: Position | undefined | { start?: Position, end?: Position; }, end: Position = this.end): Range { if (startOrChange === null || end === null) { throw illegalArgument(); @@ -589,15 +589,15 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { private _edits = new Array(); - renameFile(from: vscode.Uri, to: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void { + renameFile(from: vscode.Uri, to: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }): void { this._edits.push({ _type: 1, from, to, options }); } - createFile(uri: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean }): void { + createFile(uri: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }): void { this._edits.push({ _type: 1, from: undefined, to: uri, options }); } - deleteFile(uri: vscode.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean }): void { + deleteFile(uri: vscode.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean; }): void { this._edits.push({ _type: 1, from: uri, to: undefined, options }); } @@ -1142,6 +1142,10 @@ export class SelectionRange { } export class CallHierarchyItem { + + _sessionId: string; + _itemId: string; + kind: SymbolKind; name: string; detail?: string; @@ -1496,7 +1500,7 @@ export class Color { } } -export type IColorFormat = string | { opaque: string, transparent: string }; +export type IColorFormat = string | { opaque: string, transparent: string; }; @es5ClassCompat export class ColorInformation { @@ -2051,13 +2055,13 @@ export class TreeItem { label?: string | vscode.TreeItemLabel; resourceUri?: URI; - iconPath?: string | URI | { light: string | URI; dark: string | URI }; + iconPath?: string | URI | { light: string | URI; dark: string | URI; }; command?: vscode.Command; contextValue?: string; tooltip?: string; - constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState) - constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState) + constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState); + constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState); constructor(arg1: string | vscode.TreeItemLabel | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { if (URI.isUri(arg1)) { this.resourceUri = arg1; diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts index 745780da5ac151a04bb74f52c92702f8281065e5..cad37346668acccf3f3c9f3d0678a70540bcb969 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.ts @@ -9,10 +9,14 @@ import { ITextModel } from 'vs/editor/common/model'; import { CancellationToken } from 'vs/base/common/cancellation'; import { LanguageFeatureRegistry } from 'vs/editor/common/modes/languageFeatureRegistry'; import { URI } from 'vs/base/common/uri'; -import { IPosition } from 'vs/editor/common/core/position'; +import { IPosition, Position } from 'vs/editor/common/core/position'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { onUnexpectedExternalError } from 'vs/base/common/errors'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { assertType } from 'vs/base/common/types'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { ITextModelService } from 'vs/editor/common/services/resolverService'; export const enum CallHierarchyDirection { CallsTo = 1, @@ -20,7 +24,8 @@ export const enum CallHierarchyDirection { } export interface CallHierarchyItem { - id: string; + _sessionId: string; + _itemId: string; kind: SymbolKind; name: string; detail?: string; @@ -87,10 +92,11 @@ export class CallHierarchyModel { if (!session) { return undefined; } - return new CallHierarchyModel(provider, session.root, new RefCountedDisposabled(session)); + return new CallHierarchyModel(session.root._sessionId, provider, session.root, new RefCountedDisposabled(session)); } private constructor( + readonly id: string, readonly provider: CallHierarchyProvider, readonly root: CallHierarchyItem, readonly ref: RefCountedDisposabled, @@ -104,7 +110,7 @@ export class CallHierarchyModel { const that = this; return new class extends CallHierarchyModel { constructor() { - super(that.provider, item, that.ref.acquire()); + super(that.id, that.provider, item, that.ref.acquire()); } }; } @@ -134,3 +140,71 @@ export class CallHierarchyModel { } } +// --- API command support + +const _models = new Map(); + +CommandsRegistry.registerCommand('_executePrepareCallHierarchy', async (accessor, ...args) => { + const [resource, position] = args; + assertType(URI.isUri(resource)); + assertType(Position.isIPosition(position)); + + const modelService = accessor.get(IModelService); + let textModel = modelService.getModel(resource); + let textModelReference: IDisposable | undefined; + if (!textModel) { + const textModelService = accessor.get(ITextModelService); + const result = await textModelService.createModelReference(resource); + textModel = result.object.textEditorModel; + textModelReference = result; + } + + try { + const model = await CallHierarchyModel.create(textModel, position, CancellationToken.None); + if (!model) { + return undefined; + } + // + _models.set(model.id, model); + _models.forEach((value, key, map) => { + if (map.size > 10) { + value.dispose(); + _models.delete(key); + } + }); + return model.root; + + } finally { + dispose(textModelReference); + } +}); + +function isCallHierarchyItemDto(obj: any): obj is CallHierarchyItem { + return true; +} + +CommandsRegistry.registerCommand('_executeProvideIncomingCalls', async (_accessor, ...args) => { + const [item] = args; + assertType(isCallHierarchyItemDto(item)); + + // find model + const model = _models.get(item._sessionId); + if (!model) { + return undefined; + } + + return model.resolveIncomingCalls(item, CancellationToken.None); +}); + +CommandsRegistry.registerCommand('_executeProvideOutgoingCalls', async (_accessor, ...args) => { + const [item] = args; + assertType(isCallHierarchyItemDto(item)); + + // find model + const model = _models.get(item._sessionId); + if (!model) { + return undefined; + } + + return model.resolveOutgoingCalls(item, CancellationToken.None); +}); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts b/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts index 07006b77f263b9fcbdf2e6d9eefebdb567cd9b6e..206a53472e1fd0eb76b965614f75905251aa34c0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts @@ -26,10 +26,10 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench @IHostService private readonly hostService: IHostService ) { super(); - CommandsRegistry.registerCommand('workbench.extensions.installMissingDepenencies', () => this.installMissingDependencies()); + CommandsRegistry.registerCommand('workbench.extensions.installMissingDependencies', () => this.installMissingDependencies()); MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { - id: 'workbench.extensions.installMissingDepenencies', + id: 'workbench.extensions.installMissingDependencies', category: localize('extensions', "Extensions"), title: localize('auto install missing deps', "Install Missing Dependencies") } diff --git a/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts b/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts index ec0dd5602d484f70cf6cdf19e8c8b6320880b356..28a84bbb3f362f07dfc159d863feeb730635e445 100644 --- a/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts +++ b/src/vs/workbench/contrib/markers/browser/markersPanelActions.ts @@ -119,20 +119,6 @@ export class MarkersFilterAction extends Action { } } - focus(): void { - this._onFocus.fire(); - } - - layout(width: number): void { - if (width > 600) { - this.class = 'markers-panel-action-filter grow'; - } else if (width < 400) { - this.class = 'markers-panel-action-filter small'; - } else { - this.class = 'markers-panel-action-filter'; - } - } - private _showWarnings: boolean = true; get showWarnings(): boolean { return this._showWarnings; @@ -165,6 +151,20 @@ export class MarkersFilterAction extends Action { this._onDidChange.fire({ showInfos: true }); } } + + focus(): void { + this._onFocus.fire(); + } + + layout(width: number): void { + if (width > 600) { + this.class = 'markers-panel-action-filter grow'; + } else if (width < 400) { + this.class = 'markers-panel-action-filter small'; + } else { + this.class = 'markers-panel-action-filter'; + } + } } export interface IMarkerFilterController { diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 1f9dd15dda5ca58b1cd668a763a9ab3c6bfea55f..20bb18053aeb5dafe52acdbe1b26fdd95b03b6d8 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -67,13 +67,13 @@ suite('ExtHostLanguageFeatureCommands', function () { rpcProtocol = new TestRPCProtocol(); instantiationService.stub(ICommandService, { _serviceBrand: undefined, - executeCommand(id: string, args: any): any { + executeCommand(id: string, ...args: any): any { const command = CommandsRegistry.getCommands().get(id); if (!command) { return Promise.reject(new Error(id + ' NOT known')); } const { handler } = command; - return Promise.resolve(instantiationService.invokeFunction(handler, args)); + return Promise.resolve(instantiationService.invokeFunction(handler, ...args)); } }); instantiationService.stub(IMarkerService, new MarkerService()); @@ -856,4 +856,46 @@ suite('ExtHostLanguageFeatureCommands', function () { assert.equal(value.length, 1); assert.ok(value[0].parent); }); + + // --- call hierarcht + + test('CallHierarchy, back and forth', async function () { + + disposables.push(extHost.registerCallHierarchyProvider(nullExtensionDescription, defaultSelector, new class implements vscode.CallHierarchyProvider { + + prepareCallHierarchy(document: vscode.TextDocument, position: vscode.Position, ): vscode.ProviderResult { + return new types.CallHierarchyItem(types.SymbolKind.Constant, 'ROOT', 'ROOT', document.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0)); + } + + provideCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): vscode.ProviderResult { + + return [new types.CallHierarchyIncomingCall( + new types.CallHierarchyItem(types.SymbolKind.Constant, 'INCOMING', 'INCOMING', item.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0)), + [new types.Range(0, 0, 0, 0)] + )]; + } + + provideCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): vscode.ProviderResult { + return [new types.CallHierarchyOutgoingCall( + new types.CallHierarchyItem(types.SymbolKind.Constant, 'OUTGOING', 'OUTGOING', item.uri, new types.Range(0, 0, 0, 0), new types.Range(0, 0, 0, 0)), + [new types.Range(0, 0, 0, 0)] + )]; + } + })); + + await rpcProtocol.sync(); + + const root = await commands.executeCommand('vscode.prepareCallHierarchy', model.uri, new types.Position(0, 0)); + + assert.ok(root); + assert.equal(root.name, 'ROOT'); + + const incoming = await commands.executeCommand('vscode.provideIncomingCalls', root); + assert.equal(incoming.length, 1); + assert.equal(incoming[0].from.name, 'INCOMING'); + + const outgoing = await commands.executeCommand('vscode.provideOutgoingCalls', root); + assert.equal(outgoing.length, 1); + assert.equal(outgoing[0].to.name, 'OUTGOING'); + }); }); diff --git a/yarn.lock b/yarn.lock index 49346cb3369d75d509bbe28cd6a3ca55ab47f06a..c965f033387acbadb4be6e1cdf1638225bf9f54a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -195,6 +195,20 @@ resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518" integrity sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg= +"@types/yauzl@^2.9.1": + version "2.9.1" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af" + integrity sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA== + dependencies: + "@types/node" "*" + +"@types/yazl@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/yazl/-/yazl-2.4.2.tgz#d5f8a4752261badbf1a36e8b49e042dc18ec84bc" + integrity sha512-T+9JH8O2guEjXNxqmybzQ92mJUh2oCwDDMSSimZSe1P+pceZiFROZLYmcbqkzV5EUwz6VwcKXCO2S2yUpra6XQ== + dependencies: + "@types/node" "*" + "@webassemblyjs/ast@1.5.13": version "1.5.13" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25"