aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-02-07 17:38:12 +0000
committerLukas Wirth <[email protected]>2021-02-12 17:58:28 +0000
commitd644728d82df10b034d0ea736590c781afa2ba15 (patch)
tree4591c44955de42387165e7a59789d7e636284bc6 /crates/assists/src
parent43ccbf4360271d5da2fd3688a04b34c66357e0b6 (diff)
Refactor reference searching to work with the ast
Diffstat (limited to 'crates/assists/src')
-rw-r--r--crates/assists/src/handlers/inline_local_variable.rs110
1 files changed, 60 insertions, 50 deletions
diff --git a/crates/assists/src/handlers/inline_local_variable.rs b/crates/assists/src/handlers/inline_local_variable.rs
index 0e63a60e8..e4f984713 100644
--- a/crates/assists/src/handlers/inline_local_variable.rs
+++ b/crates/assists/src/handlers/inline_local_variable.rs
@@ -1,7 +1,6 @@
1use ide_db::{ 1use std::collections::HashMap;
2 defs::Definition, 2
3 search::{FileReference, ReferenceKind}, 3use ide_db::{defs::Definition, search::FileReference};
4};
5use syntax::{ 4use syntax::{
6 ast::{self, AstNode, AstToken}, 5 ast::{self, AstNode, AstToken},
7 TextRange, 6 TextRange,
@@ -68,44 +67,51 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
68 67
69 let wrap_in_parens = usages 68 let wrap_in_parens = usages
70 .references 69 .references
71 .values() 70 .iter()
72 .flatten() 71 .map(|(&file_id, refs)| {
73 .map(|&FileReference { range, .. }| { 72 refs.iter()
74 let usage_node = 73 .map(|&FileReference { range, .. }| {
75 ctx.covering_node_for_range(range).ancestors().find_map(ast::PathExpr::cast)?; 74 let usage_node = ctx
76 let usage_parent_option = usage_node.syntax().parent().and_then(ast::Expr::cast); 75 .covering_node_for_range(range)
77 let usage_parent = match usage_parent_option { 76 .ancestors()
78 Some(u) => u, 77 .find_map(ast::PathExpr::cast)?;
79 None => return Ok(false), 78 let usage_parent_option =
80 }; 79 usage_node.syntax().parent().and_then(ast::Expr::cast);
81 80 let usage_parent = match usage_parent_option {
82 Ok(!matches!( 81 Some(u) => u,
83 (&initializer_expr, usage_parent), 82 None => return Ok(false),
84 (ast::Expr::CallExpr(_), _) 83 };
85 | (ast::Expr::IndexExpr(_), _) 84
86 | (ast::Expr::MethodCallExpr(_), _) 85 Ok(!matches!(
87 | (ast::Expr::FieldExpr(_), _) 86 (&initializer_expr, usage_parent),
88 | (ast::Expr::TryExpr(_), _) 87 (ast::Expr::CallExpr(_), _)
89 | (ast::Expr::RefExpr(_), _) 88 | (ast::Expr::IndexExpr(_), _)
90 | (ast::Expr::Literal(_), _) 89 | (ast::Expr::MethodCallExpr(_), _)
91 | (ast::Expr::TupleExpr(_), _) 90 | (ast::Expr::FieldExpr(_), _)
92 | (ast::Expr::ArrayExpr(_), _) 91 | (ast::Expr::TryExpr(_), _)
93 | (ast::Expr::ParenExpr(_), _) 92 | (ast::Expr::RefExpr(_), _)
94 | (ast::Expr::PathExpr(_), _) 93 | (ast::Expr::Literal(_), _)
95 | (ast::Expr::BlockExpr(_), _) 94 | (ast::Expr::TupleExpr(_), _)
96 | (ast::Expr::EffectExpr(_), _) 95 | (ast::Expr::ArrayExpr(_), _)
97 | (_, ast::Expr::CallExpr(_)) 96 | (ast::Expr::ParenExpr(_), _)
98 | (_, ast::Expr::TupleExpr(_)) 97 | (ast::Expr::PathExpr(_), _)
99 | (_, ast::Expr::ArrayExpr(_)) 98 | (ast::Expr::BlockExpr(_), _)
100 | (_, ast::Expr::ParenExpr(_)) 99 | (ast::Expr::EffectExpr(_), _)
101 | (_, ast::Expr::ForExpr(_)) 100 | (_, ast::Expr::CallExpr(_))
102 | (_, ast::Expr::WhileExpr(_)) 101 | (_, ast::Expr::TupleExpr(_))
103 | (_, ast::Expr::BreakExpr(_)) 102 | (_, ast::Expr::ArrayExpr(_))
104 | (_, ast::Expr::ReturnExpr(_)) 103 | (_, ast::Expr::ParenExpr(_))
105 | (_, ast::Expr::MatchExpr(_)) 104 | (_, ast::Expr::ForExpr(_))
106 )) 105 | (_, ast::Expr::WhileExpr(_))
106 | (_, ast::Expr::BreakExpr(_))
107 | (_, ast::Expr::ReturnExpr(_))
108 | (_, ast::Expr::MatchExpr(_))
109 ))
110 })
111 .collect::<Result<_, _>>()
112 .map(|b| (file_id, b))
107 }) 113 })
108 .collect::<Result<Vec<_>, _>>()?; 114 .collect::<Result<HashMap<_, Vec<_>>, _>>()?;
109 115
110 let init_str = initializer_expr.syntax().text().to_string(); 116 let init_str = initializer_expr.syntax().text().to_string();
111 let init_in_paren = format!("({})", &init_str); 117 let init_in_paren = format!("({})", &init_str);
@@ -117,16 +123,20 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
117 target, 123 target,
118 move |builder| { 124 move |builder| {
119 builder.delete(delete_range); 125 builder.delete(delete_range);
120 for (reference, should_wrap) in usages.references.values().flatten().zip(wrap_in_parens) 126 for (file_id, references) in usages.references {
121 { 127 let root = ctx.sema.parse(file_id);
122 let replacement = 128 for (&should_wrap, reference) in wrap_in_parens[&file_id].iter().zip(references) {
123 if should_wrap { init_in_paren.clone() } else { init_str.clone() }; 129 let replacement =
124 match reference.kind { 130 if should_wrap { init_in_paren.clone() } else { init_str.clone() };
125 ReferenceKind::FieldShorthandForLocal => { 131 match &reference.as_name_ref(root.syntax()) {
126 mark::hit!(inline_field_shorthand); 132 Some(name_ref)
127 builder.insert(reference.range.end(), format!(": {}", replacement)) 133 if ast::RecordExprField::for_field_name(name_ref).is_some() =>
134 {
135 mark::hit!(inline_field_shorthand);
136 builder.insert(reference.range.end(), format!(": {}", replacement));
137 }
138 _ => builder.replace(reference.range, replacement),
128 } 139 }
129 _ => builder.replace(reference.range, replacement),
130 } 140 }
131 } 141 }
132 }, 142 },