From dc496d05160f9693a4e48977b7f7a3fe2689ac51 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 13:14:39 +0300 Subject: move highlightning to a separate file --- crates/ra_analysis/src/lib.rs | 4 ++-- crates/ra_analysis/src/syntax_highlighting.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 crates/ra_analysis/src/syntax_highlighting.rs (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 65c3eb3ec..b26e9e9ff 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -14,6 +14,7 @@ mod db; mod imp; mod completion; mod symbol_index; +mod syntax_highlighting; pub mod mock_analysis; use std::{fmt, sync::Arc}; @@ -340,8 +341,7 @@ impl Analysis { Ok(ra_editor::runnables(&file)) } pub fn highlight(&self, file_id: FileId) -> Cancelable> { - let file = self.imp.file_syntax(file_id); - Ok(ra_editor::highlight(&file)) + syntax_highlighting::highlight(&*self.imp.db, file_id) } pub fn completions(&self, position: FilePosition) -> Cancelable>> { self.imp.completions(position) diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs new file mode 100644 index 000000000..65409beb2 --- /dev/null +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -0,0 +1,12 @@ +use ra_editor::HighlightedRange; +use ra_db::SyntaxDatabase; + +use crate::{ + db::RootDatabase, + FileId, Cancelable, +}; + +pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable> { + let file = db.source_file(file_id); + Ok(ra_editor::highlight(&file)) +} -- cgit v1.2.3 From 072028e67996162f5a9da14cfd59ed64de5e8729 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 13:27:30 +0300 Subject: add macro-call node --- crates/ra_analysis/src/syntax_highlighting.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 65409beb2..0bf19eea0 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -7,6 +7,8 @@ use crate::{ }; pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable> { - let file = db.source_file(file_id); - Ok(ra_editor::highlight(&file)) + let source_file = db.source_file(file_id); + let mut res = ra_editor::highlight(&source_file); + for node in source_file.syntax().descendants() {} + Ok(res) } -- cgit v1.2.3 From 406505e096b4e6626ba8eb6c035671783ed2a577 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 16:59:58 +0300 Subject: super simplistic macro expansion --- crates/ra_analysis/src/syntax_highlighting.rs | 109 +++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 0bf19eea0..80f51a09c 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -1,3 +1,4 @@ +use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; use ra_editor::HighlightedRange; use ra_db::SyntaxDatabase; @@ -9,6 +10,112 @@ use crate::{ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable> { let source_file = db.source_file(file_id); let mut res = ra_editor::highlight(&source_file); - for node in source_file.syntax().descendants() {} + for macro_call in source_file + .syntax() + .descendants() + .filter_map(ast::MacroCall::cast) + { + if let Some(exp) = expand(db, file_id, macro_call) { + let mapped_ranges = ra_editor::highlight(exp.source_file()) + .into_iter() + .filter_map(|r| { + let mapped_range = exp.map_range_back(r.range)?; + let res = HighlightedRange { + range: mapped_range, + tag: r.tag, + }; + Some(res) + }); + res.extend(mapped_ranges); + } + } Ok(res) } + +fn expand( + _db: &RootDatabase, + _file_id: FileId, + macro_call: ast::MacroCall, +) -> Option { + let path = macro_call.path()?; + if path.qualifier().is_some() { + return None; + } + let name_ref = path.segment()?.name_ref()?; + if name_ref.text() != "ctry" { + return None; + } + + let arg = macro_call.token_tree()?; + let text = format!( + r" + fn dummy() {{ + match {} {{ + None => return Ok(None), + Some(it) => it, + }} + }}", + arg.syntax().text() + ); + let file = SourceFileNode::parse(&text); + let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; + let match_arg = match_expr.expr()?; + let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())]; + let res = MacroExpansion { + source_file: file, + ranges_map, + }; + Some(res) +} + +struct MacroExpansion { + source_file: SourceFileNode, + ranges_map: Vec<(TextRange, TextRange)>, +} + +impl MacroExpansion { + fn source_file(&self) -> &SourceFileNode { + &self.source_file + } + fn map_range_back(&self, tgt_range: TextRange) -> Option { + for (s_range, t_range) in self.ranges_map.iter() { + if tgt_range.is_subrange(&t_range) { + let tgt_at_zero_range = tgt_range - tgt_range.start(); + let tgt_range_offset = tgt_range.start() - t_range.start(); + let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); + return Some(src_range); + } + } + None + } +} + +#[cfg(test)] +mod tests { + use crate::mock_analysis::single_file; + use test_utils::assert_eq_dbg; + + #[test] + fn highlights_code_inside_macros() { + let (analysis, file_id) = single_file( + " + fn main() { + ctry!({ let x = 92; x}); + } + ", + ); + let highlights = analysis.highlight(file_id).unwrap(); + assert_eq_dbg( + r#"[HighlightedRange { range: [13; 15), tag: "keyword" }, + HighlightedRange { range: [16; 20), tag: "function" }, + HighlightedRange { range: [41; 45), tag: "text" }, + HighlightedRange { range: [49; 52), tag: "keyword" }, + HighlightedRange { range: [57; 59), tag: "literal" }, + HighlightedRange { range: [49; 52), tag: "keyword" }, + HighlightedRange { range: [53; 54), tag: "function" }, + HighlightedRange { range: [57; 59), tag: "literal" }, + HighlightedRange { range: [61; 62), tag: "text" }]"#, + &highlights, + ) + } +} -- cgit v1.2.3 From d7440a5f4928415f2d2a9f7b2badaff8a9376a09 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 17:39:12 +0300 Subject: highlight macro idents --- crates/ra_analysis/src/syntax_highlighting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 80f51a09c..98551df8f 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -108,7 +108,7 @@ mod tests { assert_eq_dbg( r#"[HighlightedRange { range: [13; 15), tag: "keyword" }, HighlightedRange { range: [16; 20), tag: "function" }, - HighlightedRange { range: [41; 45), tag: "text" }, + HighlightedRange { range: [41; 46), tag: "macro" }, HighlightedRange { range: [49; 52), tag: "keyword" }, HighlightedRange { range: [57; 59), tag: "literal" }, HighlightedRange { range: [49; 52), tag: "keyword" }, -- cgit v1.2.3 From 02924174bb084d73cab67af6665ddf00e91983f6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 18:03:03 +0300 Subject: introduce FileRange --- crates/ra_analysis/src/imp.rs | 24 ++++++++++++++---------- crates/ra_analysis/src/lib.rs | 16 ++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index e6663810d..fcb4cd957 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -23,7 +23,7 @@ use crate::{ AnalysisChange, Cancelable, completion::{CompletionItem, completions}, - CrateId, db, Diagnostic, FileId, FilePosition, FileSystemEdit, + CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, symbol_index::{LibrarySymbolsQuery, SymbolIndex, SymbolsDatabase}, }; @@ -404,19 +404,21 @@ impl AnalysisImpl { Ok(res) } - pub fn assists(&self, file_id: FileId, range: TextRange) -> Vec { - let file = self.file_syntax(file_id); - let offset = range.start(); + pub fn assists(&self, frange: FileRange) -> Vec { + let file = self.file_syntax(frange.file_id); + let offset = frange.range.start(); let actions = vec![ ra_editor::flip_comma(&file, offset).map(|f| f()), ra_editor::add_derive(&file, offset).map(|f| f()), ra_editor::add_impl(&file, offset).map(|f| f()), ra_editor::make_pub_crate(&file, offset).map(|f| f()), - ra_editor::introduce_variable(&file, range).map(|f| f()), + ra_editor::introduce_variable(&file, frange.range).map(|f| f()), ]; actions .into_iter() - .filter_map(|local_edit| Some(SourceChange::from_local_edit(file_id, local_edit?))) + .filter_map(|local_edit| { + Some(SourceChange::from_local_edit(frange.file_id, local_edit?)) + }) .collect() } @@ -487,13 +489,15 @@ impl AnalysisImpl { Ok(None) } - pub fn type_of(&self, file_id: FileId, range: TextRange) -> Cancelable> { - let file = self.db.source_file(file_id); + pub fn type_of(&self, frange: FileRange) -> Cancelable> { + let file = self.db.source_file(frange.file_id); let syntax = file.syntax(); - let node = find_covering_node(syntax, range); + let node = find_covering_node(syntax, frange.range); let parent_fn = ctry!(node.ancestors().find_map(FnDef::cast)); let function = ctry!(source_binder::function_from_source( - &*self.db, file_id, parent_fn + &*self.db, + frange.file_id, + parent_fn )?); let infer = function.infer(&*self.db)?; Ok(infer.type_of_node(node).map(|t| t.to_string())) diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index b26e9e9ff..3fa4189ce 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -38,7 +38,7 @@ pub use ra_editor::{ pub use hir::FnSignatureInfo; pub use ra_db::{ - Canceled, Cancelable, FilePosition, + Canceled, Cancelable, FilePosition, FileRange, CrateGraph, CrateId, SourceRootId, FileId }; @@ -287,9 +287,9 @@ impl Analysis { let file = self.imp.file_syntax(file_id); ra_editor::syntax_tree(&file) } - pub fn join_lines(&self, file_id: FileId, range: TextRange) -> SourceChange { - let file = self.imp.file_syntax(file_id); - SourceChange::from_local_edit(file_id, ra_editor::join_lines(&file, range)) + pub fn join_lines(&self, frange: FileRange) -> SourceChange { + let file = self.imp.file_syntax(frange.file_id); + SourceChange::from_local_edit(frange.file_id, ra_editor::join_lines(&file, frange.range)) } pub fn on_enter(&self, position: FilePosition) -> Option { let file = self.imp.file_syntax(position.file_id); @@ -346,8 +346,8 @@ impl Analysis { pub fn completions(&self, position: FilePosition) -> Cancelable>> { self.imp.completions(position) } - pub fn assists(&self, file_id: FileId, range: TextRange) -> Cancelable> { - Ok(self.imp.assists(file_id, range)) + pub fn assists(&self, frange: FileRange) -> Cancelable> { + Ok(self.imp.assists(frange)) } pub fn diagnostics(&self, file_id: FileId) -> Cancelable> { self.imp.diagnostics(file_id) @@ -358,8 +358,8 @@ impl Analysis { ) -> Cancelable)>> { self.imp.resolve_callable(position) } - pub fn type_of(&self, file_id: FileId, range: TextRange) -> Cancelable> { - self.imp.type_of(file_id, range) + pub fn type_of(&self, frange: FileRange) -> Cancelable> { + self.imp.type_of(frange) } } -- cgit v1.2.3 From fd33c89207f6dc621ef6e8c26ea288089448d811 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 18:15:19 +0300 Subject: switch to FileRange --- crates/ra_analysis/src/extend_selection.rs | 11 +++++++++++ crates/ra_analysis/src/lib.rs | 8 +++++--- 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 crates/ra_analysis/src/extend_selection.rs (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/extend_selection.rs b/crates/ra_analysis/src/extend_selection.rs new file mode 100644 index 000000000..5e1fbee18 --- /dev/null +++ b/crates/ra_analysis/src/extend_selection.rs @@ -0,0 +1,11 @@ +use ra_db::SyntaxDatabase; + +use crate::{ + TextRange, FileRange, + db::RootDatabase, +}; + +pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { + let file = db.source_file(frange.file_id); + ra_editor::extend_selection(&file, frange.range).unwrap_or(frange.range) +} diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 3fa4189ce..98abe8523 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -14,9 +14,11 @@ mod db; mod imp; mod completion; mod symbol_index; -mod syntax_highlighting; pub mod mock_analysis; +mod extend_selection; +mod syntax_highlighting; + use std::{fmt, sync::Arc}; use rustc_hash::FxHashMap; @@ -277,8 +279,8 @@ impl Analysis { pub fn file_line_index(&self, file_id: FileId) -> Arc { self.imp.file_line_index(file_id) } - pub fn extend_selection(&self, file: &SourceFileNode, range: TextRange) -> TextRange { - ra_editor::extend_selection(file, range).unwrap_or(range) + pub fn extend_selection(&self, frange: FileRange) -> TextRange { + extend_selection::extend_selection(&self.imp.db, frange) } pub fn matching_brace(&self, file: &SourceFileNode, offset: TextUnit) -> Option { ra_editor::matching_brace(file, offset) -- cgit v1.2.3 From b911ee542b2f4d1cd62a655f24197856cd9b9097 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 18:21:30 +0300 Subject: move macro to a separate module --- crates/ra_analysis/src/lib.rs | 1 + crates/ra_analysis/src/macros.rs | 64 +++++++++++++++++++++++++++ crates/ra_analysis/src/syntax_highlighting.rs | 62 +------------------------- 3 files changed, 67 insertions(+), 60 deletions(-) create mode 100644 crates/ra_analysis/src/macros.rs (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 98abe8523..67b1c1482 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -18,6 +18,7 @@ pub mod mock_analysis; mod extend_selection; mod syntax_highlighting; +mod macros; use std::{fmt, sync::Arc}; diff --git a/crates/ra_analysis/src/macros.rs b/crates/ra_analysis/src/macros.rs new file mode 100644 index 000000000..c0dd49dc8 --- /dev/null +++ b/crates/ra_analysis/src/macros.rs @@ -0,0 +1,64 @@ +/// Begining of macro expansion. +/// +/// This code should be moved out of ra_analysis into hir (?) ideally. +use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; + +use crate::{db::RootDatabase, FileId}; + +pub(crate) fn expand( + _db: &RootDatabase, + _file_id: FileId, + macro_call: ast::MacroCall, +) -> Option { + let path = macro_call.path()?; + if path.qualifier().is_some() { + return None; + } + let name_ref = path.segment()?.name_ref()?; + if name_ref.text() != "ctry" { + return None; + } + + let arg = macro_call.token_tree()?; + let text = format!( + r" + fn dummy() {{ + match {} {{ + None => return Ok(None), + Some(it) => it, + }} + }}", + arg.syntax().text() + ); + let file = SourceFileNode::parse(&text); + let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; + let match_arg = match_expr.expr()?; + let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())]; + let res = MacroExpansion { + source_file: file, + ranges_map, + }; + Some(res) +} + +pub(crate) struct MacroExpansion { + pub(crate) source_file: SourceFileNode, + pub(crate) ranges_map: Vec<(TextRange, TextRange)>, +} + +impl MacroExpansion { + pub(crate) fn source_file(&self) -> &SourceFileNode { + &self.source_file + } + pub(crate) fn map_range_back(&self, tgt_range: TextRange) -> Option { + for (s_range, t_range) in self.ranges_map.iter() { + if tgt_range.is_subrange(&t_range) { + let tgt_at_zero_range = tgt_range - tgt_range.start(); + let tgt_range_offset = tgt_range.start() - t_range.start(); + let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); + return Some(src_range); + } + } + None + } +} diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 98551df8f..38219da71 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs @@ -1,4 +1,4 @@ -use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; +use ra_syntax::{ast, AstNode,}; use ra_editor::HighlightedRange; use ra_db::SyntaxDatabase; @@ -15,7 +15,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable Cancelable Option { - let path = macro_call.path()?; - if path.qualifier().is_some() { - return None; - } - let name_ref = path.segment()?.name_ref()?; - if name_ref.text() != "ctry" { - return None; - } - - let arg = macro_call.token_tree()?; - let text = format!( - r" - fn dummy() {{ - match {} {{ - None => return Ok(None), - Some(it) => it, - }} - }}", - arg.syntax().text() - ); - let file = SourceFileNode::parse(&text); - let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; - let match_arg = match_expr.expr()?; - let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())]; - let res = MacroExpansion { - source_file: file, - ranges_map, - }; - Some(res) -} - -struct MacroExpansion { - source_file: SourceFileNode, - ranges_map: Vec<(TextRange, TextRange)>, -} - -impl MacroExpansion { - fn source_file(&self) -> &SourceFileNode { - &self.source_file - } - fn map_range_back(&self, tgt_range: TextRange) -> Option { - for (s_range, t_range) in self.ranges_map.iter() { - if tgt_range.is_subrange(&t_range) { - let tgt_at_zero_range = tgt_range - tgt_range.start(); - let tgt_range_offset = tgt_range.start() - t_range.start(); - let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); - return Some(src_range); - } - } - None - } -} - #[cfg(test)] mod tests { use crate::mock_analysis::single_file; -- cgit v1.2.3