aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-04-20 15:34:01 +0100
committerAleksey Kladov <[email protected]>2020-04-20 15:34:01 +0100
commit8a04372fec5f26a0650395a1e420fea062b3a7ab (patch)
treeede61469d8f4e180f0cfa7cbe00d889737d45551 /crates/ra_syntax/src
parent90f837829d4f2c1054751de2de695ba1c0b8ae5c (diff)
Fix panic in split_imports assist
The fix is admittedly quit literally just papering over. Long-term, I see two more principled approaches: * we switch to a fully tree-based impl, without parse . to_string step; with this approach, there shouldn't be any panics. The results might be nonsensical, but so was the original input. * we preserve the invariant that re-parsing constructed node is an identity, and make all the `make_xxx` method return an `Option`. closes #4044
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/algo.rs8
-rw-r--r--crates/ra_syntax/src/ast/edit.rs6
2 files changed, 11 insertions, 3 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index ea41bf85d..06df8495c 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -10,8 +10,8 @@ use ra_text_edit::TextEditBuilder;
10use rustc_hash::FxHashMap; 10use rustc_hash::FxHashMap;
11 11
12use crate::{ 12use crate::{
13 AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, 13 AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
14 TextRange, TextUnit, 14 SyntaxToken, TextRange, TextUnit,
15}; 15};
16 16
17/// Returns ancestors of the node at the offset, sorted by length. This should 17/// Returns ancestors of the node at the offset, sorted by length. This should
@@ -90,6 +90,10 @@ pub fn neighbor<T: AstNode>(me: &T, direction: Direction) -> Option<T> {
90 me.syntax().siblings(direction).skip(1).find_map(T::cast) 90 me.syntax().siblings(direction).skip(1).find_map(T::cast)
91} 91}
92 92
93pub fn has_errors(node: &SyntaxNode) -> bool {
94 node.children().any(|it| it.kind() == SyntaxKind::ERROR)
95}
96
93#[derive(Debug, PartialEq, Eq, Clone, Copy)] 97#[derive(Debug, PartialEq, Eq, Clone, Copy)]
94pub enum InsertPosition<T> { 98pub enum InsertPosition<T> {
95 First, 99 First,
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 9e5411ee5..26e4576ff 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -307,7 +307,11 @@ impl ast::UseTree {
307 307
308 fn split_path_prefix(prefix: &ast::Path) -> Option<ast::Path> { 308 fn split_path_prefix(prefix: &ast::Path) -> Option<ast::Path> {
309 let parent = prefix.parent_path()?; 309 let parent = prefix.parent_path()?;
310 let mut res = make::path_unqualified(parent.segment()?); 310 let segment = parent.segment()?;
311 if algo::has_errors(segment.syntax()) {
312 return None;
313 }
314 let mut res = make::path_unqualified(segment);
311 for p in iter::successors(parent.parent_path(), |it| it.parent_path()) { 315 for p in iter::successors(parent.parent_path(), |it| it.parent_path()) {
312 res = make::path_qualified(res, p.segment()?); 316 res = make::path_qualified(res, p.segment()?);
313 } 317 }