diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/vfs/src/loader.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/vfs/src/loader.rs')
-rw-r--r-- | crates/vfs/src/loader.rs | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/crates/vfs/src/loader.rs b/crates/vfs/src/loader.rs index 6de2e5b3f..40cf96020 100644 --- a/crates/vfs/src/loader.rs +++ b/crates/vfs/src/loader.rs | |||
@@ -3,10 +3,25 @@ use std::fmt; | |||
3 | 3 | ||
4 | use paths::{AbsPath, AbsPathBuf}; | 4 | use paths::{AbsPath, AbsPathBuf}; |
5 | 5 | ||
6 | #[derive(Debug)] | 6 | #[derive(Debug, Clone)] |
7 | pub enum Entry { | 7 | pub enum Entry { |
8 | Files(Vec<AbsPathBuf>), | 8 | Files(Vec<AbsPathBuf>), |
9 | Directory { path: AbsPathBuf, include: Vec<String> }, | 9 | Directories(Directories), |
10 | } | ||
11 | |||
12 | /// Specifies a set of files on the file system. | ||
13 | /// | ||
14 | /// A file is included if: | ||
15 | /// * it has included extension | ||
16 | /// * it is under an `include` path | ||
17 | /// * it is not under `exclude` path | ||
18 | /// | ||
19 | /// If many include/exclude paths match, the longest one wins. | ||
20 | #[derive(Debug, Clone, Default)] | ||
21 | pub struct Directories { | ||
22 | pub extensions: Vec<String>, | ||
23 | pub include: Vec<AbsPathBuf>, | ||
24 | pub exclude: Vec<AbsPathBuf>, | ||
10 | } | 25 | } |
11 | 26 | ||
12 | #[derive(Debug)] | 27 | #[derive(Debug)] |
@@ -33,21 +48,66 @@ pub trait Handle: fmt::Debug { | |||
33 | 48 | ||
34 | impl Entry { | 49 | impl Entry { |
35 | pub fn rs_files_recursively(base: AbsPathBuf) -> Entry { | 50 | pub fn rs_files_recursively(base: AbsPathBuf) -> Entry { |
36 | Entry::Directory { path: base, include: globs(&["*.rs", "!/.git/"]) } | 51 | Entry::Directories(dirs(base, &[".git"])) |
37 | } | 52 | } |
38 | pub fn local_cargo_package(base: AbsPathBuf) -> Entry { | 53 | pub fn local_cargo_package(base: AbsPathBuf) -> Entry { |
39 | Entry::Directory { path: base, include: globs(&["*.rs", "!/target/", "!/.git/"]) } | 54 | Entry::Directories(dirs(base, &[".git", "target"])) |
40 | } | 55 | } |
41 | pub fn cargo_package_dependency(base: AbsPathBuf) -> Entry { | 56 | pub fn cargo_package_dependency(base: AbsPathBuf) -> Entry { |
42 | Entry::Directory { | 57 | Entry::Directories(dirs(base, &[".git", "/tests", "/examples", "/benches"])) |
43 | path: base, | 58 | } |
44 | include: globs(&["*.rs", "!/tests/", "!/examples/", "!/benches/", "!/.git/"]), | 59 | |
60 | pub fn contains_file(&self, path: &AbsPath) -> bool { | ||
61 | match self { | ||
62 | Entry::Files(files) => files.iter().any(|it| it == path), | ||
63 | Entry::Directories(dirs) => dirs.contains_file(path), | ||
64 | } | ||
65 | } | ||
66 | pub fn contains_dir(&self, path: &AbsPath) -> bool { | ||
67 | match self { | ||
68 | Entry::Files(_) => false, | ||
69 | Entry::Directories(dirs) => dirs.contains_dir(path), | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl Directories { | ||
75 | pub fn contains_file(&self, path: &AbsPath) -> bool { | ||
76 | let ext = path.extension().unwrap_or_default(); | ||
77 | if self.extensions.iter().all(|it| it.as_str() != ext) { | ||
78 | return false; | ||
79 | } | ||
80 | self.includes_path(path) | ||
81 | } | ||
82 | pub fn contains_dir(&self, path: &AbsPath) -> bool { | ||
83 | self.includes_path(path) | ||
84 | } | ||
85 | fn includes_path(&self, path: &AbsPath) -> bool { | ||
86 | let mut include: Option<&AbsPathBuf> = None; | ||
87 | for incl in &self.include { | ||
88 | if path.starts_with(incl) { | ||
89 | include = Some(match include { | ||
90 | Some(prev) if prev.starts_with(incl) => prev, | ||
91 | _ => incl, | ||
92 | }) | ||
93 | } | ||
94 | } | ||
95 | let include = match include { | ||
96 | Some(it) => it, | ||
97 | None => return false, | ||
98 | }; | ||
99 | for excl in &self.exclude { | ||
100 | if path.starts_with(excl) && excl.starts_with(include) { | ||
101 | return false; | ||
102 | } | ||
45 | } | 103 | } |
104 | true | ||
46 | } | 105 | } |
47 | } | 106 | } |
48 | 107 | ||
49 | fn globs(globs: &[&str]) -> Vec<String> { | 108 | fn dirs(base: AbsPathBuf, exclude: &[&str]) -> Directories { |
50 | globs.iter().map(|it| it.to_string()).collect() | 109 | let exclude = exclude.iter().map(|it| base.join(it)).collect::<Vec<_>>(); |
110 | Directories { extensions: vec!["rs".to_string()], include: vec![base], exclude } | ||
51 | } | 111 | } |
52 | 112 | ||
53 | impl fmt::Debug for Message { | 113 | impl fmt::Debug for Message { |