Repository: rust-analyzer/rust-analyzer
Pull request #1703 (2019-08-19 12:41:50)

don't load sysroot in most heavy tests


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 3a6f0cc82a..071fbf147c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1290,6 +1290,7 @@ name = "ra_tools"
 version = "0.1.0"
 dependencies = [
  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs
index 6dcdc695a7..71838b89cd 100644
--- a/crates/ra_lsp_server/src/config.rs
+++ b/crates/ra_lsp_server/src/config.rs
@@ -21,6 +21,10 @@ pub struct ServerConfig {
     pub exclude_globs: Vec<String>,
 
     pub lru_capacity: Option<usize>,
+
+    /// For internal usage to make integrated tests faster.
+    #[serde(deserialize_with = "nullable_bool_true")]
+    pub with_sysroot: bool,
 }
 
 impl Default for ServerConfig {
@@ -30,6 +34,7 @@ impl Default for ServerConfig {
             show_workspace_loaded: true,
             exclude_globs: Vec::new(),
             lru_capacity: None,
+            with_sysroot: true,
         }
     }
 }
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index b9c99a2236..3ee0ad6522 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -59,7 +59,7 @@ pub fn main_loop(
     log::debug!("server_config: {:?}", config);
     // FIXME: support dynamic workspace loading.
     let workspaces = {
-        let ws_worker = workspace_loader();
+        let ws_worker = workspace_loader(config.with_sysroot);
         let mut loaded_workspaces = Vec::new();
         for ws_root in &ws_roots {
             ws_worker.sender().send(ws_root.clone()).unwrap();
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs
index 1130d08de9..ad59cde64c 100644
--- a/crates/ra_lsp_server/src/project_model.rs
+++ b/crates/ra_lsp_server/src/project_model.rs
@@ -8,14 +8,14 @@ pub use ra_project_model::{
     CargoWorkspace, Package, ProjectWorkspace, Sysroot, Target, TargetKind,
 };
 
-pub fn workspace_loader() -> Worker<PathBuf, Result<ProjectWorkspace>> {
+pub fn workspace_loader(with_sysroot: bool) -> Worker<PathBuf, Result<ProjectWorkspace>> {
     Worker::<PathBuf, Result<ProjectWorkspace>>::spawn(
         "workspace loader",
         1,
-        |input_receiver, output_sender| {
+        move |input_receiver, output_sender| {
             input_receiver
                 .into_iter()
-                .map(|path| ProjectWorkspace::discover(path.as_path()))
+                .map(|path| ProjectWorkspace::discover_with_sysroot(path.as_path(), with_sysroot))
                 .try_for_each(|it| output_sender.send(it))
                 .unwrap()
         },
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 55b94b9113..676dc49418 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -57,6 +57,10 @@ impl PackageRoot {
 
 impl ProjectWorkspace {
     pub fn discover(path: &Path) -> Result<ProjectWorkspace> {
+        ProjectWorkspace::discover_with_sysroot(path, true)
+    }
+
+    pub fn discover_with_sysroot(path: &Path, with_sysroot: bool) -> Result<ProjectWorkspace> {
         match find_rust_project_json(path) {
             Some(json_path) => {
                 let file = File::open(json_path)?;
@@ -65,10 +69,10 @@ impl ProjectWorkspace {
             }
             None => {
                 let cargo_toml = find_cargo_toml(path)?;
-                Ok(ProjectWorkspace::Cargo {
-                    cargo: CargoWorkspace::from_cargo_metadata(&cargo_toml)?,
-                    sysroot: Sysroot::discover(&cargo_toml)?,
-                })
+                let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?;
+                let sysroot =
+                    if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() };
+                Ok(ProjectWorkspace::Cargo { cargo, sysroot })
             }
         }
     }
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 3f34d51ccb..2a7927f7ef 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -7,7 +7,7 @@ use ra_arena::{impl_arena_id, Arena, RawId};
 
 use crate::Result;
 
-#[derive(Debug, Clone)]
+#[derive(Default, Debug, Clone)]
 pub struct Sysroot {
     crates: Arena<SysrootCrate, SysrootCrateData>,
 }
diff --git a/crates/ra_tools/Cargo.toml b/crates/ra_tools/Cargo.toml
index 1ab3573f9d..4c9aa1cc3f 100644
--- a/crates/ra_tools/Cargo.toml
+++ b/crates/ra_tools/Cargo.toml
@@ -12,4 +12,5 @@ clap = "2.32.0"
 quote = "1.0.2"
 proc-macro2 = "1.0.1"
 ron = "0.5.1"
+heck = "0.3.0"
 serde = { version = "1.0.0", features = ["derive"] }
diff --git a/crates/ra_tools/src/boilerplate_gen.rs b/crates/ra_tools/src/boilerplate_gen.rs
index 578f13a3e0..01d092d484 100644
--- a/crates/ra_tools/src/boilerplate_gen.rs
+++ b/crates/ra_tools/src/boilerplate_gen.rs
@@ -5,6 +5,7 @@ use std::{
     process::{Command, Stdio},
 };
 
+use heck::{ShoutySnakeCase, SnakeCase};
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
 use ron;
@@ -37,7 +38,7 @@ fn generate_ast(grammar: &Grammar) -> Result<String> {
         let name = format_ident!("{}", name);
 
         let adt = if variants.is_empty() {
-            let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
+            let kind = format_ident!("{}", name.to_string().to_shouty_snake_case());
             quote! {
                 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
                 pub struct #name {
@@ -60,7 +61,7 @@ fn generate_ast(grammar: &Grammar) -> Result<String> {
         } else {
             let kinds = variants
                 .iter()
-                .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
+                .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case()))
                 .collect::<Vec<_>>();
 
             quote! {
@@ -121,7 +122,7 @@ fn generate_ast(grammar: &Grammar) -> Result<String> {
 
         let options = ast_node.options.iter().map(|attr| {
             let method_name = match attr {
-                Attr::Type(t) => format_ident!("{}", to_lower_snake_case(&t)),
+                Attr::Type(t) => format_ident!("{}", t.to_snake_case()),
                 Attr::NameType(n, _) => format_ident!("{}", n),
             };
             let ty = match attr {
@@ -188,14 +189,14 @@ fn generate_syntax_kinds(grammar: &Grammar) -> Result<String> {
 
     let full_keywords_values = &grammar.keywords;
     let full_keywords =
-        full_keywords_values.iter().map(|kw| format_ident!("{}_KW", to_upper_snake_case(&kw)));
+        full_keywords_values.iter().map(|kw| format_ident!("{}_KW", kw.to_shouty_snake_case()));
 
     let all_keywords_values =
         grammar.keywords.iter().chain(grammar.contextual_keywords.iter()).collect::<Vec<_>>();
     let all_keywords_idents = all_keywords_values.iter().map(|kw| format_ident!("{}", kw));
     let all_keywords = all_keywords_values
         .iter()
-        .map(|name| format_ident!("{}_KW", to_upper_snake_case(&name)))
+        .map(|name| format_ident!("{}_KW", name.to_shouty_snake_case()))
         .collect::<Vec<_>>();
 
     let literals =
@@ -324,31 +325,3 @@ enum Attr {
     Type(String),
     NameType(String, String),
 }
-
-fn to_upper_snake_case(s: &str) -> String {
-    let mut buf = String::with_capacity(s.len());
-    let mut prev_is_upper = None;
-    for c in s.chars() {
-        if c.is_ascii_uppercase() && prev_is_upper == Some(false) {
-            buf.push('_')
-        }
-        prev_is_upper = Some(c.is_ascii_uppercase());
-
-        buf.push(c.to_ascii_uppercase());
-    }
-    buf
-}
-
-fn to_lower_snake_case(s: &str) -> String {
-    let mut buf = String::with_capacity(s.len());
-    let mut prev_is_upper = None;
-    for c in s.chars() {
-        if c.is_ascii_uppercase() && prev_is_upper == Some(false) {
-            buf.push('_')
-        }
-        prev_is_upper = Some(c.is_ascii_uppercase());
-
-        buf.push(c.to_ascii_lowercase());
-    }
-    buf
-}


Test patch:
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs
index 451be32a8b..de3bd5bc55 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/main.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs
@@ -22,7 +22,7 @@ const PROFILE: &'static str = "";
 #[test]
 fn completes_items_from_standard_library() {
     let project_start = Instant::now();
-    let server = project(
+    let server = Project::with_fixture(
         r#"
 //- Cargo.toml
 [package]
@@ -32,7 +32,9 @@ version = "0.0.0"
 //- src/lib.rs
 use std::collections::Spam;
 "#,
-    );
+    )
+    .with_sysroot(true)
+    .server();
     server.wait_until_workspace_is_loaded();
     eprintln!("loading took    {:?}", project_start.elapsed());
     let completion_start = Instant::now();
@@ -349,7 +351,7 @@ fn main() {{}}
 fn diagnostics_dont_block_typing() {
     let librs: String = (0..10).map(|i| format!("mod m{};", i)).collect();
     let libs: String = (0..10).map(|i| format!("//- src/m{}.rs\nfn foo() {{}}\n\n", i)).collect();
-    let server = project(&format!(
+    let server = Project::with_fixture(&format!(
         r#"
 //- Cargo.toml
 [package]
@@ -364,7 +366,10 @@ version = "0.0.0"
 fn main() {{}}
 "#,
         librs, libs
-    ));
+    ))
+    .with_sysroot(true)
+    .server();
+
     server.wait_until_workspace_is_loaded();
     for i in 0..10 {
         server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams {
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs
index ba8ee8b062..055c8fff22 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/support.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs
@@ -26,13 +26,14 @@ use ra_lsp_server::{main_loop, req, ServerConfig};
 
 pub struct Project<'a> {
     fixture: &'a str,
+    with_sysroot: bool,
     tmp_dir: Option<TempDir>,
     roots: Vec<PathBuf>,
 }
 
 impl<'a> Project<'a> {
     pub fn with_fixture(fixture: &str) -> Project {
-        Project { fixture, tmp_dir: None, roots: vec![] }
+        Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false }
     }
 
     pub fn tmp_dir(mut self, tmp_dir: TempDir) -> Project<'a> {
@@ -45,6 +46,11 @@ impl<'a> Project<'a> {
         self
     }
 
+    pub fn with_sysroot(mut self, sysroot: bool) -> Project<'a> {
+        self.with_sysroot = sysroot;
+        self
+    }
+
     pub fn server(self) -> Server {
         let tmp_dir = self.tmp_dir.unwrap_or_else(|| TempDir::new().unwrap());
         static INIT: Once = Once::new();
@@ -68,7 +74,7 @@ impl<'a> Project<'a> {
 
         let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect();
 
-        Server::new(tmp_dir, roots, paths)
+        Server::new(tmp_dir, self.with_sysroot, roots, paths)
     }
 }
 
@@ -84,7 +90,12 @@ pub struct Server {
 }
 
 impl Server {
-    fn new(dir: TempDir, roots: Vec<PathBuf>, files: Vec<(PathBuf, String)>) -> Server {
+    fn new(
+        dir: TempDir,
+        with_sysroot: bool,
+        roots: Vec<PathBuf>,
+        files: Vec<(PathBuf, String)>,
+    ) -> Server {
         let path = dir.path().to_path_buf();
 
         let roots = if roots.is_empty() { vec![path] } else { roots };
@@ -107,7 +118,7 @@ impl Server {
                         window: None,
                         experimental: None,
                     },
-                    ServerConfig::default(),
+                    ServerConfig { with_sysroot, ..ServerConfig::default() },
                     &msg_receiver,
                     &msg_sender,
                 )