From 0343c4a815a0e82d5e55e76a01d21b0f7a00ff5b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 19 Jul 2019 11:24:41 +0300 Subject: migrate ra_assists to the new AST --- crates/ra_assists/src/add_derive.rs | 2 +- crates/ra_assists/src/add_explicit_type.rs | 2 +- crates/ra_assists/src/add_impl.rs | 6 +- crates/ra_assists/src/add_missing_impl_members.rs | 46 ++++--- crates/ra_assists/src/assist_ctx.rs | 14 +- crates/ra_assists/src/ast_editor.rs | 123 +++++++++--------- crates/ra_assists/src/auto_import.rs | 143 +++++++++++---------- crates/ra_assists/src/change_visibility.rs | 4 +- crates/ra_assists/src/fill_match_arms.rs | 4 +- crates/ra_assists/src/flip_binexpr.rs | 4 +- crates/ra_assists/src/flip_comma.rs | 4 +- crates/ra_assists/src/inline_local_variable.rs | 10 +- crates/ra_assists/src/introduce_variable.rs | 24 ++-- crates/ra_assists/src/move_guard.rs | 10 +- crates/ra_assists/src/remove_dbg.rs | 6 +- crates/ra_assists/src/replace_if_let_with_match.rs | 13 +- 16 files changed, 212 insertions(+), 203 deletions(-) (limited to 'crates/ra_assists') diff --git a/crates/ra_assists/src/add_derive.rs b/crates/ra_assists/src/add_derive.rs index bf7d55d6d..f19196f53 100644 --- a/crates/ra_assists/src/add_derive.rs +++ b/crates/ra_assists/src/add_derive.rs @@ -9,7 +9,7 @@ use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn add_derive(mut ctx: AssistCtx) -> Option { let nominal = ctx.node_at_offset::()?; - let node_start = derive_insertion_offset(nominal)?; + let node_start = derive_insertion_offset(&nominal)?; ctx.add_action(AssistId("add_derive"), "add `#[derive]`", |edit| { let derive_attr = nominal .attrs() diff --git a/crates/ra_assists/src/add_explicit_type.rs b/crates/ra_assists/src/add_explicit_type.rs index bb47a32f0..a69cfc8e3 100644 --- a/crates/ra_assists/src/add_explicit_type.rs +++ b/crates/ra_assists/src/add_explicit_type.rs @@ -27,7 +27,7 @@ pub(crate) fn add_explicit_type(mut ctx: AssistCtx) -> Option< // Infer type let db = ctx.db; let analyzer = hir::SourceAnalyzer::new(db, ctx.frange.file_id, stmt.syntax(), None); - let ty = analyzer.type_of(db, expr)?; + let ty = analyzer.type_of(db, &expr)?; // Assist not applicable if the type is unknown if is_unknown(&ty) { return None; diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs index b81922c1d..cebc19539 100644 --- a/crates/ra_assists/src/add_impl.rs +++ b/crates/ra_assists/src/add_impl.rs @@ -16,7 +16,7 @@ pub(crate) fn add_impl(mut ctx: AssistCtx) -> Option { let start_offset = nominal.syntax().range().end(); let mut buf = String::new(); buf.push_str("\n\nimpl"); - if let Some(type_params) = type_params { + if let Some(type_params) = &type_params { type_params.syntax().text().push_to(&mut buf); } buf.push_str(" "); @@ -25,9 +25,9 @@ pub(crate) fn add_impl(mut ctx: AssistCtx) -> Option { let lifetime_params = type_params .lifetime_params() .filter_map(|it| it.lifetime_token()) - .map(|it| it.text()); + .map(|it| it.text().clone()); let type_params = - type_params.type_params().filter_map(|it| it.name()).map(|it| it.text()); + type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); join(lifetime_params.chain(type_params)).surround_with("<", ">").to_buf(&mut buf); } buf.push_str(" {\n"); diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs index 6ffdad0b1..b992a4dc8 100644 --- a/crates/ra_assists/src/add_missing_impl_members.rs +++ b/crates/ra_assists/src/add_missing_impl_members.rs @@ -5,8 +5,8 @@ use crate::{ use hir::{db::HirDatabase, HasSource}; use ra_db::FilePosition; -use ra_syntax::ast::{self, AstNode, ImplItem, ImplItemKind, NameOwner}; -use ra_syntax::{SmolStr, TreeArc}; +use ra_syntax::ast::{self, AstNode, ImplItemKind, NameOwner}; +use ra_syntax::SmolStr; #[derive(PartialEq)] enum AddMissingImplMembersMode { @@ -46,16 +46,16 @@ fn add_missing_impl_members_inner( let position = FilePosition { file_id, offset: impl_node.syntax().range().start() }; let analyzer = hir::SourceAnalyzer::new(ctx.db, position.file_id, impl_node.syntax(), None); - resolve_target_trait_def(ctx.db, &analyzer, impl_node)? + resolve_target_trait_def(ctx.db, &analyzer, &impl_node)? }; - let def_name = |kind| -> Option<&SmolStr> { + let def_name = |kind| -> Option { match kind { - ImplItemKind::FnDef(def) => def.name(), - ImplItemKind::TypeAliasDef(def) => def.name(), - ImplItemKind::ConstDef(def) => def.name(), + ast::ImplItemKind::FnDef(def) => def.name(), + ast::ImplItemKind::TypeAliasDef(def) => def.name(), + ast::ImplItemKind::ConstDef(def) => def.name(), } - .map(ast::Name::text) + .map(|it| it.text().clone()) }; let trait_items = trait_def.item_list()?.impl_items(); @@ -78,18 +78,13 @@ fn add_missing_impl_members_inner( ctx.add_action(AssistId(assist_id), label, |edit| { let n_existing_items = impl_item_list.impl_items().count(); - let items: Vec<_> = missing_items - .into_iter() - .map(|it| match it.kind() { - ImplItemKind::FnDef(def) => { - strip_docstring(ImplItem::cast(add_body(def).syntax()).unwrap()) - } - _ => strip_docstring(it), - }) - .collect(); + let items = missing_items.into_iter().map(|it| match it.kind() { + ImplItemKind::FnDef(def) => strip_docstring(add_body(def).into()), + _ => strip_docstring(it), + }); let mut ast_editor = AstEditor::new(impl_item_list); - ast_editor.append_items(items.iter().map(|it| &**it)); + ast_editor.append_items(items); let first_new_item = ast_editor.ast().impl_items().nth(n_existing_items).unwrap(); let cursor_position = first_new_item.syntax().range().start(); @@ -101,14 +96,14 @@ fn add_missing_impl_members_inner( ctx.build() } -fn strip_docstring(item: &ast::ImplItem) -> TreeArc { +fn strip_docstring(item: ast::ImplItem) -> ast::ImplItem { let mut ast_editor = AstEditor::new(item); ast_editor.strip_attrs_and_docs(); ast_editor.ast().to_owned() } -fn add_body(fn_def: &ast::FnDef) -> TreeArc { - let mut ast_editor = AstEditor::new(fn_def); +fn add_body(fn_def: ast::FnDef) -> ast::FnDef { + let mut ast_editor = AstEditor::new(fn_def.clone()); if fn_def.body().is_none() { ast_editor.set_body(&AstBuilder::::single_expr( &AstBuilder::::unimplemented(), @@ -123,9 +118,12 @@ fn resolve_target_trait_def( db: &impl HirDatabase, analyzer: &hir::SourceAnalyzer, impl_block: &ast::ImplBlock, -) -> Option> { - let ast_path = - impl_block.target_trait().map(AstNode::syntax).and_then(ast::PathType::cast)?.path()?; +) -> Option { + let ast_path = impl_block + .target_trait() + .map(|it| it.syntax().clone()) + .and_then(ast::PathType::cast)? + .path()?; match analyzer.resolve_path(db, &ast_path) { Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def.source(db).ast), diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 34b207154..e52085f85 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs @@ -49,7 +49,7 @@ pub(crate) enum Assist { pub(crate) struct AssistCtx<'a, DB> { pub(crate) db: &'a DB, pub(crate) frange: FileRange, - source_file: &'a SourceFile, + source_file: SourceFile, should_compute_edit: bool, assist: Assist, } @@ -59,7 +59,7 @@ impl<'a, DB> Clone for AssistCtx<'a, DB> { AssistCtx { db: self.db, frange: self.frange, - source_file: self.source_file, + source_file: self.source_file.clone(), should_compute_edit: self.should_compute_edit, assist: self.assist.clone(), } @@ -104,18 +104,18 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { Some(self.assist) } - pub(crate) fn token_at_offset(&self) -> TokenAtOffset> { + pub(crate) fn token_at_offset(&self) -> TokenAtOffset { find_token_at_offset(self.source_file.syntax(), self.frange.range.start()) } - pub(crate) fn node_at_offset(&self) -> Option<&'a N> { + pub(crate) fn node_at_offset(&self) -> Option { find_node_at_offset(self.source_file.syntax(), self.frange.range.start()) } - pub(crate) fn covering_element(&self) -> SyntaxElement<'a> { + pub(crate) fn covering_element(&self) -> SyntaxElement { find_covering_element(self.source_file.syntax(), self.frange.range) } - pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement<'a> { + pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { find_covering_element(self.source_file.syntax(), range) } } @@ -139,7 +139,7 @@ impl AssistBuilder { ) { let mut replace_with = replace_with.into(); if let Some(indent) = leading_indent(node) { - replace_with = reindent(&replace_with, indent) + replace_with = reindent(&replace_with, &indent) } self.replace(node.range(), replace_with) } diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs index 7b743c9f0..5fbcadfee 100644 --- a/crates/ra_assists/src/ast_editor.rs +++ b/crates/ra_assists/src/ast_editor.rs @@ -4,18 +4,18 @@ use arrayvec::ArrayVec; use hir::Name; use ra_fmt::leading_indent; use ra_syntax::{ - ast, AstNode, Direction, InsertPosition, SourceFile, SyntaxElement, SyntaxKind::*, TreeArc, T, + ast, AstNode, Direction, InsertPosition, SourceFile, SyntaxElement, SyntaxKind::*, T, }; use ra_text_edit::TextEditBuilder; pub struct AstEditor { - original_ast: TreeArc, - ast: TreeArc, + original_ast: N, + ast: N, } impl AstEditor { - pub fn new(node: &N) -> AstEditor { - AstEditor { original_ast: node.to_owned(), ast: node.to_owned() } + pub fn new(node: N) -> AstEditor { + AstEditor { original_ast: node.clone(), ast: node } } pub fn into_text_edit(self, builder: &mut TextEditBuilder) { @@ -26,27 +26,27 @@ impl AstEditor { } pub fn ast(&self) -> &N { - &*self.ast + &self.ast } #[must_use] - fn insert_children<'a>( + fn insert_children( &self, - position: InsertPosition>, - to_insert: impl Iterator>, - ) -> TreeArc { + position: InsertPosition, + to_insert: impl Iterator, + ) -> N { let new_syntax = self.ast().syntax().insert_children(position, to_insert); - N::cast(&new_syntax).unwrap().to_owned() + N::cast(new_syntax).unwrap() } #[must_use] - fn replace_children<'a>( + fn replace_children( &self, - to_delete: RangeInclusive>, - to_insert: impl Iterator>, - ) -> TreeArc { + to_delete: RangeInclusive, + to_insert: impl Iterator, + ) -> N { let new_syntax = self.ast().syntax().replace_children(to_delete, to_insert); - N::cast(&new_syntax).unwrap().to_owned() + N::cast(new_syntax).unwrap() } fn do_make_multiline(&mut self) { @@ -66,16 +66,18 @@ impl AstEditor { if ws.text().contains('\n') { return; } - Some(ws) + Some(ws.clone()) } }; - let indent = leading_indent(self.ast().syntax()).unwrap_or(""); + let indent = leading_indent(self.ast().syntax()).unwrap_or("".into()); let ws = tokens::WsBuilder::new(&format!("\n{}", indent)); let to_insert = iter::once(ws.ws().into()); self.ast = match existing_ws { None => self.insert_children(InsertPosition::After(l_curly), to_insert), - Some(ws) => self.replace_children(RangeInclusive::new(ws.into(), ws.into()), to_insert), + Some(ws) => { + self.replace_children(RangeInclusive::new(ws.clone().into(), ws.into()), to_insert) + } }; } } @@ -95,7 +97,7 @@ impl AstEditor { let space = if is_multiline { ws = tokens::WsBuilder::new(&format!( "\n{} ", - leading_indent(self.ast().syntax()).unwrap_or("") + leading_indent(self.ast().syntax()).unwrap_or("".into()) )); ws.ws() } else { @@ -104,7 +106,7 @@ impl AstEditor { let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); to_insert.push(space.into()); - to_insert.push(field.syntax().into()); + to_insert.push(field.syntax().clone().into()); to_insert.push(tokens::comma().into()); macro_rules! after_l_curly { @@ -127,7 +129,7 @@ impl AstEditor { InsertPosition::After(comma) } else { to_insert.insert(0, tokens::comma().into()); - InsertPosition::After($anchor.syntax().into()) + InsertPosition::After($anchor.syntax().clone().into()) } }; }; @@ -144,7 +146,9 @@ impl AstEditor { None => after_l_curly!(), } } - InsertPosition::Before(anchor) => InsertPosition::Before(anchor.syntax().into()), + InsertPosition::Before(anchor) => { + InsertPosition::Before(anchor.syntax().clone().into()) + } InsertPosition::After(anchor) => after_field!(anchor), }; @@ -157,7 +161,7 @@ impl AstEditor { } impl AstEditor { - pub fn append_items<'a>(&mut self, items: impl Iterator) { + pub fn append_items(&mut self, items: impl Iterator) { let n_existing_items = self.ast().impl_items().count(); if n_existing_items == 0 { self.do_make_multiline(); @@ -165,22 +169,23 @@ impl AstEditor { items.for_each(|it| self.append_item(it)); } - pub fn append_item(&mut self, item: &ast::ImplItem) { + pub fn append_item(&mut self, item: ast::ImplItem) { let (indent, position) = match self.ast().impl_items().last() { Some(it) => ( - leading_indent(it.syntax()).unwrap_or("").to_string(), - InsertPosition::After(it.syntax().into()), + leading_indent(it.syntax()).unwrap_or_default().to_string(), + InsertPosition::After(it.syntax().clone().into()), ), None => match self.l_curly() { Some(it) => ( - " ".to_string() + leading_indent(self.ast().syntax()).unwrap_or(""), + " ".to_string() + &leading_indent(self.ast().syntax()).unwrap_or_default(), InsertPosition::After(it), ), None => return, }, }; let ws = tokens::WsBuilder::new(&format!("\n{}", indent)); - let to_insert: ArrayVec<[SyntaxElement; 2]> = [ws.ws().into(), item.syntax().into()].into(); + let to_insert: ArrayVec<[SyntaxElement; 2]> = + [ws.ws().into(), item.syntax().clone().into()].into(); self.ast = self.insert_children(position, to_insert.into_iter()); } @@ -197,9 +202,9 @@ impl AstEditor { .children_with_tokens() .find(|it| it.kind() == ATTR || it.kind() == COMMENT) { - let end = match start.next_sibling_or_token() { - Some(el) if el.kind() == WHITESPACE => el, - Some(_) | None => start, + let end = match &start.next_sibling_or_token() { + Some(el) if el.kind() == WHITESPACE => el.clone(), + Some(_) | None => start.clone(), }; self.ast = self.replace_children(RangeInclusive::new(start, end), iter::empty()); } @@ -210,18 +215,18 @@ impl AstEditor { pub fn set_body(&mut self, body: &ast::Block) { let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.ast().body() { - old_body.syntax().into() + old_body.syntax().clone().into() } else if let Some(semi) = self.ast().semicolon_token() { to_insert.push(tokens::single_space().into()); semi.into() } else { to_insert.push(tokens::single_space().into()); - to_insert.push(body.syntax().into()); + to_insert.push(body.syntax().clone().into()); self.ast = self.insert_children(InsertPosition::Last, to_insert.into_iter()); return; }; - to_insert.push(body.syntax().into()); - let replace_range = RangeInclusive::new(old_body_or_semi, old_body_or_semi); + to_insert.push(body.syntax().clone().into()); + let replace_range = RangeInclusive::new(old_body_or_semi.clone(), old_body_or_semi); self.ast = self.replace_children(replace_range, to_insert.into_iter()) } } @@ -231,15 +236,15 @@ pub struct AstBuilder { } impl AstBuilder { - pub fn from_name(name: &Name) -> TreeArc { + pub fn from_name(name: &Name) -> ast::NamedField { ast_node_from_file_text(&format!("fn f() {{ S {{ {}: (), }} }}", name)) } - fn from_text(text: &str) -> TreeArc { + fn from_text(text: &str) -> ast::NamedField { ast_node_from_file_text(&format!("fn f() {{ S {{ {}, }} }}", text)) } - pub fn from_pieces(name: &ast::NameRef, expr: Option<&ast::Expr>) -> TreeArc { + pub fn from_pieces(name: &ast::NameRef, expr: Option<&ast::Expr>) -> ast::NamedField { match expr { Some(expr) => Self::from_text(&format!("{}: {}", name.syntax(), expr.syntax())), None => Self::from_text(&name.syntax().to_string()), @@ -248,36 +253,36 @@ impl AstBuilder { } impl AstBuilder { - fn from_text(text: &str) -> TreeArc { + fn from_text(text: &str) -> ast::Block { ast_node_from_file_text(&format!("fn f() {}", text)) } - pub fn single_expr(e: &ast::Expr) -> TreeArc { + pub fn single_expr(e: &ast::Expr) -> ast::Block { Self::from_text(&format!("{{ {} }}", e.syntax())) } } impl AstBuilder { - fn from_text(text: &str) -> TreeArc { + fn from_text(text: &str) -> ast::Expr { ast_node_from_file_text(&format!("fn f() {{ {}; }}", text)) } - pub fn unit() -> TreeArc { + pub fn unit() -> ast::Expr { Self::from_text("()") } - pub fn unimplemented() -> TreeArc { + pub fn unimplemented() -> ast::Expr { Self::from_text("unimplemented!()") } } impl AstBuilder { - pub fn new(text: &str) -> TreeArc { + pub fn new(text: &str) -> ast::NameRef { ast_node_from_file_text(&format!("fn f() {{ {}; }}", text)) } } -fn ast_node_from_file_text(text: &str) -> TreeArc { +fn ast_node_from_file_text(text: &str) -> N { let parse = SourceFile::parse(text); let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap().to_owned(); res @@ -285,47 +290,49 @@ fn ast_node_from_file_text(text: &str) -> TreeArc { mod tokens { use once_cell::sync::Lazy; - use ra_syntax::{AstNode, SourceFile, SyntaxKind::*, SyntaxToken, TreeArc, T}; + use ra_syntax::{AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken, T}; - static SOURCE_FILE: Lazy> = - Lazy::new(|| SourceFile::parse(",\n; ;").tree().to_owned()); + static SOURCE_FILE: Lazy> = Lazy::new(|| SourceFile::parse(",\n; ;")); - pub(crate) fn comma() -> SyntaxToken<'static> { + pub(crate) fn comma() -> SyntaxToken { SOURCE_FILE + .tree() .syntax() .descendants_with_tokens() - .filter_map(|it| it.as_token()) + .filter_map(|it| it.as_token().cloned()) .find(|it| it.kind() == T![,]) .unwrap() } - pub(crate) fn single_space() -> SyntaxToken<'static> { + pub(crate) fn single_space() -> SyntaxToken { SOURCE_FILE + .tree() .syntax() .descendants_with_tokens() - .filter_map(|it| it.as_token()) + .filter_map(|it| it.as_token().cloned()) .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ") .unwrap() } #[allow(unused)] - pub(crate) fn single_newline() -> SyntaxToken<'static> { + pub(crate) fn single_newline() -> SyntaxToken { SOURCE_FILE + .tree() .syntax() .descendants_with_tokens() - .filter_map(|it| it.as_token()) + .filter_map(|it| it.as_token().cloned()) .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n") .unwrap() } - pub(crate) struct WsBuilder(TreeArc); + pub(crate) struct WsBuilder(SourceFile); impl WsBuilder { pub(crate) fn new(text: &str) -> WsBuilder { WsBuilder(SourceFile::parse(text).ok().unwrap()) } - pub(crate) fn ws(&self) -> SyntaxToken<'_> { - self.0.syntax().first_child_or_token().unwrap().as_token().unwrap() + pub(crate) fn ws(&self) -> SyntaxToken { + self.0.syntax().first_child_or_token().unwrap().as_token().cloned().unwrap() } } diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index f8f37e852..0eb4bdb62 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs @@ -12,25 +12,25 @@ use ra_syntax::{ SyntaxNode, TextRange, T, }; -fn collect_path_segments_raw<'a>( - segments: &mut Vec<&'a ast::PathSegment>, - mut path: &'a ast::Path, +fn collect_path_segments_raw( + segments: &mut Vec, + mut path: ast::Path, ) -> Option { let oldlen = segments.len(); loop { let mut children = path.syntax().children_with_tokens(); let (first, second, third) = ( - children.next().map(|n| (n, n.kind())), - children.next().map(|n| (n, n.kind())), - children.next().map(|n| (n, n.kind())), + children.next().map(|n| (n.clone(), n.kind())), + children.next().map(|n| (n.clone(), n.kind())), + children.next().map(|n| (n.clone(), n.kind())), ); match (first, second, third) { (Some((subpath, PATH)), Some((_, T![::])), Some((segment, PATH_SEGMENT))) => { - path = ast::Path::cast(subpath.as_node()?)?; - segments.push(ast::PathSegment::cast(segment.as_node()?)?); + path = ast::Path::cast(subpath.as_node()?.clone())?; + segments.push(ast::PathSegment::cast(segment.as_node()?.clone())?); } (Some((segment, PATH_SEGMENT)), _, _) => { - segments.push(ast::PathSegment::cast(segment.as_node()?)?); + segments.push(ast::PathSegment::cast(segment.as_node()?.clone())?); break; } (_, _, _) => return None, @@ -60,7 +60,7 @@ fn fmt_segments_raw(segments: &[SmolStr], buf: &mut String) { } // Returns the numeber of common segments. -fn compare_path_segments(left: &[SmolStr], right: &[&ast::PathSegment]) -> usize { +fn compare_path_segments(left: &[SmolStr], right: &[ast::PathSegment]) -> usize { left.iter().zip(right).filter(|(l, r)| compare_path_segment(l, r)).count() } @@ -81,12 +81,12 @@ fn compare_path_segment_with_name(a: &SmolStr, b: &ast::Name) -> bool { a == b.text() } -#[derive(Copy, Clone)] -enum ImportAction<'a> { +#[derive(Clone)] +enum ImportAction { Nothing, // Add a brand new use statement. AddNewUse { - anchor: Option<&'a SyntaxNode>, // anchor node + anchor: Option, // anchor node add_after_anchor: bool, }, @@ -94,9 +94,9 @@ enum ImportAction<'a> { AddNestedImport { // how may segments matched with the target path common_segments: usize, - path_to_split: &'a ast::Path, + path_to_split: ast::Path, // the first segment of path_to_split we want to add into the new nested list - first_segment_to_split: Option<&'a ast::PathSegment>, + first_segment_to_split: Option, // Wether to add 'self' in addition to the target path add_self: bool, }, @@ -104,20 +104,20 @@ enum ImportAction<'a> { AddInTreeList { common_segments: usize, // The UseTreeList where to add the target path - tree_list: &'a ast::UseTreeList, + tree_list: ast::UseTreeList, add_self: bool, }, } -impl<'a> ImportAction<'a> { - fn add_new_use(anchor: Option<&'a SyntaxNode>, add_after_anchor: bool) -> Self { +impl ImportAction { + fn add_new_use(anchor: Option, add_after_anchor: bool) -> Self { ImportAction::AddNewUse { anchor, add_after_anchor } } fn add_nested_import( common_segments: usize, - path_to_split: &'a ast::Path, - first_segment_to_split: Option<&'a ast::PathSegment>, + path_to_split: ast::Path, + first_segment_to_split: Option, add_self: bool, ) -> Self { ImportAction::AddNestedImport { @@ -130,14 +130,14 @@ impl<'a> ImportAction<'a> { fn add_in_tree_list( common_segments: usize, - tree_list: &'a ast::UseTreeList, + tree_list: ast::UseTreeList, add_self: bool, ) -> Self { ImportAction::AddInTreeList { common_segments, tree_list, add_self } } - fn better<'b>(left: &'b ImportAction<'a>, right: &'b ImportAction<'a>) -> &'b ImportAction<'a> { - if left.is_better(right) { + fn better(left: ImportAction, right: ImportAction) -> ImportAction { + if left.is_better(&right) { left } else { right @@ -166,12 +166,12 @@ impl<'a> ImportAction<'a> { // Find out the best ImportAction to import target path against current_use_tree. // If current_use_tree has a nested import the function gets called recursively on every UseTree inside a UseTreeList. -fn walk_use_tree_for_best_action<'a>( - current_path_segments: &mut Vec<&'a ast::PathSegment>, // buffer containing path segments - current_parent_use_tree_list: Option<&'a ast::UseTreeList>, // will be Some value if we are in a nested import - current_use_tree: &'a ast::UseTree, // the use tree we are currently examinating - target: &[SmolStr], // the path we want to import -) -> ImportAction<'a> { +fn walk_use_tree_for_best_action( + current_path_segments: &mut Vec, // buffer containing path segments + current_parent_use_tree_list: Option, // will be Some value if we are in a nested import + current_use_tree: ast::UseTree, // the use tree we are currently examinating + target: &[SmolStr], // the path we want to import +) -> ImportAction { // We save the number of segments in the buffer so we can restore the correct segments // before returning. Recursive call will add segments so we need to delete them. let prev_len = current_path_segments.len(); @@ -188,32 +188,36 @@ fn walk_use_tree_for_best_action<'a>( .syntax() .ancestors() .find_map(ast::UseItem::cast) - .map(AstNode::syntax), + .map(|it| it.syntax().clone()), true, ); } }; // This can happen only if current_use_tree is a direct child of a UseItem - if let Some(name) = alias.and_then(ast::NameOwner::name) { - if compare_path_segment_with_name(&target[0], name) { + if let Some(name) = alias.and_then(|it| it.name()) { + if compare_path_segment_with_name(&target[0], &name) { return ImportAction::Nothing; } } - collect_path_segments_raw(current_path_segments, path); + collect_path_segments_raw(current_path_segments, path.clone()); // We compare only the new segments added in the line just above. // The first prev_len segments were already compared in 'parent' recursive calls. let left = target.split_at(prev_len).1; let right = current_path_segments.split_at(prev_len).1; - let common = compare_path_segments(left, right); + let common = compare_path_segments(left, &right); let mut action = match common { 0 => ImportAction::add_new_use( // e.g: target is std::fmt and we can have // use foo::bar // We add a brand new use statement - current_use_tree.syntax().ancestors().find_map(ast::UseItem::cast).map(AstNode::syntax), + current_use_tree + .syntax() + .ancestors() + .find_map(ast::UseItem::cast) + .map(|it| it.syntax().clone()), true, ), common if common == left.len() && left.len() == right.len() => { @@ -223,9 +227,9 @@ fn walk_use_tree_for_best_action<'a>( if let Some(list) = tree_list { // In case 2 we need to add self to the nested list // unless it's already there - let has_self = list.use_trees().map(ast::UseTree::path).any(|p| { - p.and_then(ast::Path::segment) - .and_then(ast::PathSegment::kind) + let has_self = list.use_trees().map(|it| it.path()).any(|p| { + p.and_then(|it| it.segment()) + .and_then(|it| it.kind()) .filter(|k| *k == ast::PathSegmentKind::SelfKw) .is_some() }); @@ -248,7 +252,7 @@ fn walk_use_tree_for_best_action<'a>( ImportAction::add_nested_import( prev_len + common, path, - Some(segments_to_split[0]), + Some(segments_to_split[0].clone()), false, ) } @@ -263,14 +267,18 @@ fn walk_use_tree_for_best_action<'a>( .syntax() .ancestors() .find_map(ast::UseItem::cast) - .map(AstNode::syntax), + .map(|it| it.syntax().clone()), true, ); if let Some(list) = tree_list { // Case 2, check recursively if the path is already imported in the nested list for u in list.use_trees() { - let child_action = - walk_use_tree_for_best_action(current_path_segments, Some(list), u, target); + let child_action = walk_use_tree_for_best_action( + current_path_segments, + Some(list.clone()), + u, + target, + ); if child_action.is_better(&better_action) { better_action = child_action; if let ImportAction::Nothing = better_action { @@ -291,7 +299,7 @@ fn walk_use_tree_for_best_action<'a>( ImportAction::add_nested_import( prev_len + common, path, - Some(segments_to_split[0]), + Some(segments_to_split[0].clone()), true, ) } @@ -302,7 +310,7 @@ fn walk_use_tree_for_best_action<'a>( ImportAction::add_nested_import( prev_len + common, path, - Some(segments_to_split[0]), + Some(segments_to_split[0].clone()), false, ) } @@ -311,7 +319,7 @@ fn walk_use_tree_for_best_action<'a>( // If we are inside a UseTreeList adding a use statement become adding to the existing // tree list. - action = match (current_parent_use_tree_list, action) { + action = match (current_parent_use_tree_list, action.clone()) { (Some(use_tree_list), ImportAction::AddNewUse { .. }) => { ImportAction::add_in_tree_list(prev_len, use_tree_list, false) } @@ -323,19 +331,20 @@ fn walk_use_tree_for_best_action<'a>( action } -fn best_action_for_target<'b, 'a: 'b>( - container: &'a SyntaxNode, - anchor: &'a SyntaxNode, - target: &'b [SmolStr], -) -> ImportAction<'a> { +fn best_action_for_target( + container: SyntaxNode, + anchor: SyntaxNode, + target: &[SmolStr], +) -> ImportAction { let mut storage = Vec::with_capacity(16); // this should be the only allocation let best_action = container .children() .filter_map(ast::UseItem::cast) - .filter_map(ast::UseItem::use_tree) + .filter_map(|it| it.use_tree()) .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) - .fold(None, |best, a| { - best.and_then(|best| Some(*ImportAction::better(&best, &a))).or_else(|| Some(a)) + .fold(None, |best, a| match best { + Some(best) => Some(ImportAction::better(best, a)), + None => Some(a), }); match best_action { @@ -386,7 +395,7 @@ fn make_assist(action: &ImportAction, target: &[SmolStr], edit: &mut TextEditBui } fn make_assist_add_new_use( - anchor: &Option<&SyntaxNode>, + anchor: &Option, after: bool, target: &[SmolStr], edit: &mut TextEditBuilder, @@ -396,7 +405,7 @@ fn make_assist_add_new_use( let mut buf = String::new(); if after { buf.push_str("\n"); - if let Some(spaces) = indent { + if let Some(spaces) = &indent { buf.push_str(spaces); } } @@ -405,8 +414,8 @@ fn make_assist_add_new_use( buf.push_str(";"); if !after { buf.push_str("\n\n"); - if let Some(spaces) = indent { - buf.push_str(spaces); + if let Some(spaces) = &indent { + buf.push_str(&spaces); } } let position = if after { anchor.range().end() } else { anchor.range().start() }; @@ -444,7 +453,7 @@ fn make_assist_add_in_tree_list( fn make_assist_add_nested_import( path: &ast::Path, - first_segment_to_split: &Option<&ast::PathSegment>, + first_segment_to_split: &Option, target: &[SmolStr], add_self: bool, edit: &mut TextEditBuilder, @@ -482,7 +491,7 @@ fn apply_auto_import( target: &[SmolStr], edit: &mut TextEditBuilder, ) { - let action = best_action_for_target(container, path.syntax(), target); + let action = best_action_for_target(container.clone(), path.syntax().clone(), target); make_assist(&action, target, edit); if let Some(last) = path.segment() { // Here we are assuming the assist will provide a correct use statement @@ -522,26 +531,26 @@ pub fn auto_import_text_edit( edit: &mut TextEditBuilder, ) { let container = position.ancestors().find_map(|n| { - if let Some(module) = ast::Module::cast(n) { - return module.item_list().map(ast::AstNode::syntax); + if let Some(module) = ast::Module::cast(n.clone()) { + return module.item_list().map(|it| it.syntax().clone()); } - ast::SourceFile::cast(n).map(ast::AstNode::syntax) + ast::SourceFile::cast(n).map(|it| it.syntax().clone()) }); if let Some(container) = container { - let action = best_action_for_target(container, anchor, target); + let action = best_action_for_target(container, anchor.clone(), target); make_assist(&action, target, edit); } } pub(crate) fn auto_import(mut ctx: AssistCtx) -> Option { - let path: &ast::Path = ctx.node_at_offset()?; + let path: ast::Path = ctx.node_at_offset()?; // We don't want to mess with use statements if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() { return None; } - let hir_path = hir::Path::from_ast(path)?; + let hir_path = hir::Path::from_ast(path.clone())?; let segments = collect_hir_path_segments(&hir_path); if segments.len() < 2 { return None; @@ -554,7 +563,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx) -> Option) -> Option) -> Option { if parent.children().any(|child| child.kind() == VISIBILITY) { return None; } - (vis_offset(parent), keyword.range()) + (vis_offset(&parent), keyword.range()) } else { let ident = ctx.token_at_offset().find(|leaf| leaf.kind() == IDENT)?; let field = ident.parent().ancestors().find_map(ast::NamedFieldDef::cast)?; @@ -65,7 +65,7 @@ fn vis_offset(node: &SyntaxNode) -> TextUnit { .unwrap_or_else(|| node.range().start()) } -fn change_vis(mut ctx: AssistCtx, vis: &ast::Visibility) -> Option { +fn change_vis(mut ctx: AssistCtx, vis: ast::Visibility) -> Option { if vis.syntax().text() == "pub" { ctx.add_action(AssistId("change_visibility"), "change to pub(crate)", |edit| { edit.target(vis.syntax().range()); diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index deef166b5..b96806ac6 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs @@ -27,7 +27,7 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option { if arm_iter.next() != None { @@ -44,7 +44,7 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option Some(e), _ => None, diff --git a/crates/ra_assists/src/flip_binexpr.rs b/crates/ra_assists/src/flip_binexpr.rs index 5e41f9346..2e591ad3b 100644 --- a/crates/ra_assists/src/flip_binexpr.rs +++ b/crates/ra_assists/src/flip_binexpr.rs @@ -6,8 +6,8 @@ use crate::{Assist, AssistCtx, AssistId}; /// Flip binary expression assist. pub(crate) fn flip_binexpr(mut ctx: AssistCtx) -> Option { let expr = ctx.node_at_offset::()?; - let lhs = expr.lhs()?.syntax(); - let rhs = expr.rhs()?.syntax(); + let lhs = expr.lhs()?.syntax().clone(); + let rhs = expr.rhs()?.syntax().clone(); let op_range = expr.op_token()?.range(); // The assist should be applied only if the cursor is on the operator let cursor_in_range = ctx.frange.range.is_subrange(&op_range); diff --git a/crates/ra_assists/src/flip_comma.rs b/crates/ra_assists/src/flip_comma.rs index d8dba779f..13016ae06 100644 --- a/crates/ra_assists/src/flip_comma.rs +++ b/crates/ra_assists/src/flip_comma.rs @@ -5,8 +5,8 @@ use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn flip_comma(mut ctx: AssistCtx) -> Option { let comma = ctx.token_at_offset().find(|leaf| leaf.kind() == T![,])?; - let prev = non_trivia_sibling(comma.into(), Direction::Prev)?; - let next = non_trivia_sibling(comma.into(), Direction::Next)?; + let prev = non_trivia_sibling(comma.clone().into(), Direction::Prev)?; + let next = non_trivia_sibling(comma.clone().into(), Direction::Next)?; ctx.add_action(AssistId("flip_comma"), "flip comma", |edit| { edit.target(comma.range()); edit.replace(prev.range(), next.to_string()); diff --git a/crates/ra_assists/src/inline_local_variable.rs b/crates/ra_assists/src/inline_local_variable.rs index 554de8b46..3c17089de 100644 --- a/crates/ra_assists/src/inline_local_variable.rs +++ b/crates/ra_assists/src/inline_local_variable.rs @@ -16,18 +16,18 @@ pub(crate) fn inline_local_varialbe(mut ctx: AssistCtx) -> Opt if bind_pat.is_mutable() { return None; } - let initializer_expr = let_stmt.initializer(); + let initializer_expr = let_stmt.initializer()?; let delete_range = if let Some(whitespace) = let_stmt .syntax() .next_sibling_or_token() - .and_then(|it| ast::Whitespace::cast(it.as_token()?)) + .and_then(|it| ast::Whitespace::cast(it.as_token()?.clone())) { TextRange::from_to(let_stmt.syntax().range().start(), whitespace.syntax().range().end()) } else { let_stmt.syntax().range() }; let analyzer = hir::SourceAnalyzer::new(ctx.db, ctx.frange.file_id, bind_pat.syntax(), None); - let refs = analyzer.find_all_refs(bind_pat); + let refs = analyzer.find_all_refs(&bind_pat); let mut wrap_in_parens = vec![true; refs.len()]; @@ -45,7 +45,7 @@ pub(crate) fn inline_local_varialbe(mut ctx: AssistCtx) -> Opt } }; - wrap_in_parens[i] = match (initializer_expr?.kind(), usage_parent.kind()) { + wrap_in_parens[i] = match (initializer_expr.kind(), usage_parent.kind()) { (ExprKind::CallExpr(_), _) | (ExprKind::IndexExpr(_), _) | (ExprKind::MethodCallExpr(_), _) @@ -71,7 +71,7 @@ pub(crate) fn inline_local_varialbe(mut ctx: AssistCtx) -> Opt }; } - let init_str = initializer_expr?.syntax().text().to_string(); + let init_str = initializer_expr.syntax().text().to_string(); let init_in_paren = format!("({})", &init_str); ctx.add_action( diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index f7f5ccafa..ce28132c9 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs @@ -20,8 +20,8 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx) -> Option return None; } let expr = node.ancestors().find_map(valid_target_expr)?; - let (anchor_stmt, wrap_in_block) = anchor_stmt(expr)?; - let indent = anchor_stmt.prev_sibling_or_token()?.as_token()?; + let (anchor_stmt, wrap_in_block) = anchor_stmt(expr.clone())?; + let indent = anchor_stmt.prev_sibling_or_token()?.as_token()?.clone(); if indent.kind() != WHITESPACE { return None; } @@ -37,9 +37,9 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx) -> Option }; expr.syntax().text().push_to(&mut buf); - let full_stmt = ast::ExprStmt::cast(anchor_stmt); - let is_full_stmt = if let Some(expr_stmt) = full_stmt { - Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax()) + let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); + let is_full_stmt = if let Some(expr_stmt) = &full_stmt { + Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) } else { false }; @@ -81,7 +81,7 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx) -> Option /// Check whether the node is a valid expression which can be extracted to a variable. /// In general that's true for any expression, but in some cases that would produce invalid code. -fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> { +fn valid_target_expr(node: SyntaxNode) -> Option { match node.kind() { PATH_EXPR => None, BREAK_EXPR => ast::BreakExpr::cast(node).and_then(|e| e.expr()), @@ -96,14 +96,10 @@ fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> { /// to produce correct code. /// It can be a statement, the last in a block expression or a wanna be block /// expression like a lambda or match arm. -fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> { +fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { expr.syntax().ancestors().find_map(|node| { - if ast::Stmt::cast(node).is_some() { - return Some((node, false)); - } - if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { - if expr.syntax() == node { + if expr.syntax() == &node { tested_by!(test_introduce_var_last_expr); return Some((node, false)); } @@ -115,6 +111,10 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> { } } + if ast::Stmt::cast(node.clone()).is_some() { + return Some((node, false)); + } + None }) } diff --git a/crates/ra_assists/src/move_guard.rs b/crates/ra_assists/src/move_guard.rs index e1ce86a33..313c9ad18 100644 --- a/crates/ra_assists/src/move_guard.rs +++ b/crates/ra_assists/src/move_guard.rs @@ -18,9 +18,9 @@ pub(crate) fn move_guard_to_arm_body(mut ctx: AssistCtx) -> Op ctx.add_action(AssistId("move_guard_to_arm_body"), "move guard to arm body", |edit| { edit.target(guard.syntax().range()); - let offseting_amount = match space_before_guard { + let offseting_amount = match &space_before_guard { Some(SyntaxElement::Token(tok)) => { - if let Some(_) = ast::Whitespace::cast(tok) { + if let Some(_) = ast::Whitespace::cast(tok.clone()) { let ele = space_before_guard.unwrap().range(); edit.delete(ele); ele.len() @@ -39,11 +39,11 @@ pub(crate) fn move_guard_to_arm_body(mut ctx: AssistCtx) -> Op } pub(crate) fn move_arm_cond_to_match_guard(mut ctx: AssistCtx) -> Option { - let match_arm: &MatchArm = ctx.node_at_offset::()?; + let match_arm: MatchArm = ctx.node_at_offset::()?; let last_match_pat = match_arm.pats().last()?; let arm_body = match_arm.expr()?; - let if_expr: &IfExpr = IfExpr::cast(arm_body.syntax())?; + let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone())?; let cond = if_expr.condition()?; let then_block = if_expr.then_branch()?; @@ -65,7 +65,7 @@ pub(crate) fn move_arm_cond_to_match_guard(mut ctx: AssistCtx) edit.target(if_expr.syntax().range()); let then_only_expr = then_block.statements().next().is_none(); - match then_block.expr() { + match &then_block.expr() { Some(then_expr) if then_only_expr => { edit.replace(if_expr.syntax().range(), then_expr.syntax().text()) } diff --git a/crates/ra_assists/src/remove_dbg.rs b/crates/ra_assists/src/remove_dbg.rs index 5680f76ca..c330bc827 100644 --- a/crates/ra_assists/src/remove_dbg.rs +++ b/crates/ra_assists/src/remove_dbg.rs @@ -8,7 +8,7 @@ use ra_syntax::{ pub(crate) fn remove_dbg(mut ctx: AssistCtx) -> Option { let macro_call = ctx.node_at_offset::()?; - if !is_valid_macrocall(macro_call, "dbg")? { + if !is_valid_macrocall(¯o_call, "dbg")? { return None; } @@ -35,7 +35,7 @@ pub(crate) fn remove_dbg(mut ctx: AssistCtx) -> Option }; let macro_content = { - let macro_args = macro_call.token_tree()?.syntax(); + let macro_args = macro_call.token_tree()?.syntax().clone(); let range = macro_args.range(); let start = range.start() + TextUnit::of_char('('); let end = range.end() - TextUnit::of_char(')'); @@ -65,7 +65,7 @@ fn is_valid_macrocall(macro_call: &ast::MacroCall, macro_name: &str) -> Option) -> Option { - let if_expr: &ast::IfExpr = ctx.node_at_offset()?; + let if_expr: ast::IfExpr = ctx.node_at_offset()?; let cond = if_expr.condition()?; let pat = cond.pat()?; let expr = cond.expr()?; @@ -25,16 +25,11 @@ pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx) -> ctx.build() } -fn build_match_expr( - expr: &ast::Expr, - pat1: &ast::Pat, - arm1: &ast::Block, - arm2: &ast::Block, -) -> String { +fn build_match_expr(expr: ast::Expr, pat1: ast::Pat, arm1: ast::Block, arm2: ast::Block) -> String { let mut buf = String::new(); buf.push_str(&format!("match {} {{\n", expr.syntax().text())); - buf.push_str(&format!(" {} => {}\n", pat1.syntax().text(), format_arm(arm1))); - buf.push_str(&format!(" _ => {}\n", format_arm(arm2))); + buf.push_str(&format!(" {} => {}\n", pat1.syntax().text(), format_arm(&arm1))); + buf.push_str(&format!(" _ => {}\n", format_arm(&arm2))); buf.push_str("}"); buf } -- cgit v1.2.3