aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/lib.rs')
-rw-r--r--crates/ra_hir_expand/src/lib.rs81
1 files changed, 25 insertions, 56 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index b6a739cda..fb88d2ac2 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -13,7 +13,7 @@ pub mod diagnostics;
13pub mod builtin_macro; 13pub mod builtin_macro;
14pub mod quote; 14pub mod quote;
15 15
16use std::hash::{Hash, Hasher}; 16use std::hash::Hash;
17use std::sync::Arc; 17use std::sync::Arc;
18 18
19use ra_db::{salsa, CrateId, FileId}; 19use ra_db::{salsa, CrateId, FileId};
@@ -70,7 +70,7 @@ impl HirFileId {
70 HirFileIdRepr::FileId(file_id) => file_id, 70 HirFileIdRepr::FileId(file_id) => file_id,
71 HirFileIdRepr::MacroFile(macro_file) => { 71 HirFileIdRepr::MacroFile(macro_file) => {
72 let loc = db.lookup_intern_macro(macro_file.macro_call_id); 72 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
73 loc.ast_id.file_id().original_file(db) 73 loc.ast_id.file_id.original_file(db)
74 } 74 }
75 } 75 }
76 } 76 }
@@ -90,9 +90,9 @@ impl HirFileId {
90 let macro_arg = db.macro_arg(macro_file.macro_call_id)?; 90 let macro_arg = db.macro_arg(macro_file.macro_call_id)?;
91 91
92 Some(ExpansionInfo { 92 Some(ExpansionInfo {
93 expanded: Source::new(self, parse.syntax_node()), 93 expanded: InFile::new(self, parse.syntax_node()),
94 arg: Source::new(loc.ast_id.file_id, arg_tt), 94 arg: InFile::new(loc.ast_id.file_id, arg_tt),
95 def: Source::new(loc.ast_id.file_id, def_tt), 95 def: InFile::new(loc.ast_id.file_id, def_tt),
96 macro_arg, 96 macro_arg,
97 macro_def, 97 macro_def,
98 exp_map, 98 exp_map,
@@ -167,9 +167,9 @@ impl MacroCallId {
167/// ExpansionInfo mainly describes how to map text range between src and expanded macro 167/// ExpansionInfo mainly describes how to map text range between src and expanded macro
168#[derive(Debug, Clone, PartialEq, Eq)] 168#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct ExpansionInfo { 169pub struct ExpansionInfo {
170 expanded: Source<SyntaxNode>, 170 expanded: InFile<SyntaxNode>,
171 arg: Source<ast::TokenTree>, 171 arg: InFile<ast::TokenTree>,
172 def: Source<ast::TokenTree>, 172 def: InFile<ast::TokenTree>,
173 173
174 macro_def: Arc<(db::TokenExpander, mbe::TokenMap)>, 174 macro_def: Arc<(db::TokenExpander, mbe::TokenMap)>,
175 macro_arg: Arc<(tt::Subtree, mbe::TokenMap)>, 175 macro_arg: Arc<(tt::Subtree, mbe::TokenMap)>,
@@ -177,7 +177,7 @@ pub struct ExpansionInfo {
177} 177}
178 178
179impl ExpansionInfo { 179impl ExpansionInfo {
180 pub fn map_token_down(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { 180 pub fn map_token_down(&self, token: InFile<&SyntaxToken>) -> Option<InFile<SyntaxToken>> {
181 assert_eq!(token.file_id, self.arg.file_id); 181 assert_eq!(token.file_id, self.arg.file_id);
182 let range = 182 let range =
183 token.value.text_range().checked_sub(self.arg.value.syntax().text_range().start())?; 183 token.value.text_range().checked_sub(self.arg.value.syntax().text_range().start())?;
@@ -191,7 +191,7 @@ impl ExpansionInfo {
191 Some(self.expanded.with_value(token)) 191 Some(self.expanded.with_value(token))
192 } 192 }
193 193
194 pub fn map_token_up(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { 194 pub fn map_token_up(&self, token: InFile<&SyntaxToken>) -> Option<InFile<SyntaxToken>> {
195 let token_id = self.exp_map.token_by_range(token.value.text_range())?; 195 let token_id = self.exp_map.token_by_range(token.value.text_range())?;
196 196
197 let (token_id, origin) = self.macro_def.0.map_id_up(token_id); 197 let (token_id, origin) = self.macro_def.0.map_id_up(token_id);
@@ -214,73 +214,42 @@ impl ExpansionInfo {
214/// 214///
215/// It is stable across reparses, and can be used as salsa key/value. 215/// It is stable across reparses, and can be used as salsa key/value.
216// FIXME: isn't this just a `Source<FileAstId<N>>` ? 216// FIXME: isn't this just a `Source<FileAstId<N>>` ?
217#[derive(Debug)] 217pub type AstId<N> = InFile<FileAstId<N>>;
218pub struct AstId<N: AstNode> {
219 file_id: HirFileId,
220 file_ast_id: FileAstId<N>,
221}
222
223impl<N: AstNode> Clone for AstId<N> {
224 fn clone(&self) -> AstId<N> {
225 *self
226 }
227}
228impl<N: AstNode> Copy for AstId<N> {}
229
230impl<N: AstNode> PartialEq for AstId<N> {
231 fn eq(&self, other: &Self) -> bool {
232 (self.file_id, self.file_ast_id) == (other.file_id, other.file_ast_id)
233 }
234}
235impl<N: AstNode> Eq for AstId<N> {}
236impl<N: AstNode> Hash for AstId<N> {
237 fn hash<H: Hasher>(&self, hasher: &mut H) {
238 (self.file_id, self.file_ast_id).hash(hasher);
239 }
240}
241 218
242impl<N: AstNode> AstId<N> { 219impl<N: AstNode> AstId<N> {
243 pub fn new(file_id: HirFileId, file_ast_id: FileAstId<N>) -> AstId<N> {
244 AstId { file_id, file_ast_id }
245 }
246
247 pub fn file_id(&self) -> HirFileId {
248 self.file_id
249 }
250
251 pub fn to_node(&self, db: &dyn db::AstDatabase) -> N { 220 pub fn to_node(&self, db: &dyn db::AstDatabase) -> N {
252 let root = db.parse_or_expand(self.file_id).unwrap(); 221 let root = db.parse_or_expand(self.file_id).unwrap();
253 db.ast_id_map(self.file_id).get(self.file_ast_id).to_node(&root) 222 db.ast_id_map(self.file_id).get(self.value).to_node(&root)
254 } 223 }
255} 224}
256 225
257/// `Source<T>` stores a value of `T` inside a particular file/syntax tree. 226/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
258/// 227///
259/// Typical usages are: 228/// Typical usages are:
260/// 229///
261/// * `Source<SyntaxNode>` -- syntax node in a file 230/// * `InFile<SyntaxNode>` -- syntax node in a file
262/// * `Source<ast::FnDef>` -- ast node in a file 231/// * `InFile<ast::FnDef>` -- ast node in a file
263/// * `Source<TextUnit>` -- offset in a file 232/// * `InFile<TextUnit>` -- offset in a file
264#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] 233#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
265pub struct Source<T> { 234pub struct InFile<T> {
266 pub file_id: HirFileId, 235 pub file_id: HirFileId,
267 pub value: T, 236 pub value: T,
268} 237}
269 238
270impl<T> Source<T> { 239impl<T> InFile<T> {
271 pub fn new(file_id: HirFileId, value: T) -> Source<T> { 240 pub fn new(file_id: HirFileId, value: T) -> InFile<T> {
272 Source { file_id, value } 241 InFile { file_id, value }
273 } 242 }
274 243
275 // Similarly, naming here is stupid... 244 // Similarly, naming here is stupid...
276 pub fn with_value<U>(&self, value: U) -> Source<U> { 245 pub fn with_value<U>(&self, value: U) -> InFile<U> {
277 Source::new(self.file_id, value) 246 InFile::new(self.file_id, value)
278 } 247 }
279 248
280 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { 249 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> InFile<U> {
281 Source::new(self.file_id, f(self.value)) 250 InFile::new(self.file_id, f(self.value))
282 } 251 }
283 pub fn as_ref(&self) -> Source<&T> { 252 pub fn as_ref(&self) -> InFile<&T> {
284 self.with_value(&self.value) 253 self.with_value(&self.value)
285 } 254 }
286 pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode { 255 pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode {