about summary refs log tree commit diff
path: root/editors/code/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-03 09:03:15 +0000
committerGitHub <noreply@github.com>2021-01-03 09:03:15 +0000
commit1cc73d60bbd7149773f2eb57296d5611cbe941b1 (patch)
tree631a683b73784e633baf84c826a81903922095a7 /editors/code/src
parent520b8a5a4dde032ba6118efb02801611191acc4e (diff)
parentee7c3f79e29bf140fe6faaf52bee63dba2fc29b1 (diff)
downloadrust-1cc73d60bbd7149773f2eb57296d5611cbe941b1.tar.gz
rust-1cc73d60bbd7149773f2eb57296d5611cbe941b1.zip
Merge #7068
7068: Add VSCode command to view the hir of a function body r=theotherphil a=theotherphil

Will fix https://github.com/rust-analyzer/rust-analyzer/issues/7061. Very rough initial version just to work out where I needed to wire everything up.

@matklad would you be happy merging a hir visualiser of some kind? If so, do you have any thoughts on what you'd like it show, and how?

I've spent very little time on this thus far, so I'm fine with throwing away the contents of this PR, but I want to avoid taking the time to make this more polished/interactive/useful only to discover that no-one else has any interest in this functionality.

![image](https://user-images.githubusercontent.com/1974256/103236081-bb58f700-493b-11eb-9d12-55ae1b870f8f.png)


Co-authored-by: Phil Ellison <phil.j.ellison@gmail.com>
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/commands.ts55
-rw-r--r--editors/code/src/lsp_ext.ts1
-rw-r--r--editors/code/src/main.ts1
3 files changed, 57 insertions, 0 deletions
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index b12e134ca97..c1c9f9754dd 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -340,6 +340,61 @@ export function syntaxTree(ctx: Ctx): Cmd {
     };
 }
 
+// Opens the virtual file that will show the HIR of the function containing the cursor position
+//
+// The contents of the file come from the `TextDocumentContentProvider`
+export function viewHir(ctx: Ctx): Cmd {
+    const tdcp = new class implements vscode.TextDocumentContentProvider {
+        readonly uri = vscode.Uri.parse('rust-analyzer://viewHir/hir.txt');
+        readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
+        constructor() {
+            vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
+            vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
+        }
+
+        private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
+            if (isRustDocument(event.document)) {
+                // We need to order this after language server updates, but there's no API for that.
+                // Hence, good old sleep().
+                void sleep(10).then(() => this.eventEmitter.fire(this.uri));
+            }
+        }
+        private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
+            if (editor && isRustEditor(editor)) {
+                this.eventEmitter.fire(this.uri);
+            }
+        }
+
+        provideTextDocumentContent(_uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
+            const rustEditor = ctx.activeRustEditor;
+            const client = ctx.client;
+            if (!rustEditor || !client) return '';
+
+            const params = {
+                textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(rustEditor.document),
+                position: client.code2ProtocolConverter.asPosition(
+                    rustEditor.selection.active,
+                ),
+            };
+            return client.sendRequest(ra.viewHir, params, ct);
+        }
+
+        get onDidChange(): vscode.Event<vscode.Uri> {
+            return this.eventEmitter.event;
+        }
+    };
+
+    ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
+
+    return async () => {
+        const document = await vscode.workspace.openTextDocument(tdcp.uri);
+        tdcp.eventEmitter.fire(tdcp.uri);
+        void await vscode.window.showTextDocument(document, {
+            viewColumn: vscode.ViewColumn.Two,
+            preserveFocus: true
+        });
+    };
+}
 
 // Opens the virtual file that will show the syntax tree
 //
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index 5e877ce6511..d21a3db862d 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -24,6 +24,7 @@ export interface SyntaxTreeParams {
 }
 export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>("rust-analyzer/syntaxTree");
 
+export const viewHir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>("rust-analyzer/viewHir");
 
 export interface ExpandMacroParams {
     textDocument: lc.TextDocumentIdentifier;
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 282240d8453..60907dfd40d 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -105,6 +105,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
     ctx.registerCommand('joinLines', commands.joinLines);
     ctx.registerCommand('parentModule', commands.parentModule);
     ctx.registerCommand('syntaxTree', commands.syntaxTree);
+    ctx.registerCommand('viewHir', commands.viewHir);
     ctx.registerCommand('expandMacro', commands.expandMacro);
     ctx.registerCommand('run', commands.run);
     ctx.registerCommand('debug', commands.debug);