Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement call hierarchy #70748

Merged
merged 26 commits into from
Mar 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2f89a79
api proposal, add call hierarchy contrib
jrieken Mar 14, 2019
c9a8a1d
simple tree UX
jrieken Mar 14, 2019
b01e65c
add action to context menu
jrieken Mar 15, 2019
3a3b62c
show calls as columns
jrieken Mar 15, 2019
bb0587b
show preview in tree-mode
jrieken Mar 15, 2019
689e1ca
add 'callHierarchy.mode' setting with 'tree' or 'columns'
jrieken Mar 15, 2019
40bcd6a
use editor action, add context key for enablement,
jrieken Mar 15, 2019
8b83141
more column view work
jrieken Mar 15, 2019
793f638
resolve document when running document sumbol command
jrieken Mar 18, 2019
b77ce09
call hiearchy like reference search
jrieken Mar 18, 2019
fc57815
strict null work
jrieken Mar 18, 2019
a92a5bf
Merge branch 'master' into joh/callh
jrieken Mar 18, 2019
abae211
add overview color, use proper controller, ignore peek config
jrieken Mar 18, 2019
6a065f4
remove column view idea
jrieken Mar 18, 2019
cbe4cf4
dispose on pressing X
jrieken Mar 18, 2019
7717fc5
show loading message, no result message etc
jrieken Mar 18, 2019
ea413af
add toggle action: calls from/calls to
jrieken Mar 18, 2019
b3035a8
render filename as backup detail
jrieken Mar 19, 2019
d955886
add uri-property to CallHierarchtItem, better wording, better behavio…
jrieken Mar 19, 2019
b645c0c
persist layout info of call hierarchy ux
jrieken Mar 19, 2019
c6fa07e
use peek view theming
jrieken Mar 19, 2019
7797294
tweek icon
jrieken Mar 19, 2019
576f08a
strict null trouble
jrieken Mar 19, 2019
bb8affc
support stable peek for call hierarchy
jrieken Mar 19, 2019
d0c3791
support all peek/ref-view styles
jrieken Mar 19, 2019
0afa5f9
undo breadcrumbs change
jrieken Mar 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build/lib/i18n.resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
"name": "vs/workbench/contrib/codeinset",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/callHierarchy",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/comments",
"project": "vscode-workbench"
Expand Down
3 changes: 2 additions & 1 deletion src/tsconfig.strictNullChecks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"./vs/workbench/common/**/*",
"./vs/workbench/browser/**/*",
"./vs/workbench/electron-browser/**/*",
"./vs/workbench/contrib/callHierarchy/**/*",
"./vs/workbench/contrib/emmet/**/*",
"./vs/workbench/contrib/externalTerminal/**/*",
"./vs/workbench/contrib/scm/**/*.ts",
Expand Down Expand Up @@ -469,4 +470,4 @@
"./typings/require-monaco.d.ts",
"./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts"
]
}
}
19 changes: 16 additions & 3 deletions src/vs/editor/contrib/quickOpen/quickOpen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { DocumentSymbol, DocumentSymbolProviderRegistry } from 'vs/editor/common/modes';
import { IModelService } from 'vs/editor/common/services/modelService';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ITextModelService } from 'vs/editor/common/services/resolverService';

