diff options
Diffstat (limited to 'crates/ra_hir_expand/src')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 96 |
1 files changed, 13 insertions, 83 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index e9e275670..f3f959ac6 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! Builtin macro | 1 | //! Builtin macro |
2 | use crate::db::AstDatabase; | 2 | use crate::db::AstDatabase; |
3 | use crate::{ | 3 | use crate::{ |
4 | ast::{self, AstNode}, | 4 | ast::{self}, |
5 | name, AstId, CrateId, HirFileId, MacroCallId, MacroDefId, MacroDefKind, TextUnit, | 5 | name, AstId, CrateId, MacroCallId, MacroDefId, MacroDefKind, TextUnit, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::quote; | 8 | use crate::quote; |
@@ -61,48 +61,13 @@ register_builtin! { | |||
61 | (format_args_nl, FormatArgsNl) => format_args_expand | 61 | (format_args_nl, FormatArgsNl) => format_args_expand |
62 | } | 62 | } |
63 | 63 | ||
64 | fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { | ||
65 | let file_id = file.original_file(db); | ||
66 | |||
67 | // FIXME: if the file is coming from macro, we return a dummy value for now. | ||
68 | if file.call_node(db).map(|it| it.file_id != file_id.into()).unwrap_or(true) { | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | let text = db.file_text(file_id); | ||
73 | let mut line_num = 1; | ||
74 | |||
75 | let pos = pos.to_usize(); | ||
76 | if pos > text.len() { | ||
77 | // FIXME: `pos` at the moment could be an offset inside the "wrong" file | ||
78 | // in this case, when we know it's wrong, we return a dummy value | ||
79 | return 0; | ||
80 | } | ||
81 | // Count line end | ||
82 | for (i, c) in text.chars().enumerate() { | ||
83 | if i == pos { | ||
84 | break; | ||
85 | } | ||
86 | if c == '\n' { | ||
87 | line_num += 1; | ||
88 | } | ||
89 | } | ||
90 | line_num | ||
91 | } | ||
92 | |||
93 | fn line_expand( | 64 | fn line_expand( |
94 | db: &dyn AstDatabase, | 65 | _db: &dyn AstDatabase, |
95 | id: MacroCallId, | 66 | _id: MacroCallId, |
96 | _tt: &tt::Subtree, | 67 | _tt: &tt::Subtree, |
97 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 68 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
98 | let loc = db.lookup_intern_macro(id); | 69 | // dummy implementation for type-checking purposes |
99 | 70 | let line_num = 0; | |
100 | let arg = loc.kind.arg(db).ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; | ||
101 | let arg_start = arg.text_range().start(); | ||
102 | |||
103 | let file = id.as_file(); | ||
104 | let line_num = to_line_number(db, file, arg_start); | ||
105 | |||
106 | let expanded = quote! { | 71 | let expanded = quote! { |
107 | #line_num | 72 | #line_num |
108 | }; | 73 | }; |
@@ -154,48 +119,13 @@ fn option_env_expand( | |||
154 | Ok(expanded) | 119 | Ok(expanded) |
155 | } | 120 | } |
156 | 121 | ||
157 | fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { | ||
158 | let file_id = file.original_file(db); | ||
159 | // FIXME: if the file is coming from macro, we return a dummy value for now. | ||
160 | if file.call_node(db).map(|it| it.file_id != file_id.into()).unwrap_or(true) { | ||
161 | return 0; | ||
162 | } | ||
163 | let text = db.file_text(file_id); | ||
164 | |||
165 | let pos = pos.to_usize(); | ||
166 | if pos > text.len() { | ||
167 | // FIXME: `pos` at the moment could be an offset inside the "wrong" file | ||
168 | // in this case we return a dummy value so that we don't `panic!` | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | let mut col_num = 1; | ||
173 | for c in text[..pos].chars().rev() { | ||
174 | if c == '\n' { | ||
175 | break; | ||
176 | } | ||
177 | col_num += 1; | ||
178 | } | ||
179 | col_num | ||
180 | } | ||
181 | |||
182 | fn column_expand( | 122 | fn column_expand( |
183 | db: &dyn AstDatabase, | 123 | _db: &dyn AstDatabase, |
184 | id: MacroCallId, | 124 | _id: MacroCallId, |
185 | _tt: &tt::Subtree, | 125 | _tt: &tt::Subtree, |
186 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 126 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
187 | let loc = db.lookup_intern_macro(id); | 127 | // dummy implementation for type-checking purposes |
188 | let macro_call = match loc.kind { | 128 | let col_num = 0; |
189 | crate::MacroCallKind::FnLike(ast_id) => ast_id.to_node(db), | ||
190 | _ => panic!("column macro called as attr"), | ||
191 | }; | ||
192 | |||
193 | let _arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; | ||
194 | let col_start = macro_call.syntax().text_range().start(); | ||
195 | |||
196 | let file = id.as_file(); | ||
197 | let col_num = to_col_number(db, file, col_start); | ||
198 | |||
199 | let expanded = quote! { | 129 | let expanded = quote! { |
200 | #col_num | 130 | #col_num |
201 | }; | 131 | }; |
@@ -284,7 +214,7 @@ fn format_args_expand( | |||
284 | #[cfg(test)] | 214 | #[cfg(test)] |
285 | mod tests { | 215 | mod tests { |
286 | use super::*; | 216 | use super::*; |
287 | use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc}; | 217 | use crate::{name::AsName, test_db::TestDB, AstNode, MacroCallKind, MacroCallLoc}; |
288 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 218 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
289 | use ra_syntax::ast::NameOwner; | 219 | use ra_syntax::ast::NameOwner; |
290 | 220 | ||
@@ -330,7 +260,7 @@ mod tests { | |||
330 | "#, | 260 | "#, |
331 | ); | 261 | ); |
332 | 262 | ||
333 | assert_eq!(expanded, "13"); | 263 | assert_eq!(expanded, "0"); |
334 | } | 264 | } |
335 | 265 | ||
336 | #[test] | 266 | #[test] |
@@ -343,7 +273,7 @@ mod tests { | |||
343 | "#, | 273 | "#, |
344 | ); | 274 | ); |
345 | 275 | ||
346 | assert_eq!(expanded, "4"); | 276 | assert_eq!(expanded, "0"); |
347 | } | 277 | } |
348 | 278 | ||
349 | #[test] | 279 | #[test] |