Skip to content

Commit 7c9ae77

Browse files
bors[bot]matklad
andauthored
Merge #6096
6096: Extend **Status** command to also show dep info for the file r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 80b0b0e + af8063f commit 7c9ae77

File tree

8 files changed

+85
-32
lines changed

8 files changed

+85
-32
lines changed

crates/ide/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ impl Analysis {
216216
}
217217

218218
/// Debug info about the current state of the analysis.
219-
pub fn status(&self) -> Cancelable<String> {
220-
self.with_db(|db| status::status(&*db))
219+
pub fn status(&self, file_id: Option<FileId>) -> Cancelable<String> {
220+
self.with_db(|db| status::status(&*db, file_id))
221221
}
222222

223223
pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> {

crates/ide/src/status.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ use std::{fmt, iter::FromIterator, sync::Arc};
22

33
use base_db::{
44
salsa::debug::{DebugQueryTable, TableEntry},
5-
FileTextQuery, SourceRootId,
5+
CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId,
66
};
77
use hir::MacroFile;
88
use ide_db::{
99
symbol_index::{LibrarySymbolsQuery, SymbolIndex},
1010
RootDatabase,
1111
};
12+
use itertools::Itertools;
1213
use profile::{memory_usage, Bytes};
1314
use rustc_hash::FxHashMap;
15+
use stdx::format_to;
1416
use syntax::{ast, Parse, SyntaxNode};
1517

16-
use crate::FileId;
17-
1818
fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
1919
base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
2020
}
@@ -31,19 +31,36 @@ fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
3131
//
3232
// | VS Code | **Rust Analyzer: Status**
3333
// |===
34-
pub(crate) fn status(db: &RootDatabase) -> String {
35-
let files_stats = FileTextQuery.in_db(db).entries::<FilesStats>();
36-
let syntax_tree_stats = syntax_tree_stats(db);
37-
let macro_syntax_tree_stats = macro_syntax_tree_stats(db);
38-
let symbols_stats = LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>();
39-
format!(
40-
"{}\n{}\n{}\n{} (macros)\n{} total\n",
41-
files_stats,
42-
symbols_stats,
43-
syntax_tree_stats,
44-
macro_syntax_tree_stats,
45-
memory_usage(),
46-
)
34+
pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
35+
let mut buf = String::new();
36+
format_to!(buf, "{}\n", FileTextQuery.in_db(db).entries::<FilesStats>());
37+
format_to!(buf, "{}\n", LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>());
38+
format_to!(buf, "{}\n", syntax_tree_stats(db));
39+
format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
40+
format_to!(buf, "{} total\n", memory_usage());
41+
42+
if let Some(file_id) = file_id {
43+
format_to!(buf, "\nfile info:\n");
44+
let krate = crate::parent_module::crate_for(db, file_id).pop();
45+
match krate {
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
4764
}
4865

4966
#[derive(Default)]

crates/rust-analyzer/src/handlers.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,22 @@ use crate::{
3838
to_proto, LspError, Result,
3939
};
4040

41-
pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> {
41+
pub(crate) fn handle_analyzer_status(
42+
snap: GlobalStateSnapshot,
43+
params: lsp_ext::AnalyzerStatusParams,
44+
) -> Result<String> {
4245
let _p = profile::span("handle_analyzer_status");
4346

4447
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+
4557
if snap.workspaces.is_empty() {
4658
buf.push_str("no workspaces\n")
4759
} else {
@@ -52,7 +64,10 @@ pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result
5264
}
5365
buf.push_str("\nanalysis:\n");
5466
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()),
5671
);
5772
format_to!(buf, "\n\nrequests:\n");
5873
let requests = snap.latest_requests.read();

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ use serde::{Deserialize, Serialize};
1111
pub enum AnalyzerStatus {}
1212

1313
impl Request for AnalyzerStatus {
14-
type Params = ();
14+
type Params = AnalyzerStatusParams;
1515
type Result = String;
1616
const METHOD: &'static str = "rust-analyzer/analyzerStatus";
1717
}
1818

19+
#[derive(Deserialize, Serialize, Debug)]
20+
#[serde(rename_all = "camelCase")]
21+
pub struct AnalyzerStatusParams {
22+
pub text_document: Option<TextDocumentIdentifier>,
23+
}
24+
1925
pub enum MemoryUsage {}
2026

2127
impl Request for MemoryUsage {

docs/dev/lsp-extensions.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,14 @@ rust-analyzer supports only one `kind`, `"cargo"`. The `args` for `"cargo"` look
390390

391391
**Method:** `rust-analyzer/analyzerStatus`
392392

393-
**Request:** `null`
393+
**Request:**
394+
395+
```typescript
396+
interface AnalyzerStatusParams {
397+
/// If specified, show dependencies of the current file.
398+
textDocument?: TextDocumentIdentifier;
399+
}
400+
```
394401

395402
**Response:** `string`
396403

docs/user/manual.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ Note that installing via `xtask install` does not work for VS Code Remote, inste
113113

114114
Here are some useful self-diagnostic commands:
115115

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
116+
* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary.
117+
* **Rust Analyzer: Status** prints some statistics about the server, and dependency information for the current file.
118118
* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel.
119119
* 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.
120120
* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel.

editors/code/src/commands.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ export function analyzerStatus(ctx: Ctx): Cmd {
2121
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
2222
if (!vscode.window.activeTextEditor) return '';
2323

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);
2530
}
2631

2732
get onDidChange(): vscode.Event<vscode.Uri> {
@@ -94,7 +99,7 @@ export function matchingBrace(ctx: Ctx): Cmd {
9499
if (!editor || !client) return;
95100

96101
const response = await client.sendRequest(ra.matchingBrace, {
97-
textDocument: { uri: editor.document.uri.toString() },
102+
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
98103
positions: editor.selections.map(s =>
99104
client.code2ProtocolConverter.asPosition(s.active),
100105
),
@@ -118,7 +123,7 @@ export function joinLines(ctx: Ctx): Cmd {
118123

119124
const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
120125
ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
121-
textDocument: { uri: editor.document.uri.toString() },
126+
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
122127
});
123128
editor.edit((builder) => {
124129
client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => {
@@ -136,7 +141,7 @@ export function onEnter(ctx: Ctx): Cmd {
136141
if (!editor || !client) return false;
137142

138143
const lcEdits = await client.sendRequest(ra.onEnter, {
139-
textDocument: { uri: editor.document.uri.toString() },
144+
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
140145
position: client.code2ProtocolConverter.asPosition(
141146
editor.selection.active,
142147
),
@@ -165,7 +170,7 @@ export function parentModule(ctx: Ctx): Cmd {
165170
if (!editor || !client) return;
166171

167172
const response = await client.sendRequest(ra.parentModule, {
168-
textDocument: { uri: editor.document.uri.toString() },
173+
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
169174
position: client.code2ProtocolConverter.asPosition(
170175
editor.selection.active,
171176
),
@@ -191,7 +196,7 @@ export function ssr(ctx: Ctx): Cmd {
191196

192197
const position = editor.selection.active;
193198
const selections = editor.selections;
194-
const textDocument = { uri: editor.document.uri.toString() };
199+
const textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
195200

196201
const options: vscode.InputBoxOptions = {
197202
value: "() ==>> ()",
@@ -339,7 +344,7 @@ export function expandMacro(ctx: Ctx): Cmd {
339344
const position = editor.selection.active;
340345

341346
const expanded = await client.sendRequest(ra.expandMacro, {
342-
textDocument: { uri: editor.document.uri.toString() },
347+
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
343348
position,
344349
});
345350

editors/code/src/lsp_ext.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
import * as lc from "vscode-languageclient";
66

7-
export const analyzerStatus = new lc.RequestType0<string, void>("rust-analyzer/analyzerStatus");
7+
export interface AnalyzerStatusParams {
8+
textDocument?: lc.TextDocumentIdentifier;
9+
}
10+
export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus");
811
export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
912

1013
export type Status = "loading" | "ready" | "invalid" | "needsReload";

0 commit comments

Comments
 (0)