aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/typing.rs28
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.
85fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<TextEdit> { 91fn 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.
122fn on_eq_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { 130fn 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.
144fn on_dot_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { 154fn 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() -> { ... }`
172fn on_arrow_typed(file: &SourceFile, offset: TextSize) -> Option<TextEdit> { 184fn 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;