mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Extend **Status** command to also show dep info for the file
This should help with troubleshooting wrong project configuration
This commit is contained in:
parent
e7df0ad2fb
commit
af8063fe37
8 changed files with 85 additions and 32 deletions
|
@ -216,8 +216,8 @@ impl Analysis {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debug info about the current state of the analysis.
|
/// Debug info about the current state of the analysis.
|
||||||
pub fn status(&self) -> Cancelable<String> {
|
pub fn status(&self, file_id: Option<FileId>) -> Cancelable<String> {
|
||||||
self.with_db(|db| status::status(&*db))
|
self.with_db(|db| status::status(&*db, file_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> {
|
pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> {
|
||||||
|
|
|
@ -2,19 +2,19 @@ use std::{fmt, iter::FromIterator, sync::Arc};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
salsa::debug::{DebugQueryTable, TableEntry},
|
salsa::debug::{DebugQueryTable, TableEntry},
|
||||||
FileTextQuery, SourceRootId,
|
CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId,
|
||||||
};
|
};
|
||||||
use hir::MacroFile;
|
use hir::MacroFile;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
symbol_index::{LibrarySymbolsQuery, SymbolIndex},
|
symbol_index::{LibrarySymbolsQuery, SymbolIndex},
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use profile::{memory_usage, Bytes};
|
use profile::{memory_usage, Bytes};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use stdx::format_to;
|
||||||
use syntax::{ast, Parse, SyntaxNode};
|
use syntax::{ast, Parse, SyntaxNode};
|
||||||
|
|
||||||
use crate::FileId;
|
|
||||||
|
|
||||||
fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
|
fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
|
||||||
base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
|
base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
|
||||||
}
|
}
|
||||||
|
@ -31,19 +31,36 @@ fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
|
||||||
//
|
//
|
||||||
// | VS Code | **Rust Analyzer: Status**
|
// | VS Code | **Rust Analyzer: Status**
|
||||||
// |===
|
// |===
|
||||||
pub(crate) fn status(db: &RootDatabase) -> String {
|
pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
|
||||||
let files_stats = FileTextQuery.in_db(db).entries::<FilesStats>();
|
let mut buf = String::new();
|
||||||
let syntax_tree_stats = syntax_tree_stats(db);
|
format_to!(buf, "{}\n", FileTextQuery.in_db(db).entries::<FilesStats>());
|
||||||
let macro_syntax_tree_stats = macro_syntax_tree_stats(db);
|
format_to!(buf, "{}\n", LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>());
|
||||||
let symbols_stats = LibrarySymbolsQuery.in_db(db).entries::<LibrarySymbolsStats>();
|
format_to!(buf, "{}\n", syntax_tree_stats(db));
|
||||||
format!(
|
format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
|
||||||
"{}\n{}\n{}\n{} (macros)\n{} total\n",
|
format_to!(buf, "{} total\n", memory_usage());
|
||||||
files_stats,
|
|
||||||
symbols_stats,
|
if let Some(file_id) = file_id {
|
||||||
syntax_tree_stats,
|
format_to!(buf, "\nfile info:\n");
|
||||||
macro_syntax_tree_stats,
|
let krate = crate::parent_module::crate_for(db, file_id).pop();
|
||||||
memory_usage(),
|
match krate {
|
||||||
)
|
Some(krate) => {
|
||||||
|
let crate_graph = db.crate_graph();
|
||||||
|
let display_crate = |krate: CrateId| match &crate_graph[krate].display_name {
|
||||||
|
Some(it) => format!("{}({:?})", it, krate),
|
||||||
|
None => format!("{:?}", krate),
|
||||||
|
};
|
||||||
|
format_to!(buf, "crate: {}\n", display_crate(krate));
|
||||||
|
let deps = crate_graph[krate]
|
||||||
|
.dependencies
|
||||||
|
.iter()
|
||||||
|
.map(|dep| format!("{}={:?}", dep.name, dep.crate_id))
|
||||||
|
.format(", ");
|
||||||
|
format_to!(buf, "deps: {}\n", deps);
|
||||||
|
}
|
||||||
|
None => format_to!(buf, "does not belong to any crate"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -38,10 +38,22 @@ use crate::{
|
||||||
to_proto, LspError, Result,
|
to_proto, LspError, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> {
|
pub(crate) fn handle_analyzer_status(
|
||||||
|
snap: GlobalStateSnapshot,
|
||||||
|
params: lsp_ext::AnalyzerStatusParams,
|
||||||
|
) -> Result<String> {
|
||||||
let _p = profile::span("handle_analyzer_status");
|
let _p = profile::span("handle_analyzer_status");
|
||||||
|
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
let mut file_id = None;
|
||||||
|
if let Some(tdi) = params.text_document {
|
||||||
|
match from_proto::file_id(&snap, &tdi.uri) {
|
||||||
|
Ok(it) => file_id = Some(it),
|
||||||
|
Err(_) => format_to!(buf, "file {} not found in vfs", tdi.uri),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if snap.workspaces.is_empty() {
|
if snap.workspaces.is_empty() {
|
||||||
buf.push_str("no workspaces\n")
|
buf.push_str("no workspaces\n")
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,7 +64,10 @@ pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result
|
||||||
}
|
}
|
||||||
buf.push_str("\nanalysis:\n");
|
buf.push_str("\nanalysis:\n");
|
||||||
buf.push_str(
|
buf.push_str(
|
||||||
&snap.analysis.status().unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
|
&snap
|
||||||
|
.analysis
|
||||||
|
.status(file_id)
|
||||||
|
.unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
|
||||||
);
|
);
|
||||||
format_to!(buf, "\n\nrequests:\n");
|
format_to!(buf, "\n\nrequests:\n");
|
||||||
let requests = snap.latest_requests.read();
|
let requests = snap.latest_requests.read();
|
||||||
|
|
|
@ -11,11 +11,17 @@ use serde::{Deserialize, Serialize};
|
||||||
pub enum AnalyzerStatus {}
|
pub enum AnalyzerStatus {}
|
||||||
|
|
||||||
impl Request for AnalyzerStatus {
|
impl Request for AnalyzerStatus {
|
||||||
type Params = ();
|
type Params = AnalyzerStatusParams;
|
||||||
type Result = String;
|
type Result = String;
|
||||||
const METHOD: &'static str = "rust-analyzer/analyzerStatus";
|
const METHOD: &'static str = "rust-analyzer/analyzerStatus";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct AnalyzerStatusParams {
|
||||||
|
pub text_document: Option<TextDocumentIdentifier>,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum MemoryUsage {}
|
pub enum MemoryUsage {}
|
||||||
|
|
||||||
impl Request for MemoryUsage {
|
impl Request for MemoryUsage {
|
||||||
|
|
|
@ -390,7 +390,14 @@ rust-analyzer supports only one `kind`, `"cargo"`. The `args` for `"cargo"` look
|
||||||
|
|
||||||
**Method:** `rust-analyzer/analyzerStatus`
|
**Method:** `rust-analyzer/analyzerStatus`
|
||||||
|
|
||||||
**Request:** `null`
|
**Request:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface AnalyzerStatusParams {
|
||||||
|
/// If specified, show dependencies of the current file.
|
||||||
|
textDocument?: TextDocumentIdentifier;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Response:** `string`
|
**Response:** `string`
|
||||||
|
|
||||||
|
|
|
@ -113,8 +113,8 @@ Note that installing via `xtask install` does not work for VS Code Remote, inste
|
||||||
|
|
||||||
Here are some useful self-diagnostic commands:
|
Here are some useful self-diagnostic commands:
|
||||||
|
|
||||||
* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary
|
* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary.
|
||||||
* **Rust Analyzer: Status** prints some statistics about the server, like the few latest LSP requests
|
* **Rust Analyzer: Status** prints some statistics about the server, and dependency information for the current file.
|
||||||
* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel.
|
* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel.
|
||||||
* 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.
|
* 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.
|
||||||
* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel.
|
* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel.
|
||||||
|
|
|
@ -21,7 +21,12 @@ export function analyzerStatus(ctx: Ctx): Cmd {
|
||||||
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
|
provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
|
||||||
if (!vscode.window.activeTextEditor) return '';
|
if (!vscode.window.activeTextEditor) return '';
|
||||||
|
|
||||||
return ctx.client.sendRequest(ra.analyzerStatus);
|
const params: ra.AnalyzerStatusParams = {};
|
||||||
|
const doc = ctx.activeRustEditor?.document;
|
||||||
|
if (doc != null) {
|
||||||
|
params.textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(doc);
|
||||||
|
}
|
||||||
|
return ctx.client.sendRequest(ra.analyzerStatus, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
get onDidChange(): vscode.Event<vscode.Uri> {
|
get onDidChange(): vscode.Event<vscode.Uri> {
|
||||||
|
@ -94,7 +99,7 @@ export function matchingBrace(ctx: Ctx): Cmd {
|
||||||
if (!editor || !client) return;
|
if (!editor || !client) return;
|
||||||
|
|
||||||
const response = await client.sendRequest(ra.matchingBrace, {
|
const response = await client.sendRequest(ra.matchingBrace, {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
positions: editor.selections.map(s =>
|
positions: editor.selections.map(s =>
|
||||||
client.code2ProtocolConverter.asPosition(s.active),
|
client.code2ProtocolConverter.asPosition(s.active),
|
||||||
),
|
),
|
||||||
|
@ -118,7 +123,7 @@ export function joinLines(ctx: Ctx): Cmd {
|
||||||
|
|
||||||
const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
|
const items: lc.TextEdit[] = await client.sendRequest(ra.joinLines, {
|
||||||
ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
|
ranges: editor.selections.map((it) => client.code2ProtocolConverter.asRange(it)),
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
});
|
});
|
||||||
editor.edit((builder) => {
|
editor.edit((builder) => {
|
||||||
client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => {
|
client.protocol2CodeConverter.asTextEdits(items).forEach((edit: any) => {
|
||||||
|
@ -136,7 +141,7 @@ export function onEnter(ctx: Ctx): Cmd {
|
||||||
if (!editor || !client) return false;
|
if (!editor || !client) return false;
|
||||||
|
|
||||||
const lcEdits = await client.sendRequest(ra.onEnter, {
|
const lcEdits = await client.sendRequest(ra.onEnter, {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
position: client.code2ProtocolConverter.asPosition(
|
position: client.code2ProtocolConverter.asPosition(
|
||||||
editor.selection.active,
|
editor.selection.active,
|
||||||
),
|
),
|
||||||
|
@ -165,7 +170,7 @@ export function parentModule(ctx: Ctx): Cmd {
|
||||||
if (!editor || !client) return;
|
if (!editor || !client) return;
|
||||||
|
|
||||||
const response = await client.sendRequest(ra.parentModule, {
|
const response = await client.sendRequest(ra.parentModule, {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
position: client.code2ProtocolConverter.asPosition(
|
position: client.code2ProtocolConverter.asPosition(
|
||||||
editor.selection.active,
|
editor.selection.active,
|
||||||
),
|
),
|
||||||
|
@ -191,7 +196,7 @@ export function ssr(ctx: Ctx): Cmd {
|
||||||
|
|
||||||
const position = editor.selection.active;
|
const position = editor.selection.active;
|
||||||
const selections = editor.selections;
|
const selections = editor.selections;
|
||||||
const textDocument = { uri: editor.document.uri.toString() };
|
const textDocument = ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
|
||||||
|
|
||||||
const options: vscode.InputBoxOptions = {
|
const options: vscode.InputBoxOptions = {
|
||||||
value: "() ==>> ()",
|
value: "() ==>> ()",
|
||||||
|
@ -339,7 +344,7 @@ export function expandMacro(ctx: Ctx): Cmd {
|
||||||
const position = editor.selection.active;
|
const position = editor.selection.active;
|
||||||
|
|
||||||
const expanded = await client.sendRequest(ra.expandMacro, {
|
const expanded = await client.sendRequest(ra.expandMacro, {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
|
||||||
position,
|
position,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
import * as lc from "vscode-languageclient";
|
import * as lc from "vscode-languageclient";
|
||||||
|
|
||||||
export const analyzerStatus = new lc.RequestType0<string, void>("rust-analyzer/analyzerStatus");
|
export interface AnalyzerStatusParams {
|
||||||
|
textDocument?: lc.TextDocumentIdentifier;
|
||||||
|
}
|
||||||
|
export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>("rust-analyzer/analyzerStatus");
|
||||||
export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
|
export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
|
||||||
|
|
||||||
export type Status = "loading" | "ready" | "invalid" | "needsReload";
|
export type Status = "loading" | "ready" | "invalid" | "needsReload";
|
||||||
|
|
Loading…
Reference in a new issue