diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/utils/insert_use.rs | 51 |
1 files changed, 15 insertions, 36 deletions
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs index 5d726370a..af3fc96b6 100644 --- a/crates/assists/src/utils/insert_use.rs +++ b/crates/assists/src/utils/insert_use.rs | |||
@@ -63,47 +63,26 @@ impl ImportScope { | |||
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | fn insert_pos_after_inner_elements(&self) -> (InsertPosition<SyntaxElement>, AddBlankLine) { | 66 | fn insert_pos_after_last_inner_element(&self) -> (InsertPosition<SyntaxElement>, AddBlankLine) { |
67 | let mut last_inner_element = None; | 67 | self.as_syntax_node() |
68 | 68 | .children_with_tokens() | |
69 | for maybe_inner_element in self.as_syntax_node().children_with_tokens() { | 69 | .filter(|child| match child { |
70 | match maybe_inner_element { | 70 | NodeOrToken::Node(node) => is_inner_attribute(node.clone()), |
71 | NodeOrToken::Node(maybe_inner_node) => { | 71 | NodeOrToken::Token(token) => is_inner_comment(token.clone()), |
72 | if is_inner_node(maybe_inner_node.clone()) { | 72 | }) |
73 | last_inner_element = Some(NodeOrToken::Node(maybe_inner_node)) | 73 | .last() |
74 | } else { | 74 | .map(|last_inner_element| { |
75 | // FIXME: https://doc.rust-lang.org/reference/comments.html#doc-comments | 75 | (InsertPosition::After(last_inner_element.into()), AddBlankLine::BeforeTwice) |
76 | // states that inner comments (`//!` and `/*!`) are equal to inner attribute `#![doc="..."]` | 76 | }) |
77 | // yet RA treats them differently now: inner attributes never belong to child nodes, | 77 | .unwrap_or_else(|| self.first_insert_pos()) |
78 | // but inner comments can, ergo this check. | ||
79 | // We need to align this and treat both cases the same way. | ||
80 | if let Some(maybe_inner_token) = maybe_inner_node.first_token() { | ||
81 | if is_inner_token(maybe_inner_token.clone()) { | ||
82 | last_inner_element = Some(NodeOrToken::Token(maybe_inner_token)) | ||
83 | } | ||
84 | } | ||
85 | }; | ||
86 | } | ||
87 | NodeOrToken::Token(maybe_inner_token) => { | ||
88 | if is_inner_token(maybe_inner_token.clone()) { | ||
89 | last_inner_element = Some(NodeOrToken::Token(maybe_inner_token)) | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | match last_inner_element { | ||
96 | Some(element) => (InsertPosition::After(element.into()), AddBlankLine::BeforeTwice), | ||
97 | None => self.first_insert_pos(), | ||
98 | } | ||
99 | } | 78 | } |
100 | } | 79 | } |
101 | 80 | ||
102 | fn is_inner_node(node: SyntaxNode) -> bool { | 81 | fn is_inner_attribute(node: SyntaxNode) -> bool { |
103 | ast::Attr::cast(node).map(|attr| attr.kind()) == Some(ast::AttrKind::Inner) | 82 | ast::Attr::cast(node).map(|attr| attr.kind()) == Some(ast::AttrKind::Inner) |
104 | } | 83 | } |
105 | 84 | ||
106 | fn is_inner_token(token: SyntaxToken) -> bool { | 85 | fn is_inner_comment(token: SyntaxToken) -> bool { |
107 | ast::Comment::cast(token).and_then(|comment| comment.kind().doc) | 86 | ast::Comment::cast(token).and_then(|comment| comment.kind().doc) |
108 | == Some(ast::CommentPlacement::Inner) | 87 | == Some(ast::CommentPlacement::Inner) |
109 | } | 88 | } |
@@ -582,7 +561,7 @@ fn find_insert_position( | |||
582 | (InsertPosition::After(node.into()), AddBlankLine::BeforeTwice) | 561 | (InsertPosition::After(node.into()), AddBlankLine::BeforeTwice) |
583 | } | 562 | } |
584 | // there are no imports in this file at all | 563 | // there are no imports in this file at all |
585 | None => scope.insert_pos_after_inner_elements(), | 564 | None => scope.insert_pos_after_last_inner_element(), |
586 | }, | 565 | }, |
587 | } | 566 | } |
588 | } | 567 | } |