Skip to content

Commit 09e0a00

Browse files
committed
fetching dependencies from the server
1 parent 1201b15 commit 09e0a00

File tree

9 files changed

+155
-156
lines changed

9 files changed

+155
-156
lines changed

crates/ide/src/fetch_crates.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use ide_db::{
2+
base_db::{CrateOrigin, SourceDatabase, SourceDatabaseExt},
3+
RootDatabase,
4+
};
5+
6+
#[derive(Debug)]
7+
pub struct CrateInfo {
8+
pub name: String,
9+
pub version: String,
10+
pub path: String,
11+
}
12+
13+
pub(crate) fn fetch_crates(db: &RootDatabase) -> Vec<CrateInfo> {
14+
let crate_graph = db.crate_graph();
15+
crate_graph
16+
.iter()
17+
.map(|crate_id| &crate_graph[crate_id])
18+
.filter(|&data| !matches!(data.origin, CrateOrigin::Local { .. }))
19+
.map(|data| {
20+
let crate_name = crate_name(data);
21+
let version = data.version.clone().unwrap_or_else(|| "".to_owned());
22+
let crate_path = crate_path(db, data, &crate_name);
23+
24+
CrateInfo { name: crate_name, version, path: crate_path }
25+
})
26+
.collect()
27+
}
28+
29+
fn crate_name(data: &ide_db::base_db::CrateData) -> String {
30+
data.display_name
31+
.clone()
32+
.map(|it| it.canonical_name().to_owned())
33+
.unwrap_or("unknown".to_string())
34+
}
35+
36+
fn crate_path(db: &RootDatabase, data: &ide_db::base_db::CrateData, crate_name: &str) -> String {
37+
let source_root_id = db.file_source_root(data.root_file_id);
38+
let source_root = db.source_root(source_root_id);
39+
let source_root_path = source_root.path_for_file(&data.root_file_id);
40+
match source_root_path.cloned() {
41+
Some(mut root_path) => {
42+
let mut crate_path = "".to_string();
43+
while let Some(vfs_path) = root_path.parent() {
44+
match vfs_path.name_and_extension() {
45+
Some((name, _)) => {
46+
if name.starts_with(crate_name) {
47+
crate_path = vfs_path.to_string();
48+
break;
49+
}
50+
}
51+
None => break,
52+
}
53+
root_path = vfs_path;
54+
}
55+
crate_path
56+
}
57+
None => "".to_owned(),
58+
}
59+
}

crates/ide/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ mod view_mir;
5959
mod interpret_function;
6060
mod view_item_tree;
6161
mod shuffle_crate_graph;
62+
mod fetch_crates;
6263

6364
use std::sync::Arc;
6465

