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') 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 ++-- crates/ra_syntax/src/ast/generated.rs | 41 +++++++++++++++++++++++++++ crates/ra_syntax/src/grammar.ron | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) (limited to 'crates') 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) } diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index c22e026cf..b0d2c3e20 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1838,6 +1838,47 @@ impl> LoopExprNode { impl<'a> ast::LoopBodyOwner<'a> for LoopExpr<'a> {} impl<'a> LoopExpr<'a> {} +// MacroCall +#[derive(Debug, Clone, Copy,)] +pub struct MacroCallNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type MacroCall<'a> = MacroCallNode>; + +impl, R2: TreeRoot> PartialEq> for MacroCallNode { + fn eq(&self, other: &MacroCallNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for MacroCallNode {} +impl> Hash for MacroCallNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for MacroCall<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + MACRO_CALL => Some(MacroCall { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> MacroCallNode { + pub fn borrowed(&self) -> MacroCall { + MacroCallNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> MacroCallNode { + MacroCallNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> MacroCall<'a> { + pub fn token_tree(self) -> Option> { + super::child_opt(self) + } +} + // MatchArm #[derive(Debug, Clone, Copy,)] pub struct MatchArmNode = OwnedRoot> { diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 4bcff4e14..07b8433b2 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -484,6 +484,7 @@ Grammar( "Name": (), "NameRef": (), + "MacroCall": ( options: [ "TokenTree" ] ), "Attr": ( options: [ ["value", "TokenTree"] ] ), "TokenTree": (), "TypeParamList": ( -- 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 +++++++++++++++++++++++++- crates/ra_syntax/src/ast/generated.rs | 4 + crates/ra_syntax/src/grammar.ron | 2 +- 3 files changed, 113 insertions(+), 2 deletions(-) (limited to 'crates') 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, + ) + } +} diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index b0d2c3e20..c5ac90a62 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1877,6 +1877,10 @@ impl<'a> MacroCall<'a> { pub fn token_tree(self) -> Option> { super::child_opt(self) } + + pub fn path(self) -> Option> { + super::child_opt(self) + } } // MatchArm diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 07b8433b2..aab4839a9 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -484,7 +484,7 @@ Grammar( "Name": (), "NameRef": (), - "MacroCall": ( options: [ "TokenTree" ] ), + "MacroCall": ( options: [ "TokenTree", "Path" ] ), "Attr": ( options: [ ["value", "TokenTree"] ] ), "TokenTree": (), "TypeParamList": ( -- 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 +- crates/ra_editor/src/lib.rs | 35 ++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'crates') 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" }, diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index d9b89155b..9043026c1 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs @@ -24,9 +24,10 @@ use ra_syntax::{ SourceFileNode, Location, SyntaxKind::{self, *}, - SyntaxNodeRef, TextRange, TextUnit, + SyntaxNodeRef, TextRange, TextUnit, Direction, }; use itertools::Itertools; +use rustc_hash::FxHashSet; #[derive(Debug)] pub struct HighlightedRange { @@ -79,8 +80,13 @@ pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option Vec { + // Visited nodes to handle highlighting priorities + let mut highlighted = FxHashSet::default(); let mut res = Vec::new(); for node in file.syntax().descendants() { + if highlighted.contains(&node) { + continue; + } let tag = match node.kind() { COMMENT => "comment", STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", @@ -90,7 +96,30 @@ pub fn highlight(file: &SourceFileNode) -> Vec { INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", LIFETIME => "parameter", k if k.is_keyword() => "keyword", - _ => continue, + _ => { + if let Some(macro_call) = ast::MacroCall::cast(node) { + if let Some(path) = macro_call.path() { + if let Some(segment) = path.segment() { + if let Some(name_ref) = segment.name_ref() { + highlighted.insert(name_ref.syntax()); + let range_start = name_ref.syntax().range().start(); + let mut range_end = name_ref.syntax().range().end(); + for sibling in path.syntax().siblings(Direction::Next) { + match sibling.kind() { + EXCL | IDENT => range_end = sibling.range().end(), + _ => (), + } + } + res.push(HighlightedRange { + range: TextRange::from_to(range_start, range_end), + tag: "macro", + }) + } + } + } + } + continue; + } }; res.push(HighlightedRange { range: node.range(), @@ -235,7 +264,7 @@ fn main() {} r#"[HighlightedRange { range: [1; 11), tag: "comment" }, HighlightedRange { range: [12; 14), tag: "keyword" }, HighlightedRange { range: [15; 19), tag: "function" }, - HighlightedRange { range: [29; 36), tag: "text" }, + HighlightedRange { range: [29; 37), tag: "macro" }, HighlightedRange { range: [38; 50), tag: "string" }, HighlightedRange { range: [52; 54), tag: "literal" }]"#, &hls, -- 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 ++++++++-------- crates/ra_db/src/lib.rs | 8 +++++++- 3 files changed, 29 insertions(+), 19 deletions(-) (limited to 'crates') 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) } } diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 3028db17c..7181f2950 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -8,7 +8,7 @@ pub mod mock; use std::sync::Arc; use ra_editor::LineIndex; -use ra_syntax::{TextUnit, SourceFileNode}; +use ra_syntax::{TextUnit, TextRange, SourceFileNode}; pub use crate::{ cancelation::{Canceled, Cancelable}, @@ -70,3 +70,9 @@ pub struct FilePosition { pub file_id: FileId, pub offset: TextUnit, } + +#[derive(Clone, Copy, Debug)] +pub struct FileRange { + pub file_id: FileId, + pub range: TextRange, +} -- 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 +++++--- crates/ra_lsp_server/src/conv.rs | 13 ++++++++++++- crates/ra_lsp_server/src/main_loop/handlers.rs | 20 +++++++++----------- 4 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 crates/ra_analysis/src/extend_selection.rs (limited to 'crates') 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) diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index d3670104e..3d56ccd97 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -2,7 +2,7 @@ use languageserver_types::{ self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, }; -use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText}; +use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition,FileRange, CompletionItem, CompletionItemKind, InsertText}; use ra_editor::{LineCol, LineIndex, translate_offset_with_edit}; use ra_text_edit::{AtomTextEdit, TextEdit}; use ra_syntax::{SyntaxKind, TextRange, TextUnit}; @@ -218,6 +218,17 @@ impl<'a> TryConvWith for &'a TextDocumentPositionParams { } } +impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) { + type Ctx = ServerWorld; + type Output = FileRange; + fn try_conv_with(self, world: &ServerWorld) -> Result { + let file_id = self.0.try_conv_with(world)?; + let line_index = world.analysis().file_line_index(file_id); + let range = self.1.conv_with(&line_index); + Ok(FileRange { file_id, range }) + } +} + impl TryConvWith for Vec { type Ctx = ::Ctx; type Output = Vec<::Output>; diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 0e9a66a8a..d6f3dbe28 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -8,7 +8,7 @@ use languageserver_types::{ PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents, }; -use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition, Severity}; +use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FileRange, FilePosition, Severity}; use ra_syntax::{TextUnit, text_utils::intersect}; use ra_text_edit::text_utils::contains_offset_nonstrict; use rustc_hash::FxHashMap; @@ -33,13 +33,13 @@ pub fn handle_extend_selection( params: req::ExtendSelectionParams, ) -> Result { let file_id = params.text_document.try_conv_with(&world)?; - let file = world.analysis().file_syntax(file_id); let line_index = world.analysis().file_line_index(file_id); let selections = params .selections .into_iter() .map_conv_with(&line_index) - .map(|r| world.analysis().extend_selection(&file, r)) + .map(|range| FileRange { file_id, range }) + .map(|frange| world.analysis().extend_selection(frange)) .map_conv_with(&line_index) .collect(); Ok(req::ExtendSelectionResult { selections }) @@ -71,13 +71,8 @@ pub fn handle_join_lines( world: ServerWorld, params: req::JoinLinesParams, ) -> Result { - let file_id = params.text_document.try_conv_with(&world)?; - let line_index = world.analysis().file_line_index(file_id); - let range = params.range.conv_with(&line_index); - world - .analysis() - .join_lines(file_id, range) - .try_conv_with(&world) + let frange = (¶ms.text_document, params.range).try_conv_with(&world)?; + world.analysis().join_lines(frange).try_conv_with(&world) } pub fn handle_on_enter( @@ -614,7 +609,10 @@ pub fn handle_code_action( let line_index = world.analysis().file_line_index(file_id); let range = params.range.conv_with(&line_index); - let assists = world.analysis().assists(file_id, range)?.into_iter(); + let assists = world + .analysis() + .assists(FileRange { file_id, range })? + .into_iter(); let fixes = world .analysis() .diagnostics(file_id)? -- 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') 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