diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-06 13:54:49 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-08-06 13:54:49 +0100 |
commit | 811492aa546d83daf56f61d334d6ee295651f111 (patch) | |
tree | 066a13499c26738cae11a34819b6048c5123d88b /crates | |
parent | c9718691043b041f5db878caea687b5a029d4475 (diff) | |
parent | 3d45da9bca7ab772ea483b496a901fc500e22033 (diff) |
Merge #1657
1657: Ignore r=matklad a=matklad
closes #1616
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_batch/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_batch/src/lib.rs | 20 | ||||
-rw-r--r-- | crates/ra_batch/src/vfs_filter.rs | 54 | ||||
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/config.rs (renamed from crates/ra_lsp_server/src/init.rs) | 15 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 18 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/vfs_filter.rs | 54 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 22 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 4 | ||||
-rw-r--r-- | crates/ra_project_model/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 23 | ||||
-rw-r--r-- | crates/ra_vfs_glob/Cargo.toml | 9 | ||||
-rw-r--r-- | crates/ra_vfs_glob/src/lib.rs | 94 |
15 files changed, 165 insertions, 161 deletions
diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml index 0ee94c445..8e23826a4 100644 --- a/crates/ra_batch/Cargo.toml +++ b/crates/ra_batch/Cargo.toml | |||
@@ -9,6 +9,7 @@ log = "0.4.5" | |||
9 | rustc-hash = "1.0" | 9 | rustc-hash = "1.0" |
10 | 10 | ||
11 | ra_vfs = "0.2.0" | 11 | ra_vfs = "0.2.0" |
12 | ra_vfs_glob = { path = "../ra_vfs_glob" } | ||
12 | ra_db = { path = "../ra_db" } | 13 | ra_db = { path = "../ra_db" } |
13 | ra_ide_api = { path = "../ra_ide_api" } | 14 | ra_ide_api = { path = "../ra_ide_api" } |
14 | ra_hir = { path = "../ra_hir" } | 15 | ra_hir = { path = "../ra_hir" } |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index c01574fbc..0db751465 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -1,5 +1,3 @@ | |||
1 | mod vfs_filter; | ||
2 | |||
3 | use std::{collections::HashSet, error::Error, path::Path}; | 1 | use std::{collections::HashSet, error::Error, path::Path}; |
4 | 2 | ||
5 | use rustc_hash::FxHashMap; | 3 | use rustc_hash::FxHashMap; |
@@ -7,8 +5,8 @@ use rustc_hash::FxHashMap; | |||
7 | use ra_db::{CrateGraph, FileId, SourceRootId}; | 5 | use ra_db::{CrateGraph, FileId, SourceRootId}; |
8 | use ra_ide_api::{AnalysisChange, AnalysisHost}; | 6 | use ra_ide_api::{AnalysisChange, AnalysisHost}; |
9 | use ra_project_model::{PackageRoot, ProjectWorkspace}; | 7 | use ra_project_model::{PackageRoot, ProjectWorkspace}; |
10 | use ra_vfs::{Vfs, VfsChange}; | 8 | use ra_vfs::{RootEntry, Vfs, VfsChange}; |
11 | use vfs_filter::IncludeRustFiles; | 9 | use ra_vfs_glob::RustPackageFilterBuilder; |
12 | 10 | ||
13 | type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; | 11 | type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; |
14 | 12 | ||
@@ -23,7 +21,19 @@ pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, | |||
23 | let root = std::env::current_dir()?.join(root); | 21 | let root = std::env::current_dir()?.join(root); |
24 | let ws = ProjectWorkspace::discover(root.as_ref())?; | 22 | let ws = ProjectWorkspace::discover(root.as_ref())?; |
25 | let project_roots = ws.to_roots(); | 23 | let project_roots = ws.to_roots(); |
26 | let (mut vfs, roots) = Vfs::new(IncludeRustFiles::from_roots(project_roots.clone()).collect()); | 24 | let (mut vfs, roots) = Vfs::new( |
25 | project_roots | ||
26 | .iter() | ||
27 | .map(|pkg_root| { | ||
28 | RootEntry::new( | ||
29 | pkg_root.path().clone(), | ||
30 | RustPackageFilterBuilder::default() | ||
31 | .set_member(pkg_root.is_member()) | ||
32 | .into_vfs_filter(), | ||
33 | ) | ||
34 | }) | ||
35 | .collect(), | ||
36 | ); | ||
27 | let crate_graph = ws.to_crate_graph(&mut |path: &Path| { | 37 | let crate_graph = ws.to_crate_graph(&mut |path: &Path| { |
28 | let vfs_file = vfs.load(path); | 38 | let vfs_file = vfs.load(path); |
29 | log::debug!("vfs file {:?} -> {:?}", path, vfs_file); | 39 | log::debug!("vfs file {:?} -> {:?}", path, vfs_file); |
diff --git a/crates/ra_batch/src/vfs_filter.rs b/crates/ra_batch/src/vfs_filter.rs deleted file mode 100644 index 63bf77704..000000000 --- a/crates/ra_batch/src/vfs_filter.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | use ra_project_model::PackageRoot; | ||
2 | use ra_vfs::{Filter, RelativePath, RootEntry}; | ||
3 | use std::path::PathBuf; | ||
4 | |||
5 | /// `IncludeRustFiles` is used to convert | ||
6 | /// from `PackageRoot` to `RootEntry` for VFS | ||
7 | pub struct IncludeRustFiles { | ||
8 | root: PackageRoot, | ||
9 | } | ||
10 | |||
11 | impl IncludeRustFiles { | ||
12 | pub fn from_roots<R>(roots: R) -> impl Iterator<Item = RootEntry> | ||
13 | where | ||
14 | R: IntoIterator<Item = PackageRoot>, | ||
15 | { | ||
16 | roots.into_iter().map(IncludeRustFiles::from_root) | ||
17 | } | ||
18 | |||
19 | pub fn from_root(root: PackageRoot) -> RootEntry { | ||
20 | IncludeRustFiles::from(root).into() | ||
21 | } | ||
22 | |||
23 | #[allow(unused)] | ||
24 | pub fn external(path: PathBuf) -> RootEntry { | ||
25 | IncludeRustFiles::from_root(PackageRoot::new(path, false)) | ||
26 | } | ||
27 | |||
28 | pub fn member(path: PathBuf) -> RootEntry { | ||
29 | IncludeRustFiles::from_root(PackageRoot::new(path, true)) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl Filter for IncludeRustFiles { | ||
34 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
35 | self.root.include_dir(dir_path) | ||
36 | } | ||
37 | |||
38 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
39 | self.root.include_file(file_path) | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl From<PackageRoot> for IncludeRustFiles { | ||
44 | fn from(v: PackageRoot) -> IncludeRustFiles { | ||
45 | IncludeRustFiles { root: v } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | impl From<IncludeRustFiles> for RootEntry { | ||
50 | fn from(v: IncludeRustFiles) -> RootEntry { | ||
51 | let path = v.root.path().clone(); | ||
52 | RootEntry::new(path, Box::new(v)) | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index cec360667..c282d6db8 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -25,6 +25,7 @@ ra_ide_api = { path = "../ra_ide_api" } | |||
25 | gen_lsp_server = { path = "../gen_lsp_server" } | 25 | gen_lsp_server = { path = "../gen_lsp_server" } |
26 | ra_project_model = { path = "../ra_project_model" } | 26 | ra_project_model = { path = "../ra_project_model" } |
27 | ra_prof = { path = "../ra_prof" } | 27 | ra_prof = { path = "../ra_prof" } |
28 | ra_vfs_glob = { path = "../ra_vfs_glob" } | ||
28 | 29 | ||
29 | [dev-dependencies] | 30 | [dev-dependencies] |
30 | tempfile = "3" | 31 | tempfile = "3" |
diff --git a/crates/ra_lsp_server/src/init.rs b/crates/ra_lsp_server/src/config.rs index b894b449d..6dcdc695a 100644 --- a/crates/ra_lsp_server/src/init.rs +++ b/crates/ra_lsp_server/src/config.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use serde::{Deserialize, Deserializer}; | 1 | use serde::{Deserialize, Deserializer}; |
2 | 2 | ||
3 | /// Client provided initialization options | 3 | /// Client provided initialization options |
4 | #[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)] | 4 | #[derive(Deserialize, Clone, Debug, PartialEq, Eq)] |
5 | #[serde(rename_all = "camelCase", default)] | 5 | #[serde(rename_all = "camelCase", default)] |
6 | pub struct InitializationOptions { | 6 | pub struct ServerConfig { |
7 | /// Whether the client supports our custom highlighting publishing decorations. | 7 | /// Whether the client supports our custom highlighting publishing decorations. |
8 | /// This is different to the highlightingOn setting, which is whether the user | 8 | /// This is different to the highlightingOn setting, which is whether the user |
9 | /// wants our custom highlighting to be used. | 9 | /// wants our custom highlighting to be used. |
@@ -18,14 +18,17 @@ pub struct InitializationOptions { | |||
18 | #[serde(deserialize_with = "nullable_bool_true")] | 18 | #[serde(deserialize_with = "nullable_bool_true")] |
19 | pub show_workspace_loaded: bool, | 19 | pub show_workspace_loaded: bool, |
20 | 20 | ||
21 | pub exclude_globs: Vec<String>, | ||
22 | |||
21 | pub lru_capacity: Option<usize>, | 23 | pub lru_capacity: Option<usize>, |
22 | } | 24 | } |
23 | 25 | ||
24 | impl Default for InitializationOptions { | 26 | impl Default for ServerConfig { |
25 | fn default() -> InitializationOptions { | 27 | fn default() -> ServerConfig { |
26 | InitializationOptions { | 28 | ServerConfig { |
27 | publish_decorations: false, | 29 | publish_decorations: false, |
28 | show_workspace_loaded: true, | 30 | show_workspace_loaded: true, |
31 | exclude_globs: Vec::new(), | ||
29 | lru_capacity: None, | 32 | lru_capacity: None, |
30 | } | 33 | } |
31 | } | 34 | } |
@@ -56,7 +59,7 @@ mod test { | |||
56 | #[test] | 59 | #[test] |
57 | fn deserialize_init_options_defaults() { | 60 | fn deserialize_init_options_defaults() { |
58 | // check that null == default for both fields | 61 | // check that null == default for both fields |
59 | let default = InitializationOptions::default(); | 62 | let default = ServerConfig::default(); |
60 | assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); | 63 | assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); |
61 | assert_eq!( | 64 | assert_eq!( |
62 | default, | 65 | default, |
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 56a263aa5..795f86383 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs | |||
@@ -4,13 +4,11 @@ mod conv; | |||
4 | mod main_loop; | 4 | mod main_loop; |
5 | mod markdown; | 5 | mod markdown; |
6 | mod project_model; | 6 | mod project_model; |
7 | mod vfs_filter; | ||
8 | pub mod req; | 7 | pub mod req; |
9 | pub mod init; | 8 | pub mod config; |
10 | mod world; | 9 | mod world; |
11 | 10 | ||
12 | pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; | 11 | pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; |
13 | pub use crate::{ | 12 | pub use crate::{ |
14 | caps::server_capabilities, init::InitializationOptions, main_loop::main_loop, | 13 | caps::server_capabilities, config::ServerConfig, main_loop::main_loop, main_loop::LspError, |
15 | main_loop::LspError, | ||
16 | }; | 14 | }; |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index c1f8243be..1a2ab1bc2 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -2,7 +2,7 @@ use flexi_logger::{Duplicate, Logger}; | |||
2 | use gen_lsp_server::{run_server, stdio_transport}; | 2 | use gen_lsp_server::{run_server, stdio_transport}; |
3 | use serde::Deserialize; | 3 | use serde::Deserialize; |
4 | 4 | ||
5 | use ra_lsp_server::{InitializationOptions, Result}; | 5 | use ra_lsp_server::{Result, ServerConfig}; |
6 | use ra_prof; | 6 | use ra_prof; |
7 | 7 | ||
8 | fn main() -> Result<()> { | 8 | fn main() -> Result<()> { |
@@ -48,7 +48,7 @@ fn main_inner() -> Result<()> { | |||
48 | 48 | ||
49 | let opts = params | 49 | let opts = params |
50 | .initialization_options | 50 | .initialization_options |
51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | 51 | .and_then(|v| ServerConfig::deserialize(v).ok()) |
52 | .unwrap_or_default(); | 52 | .unwrap_or_default(); |
53 | 53 | ||
54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) | 54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 9a38d43d2..9d540a87e 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | project_model::workspace_loader, | 23 | project_model::workspace_loader, |
24 | req, | 24 | req, |
25 | world::{Options, WorldSnapshot, WorldState}, | 25 | world::{Options, WorldSnapshot, WorldState}, |
26 | InitializationOptions, Result, | 26 | Result, ServerConfig, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | const THREADPOOL_SIZE: usize = 8; | 29 | const THREADPOOL_SIZE: usize = 8; |
@@ -52,10 +52,11 @@ impl Error for LspError {} | |||
52 | pub fn main_loop( | 52 | pub fn main_loop( |
53 | ws_roots: Vec<PathBuf>, | 53 | ws_roots: Vec<PathBuf>, |
54 | client_caps: ClientCapabilities, | 54 | client_caps: ClientCapabilities, |
55 | options: InitializationOptions, | 55 | config: ServerConfig, |
56 | msg_receiver: &Receiver<RawMessage>, | 56 | msg_receiver: &Receiver<RawMessage>, |
57 | msg_sender: &Sender<RawMessage>, | 57 | msg_sender: &Sender<RawMessage>, |
58 | ) -> Result<()> { | 58 | ) -> Result<()> { |
59 | log::debug!("server_config: {:?}", config); | ||
59 | // FIXME: support dynamic workspace loading. | 60 | // FIXME: support dynamic workspace loading. |
60 | let workspaces = { | 61 | let workspaces = { |
61 | let ws_worker = workspace_loader(); | 62 | let ws_worker = workspace_loader(); |
@@ -77,14 +78,19 @@ pub fn main_loop( | |||
77 | } | 78 | } |
78 | loaded_workspaces | 79 | loaded_workspaces |
79 | }; | 80 | }; |
80 | 81 | let globs = config | |
82 | .exclude_globs | ||
83 | .iter() | ||
84 | .map(|glob| ra_vfs_glob::Glob::new(glob)) | ||
85 | .collect::<std::result::Result<Vec<_>, _>>()?; | ||
81 | let mut state = WorldState::new( | 86 | let mut state = WorldState::new( |
82 | ws_roots, | 87 | ws_roots, |
83 | workspaces, | 88 | workspaces, |
84 | options.lru_capacity, | 89 | config.lru_capacity, |
90 | &globs, | ||
85 | Options { | 91 | Options { |
86 | publish_decorations: options.publish_decorations, | 92 | publish_decorations: config.publish_decorations, |
87 | show_workspace_loaded: options.show_workspace_loaded, | 93 | show_workspace_loaded: config.show_workspace_loaded, |
88 | supports_location_link: client_caps | 94 | supports_location_link: client_caps |
89 | .text_document | 95 | .text_document |
90 | .and_then(|it| it.definition) | 96 | .and_then(|it| it.definition) |
diff --git a/crates/ra_lsp_server/src/vfs_filter.rs b/crates/ra_lsp_server/src/vfs_filter.rs deleted file mode 100644 index abdc8dbad..000000000 --- a/crates/ra_lsp_server/src/vfs_filter.rs +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | use ra_project_model::PackageRoot; | ||
2 | use ra_vfs::{Filter, RelativePath, RootEntry}; | ||
3 | use std::path::PathBuf; | ||
4 | |||
5 | /// `IncludeRustFiles` is used to convert | ||
6 | /// from `PackageRoot` to `RootEntry` for VFS | ||
7 | pub struct IncludeRustFiles { | ||
8 | root: PackageRoot, | ||
9 | } | ||
10 | |||
11 | impl IncludeRustFiles { | ||
12 | pub fn from_roots<R>(roots: R) -> impl Iterator<Item = RootEntry> | ||
13 | where | ||
14 | R: IntoIterator<Item = PackageRoot>, | ||
15 | { | ||
16 | roots.into_iter().map(IncludeRustFiles::from_root) | ||
17 | } | ||
18 | |||
19 | pub fn from_root(root: PackageRoot) -> RootEntry { | ||
20 | IncludeRustFiles::from(root).into() | ||
21 | } | ||
22 | |||
23 | #[allow(unused)] | ||
24 | pub fn external(path: PathBuf) -> RootEntry { | ||
25 | IncludeRustFiles::from_root(PackageRoot::new(path, false)) | ||
26 | } | ||
27 | |||
28 | pub fn member(path: PathBuf) -> RootEntry { | ||
29 | IncludeRustFiles::from_root(PackageRoot::new(path, true)) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl Filter for IncludeRustFiles { | ||
34 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
35 | self.root.include_dir(dir_path) | ||
36 | } | ||
37 | |||
38 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
39 | self.root.include_file(file_path) | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl std::convert::From<PackageRoot> for IncludeRustFiles { | ||
44 | fn from(v: PackageRoot) -> IncludeRustFiles { | ||
45 | IncludeRustFiles { root: v } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | impl std::convert::From<IncludeRustFiles> for RootEntry { | ||
50 | fn from(v: IncludeRustFiles) -> RootEntry { | ||
51 | let path = v.root.path().clone(); | ||
52 | RootEntry::new(path, Box::new(v)) | ||
53 | } | ||
54 | } | ||
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index b57cdf925..9990ef62e 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -9,13 +9,13 @@ use parking_lot::RwLock; | |||
9 | use ra_ide_api::{ | 9 | use ra_ide_api::{ |
10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, | 10 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, |
11 | }; | 11 | }; |
12 | use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; | 12 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; |
13 | use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; | ||
13 | use relative_path::RelativePathBuf; | 14 | use relative_path::RelativePathBuf; |
14 | 15 | ||
15 | use crate::{ | 16 | use crate::{ |
16 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, | 17 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, |
17 | project_model::ProjectWorkspace, | 18 | project_model::ProjectWorkspace, |
18 | vfs_filter::IncludeRustFiles, | ||
19 | LspError, Result, | 19 | LspError, Result, |
20 | }; | 20 | }; |
21 | 21 | ||
@@ -56,14 +56,28 @@ impl WorldState { | |||
56 | folder_roots: Vec<PathBuf>, | 56 | folder_roots: Vec<PathBuf>, |
57 | workspaces: Vec<ProjectWorkspace>, | 57 | workspaces: Vec<ProjectWorkspace>, |
58 | lru_capacity: Option<usize>, | 58 | lru_capacity: Option<usize>, |
59 | exclude_globs: &[Glob], | ||
59 | options: Options, | 60 | options: Options, |
60 | ) -> WorldState { | 61 | ) -> WorldState { |
61 | let mut change = AnalysisChange::new(); | 62 | let mut change = AnalysisChange::new(); |
62 | 63 | ||
63 | let mut roots = Vec::new(); | 64 | let mut roots = Vec::new(); |
64 | roots.extend(folder_roots.iter().cloned().map(IncludeRustFiles::member)); | 65 | roots.extend(folder_roots.iter().map(|path| { |
66 | let mut filter = RustPackageFilterBuilder::default().set_member(true); | ||
67 | for glob in exclude_globs.iter() { | ||
68 | filter = filter.exclude(glob.clone()); | ||
69 | } | ||
70 | RootEntry::new(path.clone(), filter.into_vfs_filter()) | ||
71 | })); | ||
65 | for ws in workspaces.iter() { | 72 | for ws in workspaces.iter() { |
66 | roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); | 73 | roots.extend(ws.to_roots().into_iter().map(|pkg_root| { |
74 | let mut filter = | ||
75 | RustPackageFilterBuilder::default().set_member(pkg_root.is_member()); | ||
76 | for glob in exclude_globs.iter() { | ||
77 | filter = filter.exclude(glob.clone()); | ||
78 | } | ||
79 | RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) | ||
80 | })); | ||
67 | } | 81 | } |
68 | 82 | ||
69 | let (mut vfs, vfs_roots) = Vfs::new(roots); | 83 | let (mut vfs, vfs_roots) = Vfs::new(roots); |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 5dddbbe17..ba8ee8b06 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -22,7 +22,7 @@ use tempfile::TempDir; | |||
22 | use test_utils::{find_mismatch, parse_fixture}; | 22 | use test_utils::{find_mismatch, parse_fixture}; |
23 | use thread_worker::Worker; | 23 | use thread_worker::Worker; |
24 | 24 | ||
25 | use ra_lsp_server::{main_loop, req, InitializationOptions}; | 25 | use ra_lsp_server::{main_loop, req, ServerConfig}; |
26 | 26 | ||
27 | pub struct Project<'a> { | 27 | pub struct Project<'a> { |
28 | fixture: &'a str, | 28 | fixture: &'a str, |
@@ -107,7 +107,7 @@ impl Server { | |||
107 | window: None, | 107 | window: None, |
108 | experimental: None, | 108 | experimental: None, |
109 | }, | 109 | }, |
110 | InitializationOptions::default(), | 110 | ServerConfig::default(), |
111 | &msg_receiver, | 111 | &msg_receiver, |
112 | &msg_sender, | 112 | &msg_sender, |
113 | ) | 113 | ) |
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 3545d23c9..4fd6c75ef 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml | |||
@@ -7,7 +7,6 @@ authors = ["rust-analyzer developers"] | |||
7 | [dependencies] | 7 | [dependencies] |
8 | log = "0.4.5" | 8 | log = "0.4.5" |
9 | rustc-hash = "1.0" | 9 | rustc-hash = "1.0" |
10 | relative-path = "0.4.0" | ||
11 | 10 | ||
12 | cargo_metadata = "0.8.0" | 11 | cargo_metadata = "0.8.0" |
13 | 12 | ||
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c7167046b..55b94b911 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -10,7 +10,6 @@ use std::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use ra_db::{CrateGraph, Edition, FileId}; | 12 | use ra_db::{CrateGraph, Edition, FileId}; |
13 | use relative_path::RelativePath; | ||
14 | use rustc_hash::FxHashMap; | 13 | use rustc_hash::FxHashMap; |
15 | use serde_json::from_reader; | 14 | use serde_json::from_reader; |
16 | 15 | ||
@@ -54,28 +53,6 @@ impl PackageRoot { | |||
54 | pub fn is_member(&self) -> bool { | 53 | pub fn is_member(&self) -> bool { |
55 | self.is_member | 54 | self.is_member |
56 | } | 55 | } |
57 | |||
58 | pub fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
59 | const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; | ||
60 | const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; | ||
61 | |||
62 | let is_ignored = if self.is_member { | ||
63 | dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) | ||
64 | } else { | ||
65 | dir_path.components().any(|c| { | ||
66 | let path = c.as_str(); | ||
67 | COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) | ||
68 | }) | ||
69 | }; | ||
70 | |||
71 | let hidden = dir_path.components().any(|c| c.as_str().starts_with('.')); | ||
72 | |||
73 | !is_ignored && !hidden | ||
74 | } | ||
75 | |||
76 | pub fn include_file(&self, file_path: &RelativePath) -> bool { | ||
77 | file_path.extension() == Some("rs") | ||
78 | } | ||
79 | } | 56 | } |
80 | 57 | ||
81 | impl ProjectWorkspace { | 58 | impl ProjectWorkspace { |
diff --git a/crates/ra_vfs_glob/Cargo.toml b/crates/ra_vfs_glob/Cargo.toml new file mode 100644 index 000000000..0390d7da1 --- /dev/null +++ b/crates/ra_vfs_glob/Cargo.toml | |||
@@ -0,0 +1,9 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_vfs_glob" | ||
4 | version = "0.1.0" | ||
5 | authors = ["rust-analyzer developers"] | ||
6 | |||
7 | [dependencies] | ||
8 | ra_vfs = "0.2.0" | ||
9 | globset = "0.4.4" | ||
diff --git a/crates/ra_vfs_glob/src/lib.rs b/crates/ra_vfs_glob/src/lib.rs new file mode 100644 index 000000000..12401d75a --- /dev/null +++ b/crates/ra_vfs_glob/src/lib.rs | |||
@@ -0,0 +1,94 @@ | |||
1 | //! `ra_vfs_glob` crate implements exclusion rules for vfs. | ||
2 | //! | ||
3 | //! By default, we include only `.rs` files, and skip some know offenders like | ||
4 | //! `/target` or `/node_modules` altogether. | ||
5 | //! | ||
6 | //! It's also possible to add custom exclusion globs. | ||
7 | |||
8 | use globset::{GlobSet, GlobSetBuilder}; | ||
9 | use ra_vfs::{Filter, RelativePath}; | ||
10 | |||
11 | pub use globset::{Glob, GlobBuilder}; | ||
12 | |||
13 | const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"]; | ||
14 | const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"]; | ||
15 | |||
16 | pub struct RustPackageFilterBuilder { | ||
17 | is_member: bool, | ||
18 | exclude: GlobSetBuilder, | ||
19 | } | ||
20 | |||
21 | impl Default for RustPackageFilterBuilder { | ||
22 | fn default() -> RustPackageFilterBuilder { | ||
23 | RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() } | ||
24 | } | ||
25 | } | ||
26 | |||
27 | impl RustPackageFilterBuilder { | ||
28 | pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder { | ||
29 | self.is_member = is_member; | ||
30 | self | ||
31 | } | ||
32 | pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder { | ||
33 | self.exclude.add(glob); | ||
34 | self | ||
35 | } | ||
36 | pub fn into_vfs_filter(self) -> Box<dyn Filter> { | ||
37 | let RustPackageFilterBuilder { is_member, mut exclude } = self; | ||
38 | for &glob in ALWAYS_IGNORED { | ||
39 | exclude.add(Glob::new(glob).unwrap()); | ||
40 | } | ||
41 | if !is_member { | ||
42 | for &glob in IGNORED_FOR_NON_MEMBERS { | ||
43 | exclude.add(Glob::new(glob).unwrap()); | ||
44 | } | ||
45 | } | ||
46 | Box::new(RustPackageFilter { exclude: exclude.build().unwrap() }) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | struct RustPackageFilter { | ||
51 | exclude: GlobSet, | ||
52 | } | ||
53 | |||
54 | impl Filter for RustPackageFilter { | ||
55 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
56 | !self.exclude.is_match(dir_path.as_str()) | ||
57 | } | ||
58 | |||
59 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
60 | file_path.extension() == Some("rs") | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[test] | ||
65 | fn test_globs() { | ||
66 | let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(); | ||
67 | |||
68 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
69 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
70 | assert!(filter.include_dir(RelativePath::new("tests"))); | ||
71 | assert!(filter.include_dir(RelativePath::new("benches"))); | ||
72 | |||
73 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
74 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
75 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
76 | |||
77 | let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter(); | ||
78 | |||
79 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
80 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
81 | |||
82 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
83 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
84 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
85 | assert!(!filter.include_dir(RelativePath::new("tests"))); | ||
86 | assert!(!filter.include_dir(RelativePath::new("benches"))); | ||
87 | |||
88 | let filter = RustPackageFilterBuilder::default() | ||
89 | .set_member(true) | ||
90 | .exclude(Glob::new("src/llvm-project/**").unwrap()) | ||
91 | .into_vfs_filter(); | ||
92 | |||
93 | assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); | ||
94 | } | ||