aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/Cargo.toml2
-rw-r--r--crates/ra_assists/src/introduce_variable.rs80
-rw-r--r--crates/ra_assists/src/lib.rs1
-rw-r--r--crates/ra_assists/src/marks.rs5
4 files changed, 41 insertions, 47 deletions
diff --git a/crates/ra_assists/Cargo.toml b/crates/ra_assists/Cargo.toml
index 880bc4b18..d4056a349 100644
--- a/crates/ra_assists/Cargo.toml
+++ b/crates/ra_assists/Cargo.toml
@@ -13,6 +13,4 @@ ra_text_edit = { path = "../ra_text_edit" }
13ra_fmt = { path = "../ra_fmt" } 13ra_fmt = { path = "../ra_fmt" }
14ra_db = { path = "../ra_db" } 14ra_db = { path = "../ra_db" }
15hir = { path = "../ra_hir", package = "ra_hir" } 15hir = { path = "../ra_hir", package = "ra_hir" }
16
17[dev-dependencies]
18test_utils = { path = "../test_utils" } 16test_utils = { path = "../test_utils" }
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs
index 3fab29e29..353bc4105 100644
--- a/crates/ra_assists/src/introduce_variable.rs
+++ b/crates/ra_assists/src/introduce_variable.rs
@@ -1,3 +1,4 @@
1use test_utils::tested_by;
1use hir::db::HirDatabase; 2use hir::db::HirDatabase;
2use ra_syntax::{ 3use ra_syntax::{
3 ast::{self, AstNode}, 4 ast::{self, AstNode},
@@ -13,10 +14,11 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option
13 return None; 14 return None;
14 } 15 }
15 let node = ctx.covering_node(); 16 let node = ctx.covering_node();
16 if !valid_covering_node(node) { 17 if node.kind() == COMMENT {
18 tested_by!(introduce_var_in_comment_is_not_applicable);
17 return None; 19 return None;
18 } 20 }
19 let expr = node.ancestors().filter_map(valid_target_expr).next()?; 21 let expr = node.ancestors().find_map(valid_target_expr)?;
20 let (anchor_stmt, wrap_in_block) = anchor_stmt(expr)?; 22 let (anchor_stmt, wrap_in_block) = anchor_stmt(expr)?;
21 let indent = anchor_stmt.prev_sibling()?; 23 let indent = anchor_stmt.prev_sibling()?;
22 if indent.kind() != WHITESPACE { 24 if indent.kind() != WHITESPACE {
@@ -41,6 +43,7 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option
41 false 43 false
42 }; 44 };
43 if is_full_stmt { 45 if is_full_stmt {
46 tested_by!(test_introduce_var_expr_stmt);
44 if !full_stmt.unwrap().has_semi() { 47 if !full_stmt.unwrap().has_semi() {
45 buf.push_str(";"); 48 buf.push_str(";");
46 } 49 }
@@ -76,9 +79,6 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option
76 ctx.build() 79 ctx.build()
77} 80}
78 81
79fn valid_covering_node(node: &SyntaxNode) -> bool {
80 node.kind() != COMMENT
81}
82/// Check whether the node is a valid expression which can be extracted to a variable. 82/// Check whether the node is a valid expression which can be extracted to a variable.
83/// In general that's true for any expression, but in some cases that would produce invalid code. 83/// In general that's true for any expression, but in some cases that would produce invalid code.
84fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> { 84fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> {
@@ -104,6 +104,7 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> {
104 104
105 if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { 105 if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) {
106 if expr.syntax() == node { 106 if expr.syntax() == node {
107 tested_by!(test_introduce_var_last_expr);
107 return Some((node, false)); 108 return Some((node, false));
108 } 109 }
109 } 110 }
@@ -120,9 +121,12 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> {
120 121
121#[cfg(test)] 122#[cfg(test)]
122mod tests { 123mod tests {
123 use super::*; 124 use test_utils::covers;
125
124 use crate::helpers::{check_assist_range_not_applicable, check_assist_range, check_assist_range_target}; 126 use crate::helpers::{check_assist_range_not_applicable, check_assist_range, check_assist_range_target};
125 127
128 use super::*;
129
126 #[test] 130 #[test]
127 fn test_introduce_var_simple() { 131 fn test_introduce_var_simple() {
128 check_assist_range( 132 check_assist_range(
@@ -140,7 +144,17 @@ fn foo() {
140 } 144 }
141 145
142 #[test] 146 #[test]
147 fn introduce_var_in_comment_is_not_applicable() {
148 covers!(introduce_var_in_comment_is_not_applicable);
149 check_assist_range_not_applicable(
150 introduce_variable,
151 "fn main() { 1 + /* <|>comment<|> */ 1; }",
152 );
153 }
154
155 #[test]
143 fn test_introduce_var_expr_stmt() { 156 fn test_introduce_var_expr_stmt() {
157 covers!(test_introduce_var_expr_stmt);
144 check_assist_range( 158 check_assist_range(
145 introduce_variable, 159 introduce_variable,
146 " 160 "
@@ -152,6 +166,19 @@ fn foo() {
152 let <|>var_name = 1 + 1; 166 let <|>var_name = 1 + 1;
153}", 167}",
154 ); 168 );
169 check_assist_range(
170 introduce_variable,
171 "
172fn foo() {
173 <|>{ let x = 0; x }<|>
174 something_else();
175}",
176 "
177fn foo() {
178 let <|>var_name = { let x = 0; x };
179 something_else();
180}",
181 );
155 } 182 }
156 183
157 #[test] 184 #[test]
@@ -172,6 +199,7 @@ fn foo() {
172 199
173 #[test] 200 #[test]
174 fn test_introduce_var_last_expr() { 201 fn test_introduce_var_last_expr() {
202 covers!(test_introduce_var_last_expr);
175 check_assist_range( 203 check_assist_range(
176 introduce_variable, 204 introduce_variable,
177 " 205 "
@@ -184,10 +212,6 @@ fn foo() {
184 bar(var_name) 212 bar(var_name)
185}", 213}",
186 ); 214 );
187 }
188
189 #[test]
190 fn test_introduce_var_last_full_expr() {
191 check_assist_range( 215 check_assist_range(
192 introduce_variable, 216 introduce_variable,
193 " 217 "
@@ -199,24 +223,7 @@ fn foo() {
199 let <|>var_name = bar(1 + 1); 223 let <|>var_name = bar(1 + 1);
200 var_name 224 var_name
201}", 225}",
202 ); 226 )
203 }
204
205 #[test]
206 fn test_introduce_var_block_expr_second_to_last() {
207 check_assist_range(
208 introduce_variable,
209 "
210fn foo() {
211 <|>{ let x = 0; x }<|>
212 something_else();
213}",
214 "
215fn foo() {
216 let <|>var_name = { let x = 0; x };
217 something_else();
218}",
219 );
220 } 227 }
221 228
222 #[test] 229 #[test]
@@ -481,23 +488,6 @@ fn main() {
481 ); 488 );
482 } 489 }
483 490
484 #[test]
485 fn test_introduce_var_in_comment_not_applicable() {
486 check_assist_range_not_applicable(
487 introduce_variable,
488 "
489fn main() {
490 let x = true;
491 let tuple = match x {
492 // <|>comment<|>
493 true => (2 + 2, true)
494 _ => (0, false)
495 };
496}
497",
498 );
499 }
500
501 // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic 491 // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic
502 #[test] 492 #[test]
503 fn introduce_var_target() { 493 fn introduce_var_target() {
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 8e161dd37..6c3d75d79 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -6,6 +6,7 @@
6//! becomes available. 6//! becomes available.
7 7
8mod assist_ctx; 8mod assist_ctx;
9mod marks;
9 10
10use itertools::Itertools; 11use itertools::Itertools;
11 12
diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs
new file mode 100644
index 000000000..a29f9f658
--- /dev/null
+++ b/crates/ra_assists/src/marks.rs
@@ -0,0 +1,5 @@
1test_utils::marks!(
2 introduce_var_in_comment_is_not_applicable
3 test_introduce_var_expr_stmt
4 test_introduce_var_last_expr
5);