diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-11 10:53:24 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-11 10:53:24 +0000 |
commit | ef2a9aedb6ac7f0b79e636cff7947935fecb909d (patch) | |
tree | a603361f9e6c02d90c0ae8cdfd0902370677f71d /crates/ra_hir_expand/src/builtin_macro.rs | |
parent | 5ac4ffbc121c8231fe3ea5c2bb918f7aae60f197 (diff) | |
parent | 4f7df2aac107c0de2cab851f2a4f1ab369511fc8 (diff) |
Merge #2205
2205: Implement bulitin line! macro r=matklad a=edwin0cheng
This PR implements bulitin macro `line!` and add basic infra-structure for other bulitin macros:
1. Extend `MacroDefId` to support builtin macros
2. Add a `quote!` macro for simple quasi quoting.
Note that for support others builtin macros, eager macro expansion have to be supported first, this PR not try to handle it. :)
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_hir_expand/src/builtin_macro.rs')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs new file mode 100644 index 000000000..97fb0cb55 --- /dev/null +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -0,0 +1,80 @@ | |||
1 | //! Builtin macro | ||
2 | use crate::db::AstDatabase; | ||
3 | use crate::{ | ||
4 | ast::{self, AstNode}, | ||
5 | name, AstId, CrateId, HirFileId, MacroCallId, MacroDefId, MacroDefKind, MacroFileKind, | ||
6 | TextUnit, | ||
7 | }; | ||
8 | |||
9 | use crate::quote; | ||
10 | |||
11 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
12 | pub enum BuiltinExpander { | ||
13 | Line, | ||
14 | } | ||
15 | |||
16 | impl BuiltinExpander { | ||
17 | pub fn expand( | ||
18 | &self, | ||
19 | db: &dyn AstDatabase, | ||
20 | id: MacroCallId, | ||
21 | tt: &tt::Subtree, | ||
22 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
23 | match self { | ||
24 | BuiltinExpander::Line => line_expand(db, id, tt), | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | |||
29 | pub fn find_builtin_macro( | ||
30 | ident: &name::Name, | ||
31 | krate: CrateId, | ||
32 | ast_id: AstId<ast::MacroCall>, | ||
33 | ) -> Option<MacroDefId> { | ||
34 | // FIXME: Better registering method | ||
35 | if ident == &name::LINE_MACRO { | ||
36 | Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) }) | ||
37 | } else { | ||
38 | None | ||
39 | } | ||
40 | } | ||
41 | |||
42 | fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { | ||
43 | // FIXME: Use expansion info | ||
44 | let file_id = file.original_file(db); | ||
45 | let text = db.file_text(file_id); | ||
46 | let mut line_num = 1; | ||
47 | |||
48 | // Count line end | ||
49 | for (i, c) in text.chars().enumerate() { | ||
50 | if i == pos.to_usize() { | ||
51 | break; | ||
52 | } | ||
53 | if c == '\n' { | ||
54 | line_num += 1; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | line_num | ||
59 | } | ||
60 | |||
61 | fn line_expand( | ||
62 | db: &dyn AstDatabase, | ||
63 | id: MacroCallId, | ||
64 | _tt: &tt::Subtree, | ||
65 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
66 | let loc = db.lookup_intern_macro(id); | ||
67 | let macro_call = loc.ast_id.to_node(db); | ||
68 | |||
69 | let arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; | ||
70 | let arg_start = arg.syntax().text_range().start(); | ||
71 | |||
72 | let file = id.as_file(MacroFileKind::Expr); | ||
73 | let line_num = to_line_number(db, file, arg_start); | ||
74 | |||
75 | let expanded = quote! { | ||
76 | #line_num | ||
77 | }; | ||
78 | |||
79 | Ok(expanded) | ||
80 | } | ||