diff options
Diffstat (limited to 'crates/ra_db')
-rw-r--r-- | crates/ra_db/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 6 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 76 |
3 files changed, 67 insertions, 17 deletions
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index c141f1a88..3394ae8ce 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml | |||
@@ -6,7 +6,7 @@ authors = ["rust-analyzer developers"] | |||
6 | 6 | ||
7 | [dependencies] | 7 | [dependencies] |
8 | salsa = "0.13.0" | 8 | salsa = "0.13.0" |
9 | relative-path = "0.4.0" | 9 | relative-path = "1.0.0" |
10 | rustc-hash = "1.0" | 10 | rustc-hash = "1.0" |
11 | 11 | ||
12 | ra_syntax = { path = "../ra_syntax" } | 12 | ra_syntax = { path = "../ra_syntax" } |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 23148096c..eafa95921 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -48,9 +48,6 @@ impl SourceRoot { | |||
48 | pub fn new_library() -> SourceRoot { | 48 | pub fn new_library() -> SourceRoot { |
49 | SourceRoot { is_library: true, ..SourceRoot::new() } | 49 | SourceRoot { is_library: true, ..SourceRoot::new() } |
50 | } | 50 | } |
51 | pub fn file_by_relative_path(&self, path: &RelativePath) -> Option<FileId> { | ||
52 | self.files.get(path).copied() | ||
53 | } | ||
54 | pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) { | 51 | pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) { |
55 | self.files.insert(path, file_id); | 52 | self.files.insert(path, file_id); |
56 | } | 53 | } |
@@ -60,6 +57,9 @@ impl SourceRoot { | |||
60 | pub fn walk(&self) -> impl Iterator<Item = FileId> + '_ { | 57 | pub fn walk(&self) -> impl Iterator<Item = FileId> + '_ { |
61 | self.files.values().copied() | 58 | self.files.values().copied() |
62 | } | 59 | } |
60 | pub fn file_by_relative_path(&self, path: &RelativePath) -> Option<FileId> { | ||
61 | self.files.get(path).copied() | ||
62 | } | ||
63 | } | 63 | } |
64 | 64 | ||
65 | /// `CrateGraph` is a bit of information which turns a set of text files into a | 65 | /// `CrateGraph` is a bit of information which turns a set of text files into a |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 603daed37..fc5d6d396 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -6,7 +6,7 @@ use std::{panic, sync::Arc}; | |||
6 | 6 | ||
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; | 8 | use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; |
9 | use relative_path::RelativePathBuf; | 9 | use relative_path::{RelativePath, RelativePathBuf}; |
10 | 10 | ||
11 | pub use crate::{ | 11 | pub use crate::{ |
12 | cancellation::Canceled, | 12 | cancellation::Canceled, |
@@ -64,16 +64,39 @@ pub struct FileRange { | |||
64 | 64 | ||
65 | pub const DEFAULT_LRU_CAP: usize = 128; | 65 | pub const DEFAULT_LRU_CAP: usize = 128; |
66 | 66 | ||
67 | pub trait FileLoader { | ||
68 | /// Text of the file. | ||
69 | fn file_text(&self, file_id: FileId) -> Arc<String>; | ||
70 | fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath) | ||
71 | -> Option<FileId>; | ||
72 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>; | ||
73 | } | ||
74 | |||
67 | /// Database which stores all significant input facts: source code and project | 75 | /// Database which stores all significant input facts: source code and project |
68 | /// model. Everything else in rust-analyzer is derived from these queries. | 76 | /// model. Everything else in rust-analyzer is derived from these queries. |
69 | #[salsa::query_group(SourceDatabaseStorage)] | 77 | #[salsa::query_group(SourceDatabaseStorage)] |
70 | pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { | 78 | pub trait SourceDatabase: CheckCanceled + FileLoader + std::fmt::Debug { |
71 | /// Text of the file. | ||
72 | #[salsa::input] | ||
73 | fn file_text(&self, file_id: FileId) -> Arc<String>; | ||
74 | // Parses the file into the syntax tree. | 79 | // Parses the file into the syntax tree. |
75 | #[salsa::invoke(parse_query)] | 80 | #[salsa::invoke(parse_query)] |
76 | fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; | 81 | fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; |
82 | |||
83 | /// The crate graph. | ||
84 | #[salsa::input] | ||
85 | fn crate_graph(&self) -> Arc<CrateGraph>; | ||
86 | } | ||
87 | |||
88 | fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { | ||
89 | let _p = profile("parse_query"); | ||
90 | let text = db.file_text(file_id); | ||
91 | SourceFile::parse(&*text) | ||
92 | } | ||
93 | |||
94 | /// We don't want to give HIR knowledge of source roots, hence we extract these | ||
95 | /// methods into a separate DB. | ||
96 | #[salsa::query_group(SourceDatabaseExtStorage)] | ||
97 | pub trait SourceDatabaseExt: SourceDatabase { | ||
98 | #[salsa::input] | ||
99 | fn file_text(&self, file_id: FileId) -> Arc<String>; | ||
77 | /// Path to a file, relative to the root of its source root. | 100 | /// Path to a file, relative to the root of its source root. |
78 | #[salsa::input] | 101 | #[salsa::input] |
79 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; | 102 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; |
@@ -83,21 +106,48 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { | |||
83 | /// Contents of the source root. | 106 | /// Contents of the source root. |
84 | #[salsa::input] | 107 | #[salsa::input] |
85 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; | 108 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; |
109 | |||
86 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; | 110 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; |
87 | /// The crate graph. | ||
88 | #[salsa::input] | ||
89 | fn crate_graph(&self) -> Arc<CrateGraph>; | ||
90 | } | 111 | } |
91 | 112 | ||
92 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { | 113 | fn source_root_crates( |
114 | db: &(impl SourceDatabaseExt + SourceDatabase), | ||
115 | id: SourceRootId, | ||
116 | ) -> Arc<Vec<CrateId>> { | ||
93 | let root = db.source_root(id); | 117 | let root = db.source_root(id); |
94 | let graph = db.crate_graph(); | 118 | let graph = db.crate_graph(); |
95 | let res = root.walk().filter_map(|it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>(); | 119 | let res = root.walk().filter_map(|it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>(); |
96 | Arc::new(res) | 120 | Arc::new(res) |
97 | } | 121 | } |
98 | 122 | ||
99 | fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { | 123 | /// Silly workaround for cyclic deps between the traits |
100 | let _p = profile("parse_query"); | 124 | pub struct FileLoaderDelegate<T>(pub T); |
101 | let text = db.file_text(file_id); | 125 | |
102 | SourceFile::parse(&*text) | 126 | impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> { |
127 | fn file_text(&self, file_id: FileId) -> Arc<String> { | ||
128 | SourceDatabaseExt::file_text(self.0, file_id) | ||
129 | } | ||
130 | fn resolve_relative_path( | ||
131 | &self, | ||
132 | anchor: FileId, | ||
133 | relative_path: &RelativePath, | ||
134 | ) -> Option<FileId> { | ||
135 | let path = { | ||
136 | let mut path = self.0.file_relative_path(anchor); | ||
137 | // Workaround for relative path API: turn `lib.rs` into ``. | ||
138 | if !path.pop() { | ||
139 | path = RelativePathBuf::default(); | ||
140 | } | ||
141 | path.push(relative_path); | ||
142 | path.normalize() | ||
143 | }; | ||
144 | let source_root = self.0.file_source_root(anchor); | ||
145 | let source_root = self.0.source_root(source_root); | ||
146 | source_root.file_by_relative_path(&path) | ||
147 | } | ||
148 | |||
149 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | ||
150 | let source_root = self.0.file_source_root(file_id); | ||
151 | self.0.source_root_crates(source_root) | ||
152 | } | ||
103 | } | 153 | } |