diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 16 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 15 | ||||
-rw-r--r-- | crates/ra_analysis/tests/tests.rs | 2 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_db/src/loc2id.rs | 7 | ||||
-rw-r--r-- | crates/ra_editor/src/folding_ranges.rs | 74 | ||||
-rw-r--r-- | crates/ra_hir/src/module/imp.rs | 8 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 36 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 18 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 10 | ||||
-rw-r--r-- | crates/ra_text_edit/src/text_edit.rs | 4 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 39 | ||||
-rw-r--r-- | crates/tools/src/lib.rs | 2 |
15 files changed, 159 insertions, 88 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 3d0f13f34..94729d296 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::sync::Arc; | 1 | use std::{fmt, sync::Arc}; |
2 | use salsa::{self, Database}; | 2 | use salsa::{self, Database}; |
3 | use ra_db::{LocationIntener, BaseDatabase}; | 3 | use ra_db::{LocationIntener, BaseDatabase}; |
4 | use hir::{self, DefId, DefLoc}; | 4 | use hir::{self, DefId, DefLoc}; |
@@ -13,11 +13,19 @@ pub(crate) struct RootDatabase { | |||
13 | id_maps: Arc<IdMaps>, | 13 | id_maps: Arc<IdMaps>, |
14 | } | 14 | } |
15 | 15 | ||
16 | #[derive(Debug, Default)] | 16 | #[derive(Default)] |
17 | struct IdMaps { | 17 | struct IdMaps { |
18 | defs: LocationIntener<DefLoc, DefId>, | 18 | defs: LocationIntener<DefLoc, DefId>, |
19 | } | 19 | } |
20 | 20 | ||
21 | impl fmt::Debug for IdMaps { | ||
22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
23 | f.debug_struct("IdMaps") | ||
24 | .field("n_defs", &self.defs.len()) | ||
25 | .finish() | ||
26 | } | ||
27 | } | ||
28 | |||
21 | impl salsa::Database for RootDatabase { | 29 | impl salsa::Database for RootDatabase { |
22 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { | 30 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { |
23 | &self.runtime | 31 | &self.runtime |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index b44d9297a..5701e1ae2 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -25,7 +25,7 @@ use crate::{ | |||
25 | db, | 25 | db, |
26 | symbol_index::{SymbolIndex, SymbolsDatabase, LibrarySymbolsQuery}, | 26 | symbol_index::{SymbolIndex, SymbolsDatabase, LibrarySymbolsQuery}, |
27 | AnalysisChange, RootChange, Cancelable, CrateId, Diagnostic, FileId, | 27 | AnalysisChange, RootChange, Cancelable, CrateId, Diagnostic, FileId, |
28 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, | 28 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileEdit, |
29 | ReferenceResolution, | 29 | ReferenceResolution, |
30 | }; | 30 | }; |
31 | 31 | ||
@@ -368,10 +368,11 @@ impl AnalysisImpl { | |||
368 | .collect::<Vec<_>>(); | 368 | .collect::<Vec<_>>(); |
369 | if let Some(m) = source_binder::module_from_file_id(&*self.db, file_id)? { | 369 | if let Some(m) = source_binder::module_from_file_id(&*self.db, file_id)? { |
370 | for (name_node, problem) in m.problems(&*self.db) { | 370 | for (name_node, problem) in m.problems(&*self.db) { |
371 | let source_root = self.db.file_source_root(file_id); | ||
371 | let diag = match problem { | 372 | let diag = match problem { |
372 | Problem::UnresolvedModule { candidate } => { | 373 | Problem::UnresolvedModule { candidate } => { |
373 | let create_file = FileSystemEdit::CreateFile { | 374 | let create_file = FileSystemEdit::CreateFile { |
374 | anchor: file_id, | 375 | source_root, |
375 | path: candidate.clone(), | 376 | path: candidate.clone(), |
376 | }; | 377 | }; |
377 | let fix = SourceChange { | 378 | let fix = SourceChange { |
@@ -388,11 +389,12 @@ impl AnalysisImpl { | |||
388 | } | 389 | } |
389 | Problem::NotDirOwner { move_to, candidate } => { | 390 | Problem::NotDirOwner { move_to, candidate } => { |
390 | let move_file = FileSystemEdit::MoveFile { | 391 | let move_file = FileSystemEdit::MoveFile { |
391 | file: file_id, | 392 | src: file_id, |
392 | path: move_to.clone(), | 393 | dst_source_root: source_root, |
394 | dst_path: move_to.clone(), | ||
393 | }; | 395 | }; |
394 | let create_file = FileSystemEdit::CreateFile { | 396 | let create_file = FileSystemEdit::CreateFile { |
395 | anchor: file_id, | 397 | source_root, |
396 | path: move_to.join(candidate), | 398 | path: move_to.join(candidate), |
397 | }; | 399 | }; |
398 | let fix = SourceChange { | 400 | let fix = SourceChange { |
@@ -518,9 +520,9 @@ impl AnalysisImpl { | |||
518 | 520 | ||
519 | impl SourceChange { | 521 | impl SourceChange { |
520 | pub(crate) fn from_local_edit(file_id: FileId, label: &str, edit: LocalEdit) -> SourceChange { | 522 | pub(crate) fn from_local_edit(file_id: FileId, label: &str, edit: LocalEdit) -> SourceChange { |
521 | let file_edit = SourceFileNodeEdit { | 523 | let file_edit = SourceFileEdit { |
522 | file_id, | 524 | file_id, |
523 | edits: edit.edit.into_atoms(), | 525 | edit: edit.edit, |
524 | }; | 526 | }; |
525 | SourceChange { | 527 | SourceChange { |
526 | label: label.to_string(), | 528 | label: label.to_string(), |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index a1d462528..c7e7dc1c0 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -20,7 +20,7 @@ use std::{fmt, sync::Arc}; | |||
20 | 20 | ||
21 | use rustc_hash::FxHashMap; | 21 | use rustc_hash::FxHashMap; |
22 | use ra_syntax::{SourceFileNode, TextRange, TextUnit}; | 22 | use ra_syntax::{SourceFileNode, TextRange, TextUnit}; |
23 | use ra_text_edit::AtomTextEdit; | 23 | use ra_text_edit::TextEdit; |
24 | use rayon::prelude::*; | 24 | use rayon::prelude::*; |
25 | use relative_path::RelativePathBuf; | 25 | use relative_path::RelativePathBuf; |
26 | 26 | ||
@@ -159,26 +159,27 @@ impl AnalysisHost { | |||
159 | #[derive(Debug)] | 159 | #[derive(Debug)] |
160 | pub struct SourceChange { | 160 | pub struct SourceChange { |
161 | pub label: String, | 161 | pub label: String, |
162 | pub source_file_edits: Vec<SourceFileNodeEdit>, | 162 | pub source_file_edits: Vec<SourceFileEdit>, |
163 | pub file_system_edits: Vec<FileSystemEdit>, | 163 | pub file_system_edits: Vec<FileSystemEdit>, |
164 | pub cursor_position: Option<FilePosition>, | 164 | pub cursor_position: Option<FilePosition>, |
165 | } | 165 | } |
166 | 166 | ||
167 | #[derive(Debug)] | 167 | #[derive(Debug)] |
168 | pub struct SourceFileNodeEdit { | 168 | pub struct SourceFileEdit { |
169 | pub file_id: FileId, | 169 | pub file_id: FileId, |
170 | pub edits: Vec<AtomTextEdit>, | 170 | pub edit: TextEdit, |
171 | } | 171 | } |
172 | 172 | ||
173 | #[derive(Debug)] | 173 | #[derive(Debug)] |
174 | pub enum FileSystemEdit { | 174 | pub enum FileSystemEdit { |
175 | CreateFile { | 175 | CreateFile { |
176 | anchor: FileId, | 176 | source_root: SourceRootId, |
177 | path: RelativePathBuf, | 177 | path: RelativePathBuf, |
178 | }, | 178 | }, |
179 | MoveFile { | 179 | MoveFile { |
180 | file: FileId, | 180 | src: FileId, |
181 | path: RelativePathBuf, | 181 | dst_source_root: SourceRootId, |
182 | dst_path: RelativePathBuf, | ||
182 | }, | 183 | }, |
183 | } | 184 | } |
184 | 185 | ||
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 889b568b9..67738da48 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs | |||
@@ -81,7 +81,7 @@ fn test_unresolved_module_diagnostic() { | |||
81 | fix: Some(SourceChange { | 81 | fix: Some(SourceChange { |
82 | label: "create module", | 82 | label: "create module", |
83 | source_file_edits: [], | 83 | source_file_edits: [], |
84 | file_system_edits: [CreateFile { anchor: FileId(1), path: "../foo.rs" }], | 84 | file_system_edits: [CreateFile { source_root: SourceRootId(0), path: "foo.rs" }], |
85 | cursor_position: None }) }]"#, | 85 | cursor_position: None }) }]"#, |
86 | &diagnostics, | 86 | &diagnostics, |
87 | ); | 87 | ); |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 65fa3cbfa..0aca6f343 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -15,7 +15,7 @@ pub type Cancelable<T> = Result<T, Canceled>; | |||
15 | 15 | ||
16 | impl std::fmt::Display for Canceled { | 16 | impl std::fmt::Display for Canceled { |
17 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 17 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
18 | fmt.write_str("Canceled") | 18 | fmt.write_str("canceled") |
19 | } | 19 | } |
20 | } | 20 | } |
21 | 21 | ||
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 69ba43d0f..2dc7930d8 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs | |||
@@ -42,6 +42,10 @@ where | |||
42 | ID: NumericId, | 42 | ID: NumericId, |
43 | LOC: Clone + Eq + Hash, | 43 | LOC: Clone + Eq + Hash, |
44 | { | 44 | { |
45 | pub fn len(&self) -> usize { | ||
46 | self.loc2id.len() | ||
47 | } | ||
48 | |||
45 | pub fn loc2id(&mut self, loc: &LOC) -> ID { | 49 | pub fn loc2id(&mut self, loc: &LOC) -> ID { |
46 | match self.loc2id.get(loc) { | 50 | match self.loc2id.get(loc) { |
47 | Some(id) => return id.clone(), | 51 | Some(id) => return id.clone(), |
@@ -91,6 +95,9 @@ where | |||
91 | ID: NumericId, | 95 | ID: NumericId, |
92 | LOC: Clone + Eq + Hash, | 96 | LOC: Clone + Eq + Hash, |
93 | { | 97 | { |
98 | pub fn len(&self) -> usize { | ||
99 | self.map.lock().len() | ||
100 | } | ||
94 | pub fn loc2id(&self, loc: &LOC) -> ID { | 101 | pub fn loc2id(&self, loc: &LOC) -> ID { |
95 | self.map.lock().loc2id(loc) | 102 | self.map.lock().loc2id(loc) |
96 | } | 103 | } |
diff --git a/crates/ra_editor/src/folding_ranges.rs b/crates/ra_editor/src/folding_ranges.rs index 2a8fa3cda..da542ecf0 100644 --- a/crates/ra_editor/src/folding_ranges.rs +++ b/crates/ra_editor/src/folding_ranges.rs | |||
@@ -10,6 +10,7 @@ use ra_syntax::{ | |||
10 | pub enum FoldKind { | 10 | pub enum FoldKind { |
11 | Comment, | 11 | Comment, |
12 | Imports, | 12 | Imports, |
13 | Block, | ||
13 | } | 14 | } |
14 | 15 | ||
15 | #[derive(Debug)] | 16 | #[derive(Debug)] |
@@ -62,6 +63,8 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> { | |||
62 | match kind { | 63 | match kind { |
63 | COMMENT => Some(FoldKind::Comment), | 64 | COMMENT => Some(FoldKind::Comment), |
64 | USE_ITEM => Some(FoldKind::Imports), | 65 | USE_ITEM => Some(FoldKind::Imports), |
66 | NAMED_FIELD_DEF_LIST | FIELD_PAT_LIST | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST | ||
67 | | BLOCK | ENUM_VARIANT_LIST => Some(FoldKind::Block), | ||
65 | _ => None, | 68 | _ => None, |
66 | } | 69 | } |
67 | } | 70 | } |
@@ -170,7 +173,7 @@ mod tests { | |||
170 | use test_utils::extract_ranges; | 173 | use test_utils::extract_ranges; |
171 | 174 | ||
172 | fn do_check(text: &str, fold_kinds: &[FoldKind]) { | 175 | fn do_check(text: &str, fold_kinds: &[FoldKind]) { |
173 | let (ranges, text) = extract_ranges(text); | 176 | let (ranges, text) = extract_ranges(text, "fold"); |
174 | let file = SourceFileNode::parse(&text); | 177 | let file = SourceFileNode::parse(&text); |
175 | let folds = folding_ranges(&file); | 178 | let folds = folding_ranges(&file); |
176 | 179 | ||
@@ -198,26 +201,27 @@ mod tests { | |||
198 | #[test] | 201 | #[test] |
199 | fn test_fold_comments() { | 202 | fn test_fold_comments() { |
200 | let text = r#" | 203 | let text = r#" |
201 | <|>// Hello | 204 | <fold>// Hello |
202 | // this is a multiline | 205 | // this is a multiline |
203 | // comment | 206 | // comment |
204 | //<|> | 207 | //</fold> |
205 | 208 | ||
206 | // But this is not | 209 | // But this is not |
207 | 210 | ||
208 | fn main() { | 211 | fn main() <fold>{ |
209 | <|>// We should | 212 | <fold>// We should |
210 | // also | 213 | // also |
211 | // fold | 214 | // fold |
212 | // this one.<|> | 215 | // this one.</fold> |
213 | <|>//! But this one is different | 216 | <fold>//! But this one is different |
214 | //! because it has another flavor<|> | 217 | //! because it has another flavor</fold> |
215 | <|>/* As does this | 218 | <fold>/* As does this |
216 | multiline comment */<|> | 219 | multiline comment */</fold> |
217 | }"#; | 220 | }</fold>"#; |
218 | 221 | ||
219 | let fold_kinds = &[ | 222 | let fold_kinds = &[ |
220 | FoldKind::Comment, | 223 | FoldKind::Comment, |
224 | FoldKind::Block, | ||
221 | FoldKind::Comment, | 225 | FoldKind::Comment, |
222 | FoldKind::Comment, | 226 | FoldKind::Comment, |
223 | FoldKind::Comment, | 227 | FoldKind::Comment, |
@@ -228,60 +232,66 @@ fn main() { | |||
228 | #[test] | 232 | #[test] |
229 | fn test_fold_imports() { | 233 | fn test_fold_imports() { |
230 | let text = r#" | 234 | let text = r#" |
231 | <|>use std::{ | 235 | <fold>use std::<fold>{ |
232 | str, | 236 | str, |
233 | vec, | 237 | vec, |
234 | io as iop | 238 | io as iop |
235 | };<|> | 239 | }</fold>;</fold> |
236 | 240 | ||
237 | fn main() { | 241 | fn main() <fold>{ |
238 | }"#; | 242 | }</fold>"#; |
239 | 243 | ||
240 | let folds = &[FoldKind::Imports]; | 244 | let folds = &[FoldKind::Imports, FoldKind::Block, FoldKind::Block]; |
241 | do_check(text, folds); | 245 | do_check(text, folds); |
242 | } | 246 | } |
243 | 247 | ||
244 | #[test] | 248 | #[test] |
245 | fn test_fold_import_groups() { | 249 | fn test_fold_import_groups() { |
246 | let text = r#" | 250 | let text = r#" |
247 | <|>use std::str; | 251 | <fold>use std::str; |
248 | use std::vec; | 252 | use std::vec; |
249 | use std::io as iop;<|> | 253 | use std::io as iop;</fold> |
250 | 254 | ||
251 | <|>use std::mem; | 255 | <fold>use std::mem; |
252 | use std::f64;<|> | 256 | use std::f64;</fold> |
253 | 257 | ||
254 | use std::collections::HashMap; | 258 | use std::collections::HashMap; |
255 | // Some random comment | 259 | // Some random comment |
256 | use std::collections::VecDeque; | 260 | use std::collections::VecDeque; |
257 | 261 | ||
258 | fn main() { | 262 | fn main() <fold>{ |
259 | }"#; | 263 | }</fold>"#; |
260 | 264 | ||
261 | let folds = &[FoldKind::Imports, FoldKind::Imports]; | 265 | let folds = &[FoldKind::Imports, FoldKind::Imports, FoldKind::Block]; |
262 | do_check(text, folds); | 266 | do_check(text, folds); |
263 | } | 267 | } |
264 | 268 | ||
265 | #[test] | 269 | #[test] |
266 | fn test_fold_import_and_groups() { | 270 | fn test_fold_import_and_groups() { |
267 | let text = r#" | 271 | let text = r#" |
268 | <|>use std::str; | 272 | <fold>use std::str; |
269 | use std::vec; | 273 | use std::vec; |
270 | use std::io as iop;<|> | 274 | use std::io as iop;</fold> |
271 | 275 | ||
272 | <|>use std::mem; | 276 | <fold>use std::mem; |
273 | use std::f64;<|> | 277 | use std::f64;</fold> |
274 | 278 | ||
275 | <|>use std::collections::{ | 279 | <fold>use std::collections::<fold>{ |
276 | HashMap, | 280 | HashMap, |
277 | VecDeque, | 281 | VecDeque, |
278 | };<|> | 282 | }</fold>;</fold> |
279 | // Some random comment | 283 | // Some random comment |
280 | 284 | ||
281 | fn main() { | 285 | fn main() <fold>{ |
282 | }"#; | 286 | }</fold>"#; |
283 | 287 | ||
284 | let folds = &[FoldKind::Imports, FoldKind::Imports, FoldKind::Imports]; | 288 | let folds = &[ |
289 | FoldKind::Imports, | ||
290 | FoldKind::Imports, | ||
291 | FoldKind::Imports, | ||
292 | FoldKind::Block, | ||
293 | FoldKind::Block, | ||
294 | ]; | ||
285 | do_check(text, folds); | 295 | do_check(text, folds); |
286 | } | 296 | } |
287 | 297 | ||
diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index f3a346152..748fdb64e 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs | |||
@@ -4,7 +4,7 @@ use ra_syntax::{ | |||
4 | ast::{self, NameOwner}, | 4 | ast::{self, NameOwner}, |
5 | SmolStr, | 5 | SmolStr, |
6 | }; | 6 | }; |
7 | use relative_path::{RelativePathBuf, RelativePath}; | 7 | use relative_path::RelativePathBuf; |
8 | use rustc_hash::{FxHashMap, FxHashSet}; | 8 | use rustc_hash::{FxHashMap, FxHashSet}; |
9 | use arrayvec::ArrayVec; | 9 | use arrayvec::ArrayVec; |
10 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; | 10 | use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; |
@@ -184,11 +184,7 @@ fn resolve_submodule( | |||
184 | .collect::<Vec<_>>(); | 184 | .collect::<Vec<_>>(); |
185 | let problem = if points_to.is_empty() { | 185 | let problem = if points_to.is_empty() { |
186 | Some(Problem::UnresolvedModule { | 186 | Some(Problem::UnresolvedModule { |
187 | candidate: RelativePath::new("../").join(&if is_dir_owner { | 187 | candidate: if is_dir_owner { file_mod } else { file_dir_mod }, |
188 | file_mod | ||
189 | } else { | ||
190 | file_dir_mod | ||
191 | }), | ||
192 | }) | 188 | }) |
193 | } else { | 189 | } else { |
194 | None | 190 | None |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 7467f472c..218ded4ee 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -2,7 +2,7 @@ use languageserver_types::{ | |||
2 | self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, | 2 | self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, |
3 | TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, | 3 | TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, |
4 | }; | 4 | }; |
5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileNodeEdit, FilePosition}; | 5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition}; |
6 | use ra_editor::{LineCol, LineIndex}; | 6 | use ra_editor::{LineCol, LineIndex}; |
7 | use ra_text_edit::{AtomTextEdit, TextEdit}; | 7 | use ra_text_edit::{AtomTextEdit, TextEdit}; |
8 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | 8 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; |
@@ -97,21 +97,21 @@ impl ConvWith for TextEdit { | |||
97 | type Output = Vec<languageserver_types::TextEdit>; | 97 | type Output = Vec<languageserver_types::TextEdit>; |
98 | 98 | ||
99 | fn conv_with(self, line_index: &LineIndex) -> Vec<languageserver_types::TextEdit> { | 99 | fn conv_with(self, line_index: &LineIndex) -> Vec<languageserver_types::TextEdit> { |
100 | self.into_atoms() | 100 | self.as_atoms() |
101 | .into_iter() | 101 | .into_iter() |
102 | .map_conv_with(line_index) | 102 | .map_conv_with(line_index) |
103 | .collect() | 103 | .collect() |
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | impl ConvWith for AtomTextEdit { | 107 | impl<'a> ConvWith for &'a AtomTextEdit { |
108 | type Ctx = LineIndex; | 108 | type Ctx = LineIndex; |
109 | type Output = languageserver_types::TextEdit; | 109 | type Output = languageserver_types::TextEdit; |
110 | 110 | ||
111 | fn conv_with(self, line_index: &LineIndex) -> languageserver_types::TextEdit { | 111 | fn conv_with(self, line_index: &LineIndex) -> languageserver_types::TextEdit { |
112 | languageserver_types::TextEdit { | 112 | languageserver_types::TextEdit { |
113 | range: self.delete.conv_with(line_index), | 113 | range: self.delete.conv_with(line_index), |
114 | new_text: self.insert, | 114 | new_text: self.insert.clone(), |
115 | } | 115 | } |
116 | } | 116 | } |
117 | } | 117 | } |
@@ -199,7 +199,7 @@ impl TryConvWith for SourceChange { | |||
199 | .source_file_edits | 199 | .source_file_edits |
200 | .iter() | 200 | .iter() |
201 | .find(|it| it.file_id == pos.file_id) | 201 | .find(|it| it.file_id == pos.file_id) |
202 | .map(|it| it.edits.as_slice()) | 202 | .map(|it| it.edit.as_atoms()) |
203 | .unwrap_or(&[]); | 203 | .unwrap_or(&[]); |
204 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); | 204 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); |
205 | let position = | 205 | let position = |
@@ -256,7 +256,7 @@ fn translate_offset_with_edit( | |||
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | impl TryConvWith for SourceFileNodeEdit { | 259 | impl TryConvWith for SourceFileEdit { |
260 | type Ctx = ServerWorld; | 260 | type Ctx = ServerWorld; |
261 | type Output = TextDocumentEdit; | 261 | type Output = TextDocumentEdit; |
262 | fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> { | 262 | fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> { |
@@ -265,7 +265,12 @@ impl TryConvWith for SourceFileNodeEdit { | |||
265 | version: None, | 265 | version: None, |
266 | }; | 266 | }; |
267 | let line_index = world.analysis().file_line_index(self.file_id); | 267 | let line_index = world.analysis().file_line_index(self.file_id); |
268 | let edits = self.edits.into_iter().map_conv_with(&line_index).collect(); | 268 | let edits = self |
269 | .edit | ||
270 | .as_atoms() | ||
271 | .iter() | ||
272 | .map_conv_with(&line_index) | ||
273 | .collect(); | ||
269 | Ok(TextDocumentEdit { | 274 | Ok(TextDocumentEdit { |
270 | text_document, | 275 | text_document, |
271 | edits, | 276 | edits, |
@@ -278,16 +283,17 @@ impl TryConvWith for FileSystemEdit { | |||
278 | type Output = req::FileSystemEdit; | 283 | type Output = req::FileSystemEdit; |
279 | fn try_conv_with(self, world: &ServerWorld) -> Result<req::FileSystemEdit> { | 284 | fn try_conv_with(self, world: &ServerWorld) -> Result<req::FileSystemEdit> { |
280 | let res = match self { | 285 | let res = match self { |
281 | FileSystemEdit::CreateFile { anchor, path } => { | 286 | FileSystemEdit::CreateFile { source_root, path } => { |
282 | let uri = world.file_id_to_uri(anchor)?; | 287 | let uri = world.path_to_uri(source_root, &path)?; |
283 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird | ||
284 | let uri = uri.join(path)?; | ||
285 | req::FileSystemEdit::CreateFile { uri } | 288 | req::FileSystemEdit::CreateFile { uri } |
286 | } | 289 | } |
287 | FileSystemEdit::MoveFile { file, path } => { | 290 | FileSystemEdit::MoveFile { |
288 | let src = world.file_id_to_uri(file)?; | 291 | src, |
289 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird | 292 | dst_source_root, |
290 | let dst = src.join(path)?; | 293 | dst_path, |
294 | } => { | ||
295 | let src = world.file_id_to_uri(src)?; | ||
296 | let dst = world.path_to_uri(dst_source_root, &dst_path)?; | ||
291 | req::FileSystemEdit::MoveFile { src, dst } | 297 | req::FileSystemEdit::MoveFile { src, dst } |
292 | } | 298 | } |
293 | }; | 299 | }; |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 1d6e3e5d6..afe0fec89 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -387,7 +387,7 @@ impl<'a> PoolDispatcher<'a> { | |||
387 | RawResponse::err( | 387 | RawResponse::err( |
388 | id, | 388 | id, |
389 | ErrorCode::ContentModified as i32, | 389 | ErrorCode::ContentModified as i32, |
390 | e.to_string(), | 390 | format!("content modified: {}", e), |
391 | ) | 391 | ) |
392 | } else { | 392 | } else { |
393 | RawResponse::err( | 393 | RawResponse::err( |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 572ae7fb5..1751d7fa8 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -107,9 +107,16 @@ pub fn handle_on_type_formatting( | |||
107 | }; | 107 | }; |
108 | let edits = match world.analysis().on_eq_typed(position) { | 108 | let edits = match world.analysis().on_eq_typed(position) { |
109 | None => return Ok(None), | 109 | None => return Ok(None), |
110 | Some(mut action) => action.source_file_edits.pop().unwrap().edits, | 110 | Some(mut action) => action |
111 | .source_file_edits | ||
112 | .pop() | ||
113 | .unwrap() | ||
114 | .edit | ||
115 | .as_atoms() | ||
116 | .iter() | ||
117 | .map_conv_with(&line_index) | ||
118 | .collect(), | ||
111 | }; | 119 | }; |
112 | let edits = edits.into_iter().map_conv_with(&line_index).collect(); | ||
113 | Ok(Some(edits)) | 120 | Ok(Some(edits)) |
114 | } | 121 | } |
115 | 122 | ||
@@ -446,8 +453,9 @@ pub fn handle_folding_range( | |||
446 | .into_iter() | 453 | .into_iter() |
447 | .map(|fold| { | 454 | .map(|fold| { |
448 | let kind = match fold.kind { | 455 | let kind = match fold.kind { |
449 | FoldKind::Comment => FoldingRangeKind::Comment, | 456 | FoldKind::Comment => Some(FoldingRangeKind::Comment), |
450 | FoldKind::Imports => FoldingRangeKind::Imports, | 457 | FoldKind::Imports => Some(FoldingRangeKind::Imports), |
458 | FoldKind::Block => None, | ||
451 | }; | 459 | }; |
452 | let range = fold.range.conv_with(&line_index); | 460 | let range = fold.range.conv_with(&line_index); |
453 | FoldingRange { | 461 | FoldingRange { |
@@ -455,7 +463,7 @@ pub fn handle_folding_range( | |||
455 | start_character: Some(range.start.character), | 463 | start_character: Some(range.start.character), |
456 | end_line: range.end.line, | 464 | end_line: range.end.line, |
457 | end_character: Some(range.start.character), | 465 | end_character: Some(range.start.character), |
458 | kind: Some(kind), | 466 | kind, |
459 | } | 467 | } |
460 | }) | 468 | }) |
461 | .collect(), | 469 | .collect(), |
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 785877c4b..73cccc9dd 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -8,7 +8,7 @@ use ra_analysis::{ | |||
8 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, | 8 | Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, |
9 | SourceRootId | 9 | SourceRootId |
10 | }; | 10 | }; |
11 | use ra_vfs::{Vfs, VfsChange, VfsFile}; | 11 | use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; |
12 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
13 | use relative_path::RelativePathBuf; | 13 | use relative_path::RelativePathBuf; |
14 | use parking_lot::RwLock; | 14 | use parking_lot::RwLock; |
@@ -183,4 +183,12 @@ impl ServerWorld { | |||
183 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | 183 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; |
184 | Ok(url) | 184 | Ok(url) |
185 | } | 185 | } |
186 | |||
187 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { | ||
188 | let base = self.vfs.read().root2path(VfsRoot(root.0)); | ||
189 | let path = path.to_path(base); | ||
190 | let url = Url::from_file_path(&path) | ||
191 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | ||
192 | Ok(url) | ||
193 | } | ||
186 | } | 194 | } |
diff --git a/crates/ra_text_edit/src/text_edit.rs b/crates/ra_text_edit/src/text_edit.rs index fb46f046d..392968d63 100644 --- a/crates/ra_text_edit/src/text_edit.rs +++ b/crates/ra_text_edit/src/text_edit.rs | |||
@@ -41,8 +41,8 @@ impl TextEditBuilder { | |||
41 | } | 41 | } |
42 | 42 | ||
43 | impl TextEdit { | 43 | impl TextEdit { |
44 | pub fn into_atoms(self) -> Vec<AtomTextEdit> { | 44 | pub fn as_atoms(&self) -> &[AtomTextEdit] { |
45 | self.atoms | 45 | &self.atoms |
46 | } | 46 | } |
47 | 47 | ||
48 | pub fn apply(&self, text: &str) -> String { | 48 | pub fn apply(&self, text: &str) -> String { |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 0a94adb74..1ae800d7c 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -66,15 +66,40 @@ pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> { | |||
66 | Some((TextRange::from_to(start, end), text)) | 66 | Some((TextRange::from_to(start, end), text)) |
67 | } | 67 | } |
68 | 68 | ||
69 | pub fn extract_ranges(text: &str) -> (Vec<TextRange>, String) { | 69 | /// Extracts ranges, marked with `<tag> </tag>` paris from the `text` |
70 | pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) { | ||
71 | let open = format!("<{}>", tag); | ||
72 | let close = format!("</{}>", tag); | ||
70 | let mut ranges = Vec::new(); | 73 | let mut ranges = Vec::new(); |
71 | let mut text = String::from(text); | 74 | let mut res = String::new(); |
72 | while let Some((range, new_text)) = try_extract_range(&text) { | 75 | let mut stack = Vec::new(); |
73 | text = new_text; | 76 | loop { |
74 | ranges.push(range); | 77 | match text.find('<') { |
78 | None => { | ||
79 | res.push_str(text); | ||
80 | break; | ||
81 | } | ||
82 | Some(i) => { | ||
83 | res.push_str(&text[..i]); | ||
84 | text = &text[i..]; | ||
85 | if text.starts_with(&open) { | ||
86 | text = &text[open.len()..]; | ||
87 | let from = TextUnit::of_str(&res); | ||
88 | stack.push(from); | ||
89 | } else if text.starts_with(&close) { | ||
90 | text = &text[close.len()..]; | ||
91 | let from = stack | ||
92 | .pop() | ||
93 | .unwrap_or_else(|| panic!("unmatched </{}>", tag)); | ||
94 | let to = TextUnit::of_str(&res); | ||
95 | ranges.push(TextRange::from_to(from, to)); | ||
96 | } | ||
97 | } | ||
98 | } | ||
75 | } | 99 | } |
76 | 100 | assert!(stack.is_empty(), "unmatched <{}>", tag); | |
77 | (ranges, text) | 101 | ranges.sort_by_key(|r| (r.start(), r.end())); |
102 | (ranges, res) | ||
78 | } | 103 | } |
79 | 104 | ||
80 | pub fn add_cursor(text: &str, offset: TextUnit) -> String { | 105 | pub fn add_cursor(text: &str, offset: TextUnit) -> String { |
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 580d8b802..2795afe0b 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs | |||
@@ -15,7 +15,7 @@ pub type Result<T> = std::result::Result<T, failure::Error>; | |||
15 | pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron"; | 15 | pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron"; |
16 | pub const SYNTAX_KINDS: &str = "crates/ra_syntax/src/syntax_kinds/generated.rs.tera"; | 16 | pub const SYNTAX_KINDS: &str = "crates/ra_syntax/src/syntax_kinds/generated.rs.tera"; |
17 | pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs.tera"; | 17 | pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs.tera"; |
18 | const TOOLCHAIN: &str = "1.31.0"; | 18 | const TOOLCHAIN: &str = "1.31.1"; |
19 | 19 | ||
20 | #[derive(Debug)] | 20 | #[derive(Debug)] |
21 | pub struct Test { | 21 | pub struct Test { |