From 384032442965b70001d7c15ec0db65bfe5634ee9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 27 Oct 2019 11:32:39 +0300 Subject: raw string assists work in macros --- crates/ra_assists/src/assists/raw_string.rs | 107 +++++++++++++++------------- 1 file changed, 58 insertions(+), 49 deletions(-) (limited to 'crates/ra_assists/src/assists') diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs index 2d2e31e51..9c996c902 100644 --- a/crates/ra_assists/src/assists/raw_string.rs +++ b/crates/ra_assists/src/assists/raw_string.rs @@ -1,17 +1,19 @@ //! FIXME: write short doc here use hir::db::HirDatabase; -use ra_syntax::{ast::AstNode, ast::Literal, TextRange, TextUnit}; +use ra_syntax::{ + SyntaxKind::{RAW_STRING, STRING}, + SyntaxToken, TextRange, TextUnit, +}; use rustc_lexer; use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn make_raw_string(mut ctx: AssistCtx) -> Option { - let literal = ctx.node_at_offset::()?; - if literal.token().kind() != ra_syntax::SyntaxKind::STRING { + let token = ctx.token_at_offset().right_biased()?; + if token.kind() != STRING { return None; } - let token = literal.token(); let text = token.text().as_str(); let usual_string_range = find_usual_string_range(text)?; let start_of_inside = usual_string_range.start().to_usize() + 1; @@ -30,85 +32,52 @@ pub(crate) fn make_raw_string(mut ctx: AssistCtx) -> Option usize { - let mut max_hash_streak = 0usize; - for idx in s.match_indices("\"#").map(|(i, _)| i) { - let (_, sub) = s.split_at(idx + 1); - let nb_hash = sub.chars().take_while(|c| *c == '#').count(); - if nb_hash > max_hash_streak { - max_hash_streak = nb_hash; - } - } - max_hash_streak -} - -fn find_usual_string_range(s: &str) -> Option { - Some(TextRange::from_to( - TextUnit::from(s.find('"')? as u32), - TextUnit::from(s.rfind('"')? as u32), - )) -} - pub(crate) fn make_usual_string(mut ctx: AssistCtx) -> Option { - let literal = ctx.node_at_offset::()?; - if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { - return None; - } - let token = literal.token(); + let token = raw_string_token(&ctx)?; let text = token.text().as_str(); let usual_string_range = find_usual_string_range(text)?; ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| { - edit.target(literal.syntax().text_range()); + edit.target(token.text_range()); // parse inside string to escape `"` let start_of_inside = usual_string_range.start().to_usize() + 1; let end_of_inside = usual_string_range.end().to_usize(); let inside_str = &text[start_of_inside..end_of_inside]; let escaped = inside_str.escape_default().to_string(); - edit.replace(literal.syntax().text_range(), format!("\"{}\"", escaped)); + edit.replace(token.text_range(), format!("\"{}\"", escaped)); }); ctx.build() } pub(crate) fn add_hash(mut ctx: AssistCtx) -> Option { - let literal = ctx.node_at_offset::()?; - if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { - return None; - } + let token = raw_string_token(&ctx)?; ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| { - edit.target(literal.syntax().text_range()); - edit.insert(literal.syntax().text_range().start() + TextUnit::of_char('r'), "#"); - edit.insert(literal.syntax().text_range().end(), "#"); + edit.target(token.text_range()); + edit.insert(token.text_range().start() + TextUnit::of_char('r'), "#"); + edit.insert(token.text_range().end(), "#"); }); ctx.build() } pub(crate) fn remove_hash(mut ctx: AssistCtx) -> Option { - let literal = ctx.node_at_offset::()?; - if literal.token().kind() != ra_syntax::SyntaxKind::RAW_STRING { - return None; - } - let token = literal.token(); + let token = raw_string_token(&ctx)?; let text = token.text().as_str(); if text.starts_with("r\"") { // no hash to remove return None; } ctx.add_action(AssistId("remove_hash"), "remove hash from raw string", |edit| { - edit.target(literal.syntax().text_range()); + edit.target(token.text_range()); let result = &text[2..text.len() - 1]; let result = if result.starts_with("\"") { // no more hash, escape @@ -117,11 +86,34 @@ pub(crate) fn remove_hash(mut ctx: AssistCtx) -> Option) -> Option { + ctx.token_at_offset().right_biased().filter(|it| it.kind() == RAW_STRING) +} + +fn count_hashes(s: &str) -> usize { + let mut max_hash_streak = 0usize; + for idx in s.match_indices("\"#").map(|(i, _)| i) { + let (_, sub) = s.split_at(idx + 1); + let nb_hash = sub.chars().take_while(|c| *c == '#').count(); + if nb_hash > max_hash_streak { + max_hash_streak = nb_hash; + } + } + max_hash_streak +} + +fn find_usual_string_range(s: &str) -> Option { + Some(TextRange::from_to( + TextUnit::from(s.find('"')? as u32), + TextUnit::from(s.rfind('"')? as u32), + )) +} + #[cfg(test)] mod test { use super::*; @@ -158,6 +150,23 @@ string"#; ) } + #[test] + fn make_raw_string_works_inside_macros() { + check_assist( + make_raw_string, + r#" + fn f() { + format!(<|>"x = {}", 92) + } + "#, + r##" + fn f() { + format!(<|>r#"x = {}"#, 92) + } + "##, + ) + } + #[test] fn make_raw_string_hashes_inside_works() { check_assist( -- cgit v1.2.3 From 61349a3d18353ddfbd992a3bf51a88f5f0cfcddd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 27 Oct 2019 11:45:59 +0300 Subject: extract assist helper for getting a specific token --- crates/ra_assists/src/assists/flip_comma.rs | 2 +- crates/ra_assists/src/assists/raw_string.rs | 17 +++++------------ crates/ra_assists/src/assists/split_import.rs | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) (limited to 'crates/ra_assists/src/assists') diff --git a/crates/ra_assists/src/assists/flip_comma.rs b/crates/ra_assists/src/assists/flip_comma.rs index d06c5a0e1..53ba8011d 100644 --- a/crates/ra_assists/src/assists/flip_comma.rs +++ b/crates/ra_assists/src/assists/flip_comma.rs @@ -19,7 +19,7 @@ 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 comma = ctx.find_token_at_offset(T![,])?; let prev = non_trivia_sibling(comma.clone().into(), Direction::Prev)?; let next = non_trivia_sibling(comma.clone().into(), Direction::Next)?; diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs index 9c996c902..ea756d1ca 100644 --- a/crates/ra_assists/src/assists/raw_string.rs +++ b/crates/ra_assists/src/assists/raw_string.rs @@ -3,17 +3,14 @@ use hir::db::HirDatabase; use ra_syntax::{ SyntaxKind::{RAW_STRING, STRING}, - SyntaxToken, TextRange, TextUnit, + TextRange, TextUnit, }; use rustc_lexer; use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn make_raw_string(mut ctx: AssistCtx) -> Option { - let token = ctx.token_at_offset().right_biased()?; - if token.kind() != STRING { - return None; - } + let token = ctx.find_token_at_offset(STRING)?; let text = token.text().as_str(); let usual_string_range = find_usual_string_range(text)?; let start_of_inside = usual_string_range.start().to_usize() + 1; @@ -44,7 +41,7 @@ pub(crate) fn make_raw_string(mut ctx: AssistCtx) -> Option) -> Option { - let token = raw_string_token(&ctx)?; + let token = ctx.find_token_at_offset(RAW_STRING)?; let text = token.text().as_str(); let usual_string_range = find_usual_string_range(text)?; ctx.add_action(AssistId("make_usual_string"), "make usual string", |edit| { @@ -60,7 +57,7 @@ pub(crate) fn make_usual_string(mut ctx: AssistCtx) -> Option< } pub(crate) fn add_hash(mut ctx: AssistCtx) -> Option { - let token = raw_string_token(&ctx)?; + let token = ctx.find_token_at_offset(RAW_STRING)?; ctx.add_action(AssistId("add_hash"), "add hash to raw string", |edit| { edit.target(token.text_range()); edit.insert(token.text_range().start() + TextUnit::of_char('r'), "#"); @@ -70,7 +67,7 @@ pub(crate) fn add_hash(mut ctx: AssistCtx) -> Option { } pub(crate) fn remove_hash(mut ctx: AssistCtx) -> Option { - let token = raw_string_token(&ctx)?; + let token = ctx.find_token_at_offset(RAW_STRING)?; let text = token.text().as_str(); if text.starts_with("r\"") { // no hash to remove @@ -91,10 +88,6 @@ pub(crate) fn remove_hash(mut ctx: AssistCtx) -> Option) -> Option { - ctx.token_at_offset().right_biased().filter(|it| it.kind() == RAW_STRING) -} - fn count_hashes(s: &str) -> usize { let mut max_hash_streak = 0usize; for idx in s.match_indices("\"#").map(|(i, _)| i) { diff --git a/crates/ra_assists/src/assists/split_import.rs b/crates/ra_assists/src/assists/split_import.rs index fe3e64af5..09bde1b72 100644 --- a/crates/ra_assists/src/assists/split_import.rs +++ b/crates/ra_assists/src/assists/split_import.rs @@ -8,7 +8,7 @@ use ra_syntax::{ast, AstNode, TextUnit, T}; use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn split_import(mut ctx: AssistCtx) -> Option { - let colon_colon = ctx.token_at_offset().find(|leaf| leaf.kind() == T![::])?; + let colon_colon = ctx.find_token_at_offset(T![::])?; let path = ast::Path::cast(colon_colon.parent())?; let top_path = successors(Some(path), |it| it.parent_path()).last()?; -- cgit v1.2.3 From 8118dc1bb9bc63670f72965e5115daa96e8c72fd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 27 Oct 2019 11:48:40 +0300 Subject: use more consistent naming I think this is the first time I use global rename for rust-analyzer itself :-) --- crates/ra_assists/src/assists/add_derive.rs | 2 +- crates/ra_assists/src/assists/add_explicit_type.rs | 2 +- crates/ra_assists/src/assists/add_impl.rs | 2 +- crates/ra_assists/src/assists/add_missing_impl_members.rs | 2 +- crates/ra_assists/src/assists/apply_demorgan.rs | 2 +- crates/ra_assists/src/assists/auto_import.rs | 2 +- crates/ra_assists/src/assists/change_visibility.rs | 2 +- crates/ra_assists/src/assists/early_return.rs | 2 +- crates/ra_assists/src/assists/fill_match_arms.rs | 2 +- crates/ra_assists/src/assists/flip_binexpr.rs | 2 +- crates/ra_assists/src/assists/inline_local_variable.rs | 2 +- crates/ra_assists/src/assists/merge_match_arms.rs | 2 +- crates/ra_assists/src/assists/move_bounds.rs | 2 +- crates/ra_assists/src/assists/move_guard.rs | 4 ++-- crates/ra_assists/src/assists/remove_dbg.rs | 2 +- crates/ra_assists/src/assists/replace_if_let_with_match.rs | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) (limited to 'crates/ra_assists/src/assists') diff --git a/crates/ra_assists/src/assists/add_derive.rs b/crates/ra_assists/src/assists/add_derive.rs index b077acb81..d1e925b71 100644 --- a/crates/ra_assists/src/assists/add_derive.rs +++ b/crates/ra_assists/src/assists/add_derive.rs @@ -26,7 +26,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn add_derive(mut ctx: AssistCtx) -> Option { - let nominal = ctx.node_at_offset::()?; + let nominal = ctx.find_node_at_offset::()?; let node_start = derive_insertion_offset(&nominal)?; ctx.add_action(AssistId("add_derive"), "add `#[derive]`", |edit| { let derive_attr = nominal diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs index 2903c1781..ffbdc0b62 100644 --- a/crates/ra_assists/src/assists/add_explicit_type.rs +++ b/crates/ra_assists/src/assists/add_explicit_type.rs @@ -22,7 +22,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn add_explicit_type(mut ctx: AssistCtx) -> Option { - let stmt = ctx.node_at_offset::()?; + let stmt = ctx.find_node_at_offset::()?; let expr = stmt.initializer()?; let pat = stmt.pat()?; // Must be a binding diff --git a/crates/ra_assists/src/assists/add_impl.rs b/crates/ra_assists/src/assists/add_impl.rs index 142777b06..fd3588d24 100644 --- a/crates/ra_assists/src/assists/add_impl.rs +++ b/crates/ra_assists/src/assists/add_impl.rs @@ -28,7 +28,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn add_impl(mut ctx: AssistCtx) -> Option { - let nominal = ctx.node_at_offset::()?; + let nominal = ctx.find_node_at_offset::()?; let name = nominal.name()?; ctx.add_action(AssistId("add_impl"), "add impl", |edit| { edit.target(nominal.syntax().text_range()); diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs index 4ee4d47fa..2585f3045 100644 --- a/crates/ra_assists/src/assists/add_missing_impl_members.rs +++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs @@ -96,7 +96,7 @@ fn add_missing_impl_members_inner( assist_id: &'static str, label: &'static str, ) -> Option { - let impl_node = ctx.node_at_offset::()?; + let impl_node = ctx.find_node_at_offset::()?; let impl_item_list = impl_node.item_list()?; let trait_def = { diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs index 75144cefe..8d5984a58 100644 --- a/crates/ra_assists/src/assists/apply_demorgan.rs +++ b/crates/ra_assists/src/assists/apply_demorgan.rs @@ -24,7 +24,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn apply_demorgan(mut ctx: AssistCtx) -> Option { - let expr = ctx.node_at_offset::()?; + let expr = ctx.find_node_at_offset::()?; let op = expr.op_kind()?; let op_range = expr.op_token()?.text_range(); let opposite_op = opposite_logic_op(op)?; diff --git a/crates/ra_assists/src/assists/auto_import.rs b/crates/ra_assists/src/assists/auto_import.rs index 02c58e7c6..a1c2aaa72 100644 --- a/crates/ra_assists/src/assists/auto_import.rs +++ b/crates/ra_assists/src/assists/auto_import.rs @@ -547,7 +547,7 @@ pub fn auto_import_text_edit( } pub(crate) fn auto_import(mut ctx: AssistCtx) -> Option { - let path: ast::Path = ctx.node_at_offset()?; + let path: ast::Path = ctx.find_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; diff --git a/crates/ra_assists/src/assists/change_visibility.rs b/crates/ra_assists/src/assists/change_visibility.rs index bed343677..770ea04fa 100644 --- a/crates/ra_assists/src/assists/change_visibility.rs +++ b/crates/ra_assists/src/assists/change_visibility.rs @@ -23,7 +23,7 @@ use crate::{Assist, AssistCtx, AssistId}; // pub(crate) fn frobnicate() {} // ``` pub(crate) fn change_visibility(ctx: AssistCtx) -> Option { - if let Some(vis) = ctx.node_at_offset::() { + if let Some(vis) = ctx.find_node_at_offset::() { return change_vis(ctx, vis); } add_vis(ctx) diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs index 48782db42..75822dc65 100644 --- a/crates/ra_assists/src/assists/early_return.rs +++ b/crates/ra_assists/src/assists/early_return.rs @@ -36,7 +36,7 @@ use crate::{ // } // ``` pub(crate) fn convert_to_guarded_return(mut ctx: AssistCtx) -> Option { - let if_expr: ast::IfExpr = ctx.node_at_offset()?; + let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; let expr = if_expr.condition()?.expr()?; let then_block = if_expr.then_branch()?.block()?; if if_expr.else_branch().is_some() { diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index b6166f947..c62c0efbe 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs @@ -32,7 +32,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn fill_match_arms(mut ctx: AssistCtx) -> Option { - let match_expr = ctx.node_at_offset::()?; + let match_expr = ctx.find_node_at_offset::()?; let match_arm_list = match_expr.match_arm_list()?; // We already have some match arms, so we don't provide any assists. diff --git a/crates/ra_assists/src/assists/flip_binexpr.rs b/crates/ra_assists/src/assists/flip_binexpr.rs index 3a1e5cbe1..9765d5ddd 100644 --- a/crates/ra_assists/src/assists/flip_binexpr.rs +++ b/crates/ra_assists/src/assists/flip_binexpr.rs @@ -19,7 +19,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn flip_binexpr(mut ctx: AssistCtx) -> Option { - let expr = ctx.node_at_offset::()?; + let expr = ctx.find_node_at_offset::()?; let lhs = expr.lhs()?.syntax().clone(); let rhs = expr.rhs()?.syntax().clone(); let op_range = expr.op_token()?.text_range(); diff --git a/crates/ra_assists/src/assists/inline_local_variable.rs b/crates/ra_assists/src/assists/inline_local_variable.rs index 1997781db..fe8fa2a86 100644 --- a/crates/ra_assists/src/assists/inline_local_variable.rs +++ b/crates/ra_assists/src/assists/inline_local_variable.rs @@ -24,7 +24,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn inline_local_varialbe(mut ctx: AssistCtx) -> Option { - let let_stmt = ctx.node_at_offset::()?; + let let_stmt = ctx.find_node_at_offset::()?; let bind_pat = match let_stmt.pat()? { ast::Pat::BindPat(pat) => pat, _ => return None, diff --git a/crates/ra_assists/src/assists/merge_match_arms.rs b/crates/ra_assists/src/assists/merge_match_arms.rs index f5ddd7159..b0c4ee78b 100644 --- a/crates/ra_assists/src/assists/merge_match_arms.rs +++ b/crates/ra_assists/src/assists/merge_match_arms.rs @@ -27,7 +27,7 @@ use ra_syntax::ast::{AstNode, MatchArm}; // } // ``` pub(crate) fn merge_match_arms(mut ctx: AssistCtx) -> Option { - let current_arm = ctx.node_at_offset::()?; + let current_arm = ctx.find_node_at_offset::()?; // We check if the following match arm matches this one. We could, but don't, // compare to the previous match arm as well. diff --git a/crates/ra_assists/src/assists/move_bounds.rs b/crates/ra_assists/src/assists/move_bounds.rs index f96e19a9f..edf2897c6 100644 --- a/crates/ra_assists/src/assists/move_bounds.rs +++ b/crates/ra_assists/src/assists/move_bounds.rs @@ -23,7 +23,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn move_bounds_to_where_clause(mut ctx: AssistCtx) -> Option { - let type_param_list = ctx.node_at_offset::()?; + let type_param_list = ctx.find_node_at_offset::()?; let mut type_params = type_param_list.type_params(); if type_params.all(|p| p.type_bound_list().is_none()) { diff --git a/crates/ra_assists/src/assists/move_guard.rs b/crates/ra_assists/src/assists/move_guard.rs index 36c95128d..e820a73c8 100644 --- a/crates/ra_assists/src/assists/move_guard.rs +++ b/crates/ra_assists/src/assists/move_guard.rs @@ -33,7 +33,7 @@ use crate::{Assist, AssistCtx, AssistId}; // } // ``` pub(crate) fn move_guard_to_arm_body(mut ctx: AssistCtx) -> Option { - let match_arm = ctx.node_at_offset::()?; + let match_arm = ctx.find_node_at_offset::()?; let guard = match_arm.guard()?; let space_before_guard = guard.syntax().prev_sibling_or_token(); @@ -91,7 +91,7 @@ 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.find_node_at_offset::()?; let last_match_pat = match_arm.pats().last()?; let arm_body = match_arm.expr()?; diff --git a/crates/ra_assists/src/assists/remove_dbg.rs b/crates/ra_assists/src/assists/remove_dbg.rs index 1a7e2b305..ac2c43e1a 100644 --- a/crates/ra_assists/src/assists/remove_dbg.rs +++ b/crates/ra_assists/src/assists/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::()?; + let macro_call = ctx.find_node_at_offset::()?; if !is_valid_macrocall(¯o_call, "dbg")? { return None; diff --git a/crates/ra_assists/src/assists/replace_if_let_with_match.rs b/crates/ra_assists/src/assists/replace_if_let_with_match.rs index 749ff338a..da276e47b 100644 --- a/crates/ra_assists/src/assists/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/assists/replace_if_let_with_match.rs @@ -8,7 +8,7 @@ use ra_syntax::{ast, AstNode}; use crate::{Assist, AssistCtx, AssistId}; pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx) -> Option { - let if_expr: ast::IfExpr = ctx.node_at_offset()?; + let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; let cond = if_expr.condition()?; let pat = cond.pat()?; let expr = cond.expr()?; -- cgit v1.2.3