6566
use cfg::CfgOptions;
67+
use fetch_crates::CrateInfo;
6668
use ide_db::{
6769
base_db::{
6870
salsa::{self, ParallelDatabase},
@@ -331,6 +333,10 @@ impl Analysis {
331333
self.with_db(|db| view_crate_graph::view_crate_graph(db, full))
332334
}
333335

336+
pub fn fetch_crates(&self) -> Cancellable<Vec<CrateInfo>> {
337+
self.with_db(|db| fetch_crates::fetch_crates(db))
338+
}
339+
334340
pub fn expand_macro(&self, position: FilePosition) -> Cancellable<Option<ExpandedMacro>> {
335341
self.with_db(|db| expand_macro::expand_macro(db, position))
336342
}

crates/rust-analyzer/src/handlers.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ use ide::AssistResolveStrategy;
66
use lsp_types::{Diagnostic, DiagnosticTag, NumberOrString};
77
use vfs::FileId;
88

9-
use crate::{global_state::GlobalStateSnapshot, to_proto, Result};
9+
use crate::{
10+
global_state::GlobalStateSnapshot, to_proto, Result,
11+
lsp_ext::{
12+
CrateInfoResult, FetchDependencyGraphResult, FetchDependencyGraphParams,
13+
},
14+
};
15+
1016

1117
pub(crate) mod request;
1218
pub(crate) mod notification;
@@ -31,7 +37,7 @@ pub(crate) fn publish_diagnostics(
3137
"https://rust-analyzer.github.io/manual.html#{}",
3238
d.code.as_str()
3339
))
34-
.unwrap(),
40+
.unwrap(),
3541
}),
3642
source: Some("rust-analyzer".to_string()),
3743
message: d.message,
@@ -42,3 +48,16 @@ pub(crate) fn publish_diagnostics(
4248
.collect();
4349
Ok(diagnostics)
4450
}
51+
52+
pub(crate) fn fetch_dependency_graph(
53+
state: GlobalStateSnapshot,
54+
_params: FetchDependencyGraphParams,
55+
) -> Result<FetchDependencyGraphResult> {
56+
let crates = state.analysis.fetch_crates()?;
57+
Ok(FetchDependencyGraphResult {
58+
crates: crates
59+
.into_iter()
60+
.map(|it| CrateInfoResult { name: it.name, version: it.version, path: it.path })
61+
.collect(),
62+
})
63+
}

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ pub struct AnalyzerStatusParams {
2727
pub text_document: Option<TextDocumentIdentifier>,
2828
}
2929

30+
#[derive(Deserialize, Serialize, Debug)]
31+
#[serde(rename_all = "camelCase")]
32+
pub struct CrateInfoResult {
33+
pub name: String,
34+
pub version: String,
35+
pub path: String,
36+
}
3037
pub enum FetchDependencyGraph {}
3138

