diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-28 16:17:19 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-28 16:17:19 +0000 |
commit | 7a268b9b9635425176f93d3c893fb5345e84e9ce (patch) | |
tree | 6ea69024cb22d3fc48a3b392a0185163fa452014 /crates/ra_analysis/src/syntax_highlighting.rs | |
parent | 9d6740a9c9ad2ca47c4885bd994f849e90bbef86 (diff) | |
parent | b911ee542b2f4d1cd62a655f24197856cd9b9097 (diff) |
Merge #350
350: Super simple macro support r=matklad a=matklad
Super simple support for macros, mostly for figuring out how to fit them into the current architecture. Expansion is hard-coded and string based (mid-term, we should try to copy-paste macro-by-example expander from rustc).
Ideally, we should handle
* highlighting inside the macro (done)
* extend selection inside the macro
* completion inside the macro
* indexing structs, produced by the macro
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ra_analysis/src/syntax_highlighting.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs new file mode 100644 index 000000000..38219da71 --- /dev/null +++ b/crates/ra_analysis/src/syntax_highlighting.rs | |||
@@ -0,0 +1,63 @@ | |||
1 | use ra_syntax::{ast, AstNode,}; | ||
2 | use ra_editor::HighlightedRange; | ||
3 | use ra_db::SyntaxDatabase; | ||
4 | |||
5 | use crate::{ | ||
6 | db::RootDatabase, | ||
7 | FileId, Cancelable, | ||
8 | }; | ||
9 | |||
10 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { | ||
11 | let source_file = db.source_file(file_id); | ||
12 | let mut res = ra_editor::highlight(&source_file); | ||
13 | for macro_call in source_file | ||
14 | .syntax() | ||
15 | .descendants() | ||
16 | .filter_map(ast::MacroCall::cast) | ||
17 | { | ||
18 | if let Some(exp) = crate::macros::expand(db, file_id, macro_call) { | ||
19 | let mapped_ranges = ra_editor::highlight(exp.source_file()) | ||
20 | .into_iter() | ||
21 | .filter_map(|r| { | ||
22 | let mapped_range = exp.map_range_back(r.range)?; | ||
23 | let res = HighlightedRange { | ||
24 | range: mapped_range, | ||
25 | tag: r.tag, | ||
26 | }; | ||
27 | Some(res) | ||
28 | }); | ||
29 | res.extend(mapped_ranges); | ||
30 | } | ||
31 | } | ||
32 | Ok(res) | ||
33 | } | ||
34 | |||
35 | #[cfg(test)] | ||
36 | mod tests { | ||
37 | use crate::mock_analysis::single_file; | ||
38 | use test_utils::assert_eq_dbg; | ||
39 | |||
40 | #[test] | ||
41 | fn highlights_code_inside_macros() { | ||
42 | let (analysis, file_id) = single_file( | ||
43 | " | ||
44 | fn main() { | ||
45 | ctry!({ let x = 92; x}); | ||
46 | } | ||
47 | ", | ||
48 | ); | ||
49 | let highlights = analysis.highlight(file_id).unwrap(); | ||
50 | assert_eq_dbg( | ||
51 | r#"[HighlightedRange { range: [13; 15), tag: "keyword" }, | ||
52 | HighlightedRange { range: [16; 20), tag: "function" }, | ||
53 | HighlightedRange { range: [41; 46), tag: "macro" }, | ||
54 | HighlightedRange { range: [49; 52), tag: "keyword" }, | ||
55 | HighlightedRange { range: [57; 59), tag: "literal" }, | ||
56 | HighlightedRange { range: [49; 52), tag: "keyword" }, | ||
57 | HighlightedRange { range: [53; 54), tag: "function" }, | ||
58 | HighlightedRange { range: [57; 59), tag: "literal" }, | ||
59 | HighlightedRange { range: [61; 62), tag: "text" }]"#, | ||
60 | &highlights, | ||
61 | ) | ||
62 | } | ||
63 | } | ||