diff options
| author | Jonas Schievink <jonas.schievink@ferrous-systems.com> | 2021-12-07 15:38:12 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonas.schievink@ferrous-systems.com> | 2021-12-07 16:37:19 +0100 |
| commit | deb5c1426d1ca8150a9a7e4eddb53a84f51b58b9 (patch) | |
| tree | 44ecbfe4aeb48532ae9a3f41b7b451e1750ee1a9 | |
| parent | 9ae3158292a61974cc319c99f7c3c74a3129521a (diff) | |
| download | rust-deb5c1426d1ca8150a9a7e4eddb53a84f51b58b9.tar.gz rust-deb5c1426d1ca8150a9a7e4eddb53a84f51b58b9.zip | |
internal: add "Shuffle Crate Graph" command
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | crates/ide/src/lib.rs | 5 | ||||
| -rw-r--r-- | crates/ide/src/shuffle_crate_graph.rs | 70 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 5 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/lsp_ext.rs | 8 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 1 | ||||
| -rw-r--r-- | editors/code/package.json | 5 | ||||
| -rw-r--r-- | editors/code/src/commands.ts | 9 | ||||
| -rw-r--r-- | editors/code/src/lsp_ext.ts | 1 | ||||
| -rw-r--r-- | editors/code/src/main.ts | 1 |
10 files changed, 106 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index f3e3cab1d6e..68c87a6b1ed 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ generated_diagnostic.adoc .DS_Store /out/ /dump.lsif +.envrc diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index e7feb042b22..5bd9f054dd3 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -56,6 +56,7 @@ mod typing; mod view_crate_graph; mod view_hir; mod view_item_tree; +mod shuffle_crate_graph; use std::sync::Arc; @@ -177,6 +178,10 @@ impl AnalysisHost { pub fn raw_database_mut(&mut self) -> &mut RootDatabase { &mut self.db } + + pub fn shuffle_crate_graph(&mut self) { + shuffle_crate_graph::shuffle_crate_graph(&mut self.db); + } } impl Default for AnalysisHost { diff --git a/crates/ide/src/shuffle_crate_graph.rs b/crates/ide/src/shuffle_crate_graph.rs new file mode 100644 index 00000000000..9c3cce5dfe4 --- /dev/null +++ b/crates/ide/src/shuffle_crate_graph.rs @@ -0,0 +1,70 @@ +use std::sync::Arc; + +use ide_db::base_db::salsa::Durability; +use ide_db::base_db::{CrateGraph, SourceDatabase}; +use ide_db::RootDatabase; +use rustc_hash::FxHashMap; + +// Feature: Shuffle Crate Graph +// +// Randomizes all crate IDs in the crate graph, for debugging. +// +// |=== +// | Editor | Action Name +// +// | VS Code | **Rust Analyzer: Shuffle Crate Graph** +// |=== +pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) { + let crate_graph = db.crate_graph(); + + let mut shuffled_ids = crate_graph.iter().collect::<Vec<_>>(); + shuffle(&mut shuffled_ids); + + let mut new_graph = CrateGraph::default(); + + let mut map = FxHashMap::default(); + for old_id in shuffled_ids.iter().copied() { + let data = &crate_graph[old_id]; + let new_id = new_graph.add_crate_root( + data.root_file_id, + data.edition, + data.display_name.clone(), + data.version.clone(), + data.cfg_options.clone(), + data.potential_cfg_options.clone(), + data.env.clone(), + data.proc_macro.clone(), + data.origin.clone(), + ); + map.insert(old_id, new_id); + } + + for old_id in shuffled_ids.iter().copied() { + let data = &crate_graph[old_id]; + for dep in &data.dependencies { + let mut new_dep = dep.clone(); + new_dep.crate_id = map[&dep.crate_id]; + new_graph.add_dep(map[&old_id], new_dep).unwrap(); + } + } + + db.set_crate_graph_with_durability(Arc::new(new_graph), Durability::HIGH); +} + +fn shuffle<T>(slice: &mut [T]) { + let mut rng = oorandom::Rand32::new(seed()); + + let mut remaining = slice.len() - 1; + while remaining > 0 { + let index = rng.rand_range(0..remaining as u32); + slice.swap(remaining, index as usize); + remaining -= 1; + } +} + +fn seed() -> u64 { + use std::collections::hash_map::RandomState; + use std::hash::{BuildHasher, Hasher}; + + RandomState::new().build_hasher().finish() +} diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index bf153012d94..ab3c9e8227d 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -97,6 +97,11 @@ pub(crate) fn handle_memory_usage(state: &mut GlobalState, _: ()) -> Result<Stri Ok(out) } +pub(crate) fn handle_shuffle_crate_graph(state: &mut GlobalState, _: ()) -> Result<()> { + state.analysis_host.shuffle_crate_graph(); + Ok(()) +} + pub(crate) fn handle_syntax_tree( snap: GlobalStateSnapshot, params: lsp_ext::SyntaxTreeParams, diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 19137b942eb..0e23094199f 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -31,6 +31,14 @@ impl Request for MemoryUsage { const METHOD: &'static str = "rust-analyzer/memoryUsage"; } +pub enum ShuffleCrateGraph {} + +impl Request for ShuffleCrateGraph { + type Params = (); + type Result = (); + const METHOD: &'static str = "rust-analyzer/shuffleCrateGraph"; +} + pub enum ReloadWorkspace {} impl Request for ReloadWorkspace { diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 2d83cbee669..65f9c873673 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -567,6 +567,7 @@ impl GlobalState { Ok(()) })? .on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)? + .on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)? .on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)? .on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)? .on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)? diff --git a/editors/code/package.json b/editors/code/package.json index da4fa15b02f..4b6e5ef3332 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -172,6 +172,11 @@ "category": "Rust Analyzer" }, { + "command": "rust-analyzer.shuffleCrateGraph", + "title": "Shuffle Crate Graph", + "category": "Rust Analyzer" + }, + { "command": "rust-analyzer.reloadWorkspace", "title": "Reload workspace", "category": "Rust Analyzer" diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index c9385361f88..fe006a63e27 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -85,6 +85,15 @@ export function memoryUsage(ctx: Ctx): Cmd { }; } +export function shuffleCrateGraph(ctx: Ctx): Cmd { + return async () => { + const client = ctx.client; + if (!client) return; + + await client.sendRequest(ra.shuffleCrateGraph); + }; +} + export function matchingBrace(ctx: Ctx): Cmd { return async () => { const editor = ctx.activeRustEditor; diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 90796e611e6..a21a742a571 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -9,6 +9,7 @@ export interface AnalyzerStatusParams { } 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 shuffleCrateGraph = new lc.RequestType0<null, void>("rust-analyzer/shuffleCrateGraph"); export interface ServerStatusParams { health: "ok" | "warning" | "error"; diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 734f2245036..a06fc09fc8e 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -117,6 +117,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) { ctx.registerCommand('analyzerStatus', commands.analyzerStatus); ctx.registerCommand('memoryUsage', commands.memoryUsage); + ctx.registerCommand('shuffleCrateGraph', commands.shuffleCrateGraph); ctx.registerCommand('reloadWorkspace', commands.reloadWorkspace); ctx.registerCommand('matchingBrace', commands.matchingBrace); ctx.registerCommand('joinLines', commands.joinLines); |