export function getDocumentSymbols(model: ITextModel, flat: boolean, token: CancellationToken): Promise<DocumentSymbol[]> {

Expand Down Expand Up @@ -70,8 +71,20 @@ registerLanguageCommand('_executeDocumentSymbolProvider', function (accessor, ar
throw illegalArgument('resource');
}
const model = accessor.get(IModelService).getModel(resource);
if (!model) {
throw illegalArgument('resource');
if (model) {
return getDocumentSymbols(model, false, CancellationToken.None);
}
return getDocumentSymbols(model, false, CancellationToken.None);

return accessor.get(ITextModelService).createModelReference(resource).then(reference => {
return new Promise((resolve, reject) => {
try {
const result = getDocumentSymbols(reference.object.textEditorModel, false, CancellationToken.None);
resolve(result);
} catch (err) {
reject(err);
}
}).finally(() => {
reference.dispose();
});
});
});
40 changes: 40 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,46 @@

declare module 'vscode' {

//#region Joh - call hierarchy

export enum CallHierarchyDirection {
CallsFrom = 1,
CallsTo = 2,
}

export class CallHierarchyItem {
kind: SymbolKind;
name: string;
detail?: string;
uri: Uri;
range: Range;
selectionRange: Range;

constructor(kind: SymbolKind, name: string, detail: string, uri: Uri, range: Range, selectionRange: Range);
}

export interface CallHierarchyItemProvider {

provideCallHierarchyItem(
document: TextDocument,
postion: Position,
token: CancellationToken
): ProviderResult<CallHierarchyItem>;

resolveCallHierarchyItem(
item: CallHierarchyItem,
direction: CallHierarchyDirection,
token: CancellationToken
): ProviderResult<[CallHierarchyItem, Location[]][]>;
}

export namespace languages {
export function registerCallHierarchyProvider(selector: DocumentSelector, provider: CallHierarchyItemProvider): Disposable;
}

//#endregion


//#region Alex - resolvers

export class ResolvedAuthority {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as search from 'vs/workbench/contrib/search/common/search';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Position as EditorPosition } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter, DefinitionLinkDto, ISerializedSignatureHelpProviderMetadata, CodeInsetDto, LinkDto } from '../node/extHost.protocol';
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter, DefinitionLinkDto, ISerializedSignatureHelpProviderMetadata, CodeInsetDto, LinkDto, CallHierarchyDto } from '../node/extHost.protocol';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { LanguageConfiguration, IndentationRule, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration';
import { IHeapService } from './mainThreadHeapService';
Expand All @@ -22,6 +22,7 @@ import { URI } from 'vs/base/common/uri';
import { Selection } from 'vs/editor/common/core/selection';
import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import * as callh from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';

@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesShape {
Expand Down Expand Up @@ -114,6 +115,13 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
return <modes.ILink>data;
}

private static _reviveCallHierarchyItemDto(data: CallHierarchyDto | undefined): callh.CallHierarchyItem {
if (data) {
data.uri = URI.revive(data.uri);
}
return data as callh.CallHierarchyItem;
}

//#endregion

// --- outline
Expand Down Expand Up @@ -471,6 +479,30 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
});
}

// --- call hierarchy

$registerCallHierarchyProvider(handle: number, selector: ISerializedDocumentFilter[]): void {
this._registrations[handle] = callh.CallHierarchyProviderRegistry.register(typeConverters.LanguageSelector.from(selector), {
provideCallHierarchyItem: (document, position, token) => {
return this._proxy.$provideCallHierarchyItem(handle, document.uri, position, token).then(MainThreadLanguageFeatures._reviveCallHierarchyItemDto);
},
resolveCallHierarchyItem: (item, direction, token) => {
return this._proxy.$resolveCallHierarchyItem(handle, item, direction, token).then(data => {
if (data) {
for (let i = 0; i < data.length; i++) {
const [item, locations] = data[i];
data[i] = [
MainThreadLanguageFeatures._reviveCallHierarchyItemDto(item),
MainThreadLanguageFeatures._reviveLocationDto(locations)
];
}
}
return data as [callh.CallHierarchyItem, modes.Location[]][];
});
}
});
}

// --- configuration

private static _reviveRegExp(regExp: ISerializedRegExp): RegExp {
Expand Down
8 changes: 7 additions & 1 deletion src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ export function createApiFactory(
registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable {
return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider);
},
registerCallHierarchyProvider(selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable {
checkProposedApiEnabled(extension);
return extHostLanguageFeatures.registerCallHierarchyProvider(extension, selector, provider);
},
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
return extHostLanguageFeatures.setLanguageConfiguration(language, configuration);
}
Expand Down Expand Up @@ -831,7 +835,9 @@ export function createApiFactory(
Uri: URI,
ViewColumn: extHostTypes.ViewColumn,
WorkspaceEdit: extHostTypes.WorkspaceEdit,
// functions
// proposed
CallHierarchyDirection: extHostTypes.CallHierarchyDirection,
CallHierarchyItem: extHostTypes.CallHierarchyItem
};
};
}
Expand Down
14 changes: 14 additions & 0 deletions src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityReso
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { IRemoteConsoleLog } from 'vs/base/node/console';
import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import * as callHierarchy from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';

export interface IEnvironment {
isExtensionDevelopmentDebug: boolean;
Expand Down Expand Up @@ -335,6 +336,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerCallHierarchyProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$setLanguageConfiguration(handle: number, languageId: string, configuration: ISerializedLanguageConfiguration): void;
}

