aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api')
-rw-r--r--crates/ra_ide_api/src/call_info.rs4
-rw-r--r--crates/ra_ide_api/src/completion/complete_keyword.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_postfix.rs2
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs32
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs12
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs6
-rw-r--r--crates/ra_ide_api/src/display/structure.rs8
-rw-r--r--crates/ra_ide_api/src/extend_selection.rs48
-rw-r--r--crates/ra_ide_api/src/folding_ranges.rs9
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs4
-rw-r--r--crates/ra_ide_api/src/goto_type_definition.rs2
-rw-r--r--crates/ra_ide_api/src/hover.rs10
-rw-r--r--crates/ra_ide_api/src/impls.rs4
-rw-r--r--crates/ra_ide_api/src/join_lines.rs22
-rw-r--r--crates/ra_ide_api/src/matching_brace.rs2
-rw-r--r--crates/ra_ide_api/src/references.rs2
-rw-r--r--crates/ra_ide_api/src/runnables.rs4
-rw-r--r--crates/ra_ide_api/src/symbol_index.rs2
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs14
-rw-r--r--crates/ra_ide_api/src/syntax_tree.rs8
-rw-r--r--crates/ra_ide_api/src/typing.rs8
22 files changed, 111 insertions, 96 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs
index 270499612..212448d41 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide_api/src/call_info.rs
@@ -47,7 +47,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
47 // Number of arguments specified at the call site 47 // Number of arguments specified at the call site
48 let num_args_at_callsite = arg_list.args().count(); 48 let num_args_at_callsite = arg_list.args().count();
49 49
50 let arg_list_range = arg_list.syntax().range(); 50 let arg_list_range = arg_list.syntax().text_range();
51 if !arg_list_range.contains_inclusive(position.offset) { 51 if !arg_list_range.contains_inclusive(position.offset) {
52 tested_by!(call_info_bad_offset); 52 tested_by!(call_info_bad_offset);
53 return None; 53 return None;
@@ -57,7 +57,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
57 num_args_at_callsite, 57 num_args_at_callsite,
58 arg_list 58 arg_list
59 .args() 59 .args()
60 .take_while(|arg| arg.syntax().range().end() < position.offset) 60 .take_while(|arg| arg.syntax().text_range().end() < position.offset)
61 .count(), 61 .count(),
62 ); 62 );
63 63
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide_api/src/completion/complete_keyword.rs
index 4cf34eff8..18c1839dc 100644
--- a/crates/ra_ide_api/src/completion/complete_keyword.rs
+++ b/crates/ra_ide_api/src/completion/complete_keyword.rs
@@ -88,7 +88,7 @@ fn is_in_loop_body(leaf: &SyntaxToken) -> bool {
88 .visit::<ast::LoopExpr, _>(|it| it.loop_body()) 88 .visit::<ast::LoopExpr, _>(|it| it.loop_body())
89 .accept(&node); 89 .accept(&node);
90 if let Some(Some(body)) = loop_body { 90 if let Some(Some(body)) = loop_body {
91 if leaf.range().is_subrange(&body.syntax().range()) { 91 if leaf.text_range().is_subrange(&body.syntax().text_range()) {
92 return true; 92 return true;
93 } 93 }
94 } 94 }
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 29586cd1f..5fd41eeb3 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -26,7 +26,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
26 if Some(module) == ctx.module { 26 if Some(module) == ctx.module {
27 if let Some(import) = res.import { 27 if let Some(import) = res.import {
28 if let Either::A(use_tree) = module.import_source(ctx.db, import) { 28 if let Either::A(use_tree) = module.import_source(ctx.db, import) {
29 if use_tree.syntax().range().contains_inclusive(ctx.offset) { 29 if use_tree.syntax().text_range().contains_inclusive(ctx.offset) {
30 // for `use self::foo<|>`, don't suggest `foo` as a completion 30 // for `use self::foo<|>`, don't suggest `foo` as a completion
31 tested_by!(dont_complete_current_use); 31 tested_by!(dont_complete_current_use);
32 continue; 32 continue;
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs
index c75b1c159..6d834f6ce 100644
--- a/crates/ra_ide_api/src/completion/complete_postfix.rs
+++ b/crates/ra_ide_api/src/completion/complete_postfix.rs
@@ -12,7 +12,7 @@ use ra_text_edit::TextEditBuilder;
12fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder { 12fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder {
13 let edit = { 13 let edit = {
14 let receiver_range = 14 let receiver_range =
15 ctx.dot_receiver.as_ref().expect("no receiver available").syntax().range(); 15 ctx.dot_receiver.as_ref().expect("no receiver available").syntax().text_range();
16 let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end()); 16 let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end());
17 let mut builder = TextEditBuilder::default(); 17 let mut builder = TextEditBuilder::default();
18 builder.replace(delete_range, snippet.to_string()); 18 builder.replace(delete_range, snippet.to_string());
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index b803271ab..2f78d5409 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -78,7 +78,7 @@ impl<'a> CompletionContext<'a> {
78 pub(crate) fn source_range(&self) -> TextRange { 78 pub(crate) fn source_range(&self) -> TextRange {
79 match self.token.kind() { 79 match self.token.kind() {
80 // workaroud when completion is triggered by trigger characters. 80 // workaroud when completion is triggered by trigger characters.
81 IDENT => self.token.range(), 81 IDENT => self.token.text_range(),
82 _ => TextRange::offset_len(self.offset, 0.into()), 82 _ => TextRange::offset_len(self.offset, 0.into()),
83 } 83 }
84 } 84 }
@@ -123,13 +123,17 @@ impl<'a> CompletionContext<'a> {
123 } 123 }
124 124
125 fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) { 125 fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) {
126 let name_range = name_ref.syntax().range(); 126 let name_range = name_ref.syntax().text_range();
127 if name_ref.syntax().parent().and_then(ast::NamedField::cast).is_some() { 127 if name_ref.syntax().parent().and_then(ast::NamedField::cast).is_some() {
128 self.struct_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); 128 self.struct_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset);
129 } 129 }
130 130
131 let top_node = 131 let top_node = name_ref
132 name_ref.syntax().ancestors().take_while(|it| it.range() == name_range).last().unwrap(); 132 .syntax()
133 .ancestors()
134 .take_while(|it| it.text_range() == name_range)
135 .last()
136 .unwrap();
133 137
134 match top_node.parent().map(|it| it.kind()) { 138 match top_node.parent().map(|it| it.kind()) {
135 Some(SOURCE_FILE) | Some(ITEM_LIST) => { 139 Some(SOURCE_FILE) | Some(ITEM_LIST) => {
@@ -180,23 +184,27 @@ impl<'a> CompletionContext<'a> {
180 .ancestors() 184 .ancestors()
181 .find_map(|node| { 185 .find_map(|node| {
182 if let Some(stmt) = ast::ExprStmt::cast(node.clone()) { 186 if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
183 return Some(stmt.syntax().range() == name_ref.syntax().range()); 187 return Some(
188 stmt.syntax().text_range() == name_ref.syntax().text_range(),
189 );
184 } 190 }
185 if let Some(block) = ast::Block::cast(node) { 191 if let Some(block) = ast::Block::cast(node) {
186 return Some( 192 return Some(
187 block.expr().map(|e| e.syntax().range()) 193 block.expr().map(|e| e.syntax().text_range())
188 == Some(name_ref.syntax().range()), 194 == Some(name_ref.syntax().text_range()),
189 ); 195 );
190 } 196 }
191 None 197 None
192 }) 198 })
193 .unwrap_or(false); 199 .unwrap_or(false);
194 200
195 if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { 201 if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
196 if let Some(if_expr) = 202 if let Some(if_expr) =
197 find_node_at_offset::<ast::IfExpr>(original_file.syntax(), off) 203 find_node_at_offset::<ast::IfExpr>(original_file.syntax(), off)
198 { 204 {
199 if if_expr.syntax().range().end() < name_ref.syntax().range().start() { 205 if if_expr.syntax().text_range().end()
206 < name_ref.syntax().text_range().start()
207 {
200 self.after_if = true; 208 self.after_if = true;
201 } 209 }
202 } 210 }
@@ -208,14 +216,14 @@ impl<'a> CompletionContext<'a> {
208 // ident, so it should have the same range in the non-modified file 216 // ident, so it should have the same range in the non-modified file
209 self.dot_receiver = field_expr 217 self.dot_receiver = field_expr
210 .expr() 218 .expr()
211 .map(|e| e.syntax().range()) 219 .map(|e| e.syntax().text_range())
212 .and_then(|r| find_node_with_range(original_file.syntax(), r)); 220 .and_then(|r| find_node_with_range(original_file.syntax(), r));
213 } 221 }
214 if let Some(method_call_expr) = ast::MethodCallExpr::cast(parent) { 222 if let Some(method_call_expr) = ast::MethodCallExpr::cast(parent) {
215 // As above 223 // As above
216 self.dot_receiver = method_call_expr 224 self.dot_receiver = method_call_expr
217 .expr() 225 .expr()
218 .map(|e| e.syntax().range()) 226 .map(|e| e.syntax().text_range())
219 .and_then(|r| find_node_with_range(original_file.syntax(), r)); 227 .and_then(|r| find_node_with_range(original_file.syntax(), r));
220 self.is_call = true; 228 self.is_call = true;
221 } 229 }
@@ -229,6 +237,6 @@ fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Op
229fn is_node<N: AstNode>(node: &SyntaxNode) -> bool { 237fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
230 match node.ancestors().filter_map(N::cast).next() { 238 match node.ancestors().filter_map(N::cast).next() {
231 None => false, 239 None => false,
232 Some(n) => n.syntax().range() == node.range(), 240 Some(n) => n.syntax().text_range() == node.text_range(),
233 } 241 }
234} 242}
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index affbad6cd..028dc3d4f 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -96,7 +96,7 @@ fn check_unnecessary_braces_in_use_statement(
96) -> Option<()> { 96) -> Option<()> {
97 let use_tree_list = ast::UseTreeList::cast(node.clone())?; 97 let use_tree_list = ast::UseTreeList::cast(node.clone())?;
98 if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() { 98 if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() {
99 let range = use_tree_list.syntax().range(); 99 let range = use_tree_list.syntax().text_range();
100 let edit = 100 let edit =
101 text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(&single_use_tree) 101 text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(&single_use_tree)
102 .unwrap_or_else(|| { 102 .unwrap_or_else(|| {
@@ -126,8 +126,8 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
126) -> Option<TextEdit> { 126) -> Option<TextEdit> {
127 let use_tree_list_node = single_use_tree.syntax().parent()?; 127 let use_tree_list_node = single_use_tree.syntax().parent()?;
128 if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind() == T![self] { 128 if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind() == T![self] {
129 let start = use_tree_list_node.prev_sibling_or_token()?.range().start(); 129 let start = use_tree_list_node.prev_sibling_or_token()?.text_range().start();
130 let end = use_tree_list_node.range().end(); 130 let end = use_tree_list_node.text_range().end();
131 let range = TextRange::from_to(start, end); 131 let range = TextRange::from_to(start, end);
132 let mut edit_builder = TextEditBuilder::default(); 132 let mut edit_builder = TextEditBuilder::default();
133 edit_builder.delete(range); 133 edit_builder.delete(range);
@@ -149,12 +149,12 @@ fn check_struct_shorthand_initialization(
149 let field_expr = expr.syntax().text().to_string(); 149 let field_expr = expr.syntax().text().to_string();
150 if field_name == field_expr { 150 if field_name == field_expr {
151 let mut edit_builder = TextEditBuilder::default(); 151 let mut edit_builder = TextEditBuilder::default();
152 edit_builder.delete(named_field.syntax().range()); 152 edit_builder.delete(named_field.syntax().text_range());
153 edit_builder.insert(named_field.syntax().range().start(), field_name); 153 edit_builder.insert(named_field.syntax().text_range().start(), field_name);
154 let edit = edit_builder.finish(); 154 let edit = edit_builder.finish();
155 155
156 acc.push(Diagnostic { 156 acc.push(Diagnostic {
157 range: named_field.syntax().range(), 157 range: named_field.syntax().text_range(),
158 message: "Shorthand struct initialization".to_string(), 158 message: "Shorthand struct initialization".to_string(),
159 severity: Severity::WeakWarning, 159 severity: Severity::WeakWarning,
160 fix: Some(SourceChange::source_file_edit( 160 fix: Some(SourceChange::source_file_edit(
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index 8aff5f2cd..84fabdb9e 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -233,7 +233,7 @@ impl NavigationTarget {
233 233
234 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { 234 pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
235 let src = macro_call.source(db); 235 let src = macro_call.source(db);
236 log::debug!("nav target {}", src.ast.syntax().debug_dump()); 236 log::debug!("nav target {:#?}", src.ast.syntax());
237 NavigationTarget::from_named( 237 NavigationTarget::from_named(
238 src.file_id.original_file(db), 238 src.file_id.original_file(db),
239 &src.ast, 239 &src.ast,
@@ -275,7 +275,7 @@ impl NavigationTarget {
275 ) -> NavigationTarget { 275 ) -> NavigationTarget {
276 //FIXME: use `_` instead of empty string 276 //FIXME: use `_` instead of empty string
277 let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); 277 let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
278 let focus_range = node.name().map(|it| it.syntax().range()); 278 let focus_range = node.name().map(|it| it.syntax().text_range());
279 NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description) 279 NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description)
280 } 280 }
281 281
@@ -291,7 +291,7 @@ impl NavigationTarget {
291 file_id, 291 file_id,
292 name, 292 name,
293 kind: node.kind(), 293 kind: node.kind(),
294 full_range: node.range(), 294 full_range: node.text_range(),
295 focus_range, 295 focus_range,
296 // ptr: Some(LocalSyntaxPtr::new(node)), 296 // ptr: Some(LocalSyntaxPtr::new(node)),
297 container_name: None, 297 container_name: None,
diff --git a/crates/ra_ide_api/src/display/structure.rs b/crates/ra_ide_api/src/display/structure.rs
index 0b1a8b6e6..2ba10b2ef 100644
--- a/crates/ra_ide_api/src/display/structure.rs
+++ b/crates/ra_ide_api/src/display/structure.rs
@@ -73,8 +73,8 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
73 Some(StructureNode { 73 Some(StructureNode {
74 parent: None, 74 parent: None,
75 label: name.text().to_string(), 75 label: name.text().to_string(),
76 navigation_range: name.syntax().range(), 76 navigation_range: name.syntax().text_range(),
77 node_range: node.syntax().range(), 77 node_range: node.syntax().text_range(),
78 kind: node.syntax().kind(), 78 kind: node.syntax().kind(),
79 detail, 79 detail,
80 deprecated: node.attrs().filter_map(|x| x.as_named()).any(|x| x == "deprecated"), 80 deprecated: node.attrs().filter_map(|x| x.as_named()).any(|x| x == "deprecated"),
@@ -140,8 +140,8 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
140 let node = StructureNode { 140 let node = StructureNode {
141 parent: None, 141 parent: None,
142 label, 142 label,
143 navigation_range: target_type.syntax().range(), 143 navigation_range: target_type.syntax().text_range(),
144 node_range: im.syntax().range(), 144 node_range: im.syntax().text_range(),
145 kind: im.syntax().kind(), 145 kind: im.syntax().kind(),
146 detail: None, 146 detail: None,
147 deprecated: false, 147 deprecated: false,
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs
index 292f61f4a..140820df6 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide_api/src/extend_selection.rs
@@ -42,19 +42,20 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange
42 TokenAtOffset::None => return None, 42 TokenAtOffset::None => return None,
43 TokenAtOffset::Single(l) => { 43 TokenAtOffset::Single(l) => {
44 if string_kinds.contains(&l.kind()) { 44 if string_kinds.contains(&l.kind()) {
45 extend_single_word_in_comment_or_string(&l, offset).unwrap_or_else(|| l.range()) 45 extend_single_word_in_comment_or_string(&l, offset)
46 .unwrap_or_else(|| l.text_range())
46 } else { 47 } else {
47 l.range() 48 l.text_range()
48 } 49 }
49 } 50 }
50 TokenAtOffset::Between(l, r) => pick_best(l, r).range(), 51 TokenAtOffset::Between(l, r) => pick_best(l, r).text_range(),
51 }; 52 };
52 return Some(leaf_range); 53 return Some(leaf_range);
53 }; 54 };
54 let node = match find_covering_element(root, range) { 55 let node = match find_covering_element(root, range) {
55 SyntaxElement::Token(token) => { 56 SyntaxElement::Token(token) => {
56 if token.range() != range { 57 if token.text_range() != range {
57 return Some(token.range()); 58 return Some(token.text_range());
58 } 59 }
59 if let Some(comment) = ast::Comment::cast(token.clone()) { 60 if let Some(comment) = ast::Comment::cast(token.clone()) {
60 if let Some(range) = extend_comments(comment) { 61 if let Some(range) = extend_comments(comment) {
@@ -65,12 +66,12 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange
65 } 66 }
66 SyntaxElement::Node(node) => node, 67 SyntaxElement::Node(node) => node,
67 }; 68 };
68 if node.range() != range { 69 if node.text_range() != range {
69 return Some(node.range()); 70 return Some(node.text_range());
70 } 71 }
71 72
72 // Using shallowest node with same range allows us to traverse siblings. 73 // Using shallowest node with same range allows us to traverse siblings.
73 let node = node.ancestors().take_while(|n| n.range() == node.range()).last().unwrap(); 74 let node = node.ancestors().take_while(|n| n.text_range() == node.text_range()).last().unwrap();
74 75
75 if node.parent().map(|n| list_kinds.contains(&n.kind())) == Some(true) { 76 if node.parent().map(|n| list_kinds.contains(&n.kind())) == Some(true) {
76 if let Some(range) = extend_list_item(&node) { 77 if let Some(range) = extend_list_item(&node) {
@@ -78,7 +79,7 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange
78 } 79 }
79 } 80 }
80 81
81 node.parent().map(|it| it.range()) 82 node.parent().map(|it| it.text_range())
82} 83}
83 84
84fn extend_single_word_in_comment_or_string( 85fn extend_single_word_in_comment_or_string(
@@ -86,7 +87,7 @@ fn extend_single_word_in_comment_or_string(
86 offset: TextUnit, 87 offset: TextUnit,
87) -> Option<TextRange> { 88) -> Option<TextRange> {
88 let text: &str = leaf.text(); 89 let text: &str = leaf.text();
89 let cursor_position: u32 = (offset - leaf.range().start()).into(); 90 let cursor_position: u32 = (offset - leaf.text_range().start()).into();
90 91
91 let (before, after) = text.split_at(cursor_position as usize); 92 let (before, after) = text.split_at(cursor_position as usize);
92 93
@@ -104,31 +105,31 @@ fn extend_single_word_in_comment_or_string(
104 if range.is_empty() { 105 if range.is_empty() {
105 None 106 None
106 } else { 107 } else {
107 Some(range + leaf.range().start()) 108 Some(range + leaf.text_range().start())
108 } 109 }
109} 110}
110 111
111fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange { 112fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange {
112 let ws_text = ws.text(); 113 let ws_text = ws.text();
113 let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); 114 let suffix = TextRange::from_to(offset, ws.text_range().end()) - ws.text_range().start();
114 let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start(); 115 let prefix = TextRange::from_to(ws.text_range().start(), offset) - ws.text_range().start();
115 let ws_suffix = &ws_text.as_str()[suffix]; 116 let ws_suffix = &ws_text.as_str()[suffix];
116 let ws_prefix = &ws_text.as_str()[prefix]; 117 let ws_prefix = &ws_text.as_str()[prefix];
117 if ws_text.contains('\n') && !ws_suffix.contains('\n') { 118 if ws_text.contains('\n') && !ws_suffix.contains('\n') {
118 if let Some(node) = ws.next_sibling_or_token() { 119 if let Some(node) = ws.next_sibling_or_token() {
119 let start = match ws_prefix.rfind('\n') { 120 let start = match ws_prefix.rfind('\n') {
120 Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32), 121 Some(idx) => ws.text_range().start() + TextUnit::from((idx + 1) as u32),
121 None => node.range().start(), 122 None => node.text_range().start(),
122 }; 123 };
123 let end = if root.text().char_at(node.range().end()) == Some('\n') { 124 let end = if root.text().char_at(node.text_range().end()) == Some('\n') {
124 node.range().end() + TextUnit::of_char('\n') 125 node.text_range().end() + TextUnit::of_char('\n')
125 } else { 126 } else {
126 node.range().end() 127 node.text_range().end()
127 }; 128 };
128 return TextRange::from_to(start, end); 129 return TextRange::from_to(start, end);
129 } 130 }
130 } 131 }
131 ws.range() 132 ws.text_range()
132} 133}
133 134
134fn pick_best<'a>(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken { 135fn pick_best<'a>(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken {
@@ -161,7 +162,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
161 } 162 }
162 163
163 if let Some(comma_node) = nearby_comma(node, Direction::Prev) { 164 if let Some(comma_node) = nearby_comma(node, Direction::Prev) {
164 return Some(TextRange::from_to(comma_node.range().start(), node.range().end())); 165 return Some(TextRange::from_to(comma_node.text_range().start(), node.text_range().end()));
165 } 166 }
166 if let Some(comma_node) = nearby_comma(node, Direction::Next) { 167 if let Some(comma_node) = nearby_comma(node, Direction::Next) {
167 // Include any following whitespace when comma if after list item. 168 // Include any following whitespace when comma if after list item.
@@ -171,7 +172,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
171 .filter(|node| is_single_line_ws(node)) 172 .filter(|node| is_single_line_ws(node))
172 .unwrap_or(comma_node); 173 .unwrap_or(comma_node);
173 174
174 return Some(TextRange::from_to(node.range().start(), final_node.range().end())); 175 return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end()));
175 } 176 }
176 177
177 None 178 None
@@ -181,7 +182,10 @@ fn extend_comments(comment: ast::Comment) -> Option<TextRange> {
181 let prev = adj_comments(&comment, Direction::Prev); 182 let prev = adj_comments(&comment, Direction::Prev);
182 let next = adj_comments(&comment, Direction::Next); 183 let next = adj_comments(&comment, Direction::Next);
183 if prev != next { 184 if prev != next {
184 Some(TextRange::from_to(prev.syntax().range().start(), next.syntax().range().end())) 185 Some(TextRange::from_to(
186 prev.syntax().text_range().start(),
187 next.syntax().text_range().end(),
188 ))
185 } else { 189 } else {
186 None 190 None
187 } 191 }
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs
index c2b981aed..9699000db 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide_api/src/folding_ranges.rs
@@ -35,7 +35,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
35 SyntaxElement::Token(token) => token.text().contains('\n'), 35 SyntaxElement::Token(token) => token.text().contains('\n'),
36 }; 36 };
37 if is_multiline { 37 if is_multiline {
38 res.push(Fold { range: element.range(), kind }); 38 res.push(Fold { range: element.text_range(), kind });
39 continue; 39 continue;
40 } 40 }
41 } 41 }
@@ -132,7 +132,7 @@ fn contiguous_range_for_group_unless(
132 } 132 }
133 133
134 if first != &last { 134 if first != &last {
135 Some(TextRange::from_to(first.range().start(), last.range().end())) 135 Some(TextRange::from_to(first.text_range().start(), last.text_range().end()))
136 } else { 136 } else {
137 // The group consists of only one element, therefore it cannot be folded 137 // The group consists of only one element, therefore it cannot be folded
138 None 138 None
@@ -178,7 +178,10 @@ fn contiguous_range_for_comment(
178 } 178 }
179 179
180 if first != last { 180 if first != last {
181 Some(TextRange::from_to(first.syntax().range().start(), last.syntax().range().end())) 181 Some(TextRange::from_to(
182 first.syntax().text_range().start(),
183 last.syntax().text_range().end(),
184 ))
182 } else { 185 } else {
183 // The group consists of only one element, therefore it cannot be folded 186 // The group consists of only one element, therefore it cannot be folded
184 None 187 None
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 82b5e3b5e..ddd55a9c1 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -23,11 +23,11 @@ pub(crate) fn goto_definition(
23 let syntax = parse.tree().syntax().clone(); 23 let syntax = parse.tree().syntax().clone();
24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&syntax, position.offset) { 24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&syntax, position.offset) {
25 let navs = reference_definition(db, position.file_id, &name_ref).to_vec(); 25 let navs = reference_definition(db, position.file_id, &name_ref).to_vec();
26 return Some(RangeInfo::new(name_ref.syntax().range(), navs.to_vec())); 26 return Some(RangeInfo::new(name_ref.syntax().text_range(), navs.to_vec()));
27 } 27 }
28 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) { 28 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) {
29 let navs = name_definition(db, position.file_id, &name)?; 29 let navs = name_definition(db, position.file_id, &name)?;
30 return Some(RangeInfo::new(name.syntax().range(), navs)); 30 return Some(RangeInfo::new(name.syntax().text_range(), navs));
31 } 31 }
32 None 32 None
33} 33}
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs
index fc4b6e1af..007259d9e 100644
--- a/crates/ra_ide_api/src/goto_type_definition.rs
+++ b/crates/ra_ide_api/src/goto_type_definition.rs
@@ -32,7 +32,7 @@ pub(crate) fn goto_type_definition(
32 let adt_def = analyzer.autoderef(db, ty).find_map(|ty| ty.as_adt().map(|adt| adt.0))?; 32 let adt_def = analyzer.autoderef(db, ty).find_map(|ty| ty.as_adt().map(|adt| adt.0))?;
33 33
34 let nav = NavigationTarget::from_adt_def(db, adt_def); 34 let nav = NavigationTarget::from_adt_def(db, adt_def);
35 Some(RangeInfo::new(node.range(), vec![nav])) 35 Some(RangeInfo::new(node.text_range(), vec![nav]))
36} 36}
37 37
38#[cfg(test)] 38#[cfg(test)]
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index e503bf6a9..2a5ac7821 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -172,7 +172,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
172 } 172 }
173 173
174 if !res.is_empty() { 174 if !res.is_empty() {
175 range = Some(name_ref.syntax().range()) 175 range = Some(name_ref.syntax().text_range())
176 } 176 }
177 } else if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) { 177 } else if let Some(name) = find_node_at_offset::<ast::Name>(file.syntax(), position.offset) {
178 if let Some(parent) = name.syntax().parent() { 178 if let Some(parent) = name.syntax().parent() {
@@ -210,7 +210,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
210 } 210 }
211 211
212 if !res.is_empty() && range.is_none() { 212 if !res.is_empty() && range.is_none() {
213 range = Some(name.syntax().range()); 213 range = Some(name.syntax().text_range());
214 } 214 }
215 } 215 }
216 216
@@ -218,9 +218,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
218 let node = ancestors_at_offset(file.syntax(), position.offset).find(|n| { 218 let node = ancestors_at_offset(file.syntax(), position.offset).find(|n| {
219 ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some() 219 ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some()
220 })?; 220 })?;
221 let frange = FileRange { file_id: position.file_id, range: node.range() }; 221 let frange = FileRange { file_id: position.file_id, range: node.text_range() };
222 res.extend(type_of(db, frange).map(rust_code_markup)); 222 res.extend(type_of(db, frange).map(rust_code_markup));
223 range = Some(node.range()); 223 range = Some(node.text_range());
224 } 224 }
225 225
226 let range = range?; 226 let range = range?;
@@ -246,7 +246,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
246 // if we picked identifier, expand to pattern/expression 246 // if we picked identifier, expand to pattern/expression
247 let node = leaf_node 247 let node = leaf_node
248 .ancestors() 248 .ancestors()
249 .take_while(|it| it.range() == leaf_node.range()) 249 .take_while(|it| it.text_range() == leaf_node.text_range())
250 .find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?; 250 .find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?;
251 let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, &node, None); 251 let analyzer = hir::SourceAnalyzer::new(db, frange.file_id, &node, None);
252 let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) 252 let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs
index 15999d433..f5b6ffd61 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide_api/src/impls.rs
@@ -15,12 +15,12 @@ pub(crate) fn goto_implementation(
15 15
16 if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { 16 if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) {
17 return Some(RangeInfo::new( 17 return Some(RangeInfo::new(
18 nominal_def.syntax().range(), 18 nominal_def.syntax().text_range(),
19 impls_for_def(db, &nominal_def, module)?, 19 impls_for_def(db, &nominal_def, module)?,
20 )); 20 ));
21 } else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) { 21 } else if let Some(trait_def) = find_node_at_offset::<ast::TraitDef>(&syntax, position.offset) {
22 return Some(RangeInfo::new( 22 return Some(RangeInfo::new(
23 trait_def.syntax().range(), 23 trait_def.syntax().text_range(),
24 impls_for_trait(db, &trait_def, module)?, 24 impls_for_trait(db, &trait_def, module)?,
25 )); 25 ));
26 } 26 }
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index 9b81ad9e4..fa998ebe1 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -28,14 +28,14 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
28 }; 28 };
29 let mut edit = TextEditBuilder::default(); 29 let mut edit = TextEditBuilder::default();
30 for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) { 30 for token in node.descendants_with_tokens().filter_map(|it| it.into_token()) {
31 let range = match range.intersection(&token.range()) { 31 let range = match range.intersection(&token.text_range()) {
32 Some(range) => range, 32 Some(range) => range,
33 None => continue, 33 None => continue,
34 } - token.range().start(); 34 } - token.text_range().start();
35 let text = token.text(); 35 let text = token.text();
36 for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') { 36 for (pos, _) in text[range].bytes().enumerate().filter(|&(_, b)| b == b'\n') {
37 let pos: TextUnit = (pos as u32).into(); 37 let pos: TextUnit = (pos as u32).into();
38 let off = token.range().start() + range.start() + pos; 38 let off = token.text_range().start() + range.start() + pos;
39 if !edit.invalidates_offset(off) { 39 if !edit.invalidates_offset(off) {
40 remove_newline(&mut edit, &token, off); 40 remove_newline(&mut edit, &token, off);
41 } 41 }
@@ -49,7 +49,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
49 if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 { 49 if token.kind() != WHITESPACE || token.text().bytes().filter(|&b| b == b'\n').count() != 1 {
50 // The node is either the first or the last in the file 50 // The node is either the first or the last in the file
51 let suff = &token.text()[TextRange::from_to( 51 let suff = &token.text()[TextRange::from_to(
52 offset - token.range().start() + TextUnit::of_char('\n'), 52 offset - token.text_range().start() + TextUnit::of_char('\n'),
53 TextUnit::of_str(token.text()), 53 TextUnit::of_str(token.text()),
54 )]; 54 )];
55 let spaces = suff.bytes().take_while(|&b| b == b' ').count(); 55 let spaces = suff.bytes().take_while(|&b| b == b' ').count();
@@ -86,7 +86,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
86 let next = token.next_sibling_or_token().unwrap(); 86 let next = token.next_sibling_or_token().unwrap();
87 if is_trailing_comma(prev.kind(), next.kind()) { 87 if is_trailing_comma(prev.kind(), next.kind()) {
88 // Removes: trailing comma, newline (incl. surrounding whitespace) 88 // Removes: trailing comma, newline (incl. surrounding whitespace)
89 edit.delete(TextRange::from_to(prev.range().start(), token.range().end())); 89 edit.delete(TextRange::from_to(prev.text_range().start(), token.text_range().end()));
90 } else if prev.kind() == T![,] && next.kind() == T!['}'] { 90 } else if prev.kind() == T![,] && next.kind() == T!['}'] {
91 // Removes: comma, newline (incl. surrounding whitespace) 91 // Removes: comma, newline (incl. surrounding whitespace)
92 let space = if let Some(left) = prev.prev_sibling_or_token() { 92 let space = if let Some(left) = prev.prev_sibling_or_token() {
@@ -95,7 +95,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
95 " " 95 " "
96 }; 96 };
97 edit.replace( 97 edit.replace(
98 TextRange::from_to(prev.range().start(), token.range().end()), 98 TextRange::from_to(prev.text_range().start(), token.text_range().end()),
99 space.to_string(), 99 space.to_string(),
100 ); 100 );
101 } else if let (Some(_), Some(next)) = ( 101 } else if let (Some(_), Some(next)) = (
@@ -104,12 +104,12 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextU
104 ) { 104 ) {
105 // Removes: newline (incl. surrounding whitespace), start of the next comment 105 // Removes: newline (incl. surrounding whitespace), start of the next comment
106 edit.delete(TextRange::from_to( 106 edit.delete(TextRange::from_to(
107 token.range().start(), 107 token.text_range().start(),
108 next.syntax().range().start() + TextUnit::of_str(next.prefix()), 108 next.syntax().text_range().start() + TextUnit::of_str(next.prefix()),
109 )); 109 ));
110 } else { 110 } else {
111 // Remove newline but add a computed amount of whitespace characters 111 // Remove newline but add a computed amount of whitespace characters
112 edit.replace(token.range(), compute_ws(prev.kind(), next.kind()).to_string()); 112 edit.replace(token.text_range(), compute_ws(prev.kind(), next.kind()).to_string());
113 } 113 }
114} 114}
115 115
@@ -125,7 +125,7 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Op
125 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; 125 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
126 let expr = extract_trivial_expression(&block)?; 126 let expr = extract_trivial_expression(&block)?;
127 127
128 let block_range = block_expr.syntax().range(); 128 let block_range = block_expr.syntax().text_range();
129 let mut buf = expr.syntax().text().to_string(); 129 let mut buf = expr.syntax().text().to_string();
130 130
131 // Match block needs to have a comma after the block 131 // Match block needs to have a comma after the block
@@ -143,7 +143,7 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Op
143fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { 143fn join_single_use_tree(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> {
144 let use_tree_list = ast::UseTreeList::cast(token.parent())?; 144 let use_tree_list = ast::UseTreeList::cast(token.parent())?;
145 let (tree,) = use_tree_list.use_trees().collect_tuple()?; 145 let (tree,) = use_tree_list.use_trees().collect_tuple()?;
146 edit.replace(use_tree_list.syntax().range(), tree.syntax().text().to_string()); 146 edit.replace(use_tree_list.syntax().text_range(), tree.syntax().text().to_string());
147 Some(()) 147 Some(())
148} 148}
149 149
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs
index 102327fd7..1e2fac848 100644
--- a/crates/ra_ide_api/src/matching_brace.rs
+++ b/crates/ra_ide_api/src/matching_brace.rs
@@ -12,7 +12,7 @@ pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
12 let parent = brace_node.parent(); 12 let parent = brace_node.parent();
13 let matching_kind = BRACES[brace_idx ^ 1]; 13 let matching_kind = BRACES[brace_idx ^ 1];
14 let matching_node = parent.children_with_tokens().find(|node| node.kind() == matching_kind)?; 14 let matching_node = parent.children_with_tokens().find(|node| node.kind() == matching_kind)?;
15 Some(matching_node.range().start()) 15 Some(matching_node.text_range().start())
16} 16}
17 17
18#[cfg(test)] 18#[cfg(test)]
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 1c4cd49dc..5c74d3e36 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -166,7 +166,7 @@ fn rename_mod(
166 file_id: position.file_id, 166 file_id: position.file_id,
167 edit: { 167 edit: {
168 let mut builder = ra_text_edit::TextEditBuilder::default(); 168 let mut builder = ra_text_edit::TextEditBuilder::default();
169 builder.replace(ast_name.syntax().range(), new_name.into()); 169 builder.replace(ast_name.syntax().text_range(), new_name.into());
170 builder.finish() 170 builder.finish()
171 }, 171 },
172 }; 172 };
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs
index 200958434..07412a9ef 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide_api/src/runnables.rs
@@ -47,7 +47,7 @@ fn runnable_fn(fn_def: ast::FnDef) -> Option<Runnable> {
47 } else { 47 } else {
48 return None; 48 return None;
49 }; 49 };
50 Some(Runnable { range: fn_def.syntax().range(), kind }) 50 Some(Runnable { range: fn_def.syntax().text_range(), kind })
51} 51}
52 52
53fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Option<Runnable> { 53fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Option<Runnable> {
@@ -62,7 +62,7 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti
62 if !has_test_function { 62 if !has_test_function {
63 return None; 63 return None;
64 } 64 }
65 let range = module.syntax().range(); 65 let range = module.syntax().text_range();
66 let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?; 66 let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?;
67 67
68 let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); 68 let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::");
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs
index e784b5f69..d4afddab4 100644
--- a/crates/ra_ide_api/src/symbol_index.rs
+++ b/crates/ra_ide_api/src/symbol_index.rs
@@ -271,7 +271,7 @@ fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec
271fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { 271fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
272 fn decl<N: NameOwner>(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { 272 fn decl<N: NameOwner>(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
273 let name = node.name()?; 273 let name = node.name()?;
274 let name_range = name.syntax().range(); 274 let name_range = name.syntax().text_range();
275 let name = name.text().clone(); 275 let name = name.text().clone();
276 let ptr = SyntaxNodePtr::new(node.syntax()); 276 let ptr = SyntaxNodePtr::new(node.syntax());
277 277
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 477827fa7..878a94f06 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -189,11 +189,11 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
189 if let Some(segment) = path.segment() { 189 if let Some(segment) = path.segment() {
190 if let Some(name_ref) = segment.name_ref() { 190 if let Some(name_ref) = segment.name_ref() {
191 highlighted.insert(name_ref.syntax().clone().into()); 191 highlighted.insert(name_ref.syntax().clone().into());
192 let range_start = name_ref.syntax().range().start(); 192 let range_start = name_ref.syntax().text_range().start();
193 let mut range_end = name_ref.syntax().range().end(); 193 let mut range_end = name_ref.syntax().text_range().end();
194 for sibling in path.syntax().siblings_with_tokens(Direction::Next) { 194 for sibling in path.syntax().siblings_with_tokens(Direction::Next) {
195 match sibling.kind() { 195 match sibling.kind() {
196 T![!] | IDENT => range_end = sibling.range().end(), 196 T![!] | IDENT => range_end = sibling.text_range().end(),
197 _ => (), 197 _ => (),
198 } 198 }
199 } 199 }
@@ -209,7 +209,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
209 continue; 209 continue;
210 } 210 }
211 }; 211 };
212 res.push(HighlightedRange { range: node.range(), tag, binding_hash }) 212 res.push(HighlightedRange { range: node.text_range(), tag, binding_hash })
213 } 213 }
214 res 214 res
215} 215}
@@ -239,9 +239,9 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
239 buf.push_str("<pre><code>"); 239 buf.push_str("<pre><code>");
240 let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.into_token()); 240 let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.into_token());
241 for token in tokens { 241 for token in tokens {
242 could_intersect.retain(|it| token.range().start() <= it.range.end()); 242 could_intersect.retain(|it| token.text_range().start() <= it.range.end());
243 while let Some(r) = ranges.get(frontier) { 243 while let Some(r) = ranges.get(frontier) {
244 if r.range.start() <= token.range().end() { 244 if r.range.start() <= token.text_range().end() {
245 could_intersect.push(r); 245 could_intersect.push(r);
246 frontier += 1; 246 frontier += 1;
247 } else { 247 } else {
@@ -251,7 +251,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
251 let text = html_escape(&token.text()); 251 let text = html_escape(&token.text());
252 let ranges = could_intersect 252 let ranges = could_intersect
253 .iter() 253 .iter()
254 .filter(|it| token.range().is_subrange(&it.range)) 254 .filter(|it| token.text_range().is_subrange(&it.range))
255 .collect::<Vec<_>>(); 255 .collect::<Vec<_>>();
256 if ranges.is_empty() { 256 if ranges.is_empty() {
257 buf.push_str(&text); 257 buf.push_str(&text);
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index 3d7373d02..76c50f6d6 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -25,9 +25,9 @@ pub(crate) fn syntax_tree(
25 } 25 }
26 }; 26 };
27 27
28 node.debug_dump() 28 format!("{:#?}", node)
29 } else { 29 } else {
30 parse.tree().syntax().debug_dump() 30 format!("{:#?}", parse.tree().syntax())
31 } 31 }
32} 32}
33 33
@@ -45,7 +45,7 @@ fn syntax_tree_for_string(token: &SyntaxToken, text_range: TextRange) -> Option<
45 45
46fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<String> { 46fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<String> {
47 // Range of the full node 47 // Range of the full node
48 let node_range = node.range(); 48 let node_range = node.text_range();
49 let text = node.text().to_string(); 49 let text = node.text().to_string();
50 50
51 // We start at some point inside the node 51 // We start at some point inside the node
@@ -85,7 +85,7 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
85 // If the "file" parsed without errors, 85 // If the "file" parsed without errors,
86 // return its syntax 86 // return its syntax
87 if parsed.errors().is_empty() { 87 if parsed.errors().is_empty() {
88 return Some(parsed.tree().syntax().debug_dump()); 88 return Some(format!("{:#?}", parsed.tree().syntax()));
89 } 89 }
90 90
91 None 91 None
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index ad0ababcc..1747a529e 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -24,7 +24,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
24 24
25 let prefix = comment.prefix(); 25 let prefix = comment.prefix();
26 if position.offset 26 if position.offset
27 < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) 27 < comment.syntax().text_range().start() + TextUnit::of_str(prefix) + TextUnit::from(1)
28 { 28 {
29 return None; 29 return None;
30 } 30 }
@@ -45,7 +45,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
45} 45}
46 46
47fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> { 47fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> {
48 let ws = match find_token_at_offset(file.syntax(), token.range().start()) { 48 let ws = match find_token_at_offset(file.syntax(), token.text_range().start()) {
49 TokenAtOffset::Between(l, r) => { 49 TokenAtOffset::Between(l, r) => {
50 assert!(r == *token); 50 assert!(r == *token);
51 l 51 l
@@ -71,7 +71,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
71 return None; 71 return None;
72 } 72 }
73 if let Some(expr) = let_stmt.initializer() { 73 if let Some(expr) = let_stmt.initializer() {
74 let expr_range = expr.syntax().range(); 74 let expr_range = expr.syntax().text_range();
75 if expr_range.contains(eq_offset) && eq_offset != expr_range.start() { 75 if expr_range.contains(eq_offset) && eq_offset != expr_range.start() {
76 return None; 76 return None;
77 } 77 }
@@ -81,7 +81,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
81 } else { 81 } else {
82 return None; 82 return None;
83 } 83 }
84 let offset = let_stmt.syntax().range().end(); 84 let offset = let_stmt.syntax().text_range().end();
85 let mut edit = TextEditBuilder::default(); 85 let mut edit = TextEditBuilder::default();
86 edit.insert(offset, ";".to_string()); 86 edit.insert(offset, ";".to_string());
87 Some(edit.finish()) 87 Some(edit.finish())