3239
impl Request for FetchDependencyGraph {
@@ -38,9 +45,12 @@ impl Request for FetchDependencyGraph {
3845
#[derive(Deserialize, Serialize, Debug)]
3946
#[serde(rename_all = "camelCase")]
4047
pub struct FetchDependencyGraphParams {}
48+
4149
#[derive(Deserialize, Serialize, Debug)]
4250
#[serde(rename_all = "camelCase")]
43-
pub struct FetchDependencyGraphResult {}
51+
pub struct FetchDependencyGraphResult {
52+
pub crates: Vec<CrateInfoResult>,
53+
}
4454

4555
pub enum MemoryUsage {}
4656

@@ -374,6 +384,7 @@ impl Request for CodeActionRequest {
374384
}
375385

376386
pub enum CodeActionResolveRequest {}
387+
377388
impl Request for CodeActionResolveRequest {
378389
type Params = CodeAction;
379390
type Result = CodeAction;

crates/rust-analyzer/src/main_loop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,12 +655,12 @@ impl GlobalState {
655655
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
656656
.on_sync_mut::<lsp_ext::RebuildProcMacros>(handlers::handle_proc_macros_rebuild)
657657
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
658-
.on_sync_mut::<lsp_ext::FetchDependencyGraph>(handlers::fetch_dependency_graph)
659658
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
660659
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
661660
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
662661
.on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
663662
.on_sync::<lsp_ext::MatchingBrace>(handlers::handle_matching_brace)
663+
.on::<lsp_ext::FetchDependencyGraph>(handlers::fetch_dependency_graph)
664664
.on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)
665665
.on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)
666666
.on::<lsp_ext::ViewHir>(handlers::handle_view_hir)

editors/code/src/commands.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,19 @@ export function revealDependency(ctx: CtxInit): Cmd {
272272
const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
273273
const documentPath = editor.document.uri.fsPath;
274274
if (documentPath.startsWith(rootPath)) return;
275-
const dep = ctx.dependencies.getDependency(documentPath);
275+
const dep = ctx.dependencies?.getDependency(documentPath);
276276
if (dep) {
277-
await ctx.treeView.reveal(dep, { select: true, expand: true });
277+
await ctx.treeView?.reveal(dep, { select: true, expand: true });
278278
} else {
279279
let documentPath = editor.document.uri.fsPath;
280280
const parentChain: DependencyId[] = [{ id: documentPath.toLowerCase() }];
281281
do {
282282
documentPath = path.dirname(documentPath);
283283
parentChain.push({ id: documentPath.toLowerCase() });
284-
} while (!ctx.dependencies.contains(documentPath));
284+
} while (!ctx.dependencies?.contains(documentPath));
285285
parentChain.reverse();
286286
for (const idx in parentChain) {
287-
await ctx.treeView.reveal(parentChain[idx], { select: true, expand: true });
287+
await ctx.treeView?.reveal(parentChain[idx], { select: true, expand: true });
288288
}
289289
}
290290
};

editors/code/src/ctx.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,25 @@ export class Ctx {
9191
private commandFactories: Record<string, CommandFactory>;
9292
private commandDisposables: Disposable[];
9393
private unlinkedFiles: vscode.Uri[];
94-
readonly dependencies: RustDependenciesProvider;
95-
readonly treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId>;
94+
private _dependencies: RustDependenciesProvider | undefined;
95+
private _treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> | undefined;
9696

9797
get client() {
9898
return this._client;
9999
}
100100

101+
get treeView() {
102+
return this._treeView;
103+
}
104+
105+
get dependencies() {
106+
return this._dependencies;
107+
}
108+
101109
constructor(
102110
readonly extCtx: vscode.ExtensionContext,
103111
commandFactories: Record<string, CommandFactory>,
104112
workspace: Workspace,
105-
dependencies: RustDependenciesProvider,
106-
treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId>
107113
) {
108114
extCtx.subscriptions.push(this);
109115
this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
@@ -112,9 +118,6 @@ export class Ctx {
112118
this.commandDisposables = [];
113119
this.commandFactories = commandFactories;
114120
this.unlinkedFiles = [];
115-
this.dependencies = dependencies;
116-
this.treeView = treeView;
117-
118121
this.state = new PersistentState(extCtx.globalState);
119122
this.config = new Config(extCtx);
120123

@@ -123,13 +126,6 @@ export class Ctx {
123126
this.setServerStatus({
124127
health: "stopped",
125128
});
126-
vscode.window.onDidChangeActiveTextEditor((e) => {
127-
if (e && isRustEditor(e)) {
128-
execRevealDependency(e).catch((reason) => {
129-
void vscode.window.showErrorMessage(`Dependency error: ${reason}`);
130-
});
131-
}
132-
});
133129
}
134130

135131
dispose() {
@@ -267,6 +263,28 @@ export class Ctx {
267263
}
268264
await client.start();
269265
this.updateCommands();
266+
this.prepareTreeDependenciesView(client);
267+
}
268+
269+
private prepareTreeDependenciesView(client: lc.LanguageClient) {
270+
const ctxInit: CtxInit = {
271+
...this,
272+
client: client
273+
};
274+
const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
275+
this._dependencies = new RustDependenciesProvider(rootPath, ctxInit);
276+
this._treeView = vscode.window.createTreeView("rustDependencies", {
277+
treeDataProvider: this._dependencies,
278+
showCollapseAll: true,
279+
});
280+
281+
vscode.window.onDidChangeActiveTextEditor((e) => {
282+
if (e && isRustEditor(e)) {
283+
execRevealDependency(e).catch((reason) => {
284+
void vscode.window.showErrorMessage(`Dependency error: ${reason}`);
285+
});
286+
}
287+
});
270288
}
271289

272290
async restart() {
@@ -369,7 +387,7 @@ export class Ctx {
369387
statusBar.color = undefined;
370388
statusBar.backgroundColor = undefined;
371389
statusBar.command = "rust-analyzer.stopServer";
372-
this.dependencies.refresh();
390+
this.dependencies?.refresh();
373391
break;
374392
case "warning":
375393
if (status.message) {

0 commit comments

Comments
 (0)