Expand Down Expand Up @@ -918,6 +920,16 @@ export interface CodeLensDto extends ObjectIdentifier {

export type CodeInsetDto = ObjectIdentifier & codeInset.ICodeInsetSymbol;

export interface CallHierarchyDto {
_id: number;
kind: modes.SymbolKind;
name: string;
detail?: string;
uri: UriComponents;
range: IRange;
selectionRange: IRange;
}

export interface ExtHostLanguageFeaturesShape {
$provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined>;
$provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise<CodeLensDto[]>;
Expand Down Expand Up @@ -950,6 +962,8 @@ export interface ExtHostLanguageFeaturesShape {
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[] | undefined>;
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined>;
$provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]>;
$provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<CallHierarchyDto | undefined>;
$resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[CallHierarchyDto, modes.Location[]][]>;
}

export interface ExtHostQuickOpenShape {
Expand Down
75 changes: 74 additions & 1 deletion src/vs/workbench/api/node/extHostLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
import { ExtHostWebview } from 'vs/workbench/api/node/extHostWebview';
import * as codeInset from 'vs/workbench/contrib/codeinset/common/codeInset';
import { generateUuid } from 'vs/base/common/uuid';
import * as callHierarchy from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
import { LRUCache } from 'vs/base/common/map';

// --- adapter

Expand Down Expand Up @@ -963,11 +965,66 @@ class SelectionRangeAdapter {
}
}

class CallHierarchyAdapter {

// todo@joh keep object (heap service, lifecycle)
private readonly _cache = new LRUCache<number, vscode.CallHierarchyItem>(1000, 0.8);
private _idPool = 0;

constructor(
private readonly _documents: ExtHostDocuments,
private readonly _provider: vscode.CallHierarchyItemProvider
) { }

provideCallHierarchyItem(resource: URI, pos: IPosition, token: CancellationToken): Promise<undefined | callHierarchy.CallHierarchyItem> {
const document = this._documents.getDocument(resource);
const position = typeConvert.Position.to(pos);

return asPromise(() => this._provider.provideCallHierarchyItem(document, position, token)).then(item => {
if (!item) {
return undefined;
}
return this._fromItem(item);
});
}

resolveCallHierarchyItem(item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[callHierarchy.CallHierarchyItem, modes.Location[]][]> {
return asPromise(() => this._provider.resolveCallHierarchyItem(
this._cache.get(item._id)!,
direction as number, token) // todo@joh proper convert
).then(data => {
if (!data) {
return [];
}
return data.map(tuple => {
return <[callHierarchy.CallHierarchyItem, modes.Location[]]>[
this._fromItem(tuple[0]),
tuple[1].map(typeConvert.location.from)
];
});
});
}

private _fromItem(item: vscode.CallHierarchyItem, _id: number = this._idPool++): callHierarchy.CallHierarchyItem {
const res = <callHierarchy.CallHierarchyItem>{
_id,
name: item.name,
detail: item.detail,
kind: typeConvert.SymbolKind.from(item.kind),
uri: item.uri,
range: typeConvert.Range.from(item.range),
selectionRange: typeConvert.Range.from(item.selectionRange),
};
this._cache.set(_id, item);
return res;
}
}

type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter | TypeDefinitionAdapter
| ColorProviderAdapter | FoldingProviderAdapter | CodeInsetAdapter | DeclarationAdapter | SelectionRangeAdapter;
| ColorProviderAdapter | FoldingProviderAdapter | CodeInsetAdapter | DeclarationAdapter | SelectionRangeAdapter | CallHierarchyAdapter;

class AdapterData {
constructor(
Expand Down Expand Up @@ -1415,6 +1472,22 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._withAdapter(handle, SelectionRangeAdapter, adapter => adapter.provideSelectionRanges(URI.revive(resource), positions, token));
}

// --- call hierarchy

registerCallHierarchyProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable {
const handle = this._addNewAdapter(new CallHierarchyAdapter(this._documents, provider), extension);
this._proxy.$registerCallHierarchyProvider(handle, this._transformDocumentSelector(selector));
return this._createDisposable(handle);
}

$provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<undefined | callHierarchy.CallHierarchyItem> {
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.provideCallHierarchyItem(URI.revive(resource), position, token));
}

$resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[callHierarchy.CallHierarchyItem, modes.Location[]][]> {
return this._withAdapter(handle, CallHierarchyAdapter, adapter => adapter.resolveCallHierarchyItem(item, direction, token));
}

// --- configuration

private static _serializeRegExp(regExp: RegExp): ISerializedRegExp {
Expand Down
1 change: 0 additions & 1 deletion src/vs/workbench/api/node/extHostTypeConverters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,6 @@ export namespace TextDocumentSaveReason {
}
}


export namespace EndOfLine {

export function from(eol: vscode.EndOfLine): EndOfLineSequence | undefined {
Expand Down
23 changes: 23 additions & 0 deletions src/vs/workbench/api/node/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,29 @@ export class SelectionRange {
}


export enum CallHierarchyDirection {
CallsFrom = 1,
CallsTo = 2,
}

export class CallHierarchyItem {
kind: SymbolKind;
name: string;
detail?: string;
uri: URI;
range: Range;
selectionRange: Range;

constructor(kind: SymbolKind, name: string, detail: string, uri: URI, range: Range, selectionRange: Range) {
this.kind = kind;
this.name = name;
this.detail = detail;
this.uri = uri;
this.range = range;
this.selectionRange = selectionRange;
}
}

@es5ClassCompat
export class CodeLens {

Expand Down
Loading