diff options
-rw-r--r-- | crates/ide/src/typing.rs | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index 9050853ce..809ff7d20 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs | |||
@@ -58,9 +58,13 @@ pub(crate) fn on_char_typed( | |||
58 | position: FilePosition, | 58 | position: FilePosition, |
59 | char_typed: char, | 59 | char_typed: char, |
60 | ) -> Option<SourceChange> { | 60 | ) -> Option<SourceChange> { |
61 | assert!(TRIGGER_CHARS.contains(char_typed)); | 61 | if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) { |
62 | return None; | ||
63 | } | ||
62 | let file = &db.parse(position.file_id); | 64 | let file = &db.parse(position.file_id); |
63 | assert_eq!(file.tree().syntax().text().char_at(position.offset), Some(char_typed)); | 65 | if !stdx::always!(file.tree().syntax().text().char_at(position.offset) == Some(char_typed)) { |
66 | return None; | ||
67 | } | ||
64 | let edit = on_char_typed_inner(file, position.offset, char_typed)?; | 68 | let edit = on_char_typed_inner(file, position.offset, char_typed)?; |
65 | Some(SourceChange::from_text_edit(position.file_id, edit)) | 69 | Some(SourceChange::from_text_edit(position.file_id, edit)) |
66 | } | 70 | } |
@@ -70,7 +74,9 @@ fn on_char_typed_inner( | |||
70 | offset: TextSize, | 74 | offset: TextSize, |
71 | char_typed: char, | 75 | char_typed: char, |
72 | ) -> Option<TextEdit> { | 76 | ) -> Option<TextEdit> { |
73 | assert!(TRIGGER_CHARS.contains(char_typed)); | 77 | if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) { |
78 | return None; | ||
79 | } | ||
74 | match char_typed { | 80 | match char_typed { |
75 | '.' => on_dot_typed(&file.tree(), offset), | 81 | '.' => on_dot_typed(&file.tree(), offset), |
76 | '=' => on_eq_typed(&file.tree(), offset), | 82 | '=' => on_eq_typed(&file.tree(), offset), |
@@ -83,7 +89,9 @@ fn on_char_typed_inner( | |||
83 | /// Inserts a closing `}` when the user types an opening `{`, wrapping an existing expression in a | 89 | /// Inserts a closing `}` when the user types an opening `{`, wrapping an existing expression in a |
84 | /// block. | 90 | /// block. |
85 | fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<TextEdit> { | 91 | fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<TextEdit> { |
86 | stdx::always!(file.tree().syntax().text().char_at(offset) == Some('{')); | 92 | if !stdx::always!(file.tree().syntax().text().char_at(offset) == Some('{')) { |
93 | return None; | ||
94 | } | ||
87 | 95 | ||
88 | let brace_token = file.tree().syntax().token_at_offset(offset).right_biased()?; | 96 | let brace_token = file.tree().syntax().token_at_offset(offset).right_biased()?; |
89 | 97 | ||
@@ -120,7 +128,9 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option< | |||
120 | /// this works when adding `let =`. | 128 | /// this works when adding `let =`. |
121 | // FIXME: use a snippet completion instead of this hack here. | 129 | // FIXME: use a snippet completion instead of this hack here. |
122 | fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { | 130 | fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { |
123 | stdx::always!(file.syntax().text().char_at(offset) == Some('=')); | 131 | if !stdx::always!(file.syntax().text().char_at(offset) == Some('=')) { |
132 | return None; | ||
133 | } | ||
124 | let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; | 134 | let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; |
125 | if let_stmt.semicolon_token().is_some() { | 135 | if let_stmt.semicolon_token().is_some() { |
126 | return None; | 136 | return None; |
@@ -142,7 +152,9 @@ fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { | |||
142 | 152 | ||
143 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. | 153 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. |
144 | fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { | 154 | fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { |
145 | stdx::always!(file.syntax().text().char_at(offset) == Some('.')); | 155 | if !stdx::always!(file.syntax().text().char_at(offset) == Some('.')) { |
156 | return None; | ||
157 | } | ||
146 | let whitespace = | 158 | let whitespace = |
147 | file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?; | 159 | file.syntax().token_at_offset(offset).left_biased().and_then(ast::Whitespace::cast)?; |
148 | 160 | ||
@@ -171,7 +183,9 @@ fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { | |||
171 | /// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }` | 183 | /// Adds a space after an arrow when `fn foo() { ... }` is turned into `fn foo() -> { ... }` |
172 | fn on_arrow_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { | 184 | fn on_arrow_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { |
173 | let file_text = file.syntax().text(); | 185 | let file_text = file.syntax().text(); |
174 | stdx::always!(file_text.char_at(offset) == Some('>')); | 186 | if !stdx::always!(file_text.char_at(offset) == Some('>')) { |
187 | return None; | ||
188 | } | ||
175 | let after_arrow = offset + TextSize::of('>'); | 189 | let after_arrow = offset + TextSize::of('>'); |
176 | if file_text.char_at(after_arrow) != Some('{') { | 190 | if file_text.char_at(after_arrow) != Some('{') { |
177 | return None; | 191 | return None; |