diff options
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 138 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/name.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/quote.rs | 2 |
3 files changed, 99 insertions, 43 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index 857f8a444..2c119269c 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -26,6 +26,13 @@ macro_rules! register_builtin { | |||
26 | }; | 26 | }; |
27 | expander(db, id, tt) | 27 | expander(db, id, tt) |
28 | } | 28 | } |
29 | |||
30 | fn by_name(ident: &name::Name) -> Option<BuiltinFnLikeExpander> { | ||
31 | match ident { | ||
32 | $( id if id == &name::name![$name] => Some(BuiltinFnLikeExpander::$kind), )* | ||
33 | _ => return None, | ||
34 | } | ||
35 | } | ||
29 | } | 36 | } |
30 | 37 | ||
31 | pub fn find_builtin_macro( | 38 | pub fn find_builtin_macro( |
@@ -33,10 +40,7 @@ macro_rules! register_builtin { | |||
33 | krate: CrateId, | 40 | krate: CrateId, |
34 | ast_id: AstId<ast::MacroCall>, | 41 | ast_id: AstId<ast::MacroCall>, |
35 | ) -> Option<MacroDefId> { | 42 | ) -> Option<MacroDefId> { |
36 | let kind = match ident { | 43 | let kind = BuiltinFnLikeExpander::by_name(ident)?; |
37 | $( id if id == &name::name![$name] => BuiltinFnLikeExpander::$kind, )* | ||
38 | _ => return None, | ||
39 | }; | ||
40 | 44 | ||
41 | Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) }) | 45 | Some(MacroDefId { krate: Some(krate), ast_id: Some(ast_id), kind: MacroDefKind::BuiltIn(kind) }) |
42 | } | 46 | } |
@@ -50,6 +54,8 @@ register_builtin! { | |||
50 | (line, Line) => line_expand, | 54 | (line, Line) => line_expand, |
51 | (stringify, Stringify) => stringify_expand, | 55 | (stringify, Stringify) => stringify_expand, |
52 | (format_args, FormatArgs) => format_args_expand, | 56 | (format_args, FormatArgs) => format_args_expand, |
57 | (env, Env) => env_expand, | ||
58 | (option_env, OptionEnv) => option_env_expand, | ||
53 | // format_args_nl only differs in that it adds a newline in the end, | 59 | // format_args_nl only differs in that it adds a newline in the end, |
54 | // so we use the same stub expansion for now | 60 | // so we use the same stub expansion for now |
55 | (format_args_nl, FormatArgsNl) => format_args_expand | 61 | (format_args_nl, FormatArgsNl) => format_args_expand |
@@ -121,6 +127,28 @@ fn stringify_expand( | |||
121 | Ok(expanded) | 127 | Ok(expanded) |
122 | } | 128 | } |
123 | 129 | ||
130 | fn env_expand( | ||
131 | _db: &dyn AstDatabase, | ||
132 | _id: MacroCallId, | ||
133 | _tt: &tt::Subtree, | ||
134 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
135 | // dummy implementation for type-checking purposes | ||
136 | let expanded = quote! { "" }; | ||
137 | |||
138 | Ok(expanded) | ||
139 | } | ||
140 | |||
141 | fn option_env_expand( | ||
142 | _db: &dyn AstDatabase, | ||
143 | _id: MacroCallId, | ||
144 | _tt: &tt::Subtree, | ||
145 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
146 | // dummy implementation for type-checking purposes | ||
147 | let expanded = quote! { std::option::Option::None::<&str> }; | ||
148 | |||
149 | Ok(expanded) | ||
150 | } | ||
151 | |||
124 | fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { | 152 | fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { |
125 | // FIXME: Use expansion info | 153 | // FIXME: Use expansion info |
126 | let file_id = file.original_file(db); | 154 | let file_id = file.original_file(db); |
@@ -248,10 +276,11 @@ fn format_args_expand( | |||
248 | #[cfg(test)] | 276 | #[cfg(test)] |
249 | mod tests { | 277 | mod tests { |
250 | use super::*; | 278 | use super::*; |
251 | use crate::{test_db::TestDB, MacroCallKind, MacroCallLoc}; | 279 | use crate::{name::AsName, test_db::TestDB, MacroCallKind, MacroCallLoc}; |
252 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 280 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
281 | use ra_syntax::ast::NameOwner; | ||
253 | 282 | ||
254 | fn expand_builtin_macro(s: &str, expander: BuiltinFnLikeExpander) -> String { | 283 | fn expand_builtin_macro(s: &str) -> String { |
255 | let (db, file_id) = TestDB::with_single_file(&s); | 284 | let (db, file_id) = TestDB::with_single_file(&s); |
256 | let parsed = db.parse(file_id); | 285 | let parsed = db.parse(file_id); |
257 | let macro_calls: Vec<_> = | 286 | let macro_calls: Vec<_> = |
@@ -259,6 +288,9 @@ mod tests { | |||
259 | 288 | ||
260 | let ast_id_map = db.ast_id_map(file_id.into()); | 289 | let ast_id_map = db.ast_id_map(file_id.into()); |
261 | 290 | ||
291 | let expander = | ||
292 | BuiltinFnLikeExpander::by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); | ||
293 | |||
262 | // the first one should be a macro_rules | 294 | // the first one should be a macro_rules |
263 | let def = MacroDefId { | 295 | let def = MacroDefId { |
264 | krate: Some(CrateId(0)), | 296 | krate: Some(CrateId(0)), |
@@ -284,25 +316,23 @@ mod tests { | |||
284 | fn test_column_expand() { | 316 | fn test_column_expand() { |
285 | let expanded = expand_builtin_macro( | 317 | let expanded = expand_builtin_macro( |
286 | r#" | 318 | r#" |
287 | #[rustc_builtin_macro] | 319 | #[rustc_builtin_macro] |
288 | macro_rules! column {() => {}} | 320 | macro_rules! column {() => {}} |
289 | column!() | 321 | column!() |
290 | "#, | 322 | "#, |
291 | BuiltinFnLikeExpander::Column, | ||
292 | ); | 323 | ); |
293 | 324 | ||
294 | assert_eq!(expanded, "9"); | 325 | assert_eq!(expanded, "13"); |
295 | } | 326 | } |
296 | 327 | ||
297 | #[test] | 328 | #[test] |
298 | fn test_line_expand() { | 329 | fn test_line_expand() { |
299 | let expanded = expand_builtin_macro( | 330 | let expanded = expand_builtin_macro( |
300 | r#" | 331 | r#" |
301 | #[rustc_builtin_macro] | 332 | #[rustc_builtin_macro] |
302 | macro_rules! line {() => {}} | 333 | macro_rules! line {() => {}} |
303 | line!() | 334 | line!() |
304 | "#, | 335 | "#, |
305 | BuiltinFnLikeExpander::Line, | ||
306 | ); | 336 | ); |
307 | 337 | ||
308 | assert_eq!(expanded, "4"); | 338 | assert_eq!(expanded, "4"); |
@@ -312,25 +342,49 @@ mod tests { | |||
312 | fn test_stringify_expand() { | 342 | fn test_stringify_expand() { |
313 | let expanded = expand_builtin_macro( | 343 | let expanded = expand_builtin_macro( |
314 | r#" | 344 | r#" |
315 | #[rustc_builtin_macro] | 345 | #[rustc_builtin_macro] |
316 | macro_rules! stringify {() => {}} | 346 | macro_rules! stringify {() => {}} |
317 | stringify!(a b c) | 347 | stringify!(a b c) |
318 | "#, | 348 | "#, |
319 | BuiltinFnLikeExpander::Stringify, | ||
320 | ); | 349 | ); |
321 | 350 | ||
322 | assert_eq!(expanded, "\"a b c\""); | 351 | assert_eq!(expanded, "\"a b c\""); |
323 | } | 352 | } |
324 | 353 | ||
325 | #[test] | 354 | #[test] |
355 | fn test_env_expand() { | ||
356 | let expanded = expand_builtin_macro( | ||
357 | r#" | ||
358 | #[rustc_builtin_macro] | ||
359 | macro_rules! env {() => {}} | ||
360 | env!("TEST_ENV_VAR") | ||
361 | "#, | ||
362 | ); | ||
363 | |||
364 | assert_eq!(expanded, "\"\""); | ||
365 | } | ||
366 | |||
367 | #[test] | ||
368 | fn test_option_env_expand() { | ||
369 | let expanded = expand_builtin_macro( | ||
370 | r#" | ||
371 | #[rustc_builtin_macro] | ||
372 | macro_rules! option_env {() => {}} | ||
373 | option_env!("TEST_ENV_VAR") | ||
374 | "#, | ||
375 | ); | ||
376 | |||
377 | assert_eq!(expanded, "std::option::Option::None:: <&str>"); | ||
378 | } | ||
379 | |||
380 | #[test] | ||
326 | fn test_file_expand() { | 381 | fn test_file_expand() { |
327 | let expanded = expand_builtin_macro( | 382 | let expanded = expand_builtin_macro( |
328 | r#" | 383 | r#" |
329 | #[rustc_builtin_macro] | 384 | #[rustc_builtin_macro] |
330 | macro_rules! file {() => {}} | 385 | macro_rules! file {() => {}} |
331 | file!() | 386 | file!() |
332 | "#, | 387 | "#, |
333 | BuiltinFnLikeExpander::File, | ||
334 | ); | 388 | ); |
335 | 389 | ||
336 | assert_eq!(expanded, "\"\""); | 390 | assert_eq!(expanded, "\"\""); |
@@ -340,14 +394,13 @@ mod tests { | |||
340 | fn test_compile_error_expand() { | 394 | fn test_compile_error_expand() { |
341 | let expanded = expand_builtin_macro( | 395 | let expanded = expand_builtin_macro( |
342 | r#" | 396 | r#" |
343 | #[rustc_builtin_macro] | 397 | #[rustc_builtin_macro] |
344 | macro_rules! compile_error { | 398 | macro_rules! compile_error { |
345 | ($msg:expr) => ({ /* compiler built-in */ }); | 399 | ($msg:expr) => ({ /* compiler built-in */ }); |
346 | ($msg:expr,) => ({ /* compiler built-in */ }) | 400 | ($msg:expr,) => ({ /* compiler built-in */ }) |
347 | } | 401 | } |
348 | compile_error!("error!"); | 402 | compile_error!("error!"); |
349 | "#, | 403 | "#, |
350 | BuiltinFnLikeExpander::CompileError, | ||
351 | ); | 404 | ); |
352 | 405 | ||
353 | assert_eq!(expanded, r#"loop{"error!"}"#); | 406 | assert_eq!(expanded, r#"loop{"error!"}"#); |
@@ -357,14 +410,13 @@ mod tests { | |||
357 | fn test_format_args_expand() { | 410 | fn test_format_args_expand() { |
358 | let expanded = expand_builtin_macro( | 411 | let expanded = expand_builtin_macro( |
359 | r#" | 412 | r#" |
360 | #[rustc_builtin_macro] | 413 | #[rustc_builtin_macro] |
361 | macro_rules! format_args { | 414 | macro_rules! format_args { |
362 | ($fmt:expr) => ({ /* compiler built-in */ }); | 415 | ($fmt:expr) => ({ /* compiler built-in */ }); |
363 | ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) | 416 | ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) |
364 | } | 417 | } |
365 | format_args!("{} {:?}", arg1(a, b, c), arg2); | 418 | format_args!("{} {:?}", arg1(a, b, c), arg2); |
366 | "#, | 419 | "#, |
367 | BuiltinFnLikeExpander::FormatArgs, | ||
368 | ); | 420 | ); |
369 | 421 | ||
370 | assert_eq!( | 422 | assert_eq!( |
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index fd02ffa4e..e62693b68 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs | |||
@@ -170,6 +170,8 @@ pub mod known { | |||
170 | stringify, | 170 | stringify, |
171 | format_args, | 171 | format_args, |
172 | format_args_nl, | 172 | format_args_nl, |
173 | env, | ||
174 | option_env, | ||
173 | // Builtin derives | 175 | // Builtin derives |
174 | Copy, | 176 | Copy, |
175 | Clone, | 177 | Clone, |
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs index 49155fe62..4de219ce4 100644 --- a/crates/ra_hir_expand/src/quote.rs +++ b/crates/ra_hir_expand/src/quote.rs | |||
@@ -102,6 +102,8 @@ macro_rules! __quote { | |||
102 | ( : ) => {$crate::__quote!(@PUNCT ':')}; | 102 | ( : ) => {$crate::__quote!(@PUNCT ':')}; |
103 | ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; | 103 | ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; |
104 | ( . ) => {$crate::__quote!(@PUNCT '.')}; | 104 | ( . ) => {$crate::__quote!(@PUNCT '.')}; |
105 | ( < ) => {$crate::__quote!(@PUNCT '<')}; | ||
106 | ( > ) => {$crate::__quote!(@PUNCT '>')}; | ||
105 | 107 | ||
106 | ( $first:tt $($tail:tt)+ ) => { | 108 | ( $first:tt $($tail:tt)+ ) => { |
107 | { | 109 | { |