diff options
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 881303861..3eba35a24 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | use crate::{FileId, MacroCallId}; | 1 | use crate::{FileId, MacroCallId, HirDatabase}; |
2 | |||
3 | use ra_syntax::SourceFileNode; | ||
2 | 4 | ||
3 | /// hir makes a heavy use of ids: integer (u32) handlers to various things. You | 5 | /// hir makes a heavy use of ids: integer (u32) handlers to various things. You |
4 | /// can think of id as a pointer (but without a lifetime) or a file descriptor | 6 | /// can think of id as a pointer (but without a lifetime) or a file descriptor |
@@ -20,13 +22,53 @@ use crate::{FileId, MacroCallId}; | |||
20 | /// (because everything bottoms out at the real `FileId`) and small | 22 | /// (because everything bottoms out at the real `FileId`) and small |
21 | /// (`MacroCallId` uses location interner). | 23 | /// (`MacroCallId` uses location interner). |
22 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 24 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
23 | pub enum MFileId { | 25 | pub struct HirFileId(HirFileIdRepr); |
26 | |||
27 | impl HirFileId { | ||
28 | pub(crate) fn original_file_id(self, db: &impl HirDatabase) -> FileId { | ||
29 | match self.0 { | ||
30 | HirFileIdRepr::File(file_id) => file_id, | ||
31 | HirFileIdRepr::Macro(macro_call_id) => { | ||
32 | let loc = macro_call_id.loc(db); | ||
33 | loc.source_item_id.file_id.original_file_id(db) | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | pub(crate) fn as_original_file(self) -> FileId { | ||
39 | match self.0 { | ||
40 | HirFileIdRepr::File(file_id) => file_id, | ||
41 | HirFileIdRepr::Macro(_r) => panic!("macro generated file: {:?}", self), | ||
42 | } | ||
43 | } | ||
44 | pub(crate) fn source_file_query(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode { | ||
45 | match file_id.0 { | ||
46 | HirFileIdRepr::File(file_id) => db.source_file(file_id), | ||
47 | HirFileIdRepr::Macro(m) => { | ||
48 | if let Some(exp) = db.expand_macro_invocation(m) { | ||
49 | return exp.file(); | ||
50 | } | ||
51 | // returning an empty string looks fishy... | ||
52 | SourceFileNode::parse("") | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
58 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
59 | enum HirFileIdRepr { | ||
24 | File(FileId), | 60 | File(FileId), |
25 | Macro(MacroCallId), | 61 | Macro(MacroCallId), |
26 | } | 62 | } |
27 | 63 | ||
28 | impl From<FileId> for MFileId { | 64 | impl From<FileId> for HirFileId { |
29 | fn from(file_id: FileId) -> MFileId { | 65 | fn from(file_id: FileId) -> HirFileId { |
30 | MFileId::File(file_id) | 66 | HirFileId(HirFileIdRepr::File(file_id)) |
67 | } | ||
68 | } | ||
69 | |||
70 | impl From<MacroCallId> for HirFileId { | ||
71 | fn from(macro_call_id: MacroCallId) -> HirFileId { | ||
72 | HirFileId(HirFileIdRepr::Macro(macro_call_id)) | ||
31 | } | 73 | } |
32 | } | 74 | } |