diff options
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r-- | crates/ra_db/src/fixture.rs | 19 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 138 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 |
3 files changed, 97 insertions, 62 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index ade187629..e8f335e33 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; | |||
8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 8 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | CrateGraph, CrateId, Edition, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, | 11 | CrateGraph, CrateId, Edition, Env, FileId, FilePosition, RelativePathBuf, SourceDatabaseExt, |
12 | SourceRoot, SourceRootId, | 12 | SourceRoot, SourceRootId, |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -53,7 +53,12 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId { | |||
53 | source_root.insert_file(rel_path.clone(), file_id); | 53 | source_root.insert_file(rel_path.clone(), file_id); |
54 | 54 | ||
55 | let mut crate_graph = CrateGraph::default(); | 55 | let mut crate_graph = CrateGraph::default(); |
56 | crate_graph.add_crate_root(file_id, Edition::Edition2018, CfgOptions::default()); | 56 | crate_graph.add_crate_root( |
57 | file_id, | ||
58 | Edition::Edition2018, | ||
59 | CfgOptions::default(), | ||
60 | Env::default(), | ||
61 | ); | ||
57 | 62 | ||
58 | db.set_file_text(file_id, Arc::new(text.to_string())); | 63 | db.set_file_text(file_id, Arc::new(text.to_string())); |
59 | db.set_file_relative_path(file_id, rel_path); | 64 | db.set_file_relative_path(file_id, rel_path); |
@@ -93,7 +98,8 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
93 | assert!(meta.path.starts_with(&source_root_prefix)); | 98 | assert!(meta.path.starts_with(&source_root_prefix)); |
94 | 99 | ||
95 | if let Some(krate) = meta.krate { | 100 | if let Some(krate) = meta.krate { |
96 | let crate_id = crate_graph.add_crate_root(file_id, meta.edition, meta.cfg); | 101 | let crate_id = |
102 | crate_graph.add_crate_root(file_id, meta.edition, meta.cfg, Env::default()); | ||
97 | let prev = crates.insert(krate.clone(), crate_id); | 103 | let prev = crates.insert(krate.clone(), crate_id); |
98 | assert!(prev.is_none()); | 104 | assert!(prev.is_none()); |
99 | for dep in meta.deps { | 105 | for dep in meta.deps { |
@@ -123,7 +129,12 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
123 | 129 | ||
124 | if crates.is_empty() { | 130 | if crates.is_empty() { |
125 | let crate_root = default_crate_root.unwrap(); | 131 | let crate_root = default_crate_root.unwrap(); |
126 | crate_graph.add_crate_root(crate_root, Edition::Edition2018, CfgOptions::default()); | 132 | crate_graph.add_crate_root( |
133 | crate_root, | ||
134 | Edition::Edition2018, | ||
135 | CfgOptions::default(), | ||
136 | Env::default(), | ||
137 | ); | ||
127 | } else { | 138 | } else { |
128 | for (from, to) in crate_deps { | 139 | for (from, to) in crate_deps { |
129 | let from_id = crates[&from]; | 140 | let from_id = crates[&from]; |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index c0d95a13f..b6d851776 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -6,14 +6,14 @@ | |||
6 | //! actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how | 6 | //! actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how |
7 | //! actual IO is done and lowered to input. | 7 | //! actual IO is done and lowered to input. |
8 | 8 | ||
9 | use rustc_hash::FxHashMap; | 9 | use std::{fmt, str::FromStr}; |
10 | 10 | ||
11 | use ra_cfg::CfgOptions; | 11 | use ra_cfg::CfgOptions; |
12 | use ra_syntax::SmolStr; | 12 | use ra_syntax::SmolStr; |
13 | use rustc_hash::FxHashMap; | ||
13 | use rustc_hash::FxHashSet; | 14 | use rustc_hash::FxHashSet; |
14 | 15 | ||
15 | use crate::{RelativePath, RelativePathBuf}; | 16 | use crate::{RelativePath, RelativePathBuf}; |
16 | use std::str::FromStr; | ||
17 | 17 | ||
18 | /// `FileId` is an integer which uniquely identifies a file. File paths are | 18 | /// `FileId` is an integer which uniquely identifies a file. File paths are |
19 | /// messy and system-dependent, so most of the code should work directly with | 19 | /// messy and system-dependent, so most of the code should work directly with |
@@ -80,56 +80,27 @@ pub struct CrateGraph { | |||
80 | arena: FxHashMap<CrateId, CrateData>, | 80 | arena: FxHashMap<CrateId, CrateData>, |
81 | } | 81 | } |
82 | 82 | ||
83 | #[derive(Debug)] | ||
84 | pub struct CyclicDependencies; | ||
85 | |||
86 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 83 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
87 | pub struct CrateId(pub u32); | 84 | pub struct CrateId(pub u32); |
88 | 85 | ||
89 | impl CrateId { | ||
90 | pub fn shift(self, amount: u32) -> CrateId { | ||
91 | CrateId(self.0 + amount) | ||
92 | } | ||
93 | } | ||
94 | |||
95 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
96 | pub enum Edition { | ||
97 | Edition2018, | ||
98 | Edition2015, | ||
99 | } | ||
100 | |||
101 | #[derive(Debug)] | ||
102 | pub struct ParseEditionError { | ||
103 | pub msg: String, | ||
104 | } | ||
105 | |||
106 | impl FromStr for Edition { | ||
107 | type Err = ParseEditionError; | ||
108 | fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
109 | match s { | ||
110 | "2015" => Ok(Edition::Edition2015), | ||
111 | "2018" => Ok(Edition::Edition2018), | ||
112 | _ => Err(ParseEditionError { msg: format!("unknown edition: {}", s) }), | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | #[derive(Debug, Clone, PartialEq, Eq)] | 86 | #[derive(Debug, Clone, PartialEq, Eq)] |
118 | struct CrateData { | 87 | struct CrateData { |
119 | file_id: FileId, | 88 | file_id: FileId, |
120 | edition: Edition, | 89 | edition: Edition, |
121 | dependencies: Vec<Dependency>, | ||
122 | cfg_options: CfgOptions, | 90 | cfg_options: CfgOptions, |
91 | env: Env, | ||
92 | dependencies: Vec<Dependency>, | ||
123 | } | 93 | } |
124 | 94 | ||
125 | impl CrateData { | 95 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
126 | fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions) -> CrateData { | 96 | pub enum Edition { |
127 | CrateData { file_id, edition, dependencies: Vec::new(), cfg_options } | 97 | Edition2018, |
128 | } | 98 | Edition2015, |
99 | } | ||
129 | 100 | ||
130 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 101 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
131 | self.dependencies.push(Dependency { name, crate_id }) | 102 | pub struct Env { |
132 | } | 103 | entries: FxHashMap<String, String>, |
133 | } | 104 | } |
134 | 105 | ||
135 | #[derive(Debug, Clone, PartialEq, Eq)] | 106 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -138,21 +109,17 @@ pub struct Dependency { | |||
138 | pub name: SmolStr, | 109 | pub name: SmolStr, |
139 | } | 110 | } |
140 | 111 | ||
141 | impl Dependency { | ||
142 | pub fn crate_id(&self) -> CrateId { | ||
143 | self.crate_id | ||
144 | } | ||
145 | } | ||
146 | |||
147 | impl CrateGraph { | 112 | impl CrateGraph { |
148 | pub fn add_crate_root( | 113 | pub fn add_crate_root( |
149 | &mut self, | 114 | &mut self, |
150 | file_id: FileId, | 115 | file_id: FileId, |
151 | edition: Edition, | 116 | edition: Edition, |
152 | cfg_options: CfgOptions, | 117 | cfg_options: CfgOptions, |
118 | env: Env, | ||
153 | ) -> CrateId { | 119 | ) -> CrateId { |
120 | let data = CrateData::new(file_id, edition, cfg_options, env); | ||
154 | let crate_id = CrateId(self.arena.len() as u32); | 121 | let crate_id = CrateId(self.arena.len() as u32); |
155 | let prev = self.arena.insert(crate_id, CrateData::new(file_id, edition, cfg_options)); | 122 | let prev = self.arena.insert(crate_id, data); |
156 | assert!(prev.is_none()); | 123 | assert!(prev.is_none()); |
157 | crate_id | 124 | crate_id |
158 | } | 125 | } |
@@ -166,9 +133,9 @@ impl CrateGraph { | |||
166 | from: CrateId, | 133 | from: CrateId, |
167 | name: SmolStr, | 134 | name: SmolStr, |
168 | to: CrateId, | 135 | to: CrateId, |
169 | ) -> Result<(), CyclicDependencies> { | 136 | ) -> Result<(), CyclicDependenciesError> { |
170 | if self.dfs_find(from, to, &mut FxHashSet::default()) { | 137 | if self.dfs_find(from, to, &mut FxHashSet::default()) { |
171 | return Err(CyclicDependencies); | 138 | return Err(CyclicDependenciesError); |
172 | } | 139 | } |
173 | self.arena.get_mut(&from).unwrap().add_dep(name, to); | 140 | self.arena.get_mut(&from).unwrap().add_dep(name, to); |
174 | Ok(()) | 141 | Ok(()) |
@@ -239,16 +206,70 @@ impl CrateGraph { | |||
239 | } | 206 | } |
240 | } | 207 | } |
241 | 208 | ||
209 | impl CrateId { | ||
210 | pub fn shift(self, amount: u32) -> CrateId { | ||
211 | CrateId(self.0 + amount) | ||
212 | } | ||
213 | } | ||
214 | |||
215 | impl CrateData { | ||
216 | fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData { | ||
217 | CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env } | ||
218 | } | ||
219 | |||
220 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | ||
221 | self.dependencies.push(Dependency { name, crate_id }) | ||
222 | } | ||
223 | } | ||
224 | |||
225 | impl FromStr for Edition { | ||
226 | type Err = ParseEditionError; | ||
227 | |||
228 | fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
229 | let res = match s { | ||
230 | "2015" => Edition::Edition2015, | ||
231 | "2018" => Edition::Edition2018, | ||
232 | _ => Err(ParseEditionError { invalid_input: s.to_string() })?, | ||
233 | }; | ||
234 | Ok(res) | ||
235 | } | ||
236 | } | ||
237 | |||
238 | impl Dependency { | ||
239 | pub fn crate_id(&self) -> CrateId { | ||
240 | self.crate_id | ||
241 | } | ||
242 | } | ||
243 | |||
244 | #[derive(Debug)] | ||
245 | pub struct ParseEditionError { | ||
246 | invalid_input: String, | ||
247 | } | ||
248 | |||
249 | impl fmt::Display for ParseEditionError { | ||
250 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
251 | write!(f, "invalid edition: {:?}", self.invalid_input) | ||
252 | } | ||
253 | } | ||
254 | |||
255 | impl std::error::Error for ParseEditionError {} | ||
256 | |||
257 | #[derive(Debug)] | ||
258 | pub struct CyclicDependenciesError; | ||
259 | |||
242 | #[cfg(test)] | 260 | #[cfg(test)] |
243 | mod tests { | 261 | mod tests { |
244 | use super::{CfgOptions, CrateGraph, Edition::Edition2018, FileId, SmolStr}; | 262 | use super::{CfgOptions, CrateGraph, Edition::Edition2018, Env, FileId, SmolStr}; |
245 | 263 | ||
246 | #[test] | 264 | #[test] |
247 | fn it_should_panic_because_of_cycle_dependencies() { | 265 | fn it_should_panic_because_of_cycle_dependencies() { |
248 | let mut graph = CrateGraph::default(); | 266 | let mut graph = CrateGraph::default(); |
249 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); | 267 | let crate1 = |
250 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); | 268 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); |
251 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); | 269 | let crate2 = |
270 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | ||
271 | let crate3 = | ||
272 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | ||
252 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 273 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
253 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 274 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
254 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); | 275 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); |
@@ -257,9 +278,12 @@ mod tests { | |||
257 | #[test] | 278 | #[test] |
258 | fn it_works() { | 279 | fn it_works() { |
259 | let mut graph = CrateGraph::default(); | 280 | let mut graph = CrateGraph::default(); |
260 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default()); | 281 | let crate1 = |
261 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default()); | 282 | graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); |
262 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default()); | 283 | let crate2 = |
284 | graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); | ||
285 | let crate3 = | ||
286 | graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); | ||
263 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 287 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
264 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 288 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
265 | } | 289 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index b6bfd531d..f9d012cb0 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -10,7 +10,7 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; | |||
10 | 10 | ||
11 | pub use crate::{ | 11 | pub use crate::{ |
12 | cancellation::Canceled, | 12 | cancellation::Canceled, |
13 | input::{CrateGraph, CrateId, Dependency, Edition, FileId, SourceRoot, SourceRootId}, | 13 | input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId}, |
14 | }; | 14 | }; |
15 | pub use relative_path::{RelativePath, RelativePathBuf}; | 15 | pub use relative_path::{RelativePath, RelativePathBuf}; |
16 | pub use salsa; | 16 | pub use salsa; |