aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/lib.rs4
-rw-r--r--crates/ide/src/status.rs49
-rw-r--r--crates/rust-analyzer/src/handlers.rs19
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs8
-rw-r--r--docs/dev/lsp-extensions.md9
-rw-r--r--docs/user/manual.adoc4
-rw-r--r--editors/code/src/commands.ts19
-rw-r--r--editors/code/src/lsp_ext.ts5
8 files changed, 85 insertions, 32 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 96dae9ee0..6d5fd1a55 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -216,8 +216,8 @@ impl Analysis {
216 } 216 }
217 217
218 /// Debug info about the current state of the analysis. 218 /// Debug info about the current state of the analysis.
219 pub fn status(&self) -> Cancelable<String> { 219 pub fn status(&self, file_id: Option<FileId>) -> Cancelable<String> {
220 self.with_db(|db| status::status(&*db)) 220 self.with_db(|db| status::status(&*db, file_id))
221 } 221 }
222 222
223 pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> { 223 pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> {
diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs
index 1427c50cf..0af84daa0 100644
--- a/crates/ide/src/status.rs
+++ b/crates/ide/src/status.rs
@@ -2,19 +2,19 @@ use std::{fmt, iter::FromIterator, sync::Arc};
2 2
3use base_db::{ 3use base_db::{
4 salsa::debug::{DebugQueryTable, TableEntry}, 4 salsa::debug::{DebugQueryTable, TableEntry},
5 FileTextQuery, SourceRootId, 5 CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId,
6}; 6};
7use hir::MacroFile; 7use hir::MacroFile;
8use ide_db::{ 8use ide_db::{
9 symbol_index::{LibrarySymbolsQuery, SymbolIndex}, 9 symbol_index::{LibrarySymbolsQuery, SymbolIndex},
10 RootDatabase, 10 RootDatabase,
11}; 11};
12use itertools::Itertools;
12use profile::{memory_usage, Bytes}; 13use profile::{memory_usage, Bytes};
13use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
15use stdx::format_to;
14use syntax::{ast, Parse, SyntaxNode}; 16use syntax::{ast, Parse, SyntaxNode};
15 17
16use crate::FileId;
17
18fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { 18fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
19 base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>() 19 base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
20} 20}
@@ -31,19 +31,36 @@ fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
31// 31//
32// | VS Code | **Rust Analyzer: Status** 32// | VS Code | **Rust Analyzer: Status**
33// |=== 33// |===
34pub(crate) fn status(db: &RootDatabase) -> String { 34pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
35 let files_stats = FileTextQuery.in_db(db).entries::<FilesStats>(); 35 let mut buf = String::new();
36 let syntax_tree_stats = syntax_tree_stats(db); 36 format_to!(buf, "{}\n", FileTextQuery.in_db(db).entries::<FilesStats>());
37 let macro_syntax_tree_stats = macro_syntax_tree_stats(db); 37 format_to!(buf, "{}\n", LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>());
38 let symbols_stats = LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>(); 38 format_to!(buf, "{}\n", syntax_tree_stats(db));
39 format!( 39 format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
40 "{}\n{}\n{}\n{} (macros)\n{} total\n", 40 format_to!(buf, "{} total\n", memory_usage());
41 files_stats, 41
42 symbols_stats, 42 if let Some(file_id) = file_id {
43 syntax_tree_stats, 43 format_to!(buf, "\nfile info:\n");
44 macro_syntax_tree_stats, 44 let krate = crate::parent_module::crate_for(db, file_id).pop();
45 memory_usage(), 45 match krate {
46 ) 46 Some(krate) => {
47 let crate_graph = db.crate_graph();
48 let display_crate = |krate: CrateId| match &crate_graph[krate].display_name {
49 Some(it) => format!("{}({:?})", it, krate),
50 None => format!("{:?}", krate),
51 };
52 format_to!(buf, "crate: {}\n", display_crate(krate));
53 let deps = crate_graph[krate]
54 .dependencies
55 .iter()
56 .map(|dep| format!("{}={:?}", dep.name, dep.crate_id))
57 .format(", ");
58 format_to!(buf, "deps: {}\n", deps);
59 }
60 None => format_to!(buf, "does not belong to any crate"),
61 }
62 }
63 buf
47} 64}
48 65
49#[derive(Default)] 66#[derive(Default)]
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 7ac1a30f6..afcec63ad 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -38,10 +38,22 @@ use crate::{
38 to_proto, LspError, Result, 38 to_proto, LspError, Result,
39}; 39};
40 40
41pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> { 41pub(crate) fn handle_analyzer_status(
42 snap: GlobalStateSnapshot,
43 params: lsp_ext::AnalyzerStatusParams,
44) -> Result<String> {
42 let _p = profile::span("handle_analyzer_status"); 45 let _p = profile::span("handle_analyzer_status");
43 46
44 let mut buf = String::new(); 47 let mut buf = String::new();
48
49 let mut file_id = None;
50 if let Some(tdi) = params.text_document {
51 match from_proto::file_id(&snap, &tdi.uri) {
52 Ok(it) => file_id = Some(it),
53 Err(_) => format_to!(buf, "file {} not found in vfs", tdi.uri),
54 }
55 }
56
45 if snap.workspaces.is_empty() { 57 if snap.workspaces.is_empty() {
46 buf.push_str("no workspaces\n") 58 buf.push_str("no workspaces\n")
47 } else { 59 } else {
@@ -52,7 +64,10 @@ pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result
52 } 64 }
53 buf.push_str("\nanalysis:\n"); 65 buf.push_str("\nanalysis:\n");
54 buf.push_str( 66 buf.push_str(
55 &snap.analysis.status().unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()), 67 &snap
68 .analysis
69 .status(file_id)
70 .unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
56 ); 71 );
57 format_to!(buf, "\n\nrequests:\n"); 72 format_to!(buf, "\n\nrequests:\n");
58 let requests = snap.latest_requests.read(); 73 let requests = snap.latest_requests.read();
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index e1a28b1b4..43ff191da 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -11,11 +11,17 @@ use serde::{Deserialize, Serialize};
11pub enum AnalyzerStatus {} 11pub enum AnalyzerStatus {}
12 12
13impl Request for AnalyzerStatus { 13impl Request for AnalyzerStatus {
14 type Params = (); 14 type Params = AnalyzerStatusParams;
15 type Result = String; 15 type Result = String;
16 const METHOD: &'static str = "rust-analyzer/analyzerStatus"; 16 const METHOD: &'static str = "rust-analyzer/analyzerStatus";
17} 17}
18 18
19#[derive(Deserialize, Serialize, Debug)]
20#[serde(rename_all = "camelCase")]
21pub struct AnalyzerStatusParams {
22 pub text_document: Option<TextDocumentIdentifier>,
23}
24
19pub enum MemoryUsage {} 25pub enum MemoryUsage {}
20 26
21impl Request for MemoryUsage { 27impl Request for MemoryUsage {
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 2e3133449..f1160bb1c 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -390,7 +390,14 @@ rust-analyzer supports only one `kind`, `"cargo"`. The `args` for `"cargo"` look
390 390
391**Method:** `rust-analyzer/analyzerStatus` 391**Method:** `rust-analyzer/analyzerStatus`
392 392
393**Request:** `null` 393**Request:**
394
395```typescript
396interface AnalyzerStatusParams {
397 /// If specified, show dependencies of the current file.
398 textDocument?: TextDocumentIdentifier;
399}
400```
394 401
395**Response:** `string` 402**Response:** `string`
396 403
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 7d85b36cb..c1a778852 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -113,8 +113,8 @@ Note that installing via `xtask install` does not work for VS Code Remote, inste
113 113
114Here are some useful self-diagnostic commands: 114Here are some useful self-diagnostic commands:
115 115
116* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary 116* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary.
117* **Rust Analyzer: Status** prints some statistics about the server, like the few latest LSP requests 117* **Rust Analyzer: Status** prints some statistics about the server, and dependency information for the current file.
118* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel. 118* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel.
119* To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Rust Analyzer Language Server Trace` in the panel. 119* To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Rust Analyzer Language Server Trace` in the panel.
120* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel. 120* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel.
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index e9581a9b5..1a90f1b7d 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -21,7 +21,12 @@ export function analyzerStatus(ctx: Ctx): Cmd {
21 provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> { 21 provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
22 if (!vscode.window.activeTextEditor) return ''; 22 if (!vscode.window.activeTextEditor) return '';
23 23
24 return ctx.client.sendRequest(ra.analyzerStatus); 24 const params: ra.AnalyzerStatusParams = {};
25 const doc = ctx.activeRustEditor?.document;
26 if (doc != null) {
27 params.textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(doc);
28 }
29 return ctx.client.sendRequest(ra.analyzerStatus, params);
25 } 30 }
26 31
27 get onDidChange(): vscode.Event<vscode.Uri> { 32 get onDidChange(): vscode.Event<vscode.Uri> {
@@ -94,7 +99,7 @@ export function matchingBrace(ctx: Ctx): Cmd {
94 if (!editor || !client) return; 99 if (!editor || !client) return;
95 100
96 const response = await client.sendRequest(ra.matchingBrace, { 101 const response = await client.sendRequest(ra.matchingBrace, {
97 textDocument: { uri: editor.document.uri.toString() }, 102 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
98 positions: editor.selections.map(s => 103 positions: editor.selections.map(s =>
99 client.code2ProtocolConverter.asPosition(s.active), 104 client.code2ProtocolConverter.asPosition(s.active),
100 ), 105 ),
@@ -118,7 +123,7 @@ export function joinLines(ctx: Ctx): Cmd {
118 123
119 const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, { 124 const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
120 ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)), 125 ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
121 textDocument: { uri: editor.document.uri.toString() }, 126 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
122 }); 127 });
123 editor.edit((builder) => { 128 editor.edit((builder) => {
124 client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => { 129 client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => {
@@ -136,7 +141,7 @@ export function onEnter(ctx: Ctx): Cmd {
136 if (!editor || !client) return false; 141 if (!editor || !client) return false;
137 142
138 const lcEdits = await client.sendRequest(ra.onEnter, { 143 const lcEdits = await client.sendRequest(ra.onEnter, {
139 textDocument: { uri: editor.document.uri.toString() }, 144 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
140 position: client.code2ProtocolConverter.asPosition( 145 position: client.code2ProtocolConverter.asPosition(
141 editor.selection.active, 146 editor.selection.active,
142 ), 147 ),
@@ -165,7 +170,7 @@ export function parentModule(ctx: Ctx): Cmd {
165 if (!editor || !client) return; 170 if (!editor || !client) return;
166 171
167 const response = await client.sendRequest(ra.parentModule, { 172 const response = await client.sendRequest(ra.parentModule, {
168 textDocument: { uri: editor.document.uri.toString() }, 173 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
169 position: client.code2ProtocolConverter.asPosition( 174 position: client.code2ProtocolConverter.asPosition(
170 editor.selection.active, 175 editor.selection.active,
171 ), 176 ),
@@ -191,7 +196,7 @@ export function ssr(ctx: Ctx): Cmd {
191 196
192 const position = editor.selection.active; 197 const position = editor.selection.active;
193 const selections = editor.selections; 198 const selections = editor.selections;
194 const textDocument = { uri: editor.document.uri.toString() }; 199 const textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
195 200
196 const options: vscode.InputBoxOptions = { 201 const options: vscode.InputBoxOptions = {
197 value: "() ==>> ()", 202 value: "() ==>> ()",
@@ -339,7 +344,7 @@ export function expandMacro(ctx: Ctx): Cmd {
339 const position = editor.selection.active; 344 const position = editor.selection.active;
340 345
341 const expanded = await client.sendRequest(ra.expandMacro, { 346 const expanded = await client.sendRequest(ra.expandMacro, {
342 textDocument: { uri: editor.document.uri.toString() }, 347 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
343 position, 348 position,
344 }); 349 });
345 350
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index d167041c4..eb422d3e7 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -4,7 +4,10 @@
4 4
5import * as lc from "vscode-languageclient"; 5import * as lc from "vscode-languageclient";
6 6
7export const analyzerStatus = new lc.RequestType0<string, void>("rust-analyzer/analyzerStatus"); 7export interface AnalyzerStatusParams {
8 textDocument?: lc.TextDocumentIdentifier;
9}
10export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus");
8export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage"); 11export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
9 12
10export type Status = "loading" | "ready" | "invalid" | "needsReload"; 13export type Status = "loading" | "ready" | "invalid" | "needsReload";