diff --git a/package.json b/package.json index 1bbffcf..80f4c4d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,11 @@ "name": "Inheritance Hierarchy", "when": "extension.ccls.inheritanceHierarchyVisible" }, + { + "id": "ccls.dataFlowInto", + "name": "Data Flow Hierarchy", + "when": "extension.ccls.dataFlowHierarchyVisible" + }, { "id": "ccls.memberHierarchy", "name": "Member Hierarchy", @@ -89,6 +94,11 @@ "command": "ccls.base", "when": "resourceLangId == cpp", "group": "navigation@1.34" + }, + { + "command": "ccls.dataFlowInto", + "when": "resourceLangId == cpp", + "group": "navigation@1.35" } ], "view/title": [ @@ -107,6 +117,11 @@ "when": "view == ccls.callHierarchy", "group": "navigation" }, + { + "command": "ccls.closeDataFlowHierarchy", + "when": "view == ccls.dataFlowInto", + "group": "navigation" + }, { "command": "ccls.closeInheritanceHierarchy", "when": "view == ccls.inheritanceHierarchy", @@ -137,6 +152,10 @@ "command": "ccls.closeMemberHierarchy", "when": "false" }, + { + "command": "ccls.closeDataFlowHierarchy", + "when": "false" + }, { "command": "ccls.gotoForTreeView", "when": "false" @@ -229,6 +248,20 @@ "category": "ccls", "command": "ccls.vars" }, + { + "title": "Show Data Flow Into", + "category": "ccls", + "command": "ccls.dataFlowInto" + }, + { + "title": "Close", + "category": "ccls", + "command": "ccls.closeDataFlowHierarchy", + "icon": { + "light": "resources/close-light.svg", + "dark": "resources/close-dark.svg" + } + }, { "title": "Show Cross References", "category": "ccls", diff --git a/src/hierarchies/dataFlowHierarchy.ts b/src/hierarchies/dataFlowHierarchy.ts new file mode 100644 index 0000000..d8480d4 --- /dev/null +++ b/src/hierarchies/dataFlowHierarchy.ts @@ -0,0 +1,70 @@ +import { + commands, + Disposable, + Event, + EventEmitter, + Position, + Range, + TextEditor, + TreeDataProvider, + TreeItem, + TreeItemCollapsibleState, + Uri, + workspace +} from "vscode"; +import { LanguageClient } from "vscode-languageclient/lib/main"; +import { Icon, IHierarchyNode } from "../types"; +import { disposeAll, resourcePath, setContext } from "../utils"; +import { Hierarchy } from "./hierarchy"; + +interface DataFlowHierarchyNode extends IHierarchyNode { + children: DataFlowHierarchyNode[]; +} + +export class DataFlowHierarchyProvider extends Hierarchy { + protected contextValue = 'extension.ccls.dataFlowHierarchyVisible'; + private icon: Icon; + + constructor( + readonly languageClient: LanguageClient, + ) { + super(languageClient, 'ccls.dataFlowInto', 'ccls.closeDataFlowHierarchy'); + this.icon = { + dark: resourcePath("base-dark.svg"), + light: resourcePath("base-light.svg") + }; + } + + protected async onTreeItem(ti: TreeItem, element: DataFlowHierarchyNode) { + + const parentFile = await workspace.openTextDocument(Uri.parse(element.location.uri)); + ti.label = parentFile.getText( + new Range( + new Position(element.location.range.start.line, element.location.range.start.character), + new Position(element.location.range.end.line, element.location.range.end.character) + ) + ); + + ti.iconPath = this.icon; + ti.contextValue = 'cclsGoto'; + + } + + protected async onGetChildren( + element: DataFlowHierarchyNode + ): Promise { + return element.children; + } + + protected async onReveal(uri: Uri, position: Position): Promise { + return this.languageClient.sendRequest( + '$ccls/dataFlowInto', + { + position, + textDocument: { + uri: uri.toString(true), + }, + } + ); + } +} diff --git a/src/serverContext.ts b/src/serverContext.ts index 8bf9a6e..56ba35d 100644 --- a/src/serverContext.ts +++ b/src/serverContext.ts @@ -29,6 +29,7 @@ import * as ls from "vscode-languageserver-types"; import { CclsErrorHandler } from "./cclsErrorHandler"; import { cclsChan, logChan } from './globalContext'; import { CallHierarchyProvider } from "./hierarchies/callHierarchy"; +import { DataFlowHierarchyProvider } from "./hierarchies/dataFlowHierarchy"; import { InheritanceHierarchyProvider } from "./hierarchies/inheritanceHierarchy"; import { MemberHierarchyProvider } from "./hierarchies/memberHierarchy"; import { InactiveRegionsProvider } from "./inactiveRegions"; @@ -262,6 +263,12 @@ export class ServerContext implements Disposable { 'ccls.memberHierarchy', memberHierarchyProvider )); + const dfProvier = new DataFlowHierarchyProvider(this.client); + this._dispose.push(dfProvier); + this._dispose.push(window.registerTreeDataProvider( + 'ccls.dataFlowInto', dfProvier + )); + // Common between tree views. this._dispose.push(commands.registerCommand( "ccls.gotoForTreeView", this.gotoForTreeView, this