aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/utils.rs2
-rw-r--r--crates/assists/src/utils/insert_use.rs33
-rw-r--r--crates/syntax/src/ast/make.rs12
3 files changed, 20 insertions, 27 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index daa7b64f7..07afa64ff 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -16,7 +16,7 @@ use syntax::{
16 16
17use crate::assist_config::SnippetCap; 17use crate::assist_config::SnippetCap;
18 18
19pub(crate) use insert_use::{find_insert_use_container, insert_use_statement}; 19pub(crate) use insert_use::{find_insert_use_container, insert_use, MergeBehaviour};
20 20
21pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { 21pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
22 extract_trivial_expression(&block) 22 extract_trivial_expression(&block)
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index 8842068e6..030a5a935 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -9,13 +9,12 @@ use syntax::{
9 Direction, InsertPosition, SyntaxElement, SyntaxNode, T, 9 Direction, InsertPosition, SyntaxElement, SyntaxNode, T,
10}; 10};
11 11
12use crate::assist_context::AssistContext;
13use test_utils::mark; 12use test_utils::mark;
14 13
15/// Determines the containing syntax node in which to insert a `use` statement affecting `position`. 14/// Determines the containing syntax node in which to insert a `use` statement affecting `position`.
16pub(crate) fn find_insert_use_container( 15pub(crate) fn find_insert_use_container(
17 position: &SyntaxNode, 16 position: &SyntaxNode,
18 ctx: &AssistContext, 17 ctx: &crate::assist_context::AssistContext,
19) -> Option<Either<ast::ItemList, ast::SourceFile>> { 18) -> Option<Either<ast::ItemList, ast::SourceFile>> {
20 ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { 19 ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| {
21 if let Some(module) = ast::Module::cast(n.clone()) { 20 if let Some(module) = ast::Module::cast(n.clone()) {
@@ -25,19 +24,9 @@ pub(crate) fn find_insert_use_container(
25 }) 24 })
26} 25}
27 26
28pub(crate) fn insert_use_statement(
29 // Ideally the position of the cursor, used to
30 position: &SyntaxNode,
31 path_to_import: &str,
32 ctx: &crate::assist_context::AssistContext,
33 builder: &mut text_edit::TextEditBuilder,
34) {
35 insert_use(position.clone(), make::path_from_text(path_to_import), Some(MergeBehaviour::Full));
36}
37
38/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur. 27/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
39pub fn insert_use( 28pub fn insert_use(
40 where_: SyntaxNode, 29 where_: &SyntaxNode,
41 path: ast::Path, 30 path: ast::Path,
42 merge: Option<MergeBehaviour>, 31 merge: Option<MergeBehaviour>,
43) -> SyntaxNode { 32) -> SyntaxNode {
@@ -49,24 +38,21 @@ pub fn insert_use(
49 let to_delete: SyntaxElement = existing_use.syntax().clone().into(); 38 let to_delete: SyntaxElement = existing_use.syntax().clone().into();
50 let to_delete = to_delete.clone()..=to_delete; 39 let to_delete = to_delete.clone()..=to_delete;
51 let to_insert = iter::once(merged.syntax().clone().into()); 40 let to_insert = iter::once(merged.syntax().clone().into());
52 return algo::replace_children(&where_, to_delete, to_insert); 41 return algo::replace_children(where_, to_delete, to_insert);
53 } 42 }
54 } 43 }
55 } 44 }
56 45
57 // either we weren't allowed to merge or there is no import that fits the merge conditions 46 // either we weren't allowed to merge or there is no import that fits the merge conditions
58 // so look for the place we have to insert to 47 // so look for the place we have to insert to
59 let (insert_position, add_blank) = find_insert_position(&where_, path); 48 let (insert_position, add_blank) = find_insert_position(where_, path);
60 49
61 let to_insert: Vec<SyntaxElement> = { 50 let to_insert: Vec<SyntaxElement> = {
62 let mut buf = Vec::new(); 51 let mut buf = Vec::new();
63 52
64 match add_blank { 53 match add_blank {
65 AddBlankLine::Before => buf.push(make::tokens::single_newline().into()), 54 AddBlankLine::Before => buf.push(make::tokens::single_newline().into()),
66 AddBlankLine::BeforeTwice => { 55 AddBlankLine::BeforeTwice => buf.push(make::tokens::blank_line().into()),
67 buf.push(make::tokens::single_newline().into());
68 buf.push(make::tokens::single_newline().into());
69 }
70 _ => (), 56 _ => (),
71 } 57 }
72 58
@@ -74,17 +60,14 @@ pub fn insert_use(
74 60
75 match add_blank { 61 match add_blank {
76 AddBlankLine::After => buf.push(make::tokens::single_newline().into()), 62 AddBlankLine::After => buf.push(make::tokens::single_newline().into()),
77 AddBlankLine::AfterTwice => { 63 AddBlankLine::AfterTwice => buf.push(make::tokens::blank_line().into()),
78 buf.push(make::tokens::single_newline().into());
79 buf.push(make::tokens::single_newline().into());
80 }
81 _ => (), 64 _ => (),
82 } 65 }
83 66
84 buf 67 buf
85 }; 68 };
86 69
87 algo::insert_children(&where_, insert_position, to_insert) 70 algo::insert_children(where_, insert_position, to_insert)
88} 71}
89 72
90fn try_merge_imports( 73fn try_merge_imports(
@@ -613,7 +596,7 @@ use foo::bar;",
613 .find_map(ast::Path::cast) 596 .find_map(ast::Path::cast)
614 .unwrap(); 597 .unwrap();
615 598
616 let result = insert_use(file, path, mb).to_string(); 599 let result = insert_use(&file, path, mb).to_string();
617 assert_eq_text!(&result, ra_fixture_after); 600 assert_eq_text!(&result, ra_fixture_after);
618 } 601 }
619 602
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index c2c938ad1..33f1ad7b3 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -339,7 +339,7 @@ pub mod tokens {
339 use crate::{ast, AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken}; 339 use crate::{ast, AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken};
340 340
341 pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = 341 pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> =
342 Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2, !true)\n;")); 342 Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2, !true)\n;\n\n"));
343 343
344 pub fn single_space() -> SyntaxToken { 344 pub fn single_space() -> SyntaxToken {
345 SOURCE_FILE 345 SOURCE_FILE
@@ -379,6 +379,16 @@ pub mod tokens {
379 .unwrap() 379 .unwrap()
380 } 380 }
381 381
382 pub fn blank_line() -> SyntaxToken {
383 SOURCE_FILE
384 .tree()
385 .syntax()
386 .descendants_with_tokens()
387 .filter_map(|it| it.into_token())
388 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n\n")
389 .unwrap()
390 }
391
382 pub struct WsBuilder(SourceFile); 392 pub struct WsBuilder(SourceFile);
383 393
384 impl WsBuilder { 394 impl WsBuilder {