diff options
Diffstat (limited to 'crates')
61 files changed, 623 insertions, 529 deletions
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index deb9f95d7..3bbcdb0b8 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -16,11 +16,7 @@ use vfs_filter::IncludeRustFiles; | |||
16 | 16 | ||
17 | type Result<T> = std::result::Result<T, failure::Error>; | 17 | type Result<T> = std::result::Result<T, failure::Error>; |
18 | 18 | ||
19 | #[salsa::database( | 19 | #[salsa::database(ra_db::SourceDatabaseStorage, db::HirDatabaseStorage, db::DefDatabaseStorage)] |
20 | ra_db::SourceDatabaseStorage, | ||
21 | db::HirDatabaseStorage, | ||
22 | db::PersistentHirDatabaseStorage | ||
23 | )] | ||
24 | #[derive(Debug)] | 20 | #[derive(Debug)] |
25 | pub struct BatchDatabase { | 21 | pub struct BatchDatabase { |
26 | runtime: salsa::Runtime<BatchDatabase>, | 22 | runtime: salsa::Runtime<BatchDatabase>, |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 2b1001d48..a5f4e489f 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -136,7 +136,7 @@ impl CrateGraph { | |||
136 | self.arena[&crate_id].edition | 136 | self.arena[&crate_id].edition |
137 | } | 137 | } |
138 | 138 | ||
139 | // TODO: this only finds one crate with the given root; we could have multiple | 139 | // FIXME: this only finds one crate with the given root; we could have multiple |
140 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 140 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
141 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; | 141 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; |
142 | Some(crate_id) | 142 | Some(crate_id) |
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 325f1d7b6..78ea8976b 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | use crate::{ | 12 | use crate::{ |
13 | Name, AsName, Struct, Enum, EnumVariant, Crate, | 13 | Name, AsName, Struct, Enum, EnumVariant, Crate, |
14 | HirDatabase, HirFileId, StructField, FieldSource, | 14 | HirDatabase, HirFileId, StructField, FieldSource, |
15 | type_ref::TypeRef, PersistentHirDatabase, | 15 | type_ref::TypeRef, DefDatabase, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 18 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
@@ -33,7 +33,7 @@ impl AdtDef { | |||
33 | } | 33 | } |
34 | 34 | ||
35 | impl Struct { | 35 | impl Struct { |
36 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { | 36 | pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> { |
37 | db.struct_data((*self).into()).variant_data.clone() | 37 | db.struct_data((*self).into()).variant_data.clone() |
38 | } | 38 | } |
39 | } | 39 | } |
@@ -52,10 +52,7 @@ impl StructData { | |||
52 | StructData { name, variant_data } | 52 | StructData { name, variant_data } |
53 | } | 53 | } |
54 | 54 | ||
55 | pub(crate) fn struct_data_query( | 55 | pub(crate) fn struct_data_query(db: &impl DefDatabase, struct_: Struct) -> Arc<StructData> { |
56 | db: &impl PersistentHirDatabase, | ||
57 | struct_: Struct, | ||
58 | ) -> Arc<StructData> { | ||
59 | let (_, struct_def) = struct_.source(db); | 56 | let (_, struct_def) = struct_.source(db); |
60 | Arc::new(StructData::new(&*struct_def)) | 57 | Arc::new(StructData::new(&*struct_def)) |
61 | } | 58 | } |
@@ -68,7 +65,7 @@ fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> | |||
68 | impl EnumVariant { | 65 | impl EnumVariant { |
69 | pub(crate) fn source_impl( | 66 | pub(crate) fn source_impl( |
70 | &self, | 67 | &self, |
71 | db: &impl PersistentHirDatabase, | 68 | db: &impl DefDatabase, |
72 | ) -> (HirFileId, TreeArc<ast::EnumVariant>) { | 69 | ) -> (HirFileId, TreeArc<ast::EnumVariant>) { |
73 | let (file_id, enum_def) = self.parent.source(db); | 70 | let (file_id, enum_def) = self.parent.source(db); |
74 | let var = variants(&*enum_def) | 71 | let var = variants(&*enum_def) |
@@ -79,7 +76,7 @@ impl EnumVariant { | |||
79 | .to_owned(); | 76 | .to_owned(); |
80 | (file_id, var) | 77 | (file_id, var) |
81 | } | 78 | } |
82 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { | 79 | pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> { |
83 | db.enum_data(self.parent).variants[self.id].variant_data.clone() | 80 | db.enum_data(self.parent).variants[self.id].variant_data.clone() |
84 | } | 81 | } |
85 | } | 82 | } |
@@ -91,7 +88,7 @@ pub struct EnumData { | |||
91 | } | 88 | } |
92 | 89 | ||
93 | impl EnumData { | 90 | impl EnumData { |
94 | pub(crate) fn enum_data_query(db: &impl PersistentHirDatabase, e: Enum) -> Arc<EnumData> { | 91 | pub(crate) fn enum_data_query(db: &impl DefDatabase, e: Enum) -> Arc<EnumData> { |
95 | let (_file_id, enum_def) = e.source(db); | 92 | let (_file_id, enum_def) = e.source(db); |
96 | let name = enum_def.name().map(|n| n.as_name()); | 93 | let name = enum_def.name().map(|n| n.as_name()); |
97 | let variants = variants(&*enum_def) | 94 | let variants = variants(&*enum_def) |
@@ -189,7 +186,7 @@ impl VariantDef { | |||
189 | VariantDef::EnumVariant(it) => it.field(db, name), | 186 | VariantDef::EnumVariant(it) => it.field(db, name), |
190 | } | 187 | } |
191 | } | 188 | } |
192 | pub(crate) fn variant_data(self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { | 189 | pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { |
193 | match self { | 190 | match self { |
194 | VariantDef::Struct(it) => it.variant_data(db), | 191 | VariantDef::Struct(it) => it.variant_data(db), |
195 | VariantDef::EnumVariant(it) => it.variant_data(db), | 192 | VariantDef::EnumVariant(it) => it.variant_data(db), |
@@ -198,7 +195,7 @@ impl VariantDef { | |||
198 | } | 195 | } |
199 | 196 | ||
200 | impl StructField { | 197 | impl StructField { |
201 | pub(crate) fn source_impl(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { | 198 | pub(crate) fn source_impl(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) { |
202 | let var_data = self.parent.variant_data(db); | 199 | let var_data = self.parent.variant_data(db); |
203 | let fields = var_data.fields().unwrap(); | 200 | let fields = var_data.fields().unwrap(); |
204 | let ss; | 201 | let ss; |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index b00481cd5..45fa4cd11 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -6,7 +6,7 @@ use ra_syntax::{ast::self, TreeArc, SyntaxNode}; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | Name, ScopesWithSourceMap, Ty, HirFileId, | 8 | Name, ScopesWithSourceMap, Ty, HirFileId, |
9 | HirDatabase, PersistentHirDatabase, | 9 | HirDatabase, DefDatabase, |
10 | type_ref::TypeRef, | 10 | type_ref::TypeRef, |
11 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, | 11 | nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, |
12 | expr::{Body, BodySourceMap}, | 12 | expr::{Body, BodySourceMap}, |
@@ -38,24 +38,21 @@ impl Crate { | |||
38 | self.crate_id | 38 | self.crate_id |
39 | } | 39 | } |
40 | 40 | ||
41 | pub fn dependencies(&self, db: &impl PersistentHirDatabase) -> Vec<CrateDependency> { | 41 | pub fn dependencies(&self, db: &impl DefDatabase) -> Vec<CrateDependency> { |
42 | self.dependencies_impl(db) | 42 | self.dependencies_impl(db) |
43 | } | 43 | } |
44 | 44 | ||
45 | pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { | 45 | pub fn root_module(&self, db: &impl DefDatabase) -> Option<Module> { |
46 | self.root_module_impl(db) | 46 | self.root_module_impl(db) |
47 | } | 47 | } |
48 | 48 | ||
49 | pub fn edition(&self, db: &impl PersistentHirDatabase) -> Edition { | 49 | pub fn edition(&self, db: &impl DefDatabase) -> Edition { |
50 | let crate_graph = db.crate_graph(); | 50 | let crate_graph = db.crate_graph(); |
51 | crate_graph.edition(self.crate_id) | 51 | crate_graph.edition(self.crate_id) |
52 | } | 52 | } |
53 | 53 | ||
54 | // TODO: should this be in source_binder? | 54 | // FIXME: should this be in source_binder? |
55 | pub fn source_root_crates( | 55 | pub fn source_root_crates(db: &impl DefDatabase, source_root: SourceRootId) -> Vec<Crate> { |
56 | db: &impl PersistentHirDatabase, | ||
57 | source_root: SourceRootId, | ||
58 | ) -> Vec<Crate> { | ||
59 | let crate_ids = db.source_root_crates(source_root); | 56 | let crate_ids = db.source_root_crates(source_root); |
60 | crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() | 57 | crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() |
61 | } | 58 | } |
@@ -101,7 +98,6 @@ pub enum ModuleSource { | |||
101 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | 98 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] |
102 | pub enum Problem { | 99 | pub enum Problem { |
103 | UnresolvedModule { candidate: RelativePathBuf }, | 100 | UnresolvedModule { candidate: RelativePathBuf }, |
104 | NotDirOwner { move_to: RelativePathBuf, candidate: RelativePathBuf }, | ||
105 | } | 101 | } |
106 | 102 | ||
107 | impl Module { | 103 | impl Module { |
@@ -111,7 +107,7 @@ impl Module { | |||
111 | } | 107 | } |
112 | 108 | ||
113 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 109 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
114 | pub fn definition_source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, ModuleSource) { | 110 | pub fn definition_source(&self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) { |
115 | self.definition_source_impl(db) | 111 | self.definition_source_impl(db) |
116 | } | 112 | } |
117 | 113 | ||
@@ -134,14 +130,14 @@ impl Module { | |||
134 | } | 130 | } |
135 | 131 | ||
136 | /// Returns the crate this module is part of. | 132 | /// Returns the crate this module is part of. |
137 | pub fn krate(&self, _db: &impl PersistentHirDatabase) -> Option<Crate> { | 133 | pub fn krate(&self, _db: &impl DefDatabase) -> Option<Crate> { |
138 | Some(self.krate) | 134 | Some(self.krate) |
139 | } | 135 | } |
140 | 136 | ||
141 | /// Topmost parent of this module. Every module has a `crate_root`, but some | 137 | /// Topmost parent of this module. Every module has a `crate_root`, but some |
142 | /// might be missing `krate`. This can happen if a module's file is not included | 138 | /// might be missing `krate`. This can happen if a module's file is not included |
143 | /// in the module tree of any target in `Cargo.toml`. | 139 | /// in the module tree of any target in `Cargo.toml`. |
144 | pub fn crate_root(&self, db: &impl PersistentHirDatabase) -> Module { | 140 | pub fn crate_root(&self, db: &impl DefDatabase) -> Module { |
145 | self.crate_root_impl(db) | 141 | self.crate_root_impl(db) |
146 | } | 142 | } |
147 | 143 | ||
@@ -151,12 +147,12 @@ impl Module { | |||
151 | } | 147 | } |
152 | 148 | ||
153 | /// Iterates over all child modules. | 149 | /// Iterates over all child modules. |
154 | pub fn children(&self, db: &impl PersistentHirDatabase) -> impl Iterator<Item = Module> { | 150 | pub fn children(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
155 | self.children_impl(db) | 151 | self.children_impl(db) |
156 | } | 152 | } |
157 | 153 | ||
158 | /// Finds a parent module. | 154 | /// Finds a parent module. |
159 | pub fn parent(&self, db: &impl PersistentHirDatabase) -> Option<Module> { | 155 | pub fn parent(&self, db: &impl DefDatabase) -> Option<Module> { |
160 | self.parent_impl(db) | 156 | self.parent_impl(db) |
161 | } | 157 | } |
162 | 158 | ||
@@ -229,7 +225,7 @@ impl StructField { | |||
229 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() | 225 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() |
230 | } | 226 | } |
231 | 227 | ||
232 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { | 228 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, FieldSource) { |
233 | self.source_impl(db) | 229 | self.source_impl(db) |
234 | } | 230 | } |
235 | 231 | ||
@@ -257,7 +253,7 @@ pub struct Struct { | |||
257 | } | 253 | } |
258 | 254 | ||
259 | impl Struct { | 255 | impl Struct { |
260 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { | 256 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { |
261 | self.id.source(db) | 257 | self.id.source(db) |
262 | } | 258 | } |
263 | 259 | ||
@@ -289,7 +285,7 @@ impl Struct { | |||
289 | .map(|(id, _)| StructField { parent: (*self).into(), id }) | 285 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
290 | } | 286 | } |
291 | 287 | ||
292 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 288 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
293 | db.generic_params((*self).into()) | 289 | db.generic_params((*self).into()) |
294 | } | 290 | } |
295 | 291 | ||
@@ -301,7 +297,7 @@ impl Struct { | |||
301 | db.type_for_def((*self).into(), Namespace::Values) | 297 | db.type_for_def((*self).into(), Namespace::Values) |
302 | } | 298 | } |
303 | 299 | ||
304 | // TODO move to a more general type | 300 | // FIXME move to a more general type |
305 | /// Builds a resolver for type references inside this struct. | 301 | /// Builds a resolver for type references inside this struct. |
306 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 302 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
307 | // take the outer scope... | 303 | // take the outer scope... |
@@ -325,7 +321,7 @@ pub struct Enum { | |||
325 | } | 321 | } |
326 | 322 | ||
327 | impl Enum { | 323 | impl Enum { |
328 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { | 324 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { |
329 | self.id.source(db) | 325 | self.id.source(db) |
330 | } | 326 | } |
331 | 327 | ||
@@ -337,7 +333,7 @@ impl Enum { | |||
337 | db.enum_data(*self).name.clone() | 333 | db.enum_data(*self).name.clone() |
338 | } | 334 | } |
339 | 335 | ||
340 | pub fn variants(&self, db: &impl PersistentHirDatabase) -> Vec<EnumVariant> { | 336 | pub fn variants(&self, db: &impl DefDatabase) -> Vec<EnumVariant> { |
341 | db.enum_data(*self) | 337 | db.enum_data(*self) |
342 | .variants | 338 | .variants |
343 | .iter() | 339 | .iter() |
@@ -345,7 +341,7 @@ impl Enum { | |||
345 | .collect() | 341 | .collect() |
346 | } | 342 | } |
347 | 343 | ||
348 | pub fn variant(&self, db: &impl PersistentHirDatabase, name: &Name) -> Option<EnumVariant> { | 344 | pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { |
349 | db.enum_data(*self) | 345 | db.enum_data(*self) |
350 | .variants | 346 | .variants |
351 | .iter() | 347 | .iter() |
@@ -353,7 +349,7 @@ impl Enum { | |||
353 | .map(|(id, _)| EnumVariant { parent: *self, id }) | 349 | .map(|(id, _)| EnumVariant { parent: *self, id }) |
354 | } | 350 | } |
355 | 351 | ||
356 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 352 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
357 | db.generic_params((*self).into()) | 353 | db.generic_params((*self).into()) |
358 | } | 354 | } |
359 | 355 | ||
@@ -361,7 +357,7 @@ impl Enum { | |||
361 | db.type_for_def((*self).into(), Namespace::Types) | 357 | db.type_for_def((*self).into(), Namespace::Types) |
362 | } | 358 | } |
363 | 359 | ||
364 | // TODO: move to a more general type | 360 | // FIXME: move to a more general type |
365 | /// Builds a resolver for type references inside this struct. | 361 | /// Builds a resolver for type references inside this struct. |
366 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 362 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
367 | // take the outer scope... | 363 | // take the outer scope... |
@@ -386,20 +382,17 @@ pub struct EnumVariant { | |||
386 | } | 382 | } |
387 | 383 | ||
388 | impl EnumVariant { | 384 | impl EnumVariant { |
389 | pub fn source( | 385 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) { |
390 | &self, | ||
391 | db: &impl PersistentHirDatabase, | ||
392 | ) -> (HirFileId, TreeArc<ast::EnumVariant>) { | ||
393 | self.source_impl(db) | 386 | self.source_impl(db) |
394 | } | 387 | } |
395 | pub fn module(&self, db: &impl HirDatabase) -> Module { | 388 | pub fn module(&self, db: &impl HirDatabase) -> Module { |
396 | self.parent.module(db) | 389 | self.parent.module(db) |
397 | } | 390 | } |
398 | pub fn parent_enum(&self, _db: &impl PersistentHirDatabase) -> Enum { | 391 | pub fn parent_enum(&self, _db: &impl DefDatabase) -> Enum { |
399 | self.parent | 392 | self.parent |
400 | } | 393 | } |
401 | 394 | ||
402 | pub fn name(&self, db: &impl PersistentHirDatabase) -> Option<Name> { | 395 | pub fn name(&self, db: &impl DefDatabase) -> Option<Name> { |
403 | db.enum_data(self.parent).variants[self.id].name.clone() | 396 | db.enum_data(self.parent).variants[self.id].name.clone() |
404 | } | 397 | } |
405 | 398 | ||
@@ -465,11 +458,11 @@ impl FnSignature { | |||
465 | } | 458 | } |
466 | 459 | ||
467 | impl Function { | 460 | impl Function { |
468 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::FnDef>) { | 461 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::FnDef>) { |
469 | self.id.source(db) | 462 | self.id.source(db) |
470 | } | 463 | } |
471 | 464 | ||
472 | pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { | 465 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
473 | self.id.module(db) | 466 | self.id.module(db) |
474 | } | 467 | } |
475 | 468 | ||
@@ -503,17 +496,17 @@ impl Function { | |||
503 | db.infer(*self) | 496 | db.infer(*self) |
504 | } | 497 | } |
505 | 498 | ||
506 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 499 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
507 | db.generic_params((*self).into()) | 500 | db.generic_params((*self).into()) |
508 | } | 501 | } |
509 | 502 | ||
510 | /// The containing impl block, if this is a method. | 503 | /// The containing impl block, if this is a method. |
511 | pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { | 504 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { |
512 | let module_impls = db.impls_in_module(self.module(db)); | 505 | let module_impls = db.impls_in_module(self.module(db)); |
513 | ImplBlock::containing(module_impls, (*self).into()) | 506 | ImplBlock::containing(module_impls, (*self).into()) |
514 | } | 507 | } |
515 | 508 | ||
516 | // TODO: move to a more general type for 'body-having' items | 509 | // FIXME: move to a more general type for 'body-having' items |
517 | /// Builds a resolver for code inside this item. | 510 | /// Builds a resolver for code inside this item. |
518 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 511 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
519 | // take the outer scope... | 512 | // take the outer scope... |
@@ -540,11 +533,11 @@ pub struct Const { | |||
540 | } | 533 | } |
541 | 534 | ||
542 | impl Const { | 535 | impl Const { |
543 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) { | 536 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) { |
544 | self.id.source(db) | 537 | self.id.source(db) |
545 | } | 538 | } |
546 | 539 | ||
547 | pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { | 540 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
548 | self.id.module(db) | 541 | self.id.module(db) |
549 | } | 542 | } |
550 | 543 | ||
@@ -553,12 +546,12 @@ impl Const { | |||
553 | } | 546 | } |
554 | 547 | ||
555 | /// The containing impl block, if this is a method. | 548 | /// The containing impl block, if this is a method. |
556 | pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { | 549 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { |
557 | let module_impls = db.impls_in_module(self.module(db)); | 550 | let module_impls = db.impls_in_module(self.module(db)); |
558 | ImplBlock::containing(module_impls, (*self).into()) | 551 | ImplBlock::containing(module_impls, (*self).into()) |
559 | } | 552 | } |
560 | 553 | ||
561 | // TODO: move to a more general type for 'body-having' items | 554 | // FIXME: move to a more general type for 'body-having' items |
562 | /// Builds a resolver for code inside this item. | 555 | /// Builds a resolver for code inside this item. |
563 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 556 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
564 | // take the outer scope... | 557 | // take the outer scope... |
@@ -599,11 +592,11 @@ pub struct Static { | |||
599 | } | 592 | } |
600 | 593 | ||
601 | impl Static { | 594 | impl Static { |
602 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) { | 595 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) { |
603 | self.id.source(db) | 596 | self.id.source(db) |
604 | } | 597 | } |
605 | 598 | ||
606 | pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { | 599 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
607 | self.id.module(db) | 600 | self.id.module(db) |
608 | } | 601 | } |
609 | 602 | ||
@@ -630,15 +623,15 @@ pub struct Trait { | |||
630 | } | 623 | } |
631 | 624 | ||
632 | impl Trait { | 625 | impl Trait { |
633 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) { | 626 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) { |
634 | self.id.source(db) | 627 | self.id.source(db) |
635 | } | 628 | } |
636 | 629 | ||
637 | pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { | 630 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
638 | self.id.module(db) | 631 | self.id.module(db) |
639 | } | 632 | } |
640 | 633 | ||
641 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 634 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
642 | db.generic_params((*self).into()) | 635 | db.generic_params((*self).into()) |
643 | } | 636 | } |
644 | } | 637 | } |
@@ -655,28 +648,25 @@ pub struct TypeAlias { | |||
655 | } | 648 | } |
656 | 649 | ||
657 | impl TypeAlias { | 650 | impl TypeAlias { |
658 | pub fn source( | 651 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::TypeAliasDef>) { |
659 | &self, | ||
660 | db: &impl PersistentHirDatabase, | ||
661 | ) -> (HirFileId, TreeArc<ast::TypeAliasDef>) { | ||
662 | self.id.source(db) | 652 | self.id.source(db) |
663 | } | 653 | } |
664 | 654 | ||
665 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 655 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
666 | db.generic_params((*self).into()) | 656 | db.generic_params((*self).into()) |
667 | } | 657 | } |
668 | 658 | ||
669 | pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { | 659 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
670 | self.id.module(db) | 660 | self.id.module(db) |
671 | } | 661 | } |
672 | 662 | ||
673 | /// The containing impl block, if this is a method. | 663 | /// The containing impl block, if this is a method. |
674 | pub fn impl_block(&self, db: &impl PersistentHirDatabase) -> Option<ImplBlock> { | 664 | pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> { |
675 | let module_impls = db.impls_in_module(self.module(db)); | 665 | let module_impls = db.impls_in_module(self.module(db)); |
676 | ImplBlock::containing(module_impls, (*self).into()) | 666 | ImplBlock::containing(module_impls, (*self).into()) |
677 | } | 667 | } |
678 | 668 | ||
679 | pub fn type_ref(self, db: &impl PersistentHirDatabase) -> Arc<TypeRef> { | 669 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { |
680 | db.type_alias_ref(self) | 670 | db.type_alias_ref(self) |
681 | } | 671 | } |
682 | 672 | ||
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index c1654b069..334cb302b 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -5,14 +5,11 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
5 | use crate::{ | 5 | use crate::{ |
6 | Name, AsName, Function, FnSignature, | 6 | Name, AsName, Function, FnSignature, |
7 | type_ref::{TypeRef, Mutability}, | 7 | type_ref::{TypeRef, Mutability}, |
8 | PersistentHirDatabase, | 8 | DefDatabase, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl FnSignature { | 11 | impl FnSignature { |
12 | pub(crate) fn fn_signature_query( | 12 | pub(crate) fn fn_signature_query(db: &impl DefDatabase, func: Function) -> Arc<FnSignature> { |
13 | db: &impl PersistentHirDatabase, | ||
14 | func: Function, | ||
15 | ) -> Arc<FnSignature> { | ||
16 | let (_, node) = func.source(db); | 13 | let (_, node) = func.source(db); |
17 | let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | 14 | let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); |
18 | let mut params = Vec::new(); | 15 | let mut params = Vec::new(); |
diff --git a/crates/ra_hir/src/code_model_impl/konst.rs b/crates/ra_hir/src/code_model_impl/konst.rs index 8b861a81f..db4e5ce5c 100644 --- a/crates/ra_hir/src/code_model_impl/konst.rs +++ b/crates/ra_hir/src/code_model_impl/konst.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::ast::{NameOwner, TypeAscriptionOwner}; | |||
5 | use crate::{ | 5 | use crate::{ |
6 | Name, AsName, Const, ConstSignature, Static, | 6 | Name, AsName, Const, ConstSignature, Static, |
7 | type_ref::{TypeRef}, | 7 | type_ref::{TypeRef}, |
8 | PersistentHirDatabase, | 8 | DefDatabase, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> { | 11 | fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstSignature> { |
@@ -17,7 +17,7 @@ fn const_signature_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<Cons | |||
17 | 17 | ||
18 | impl ConstSignature { | 18 | impl ConstSignature { |
19 | pub(crate) fn const_signature_query( | 19 | pub(crate) fn const_signature_query( |
20 | db: &impl PersistentHirDatabase, | 20 | db: &impl DefDatabase, |
21 | konst: Const, | 21 | konst: Const, |
22 | ) -> Arc<ConstSignature> { | 22 | ) -> Arc<ConstSignature> { |
23 | let (_, node) = konst.source(db); | 23 | let (_, node) = konst.source(db); |
@@ -25,7 +25,7 @@ impl ConstSignature { | |||
25 | } | 25 | } |
26 | 26 | ||
27 | pub(crate) fn static_signature_query( | 27 | pub(crate) fn static_signature_query( |
28 | db: &impl PersistentHirDatabase, | 28 | db: &impl DefDatabase, |
29 | konst: Static, | 29 | konst: Static, |
30 | ) -> Arc<ConstSignature> { | 30 | ) -> Arc<ConstSignature> { |
31 | let (_, node) = konst.source(db); | 31 | let (_, node) = konst.source(db); |
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index cc87c6f14..914414fc3 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -1,12 +1,9 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | Crate, CrateDependency, AsName, Module, PersistentHirDatabase, | 2 | Crate, CrateDependency, AsName, Module, DefDatabase, |
3 | }; | 3 | }; |
4 | 4 | ||
5 | impl Crate { | 5 | impl Crate { |
6 | pub(crate) fn dependencies_impl( | 6 | pub(crate) fn dependencies_impl(&self, db: &impl DefDatabase) -> Vec<CrateDependency> { |
7 | &self, | ||
8 | db: &impl PersistentHirDatabase, | ||
9 | ) -> Vec<CrateDependency> { | ||
10 | let crate_graph = db.crate_graph(); | 7 | let crate_graph = db.crate_graph(); |
11 | crate_graph | 8 | crate_graph |
12 | .dependencies(self.crate_id) | 9 | .dependencies(self.crate_id) |
@@ -17,7 +14,7 @@ impl Crate { | |||
17 | }) | 14 | }) |
18 | .collect() | 15 | .collect() |
19 | } | 16 | } |
20 | pub(crate) fn root_module_impl(&self, db: &impl PersistentHirDatabase) -> Option<Module> { | 17 | pub(crate) fn root_module_impl(&self, db: &impl DefDatabase) -> Option<Module> { |
21 | let module_id = db.crate_def_map(*self).root(); | 18 | let module_id = db.crate_def_map(*self).root(); |
22 | let module = Module { krate: *self, module_id }; | 19 | let module = Module { krate: *self, module_id }; |
23 | Some(module) | 20 | Some(module) |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index f7d15c55e..52a33e981 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -4,13 +4,13 @@ use ra_syntax::{ast, SyntaxNode, TreeArc, AstNode}; | |||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Problem, Name, | 5 | Module, ModuleSource, Problem, Name, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::{CrateModuleId, ImportId}, |
7 | HirDatabase, PersistentHirDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, SourceItemId, | 8 | HirFileId, SourceItemId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl ModuleSource { | 11 | impl ModuleSource { |
12 | pub(crate) fn new( | 12 | pub(crate) fn new( |
13 | db: &impl PersistentHirDatabase, | 13 | db: &impl DefDatabase, |
14 | file_id: Option<FileId>, | 14 | file_id: Option<FileId>, |
15 | decl_id: Option<SourceItemId>, | 15 | decl_id: Option<SourceItemId>, |
16 | ) -> ModuleSource { | 16 | ) -> ModuleSource { |
@@ -49,7 +49,7 @@ impl Module { | |||
49 | 49 | ||
50 | pub(crate) fn definition_source_impl( | 50 | pub(crate) fn definition_source_impl( |
51 | &self, | 51 | &self, |
52 | db: &impl PersistentHirDatabase, | 52 | db: &impl DefDatabase, |
53 | ) -> (HirFileId, ModuleSource) { | 53 | ) -> (HirFileId, ModuleSource) { |
54 | let def_map = db.crate_def_map(self.krate); | 54 | let def_map = db.crate_def_map(self.krate); |
55 | let decl_id = def_map[self.module_id].declaration; | 55 | let decl_id = def_map[self.module_id].declaration; |
@@ -80,7 +80,7 @@ impl Module { | |||
80 | source_map.get(&source, import) | 80 | source_map.get(&source, import) |
81 | } | 81 | } |
82 | 82 | ||
83 | pub(crate) fn crate_root_impl(&self, db: &impl PersistentHirDatabase) -> Module { | 83 | pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module { |
84 | let def_map = db.crate_def_map(self.krate); | 84 | let def_map = db.crate_def_map(self.krate); |
85 | self.with_module_id(def_map.root()) | 85 | self.with_module_id(def_map.root()) |
86 | } | 86 | } |
@@ -93,10 +93,7 @@ impl Module { | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /// Iterates over all child modules. | 95 | /// Iterates over all child modules. |
96 | pub(crate) fn children_impl( | 96 | pub(crate) fn children_impl(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { |
97 | &self, | ||
98 | db: &impl PersistentHirDatabase, | ||
99 | ) -> impl Iterator<Item = Module> { | ||
100 | let def_map = db.crate_def_map(self.krate); | 97 | let def_map = db.crate_def_map(self.krate); |
101 | let children = def_map[self.module_id] | 98 | let children = def_map[self.module_id] |
102 | .children | 99 | .children |
@@ -106,7 +103,7 @@ impl Module { | |||
106 | children.into_iter() | 103 | children.into_iter() |
107 | } | 104 | } |
108 | 105 | ||
109 | pub(crate) fn parent_impl(&self, db: &impl PersistentHirDatabase) -> Option<Module> { | 106 | pub(crate) fn parent_impl(&self, db: &impl DefDatabase) -> Option<Module> { |
110 | let def_map = db.crate_def_map(self.krate); | 107 | let def_map = db.crate_def_map(self.krate); |
111 | let parent_id = def_map[self.module_id].parent?; | 108 | let parent_id = def_map[self.module_id].parent?; |
112 | Some(self.with_module_id(parent_id)) | 109 | Some(self.with_module_id(parent_id)) |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index c7bad7e2b..d3908f8ac 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -16,8 +16,8 @@ use crate::{ | |||
16 | type_ref::TypeRef, | 16 | type_ref::TypeRef, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | #[salsa::query_group(PersistentHirDatabaseStorage)] | 19 | #[salsa::query_group(DefDatabaseStorage)] |
20 | pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> { | 20 | pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { |
21 | #[salsa::invoke(HirFileId::hir_parse)] | 21 | #[salsa::invoke(HirFileId::hir_parse)] |
22 | fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; | 22 | fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; |
23 | 23 | ||
@@ -71,7 +71,7 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> { | |||
71 | } | 71 | } |
72 | 72 | ||
73 | #[salsa::query_group(HirDatabaseStorage)] | 73 | #[salsa::query_group(HirDatabaseStorage)] |
74 | pub trait HirDatabase: PersistentHirDatabase { | 74 | pub trait HirDatabase: DefDatabase { |
75 | #[salsa::invoke(ExprScopes::expr_scopes_query)] | 75 | #[salsa::invoke(ExprScopes::expr_scopes_query)] |
76 | fn expr_scopes(&self, func: Function) -> Arc<ExprScopes>; | 76 | fn expr_scopes(&self, func: Function) -> Arc<ExprScopes>; |
77 | 77 | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 0fadab560..703d99d9b 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -27,7 +27,7 @@ impl_arena_id!(ExprId); | |||
27 | /// The body of an item (function, const etc.). | 27 | /// The body of an item (function, const etc.). |
28 | #[derive(Debug, Eq, PartialEq)] | 28 | #[derive(Debug, Eq, PartialEq)] |
29 | pub struct Body { | 29 | pub struct Body { |
30 | // TODO: this should be more general, consts & statics also have bodies | 30 | // FIXME: this should be more general, consts & statics also have bodies |
31 | /// The Function of the item this body belongs to | 31 | /// The Function of the item this body belongs to |
32 | owner: Function, | 32 | owner: Function, |
33 | exprs: Arena<ExprId, Expr>, | 33 | exprs: Arena<ExprId, Expr>, |
@@ -406,7 +406,7 @@ pub enum Pat { | |||
406 | Struct { | 406 | Struct { |
407 | path: Option<Path>, | 407 | path: Option<Path>, |
408 | args: Vec<FieldPat>, | 408 | args: Vec<FieldPat>, |
409 | // TODO: 'ellipsis' option | 409 | // FIXME: 'ellipsis' option |
410 | }, | 410 | }, |
411 | Range { | 411 | Range { |
412 | start: ExprId, | 412 | start: ExprId, |
@@ -547,7 +547,7 @@ impl ExprCollector { | |||
547 | if condition.pat().is_none() { | 547 | if condition.pat().is_none() { |
548 | self.collect_expr_opt(condition.expr()) | 548 | self.collect_expr_opt(condition.expr()) |
549 | } else { | 549 | } else { |
550 | // TODO handle while let | 550 | // FIXME handle while let |
551 | return self.alloc_expr(Expr::Missing, syntax_ptr); | 551 | return self.alloc_expr(Expr::Missing, syntax_ptr); |
552 | } | 552 | } |
553 | } else { | 553 | } else { |
@@ -610,7 +610,7 @@ impl ExprCollector { | |||
610 | self.alloc_expr(path, syntax_ptr) | 610 | self.alloc_expr(path, syntax_ptr) |
611 | } | 611 | } |
612 | ast::ExprKind::ContinueExpr(_e) => { | 612 | ast::ExprKind::ContinueExpr(_e) => { |
613 | // TODO: labels | 613 | // FIXME: labels |
614 | self.alloc_expr(Expr::Continue, syntax_ptr) | 614 | self.alloc_expr(Expr::Continue, syntax_ptr) |
615 | } | 615 | } |
616 | ast::ExprKind::BreakExpr(e) => { | 616 | ast::ExprKind::BreakExpr(e) => { |
@@ -751,7 +751,7 @@ impl ExprCollector { | |||
751 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) | 751 | self.alloc_expr(Expr::Literal(lit), syntax_ptr) |
752 | } | 752 | } |
753 | 753 | ||
754 | // TODO implement HIR for these: | 754 | // FIXME implement HIR for these: |
755 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 755 | ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
756 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 756 | ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
757 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 757 | ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
@@ -844,7 +844,7 @@ impl ExprCollector { | |||
844 | Pat::Struct { path, args: fields } | 844 | Pat::Struct { path, args: fields } |
845 | } | 845 | } |
846 | 846 | ||
847 | // TODO: implement | 847 | // FIXME: implement |
848 | ast::PatKind::LiteralPat(_) => Pat::Missing, | 848 | ast::PatKind::LiteralPat(_) => Pat::Missing, |
849 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 849 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
850 | }; | 850 | }; |
@@ -910,7 +910,7 @@ pub(crate) fn body_with_source_map_query( | |||
910 | ) -> (Arc<Body>, Arc<BodySourceMap>) { | 910 | ) -> (Arc<Body>, Arc<BodySourceMap>) { |
911 | let mut collector = ExprCollector::new(func); | 911 | let mut collector = ExprCollector::new(func); |
912 | 912 | ||
913 | // TODO: consts, etc. | 913 | // FIXME: consts, etc. |
914 | collector.collect_fn_body(&func.source(db).1); | 914 | collector.collect_fn_body(&func.source(db).1); |
915 | 915 | ||
916 | let (body, source_map) = collector.finish(); | 916 | let (body, source_map) = collector.finish(); |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 81fbc509e..ed005c9f7 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -39,7 +39,7 @@ pub struct ScopeData { | |||
39 | } | 39 | } |
40 | 40 | ||
41 | impl ExprScopes { | 41 | impl ExprScopes { |
42 | // TODO: This should take something more general than Function | 42 | // FIXME: This should take something more general than Function |
43 | pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> { | 43 | pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> { |
44 | let body = db.body_hir(function); | 44 | let body = db.body_hir(function); |
45 | let res = ExprScopes::new(body); | 45 | let res = ExprScopes::new(body); |
@@ -148,7 +148,7 @@ impl ScopesWithSourceMap { | |||
148 | 148 | ||
149 | // XXX: during completion, cursor might be outside of any particular | 149 | // XXX: during completion, cursor might be outside of any particular |
150 | // expression. Try to figure out the correct scope... | 150 | // expression. Try to figure out the correct scope... |
151 | // TODO: move this to source binder? | 151 | // FIXME: move this to source binder? |
152 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { | 152 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { |
153 | let r = ptr.range(); | 153 | let r = ptr.range(); |
154 | let child_scopes = self | 154 | let child_scopes = self |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 0f759a235..84fe94289 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -8,14 +8,14 @@ use std::sync::Arc; | |||
8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner}; | 8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::PersistentHirDatabase, | 11 | db::DefDatabase, |
12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock | 12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /// Data about a generic parameter (to a function, struct, impl, ...). | 15 | /// Data about a generic parameter (to a function, struct, impl, ...). |
16 | #[derive(Clone, PartialEq, Eq, Debug)] | 16 | #[derive(Clone, PartialEq, Eq, Debug)] |
17 | pub struct GenericParam { | 17 | pub struct GenericParam { |
18 | // TODO: give generic params proper IDs | 18 | // FIXME: give generic params proper IDs |
19 | pub(crate) idx: u32, | 19 | pub(crate) idx: u32, |
20 | pub(crate) name: Name, | 20 | pub(crate) name: Name, |
21 | } | 21 | } |
@@ -40,7 +40,7 @@ impl_froms!(GenericDef: Function, Struct, Enum, Trait, TypeAlias, ImplBlock); | |||
40 | 40 | ||
41 | impl GenericParams { | 41 | impl GenericParams { |
42 | pub(crate) fn generic_params_query( | 42 | pub(crate) fn generic_params_query( |
43 | db: &impl PersistentHirDatabase, | 43 | db: &impl DefDatabase, |
44 | def: GenericDef, | 44 | def: GenericDef, |
45 | ) -> Arc<GenericParams> { | 45 | ) -> Arc<GenericParams> { |
46 | let mut generics = GenericParams::default(); | 46 | let mut generics = GenericParams::default(); |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 3d0a881c2..18401f865 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -10,7 +10,7 @@ use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; | |||
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Module, | 12 | Module, |
13 | PersistentHirDatabase, | 13 | DefDatabase, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #[derive(Debug, Default)] | 16 | #[derive(Debug, Default)] |
@@ -63,7 +63,7 @@ pub struct HirFileId(HirFileIdRepr); | |||
63 | impl HirFileId { | 63 | impl HirFileId { |
64 | /// For macro-expansion files, returns the file original source file the | 64 | /// For macro-expansion files, returns the file original source file the |
65 | /// expansion originated from. | 65 | /// expansion originated from. |
66 | pub fn original_file(self, db: &impl PersistentHirDatabase) -> FileId { | 66 | pub fn original_file(self, db: &impl DefDatabase) -> FileId { |
67 | match self.0 { | 67 | match self.0 { |
68 | HirFileIdRepr::File(file_id) => file_id, | 68 | HirFileIdRepr::File(file_id) => file_id, |
69 | HirFileIdRepr::Macro(macro_call_id) => { | 69 | HirFileIdRepr::Macro(macro_call_id) => { |
@@ -83,10 +83,7 @@ impl HirFileId { | |||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | pub(crate) fn hir_parse( | 86 | pub(crate) fn hir_parse(db: &impl DefDatabase, file_id: HirFileId) -> TreeArc<SourceFile> { |
87 | db: &impl PersistentHirDatabase, | ||
88 | file_id: HirFileId, | ||
89 | ) -> TreeArc<SourceFile> { | ||
90 | match file_id.0 { | 87 | match file_id.0 { |
91 | HirFileIdRepr::File(file_id) => db.parse(file_id), | 88 | HirFileIdRepr::File(file_id) => db.parse(file_id), |
92 | HirFileIdRepr::Macro(macro_call_id) => { | 89 | HirFileIdRepr::Macro(macro_call_id) => { |
@@ -97,10 +94,7 @@ impl HirFileId { | |||
97 | } | 94 | } |
98 | } | 95 | } |
99 | 96 | ||
100 | fn parse_macro( | 97 | fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { |
101 | db: &impl PersistentHirDatabase, | ||
102 | macro_call_id: MacroCallId, | ||
103 | ) -> Option<TreeArc<SourceFile>> { | ||
104 | let loc = macro_call_id.loc(db); | 98 | let loc = macro_call_id.loc(db); |
105 | let syntax = db.file_item(loc.source_item_id); | 99 | let syntax = db.file_item(loc.source_item_id); |
106 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); | 100 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); |
@@ -190,7 +184,7 @@ pub(crate) struct LocationCtx<DB> { | |||
190 | file_id: HirFileId, | 184 | file_id: HirFileId, |
191 | } | 185 | } |
192 | 186 | ||
193 | impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { | 187 | impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { |
194 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { | 188 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { |
195 | LocationCtx { db, module, file_id } | 189 | LocationCtx { db, module, file_id } |
196 | } | 190 | } |
@@ -205,13 +199,13 @@ impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { | |||
205 | 199 | ||
206 | pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | 200 | pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { |
207 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; | 201 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; |
208 | fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { | 202 | fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { |
209 | let items = ctx.db.file_items(ctx.file_id); | 203 | let items = ctx.db.file_items(ctx.file_id); |
210 | let item_id = items.id_of(ctx.file_id, ast.syntax()); | 204 | let item_id = items.id_of(ctx.file_id, ast.syntax()); |
211 | Self::from_source_item_id_unchecked(ctx, item_id) | 205 | Self::from_source_item_id_unchecked(ctx, item_id) |
212 | } | 206 | } |
213 | fn from_source_item_id_unchecked( | 207 | fn from_source_item_id_unchecked( |
214 | ctx: LocationCtx<&impl PersistentHirDatabase>, | 208 | ctx: LocationCtx<&impl DefDatabase>, |
215 | item_id: SourceFileItemId, | 209 | item_id: SourceFileItemId, |
216 | ) -> Self { | 210 | ) -> Self { |
217 | let raw = SourceItemId { file_id: ctx.file_id, item_id }; | 211 | let raw = SourceItemId { file_id: ctx.file_id, item_id }; |
@@ -219,7 +213,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
219 | 213 | ||
220 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | 214 | Self::interner(ctx.db.as_ref()).loc2id(&loc) |
221 | } | 215 | } |
222 | fn source(self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<N>) { | 216 | fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { |
223 | let int = Self::interner(db.as_ref()); | 217 | let int = Self::interner(db.as_ref()); |
224 | let loc = int.id2loc(self); | 218 | let loc = int.id2loc(self); |
225 | let syntax = db.file_item(loc.raw); | 219 | let syntax = db.file_item(loc.raw); |
@@ -227,7 +221,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
227 | N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); | 221 | N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); |
228 | (loc.raw.file_id, ast) | 222 | (loc.raw.file_id, ast) |
229 | } | 223 | } |
230 | fn module(self, db: &impl PersistentHirDatabase) -> Module { | 224 | fn module(self, db: &impl DefDatabase) -> Module { |
231 | let int = Self::interner(db.as_ref()); | 225 | let int = Self::interner(db.as_ref()); |
232 | let loc = int.id2loc(self); | 226 | let loc = int.id2loc(self); |
233 | loc.module | 227 | loc.module |
@@ -324,7 +318,7 @@ pub struct SourceFileItems { | |||
324 | 318 | ||
325 | impl SourceFileItems { | 319 | impl SourceFileItems { |
326 | pub(crate) fn file_items_query( | 320 | pub(crate) fn file_items_query( |
327 | db: &impl PersistentHirDatabase, | 321 | db: &impl DefDatabase, |
328 | file_id: HirFileId, | 322 | file_id: HirFileId, |
329 | ) -> Arc<SourceFileItems> { | 323 | ) -> Arc<SourceFileItems> { |
330 | let source_file = db.hir_parse(file_id); | 324 | let source_file = db.hir_parse(file_id); |
@@ -332,7 +326,7 @@ impl SourceFileItems { | |||
332 | } | 326 | } |
333 | 327 | ||
334 | pub(crate) fn file_item_query( | 328 | pub(crate) fn file_item_query( |
335 | db: &impl PersistentHirDatabase, | 329 | db: &impl DefDatabase, |
336 | source_item_id: SourceItemId, | 330 | source_item_id: SourceItemId, |
337 | ) -> TreeArc<SyntaxNode> { | 331 | ) -> TreeArc<SyntaxNode> { |
338 | let source_file = db.hir_parse(source_item_id.file_id); | 332 | let source_file = db.hir_parse(source_item_id.file_id); |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 8807a4b56..40d368cd9 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -9,7 +9,7 @@ use ra_syntax::{ | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | Const, TypeAlias, Function, HirFileId, | 11 | Const, TypeAlias, Function, HirFileId, |
12 | HirDatabase, PersistentHirDatabase, | 12 | HirDatabase, DefDatabase, |
13 | ModuleDef, Trait, Resolution, | 13 | ModuleDef, Trait, Resolution, |
14 | type_ref::TypeRef, | 14 | type_ref::TypeRef, |
15 | ids::LocationCtx, | 15 | ids::LocationCtx, |
@@ -59,7 +59,7 @@ impl ImplBlock { | |||
59 | } | 59 | } |
60 | 60 | ||
61 | /// Returns the syntax of the impl block | 61 | /// Returns the syntax of the impl block |
62 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, TreeArc<ast::ImplBlock>) { | 62 | pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ImplBlock>) { |
63 | let source_map = db.impls_in_module_source_map(self.module); | 63 | let source_map = db.impls_in_module_source_map(self.module); |
64 | let (file_id, source) = self.module.definition_source(db); | 64 | let (file_id, source) = self.module.definition_source(db); |
65 | (file_id, source_map.get(&source, self.impl_id)) | 65 | (file_id, source_map.get(&source, self.impl_id)) |
@@ -73,11 +73,11 @@ impl ImplBlock { | |||
73 | self.module | 73 | self.module |
74 | } | 74 | } |
75 | 75 | ||
76 | pub fn target_trait_ref(&self, db: &impl PersistentHirDatabase) -> Option<TypeRef> { | 76 | pub fn target_trait_ref(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
77 | db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() | 77 | db.impls_in_module(self.module).impls[self.impl_id].target_trait().cloned() |
78 | } | 78 | } |
79 | 79 | ||
80 | pub fn target_type(&self, db: &impl PersistentHirDatabase) -> TypeRef { | 80 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { |
81 | db.impls_in_module(self.module).impls[self.impl_id].target_type().clone() | 81 | db.impls_in_module(self.module).impls[self.impl_id].target_type().clone() |
82 | } | 82 | } |
83 | 83 | ||
@@ -97,11 +97,11 @@ impl ImplBlock { | |||
97 | None | 97 | None |
98 | } | 98 | } |
99 | 99 | ||
100 | pub fn items(&self, db: &impl PersistentHirDatabase) -> Vec<ImplItem> { | 100 | pub fn items(&self, db: &impl DefDatabase) -> Vec<ImplItem> { |
101 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() | 101 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() |
102 | } | 102 | } |
103 | 103 | ||
104 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 104 | pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> { |
105 | db.generic_params((*self).into()) | 105 | db.generic_params((*self).into()) |
106 | } | 106 | } |
107 | 107 | ||
@@ -124,7 +124,7 @@ pub struct ImplData { | |||
124 | 124 | ||
125 | impl ImplData { | 125 | impl ImplData { |
126 | pub(crate) fn from_ast( | 126 | pub(crate) fn from_ast( |
127 | db: &impl PersistentHirDatabase, | 127 | db: &impl DefDatabase, |
128 | file_id: HirFileId, | 128 | file_id: HirFileId, |
129 | module: Module, | 129 | module: Module, |
130 | node: &ast::ImplBlock, | 130 | node: &ast::ImplBlock, |
@@ -161,7 +161,7 @@ impl ImplData { | |||
161 | } | 161 | } |
162 | 162 | ||
163 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 163 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
164 | //TODO: rename to ImplDef? | 164 | //FIXME: rename to ImplDef? |
165 | pub enum ImplItem { | 165 | pub enum ImplItem { |
166 | Method(Function), | 166 | Method(Function), |
167 | Const(Const), | 167 | Const(Const), |
@@ -193,11 +193,7 @@ pub struct ModuleImplBlocks { | |||
193 | } | 193 | } |
194 | 194 | ||
195 | impl ModuleImplBlocks { | 195 | impl ModuleImplBlocks { |
196 | fn collect( | 196 | fn collect(db: &impl DefDatabase, module: Module, source_map: &mut ImplSourceMap) -> Self { |
197 | db: &impl PersistentHirDatabase, | ||
198 | module: Module, | ||
199 | source_map: &mut ImplSourceMap, | ||
200 | ) -> Self { | ||
201 | let mut m = ModuleImplBlocks { | 197 | let mut m = ModuleImplBlocks { |
202 | module, | 198 | module, |
203 | impls: Arena::default(), | 199 | impls: Arena::default(), |
@@ -228,7 +224,7 @@ impl ModuleImplBlocks { | |||
228 | } | 224 | } |
229 | 225 | ||
230 | pub(crate) fn impls_in_module_with_source_map_query( | 226 | pub(crate) fn impls_in_module_with_source_map_query( |
231 | db: &impl PersistentHirDatabase, | 227 | db: &impl DefDatabase, |
232 | module: Module, | 228 | module: Module, |
233 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { | 229 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { |
234 | let mut source_map = ImplSourceMap::default(); | 230 | let mut source_map = ImplSourceMap::default(); |
@@ -238,15 +234,12 @@ pub(crate) fn impls_in_module_with_source_map_query( | |||
238 | (Arc::new(result), Arc::new(source_map)) | 234 | (Arc::new(result), Arc::new(source_map)) |
239 | } | 235 | } |
240 | 236 | ||
241 | pub(crate) fn impls_in_module( | 237 | pub(crate) fn impls_in_module(db: &impl DefDatabase, module: Module) -> Arc<ModuleImplBlocks> { |
242 | db: &impl PersistentHirDatabase, | ||
243 | module: Module, | ||
244 | ) -> Arc<ModuleImplBlocks> { | ||
245 | db.impls_in_module_with_source_map(module).0 | 238 | db.impls_in_module_with_source_map(module).0 |
246 | } | 239 | } |
247 | 240 | ||
248 | pub(crate) fn impls_in_module_source_map_query( | 241 | pub(crate) fn impls_in_module_source_map_query( |
249 | db: &impl PersistentHirDatabase, | 242 | db: &impl DefDatabase, |
250 | module: Module, | 243 | module: Module, |
251 | ) -> Arc<ImplSourceMap> { | 244 | ) -> Arc<ImplSourceMap> { |
252 | db.impls_in_module_with_source_map(module).1 | 245 | db.impls_in_module_with_source_map(module).1 |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 5926b5758..a89c916f8 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -43,7 +43,7 @@ mod code_model_impl; | |||
43 | mod marks; | 43 | mod marks; |
44 | 44 | ||
45 | use crate::{ | 45 | use crate::{ |
46 | db::{HirDatabase, PersistentHirDatabase}, | 46 | db::{HirDatabase, DefDatabase}, |
47 | name::{AsName, KnownName}, | 47 | name::{AsName, KnownName}, |
48 | ids::{SourceItemId, SourceFileItems}, | 48 | ids::{SourceItemId, SourceFileItems}, |
49 | }; | 49 | }; |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index f1cad77c5..10d4c1b8c 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -13,11 +13,7 @@ use crate::{db, HirInterner}; | |||
13 | 13 | ||
14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
15 | 15 | ||
16 | #[salsa::database( | 16 | #[salsa::database(ra_db::SourceDatabaseStorage, db::HirDatabaseStorage, db::DefDatabaseStorage)] |
17 | ra_db::SourceDatabaseStorage, | ||
18 | db::HirDatabaseStorage, | ||
19 | db::PersistentHirDatabaseStorage | ||
20 | )] | ||
21 | #[derive(Debug)] | 17 | #[derive(Debug)] |
22 | pub struct MockDatabase { | 18 | pub struct MockDatabase { |
23 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, | 19 | events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index edd2f25f7..d361cf9e6 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -62,7 +62,7 @@ use test_utils::tested_by; | |||
62 | 62 | ||
63 | use crate::{ | 63 | use crate::{ |
64 | ModuleDef, Name, Crate, Module, Problem, | 64 | ModuleDef, Name, Crate, Module, Problem, |
65 | PersistentHirDatabase, Path, PathKind, HirFileId, | 65 | DefDatabase, Path, PathKind, HirFileId, |
66 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, | 66 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, |
67 | }; | 67 | }; |
68 | 68 | ||
@@ -196,10 +196,7 @@ enum ReachedFixedPoint { | |||
196 | } | 196 | } |
197 | 197 | ||
198 | impl CrateDefMap { | 198 | impl CrateDefMap { |
199 | pub(crate) fn crate_def_map_query( | 199 | pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: Crate) -> Arc<CrateDefMap> { |
200 | db: &impl PersistentHirDatabase, | ||
201 | krate: Crate, | ||
202 | ) -> Arc<CrateDefMap> { | ||
203 | let start = std::time::Instant::now(); | 200 | let start = std::time::Instant::now(); |
204 | let def_map = { | 201 | let def_map = { |
205 | let edition = krate.edition(db); | 202 | let edition = krate.edition(db); |
@@ -268,7 +265,7 @@ impl CrateDefMap { | |||
268 | 265 | ||
269 | pub(crate) fn resolve_path( | 266 | pub(crate) fn resolve_path( |
270 | &self, | 267 | &self, |
271 | db: &impl PersistentHirDatabase, | 268 | db: &impl DefDatabase, |
272 | original_module: CrateModuleId, | 269 | original_module: CrateModuleId, |
273 | path: &Path, | 270 | path: &Path, |
274 | ) -> (PerNs<ModuleDef>, Option<usize>) { | 271 | ) -> (PerNs<ModuleDef>, Option<usize>) { |
@@ -280,7 +277,7 @@ impl CrateDefMap { | |||
280 | // the result. | 277 | // the result. |
281 | fn resolve_path_fp( | 278 | fn resolve_path_fp( |
282 | &self, | 279 | &self, |
283 | db: &impl PersistentHirDatabase, | 280 | db: &impl DefDatabase, |
284 | mode: ResolveMode, | 281 | mode: ResolveMode, |
285 | original_module: CrateModuleId, | 282 | original_module: CrateModuleId, |
286 | path: &Path, | 283 | path: &Path, |
@@ -296,7 +293,7 @@ impl CrateDefMap { | |||
296 | // plain import or absolute path in 2015: crate-relative with | 293 | // plain import or absolute path in 2015: crate-relative with |
297 | // fallback to extern prelude (with the simplification in | 294 | // fallback to extern prelude (with the simplification in |
298 | // rust-lang/rust#57745) | 295 | // rust-lang/rust#57745) |
299 | // TODO there must be a nicer way to write this condition | 296 | // FIXME there must be a nicer way to write this condition |
300 | PathKind::Plain | PathKind::Abs | 297 | PathKind::Plain | PathKind::Abs |
301 | if self.edition == Edition::Edition2015 | 298 | if self.edition == Edition::Edition2015 |
302 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => | 299 | && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => |
@@ -422,7 +419,7 @@ impl CrateDefMap { | |||
422 | 419 | ||
423 | pub(crate) fn resolve_name_in_module( | 420 | pub(crate) fn resolve_name_in_module( |
424 | &self, | 421 | &self, |
425 | db: &impl PersistentHirDatabase, | 422 | db: &impl DefDatabase, |
426 | module: CrateModuleId, | 423 | module: CrateModuleId, |
427 | name: &Name, | 424 | name: &Name, |
428 | ) -> PerNs<ModuleDef> { | 425 | ) -> PerNs<ModuleDef> { |
@@ -442,7 +439,7 @@ impl CrateDefMap { | |||
442 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) | 439 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) |
443 | } | 440 | } |
444 | 441 | ||
445 | fn resolve_in_prelude(&self, db: &impl PersistentHirDatabase, name: &Name) -> PerNs<ModuleDef> { | 442 | fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs<ModuleDef> { |
446 | if let Some(prelude) = self.prelude { | 443 | if let Some(prelude) = self.prelude { |
447 | let resolution = if prelude.krate == self.krate { | 444 | let resolution = if prelude.krate == self.krate { |
448 | self[prelude.module_id].scope.items.get(name).cloned() | 445 | self[prelude.module_id].scope.items.get(name).cloned() |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 3ea8d592c..c5b73cfbe 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -6,7 +6,7 @@ use ra_db::FileId; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
9 | PersistentHirDatabase, HirFileId, Name, Path, Problem, Crate, | 9 | DefDatabase, HirFileId, Name, Path, Problem, Crate, |
10 | KnownName, | 10 | KnownName, |
11 | nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, | 11 | nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, |
12 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, | 12 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, |
@@ -14,10 +14,7 @@ use crate::{ | |||
14 | 14 | ||
15 | use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; | 15 | use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; |
16 | 16 | ||
17 | pub(super) fn collect_defs( | 17 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
18 | db: &impl PersistentHirDatabase, | ||
19 | mut def_map: CrateDefMap, | ||
20 | ) -> CrateDefMap { | ||
21 | // populate external prelude | 18 | // populate external prelude |
22 | for dep in def_map.krate.dependencies(db) { | 19 | for dep in def_map.krate.dependencies(db) { |
23 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); | 20 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); |
@@ -57,7 +54,7 @@ struct DefCollector<DB> { | |||
57 | 54 | ||
58 | impl<'a, DB> DefCollector<&'a DB> | 55 | impl<'a, DB> DefCollector<&'a DB> |
59 | where | 56 | where |
60 | DB: PersistentHirDatabase, | 57 | DB: DefDatabase, |
61 | { | 58 | { |
62 | fn collect(&mut self) { | 59 | fn collect(&mut self) { |
63 | let crate_graph = self.db.crate_graph(); | 60 | let crate_graph = self.db.crate_graph(); |
@@ -370,7 +367,7 @@ struct ModCollector<'a, D> { | |||
370 | 367 | ||
371 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> | 368 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> |
372 | where | 369 | where |
373 | DB: PersistentHirDatabase, | 370 | DB: DefDatabase, |
374 | { | 371 | { |
375 | fn collect(&mut self, items: &[raw::RawItem]) { | 372 | fn collect(&mut self, items: &[raw::RawItem]) { |
376 | for item in items { | 373 | for item in items { |
@@ -523,7 +520,7 @@ fn is_macro_rules(path: &Path) -> bool { | |||
523 | } | 520 | } |
524 | 521 | ||
525 | fn resolve_submodule( | 522 | fn resolve_submodule( |
526 | db: &impl PersistentHirDatabase, | 523 | db: &impl DefDatabase, |
527 | file_id: HirFileId, | 524 | file_id: HirFileId, |
528 | name: &Name, | 525 | name: &Name, |
529 | is_root: bool, | 526 | is_root: bool, |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 3226bbf0d..f8ba398ec 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | PersistentHirDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 15 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
16 | ids::{SourceFileItemId, SourceFileItems}, | 16 | ids::{SourceFileItemId, SourceFileItems}, |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -47,15 +47,12 @@ impl ImportSourceMap { | |||
47 | } | 47 | } |
48 | 48 | ||
49 | impl RawItems { | 49 | impl RawItems { |
50 | pub(crate) fn raw_items_query( | 50 | pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: FileId) -> Arc<RawItems> { |
51 | db: &impl PersistentHirDatabase, | ||
52 | file_id: FileId, | ||
53 | ) -> Arc<RawItems> { | ||
54 | db.raw_items_with_source_map(file_id).0 | 51 | db.raw_items_with_source_map(file_id).0 |
55 | } | 52 | } |
56 | 53 | ||
57 | pub(crate) fn raw_items_with_source_map_query( | 54 | pub(crate) fn raw_items_with_source_map_query( |
58 | db: &impl PersistentHirDatabase, | 55 | db: &impl DefDatabase, |
59 | file_id: FileId, | 56 | file_id: FileId, |
60 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | 57 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { |
61 | let mut collector = RawItemsCollector { | 58 | let mut collector = RawItemsCollector { |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 6ca373e34..6cc8104f4 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -96,7 +96,7 @@ impl Path { | |||
96 | if let Some(q) = path.qualifier() { | 96 | if let Some(q) = path.qualifier() { |
97 | return Some(q); | 97 | return Some(q); |
98 | } | 98 | } |
99 | // TODO: this bottom up traversal is not too precise. | 99 | // FIXME: this bottom up traversal is not too precise. |
100 | // Should we handle do a top-down analysis, recording results? | 100 | // Should we handle do a top-down analysis, recording results? |
101 | let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; | 101 | let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; |
102 | let use_tree = use_tree_list.parent_use_tree(); | 102 | let use_tree = use_tree_list.parent_use_tree(); |
@@ -166,7 +166,7 @@ fn expand_use_tree<'a>( | |||
166 | // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) | 166 | // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) |
167 | Some(path) => match convert_path(prefix, path) { | 167 | Some(path) => match convert_path(prefix, path) { |
168 | Some(it) => Some(it), | 168 | Some(it) => Some(it), |
169 | None => return, // TODO: report errors somewhere | 169 | None => return, // FIXME: report errors somewhere |
170 | }, | 170 | }, |
171 | }; | 171 | }; |
172 | for child_tree in use_tree_list.use_trees() { | 172 | for child_tree in use_tree_list.use_trees() { |
@@ -194,7 +194,7 @@ fn expand_use_tree<'a>( | |||
194 | cb(path, Some(segment), alias) | 194 | cb(path, Some(segment), alias) |
195 | }; | 195 | }; |
196 | } | 196 | } |
197 | // TODO: report errors somewhere | 197 | // FIXME: report errors somewhere |
198 | // We get here if we do | 198 | // We get here if we do |
199 | } | 199 | } |
200 | } | 200 | } |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 59af4ec60..f28154517 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -19,7 +19,7 @@ pub struct Resolver { | |||
19 | scopes: Vec<Scope>, | 19 | scopes: Vec<Scope>, |
20 | } | 20 | } |
21 | 21 | ||
22 | // TODO how to store these best | 22 | // FIXME how to store these best |
23 | #[derive(Debug, Clone)] | 23 | #[derive(Debug, Clone)] |
24 | pub(crate) struct ModuleItemMap { | 24 | pub(crate) struct ModuleItemMap { |
25 | crate_def_map: Arc<CrateDefMap>, | 25 | crate_def_map: Arc<CrateDefMap>, |
@@ -260,7 +260,7 @@ impl Scope { | |||
260 | fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) { | 260 | fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) { |
261 | match self { | 261 | match self { |
262 | Scope::ModuleScope(m) => { | 262 | Scope::ModuleScope(m) => { |
263 | // TODO: should we provide `self` here? | 263 | // FIXME: should we provide `self` here? |
264 | // f( | 264 | // f( |
265 | // Name::self_param(), | 265 | // Name::self_param(), |
266 | // PerNs::types(Resolution::Def { | 266 | // PerNs::types(Resolution::Def { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 902110913..3645b73b4 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -164,7 +164,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R | |||
164 | let scope = scopes.scope_for_offset(position.offset); | 164 | let scope = scopes.scope_for_offset(position.offset); |
165 | Some(expr::resolver_for_scope(func.body(db), db, scope)) | 165 | Some(expr::resolver_for_scope(func.body(db), db, scope)) |
166 | } else { | 166 | } else { |
167 | // TODO const/static/array length | 167 | // FIXME const/static/array length |
168 | None | 168 | None |
169 | } | 169 | } |
170 | } else { | 170 | } else { |
@@ -184,7 +184,7 @@ pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNo | |||
184 | let scope = scopes.scope_for(&node); | 184 | let scope = scopes.scope_for(&node); |
185 | Some(expr::resolver_for_scope(func.body(db), db, scope)) | 185 | Some(expr::resolver_for_scope(func.body(db), db, scope)) |
186 | } else { | 186 | } else { |
187 | // TODO const/static/array length | 187 | // FIXME const/static/array length |
188 | None | 188 | None |
189 | } | 189 | } |
190 | } else { | 190 | } else { |
@@ -212,7 +212,7 @@ fn try_get_resolver_for_node( | |||
212 | } else if let Some(f) = ast::FnDef::cast(node) { | 212 | } else if let Some(f) = ast::FnDef::cast(node) { |
213 | function_from_source(db, file_id, f).map(|f| f.resolver(db)) | 213 | function_from_source(db, file_id, f).map(|f| f.resolver(db)) |
214 | } else { | 214 | } else { |
215 | // TODO add missing cases | 215 | // FIXME add missing cases |
216 | None | 216 | None |
217 | } | 217 | } |
218 | } | 218 | } |
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index d95879e46..ab5f008ef 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -15,7 +15,7 @@ impl Ty { | |||
15 | } | 15 | } |
16 | 16 | ||
17 | fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> { | 17 | fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> { |
18 | // TODO Deref::deref | 18 | // FIXME Deref::deref |
19 | self.builtin_deref() | 19 | self.builtin_deref() |
20 | } | 20 | } |
21 | } | 21 | } |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7cf465266..cff7e7481 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -207,7 +207,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
207 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { | 207 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { |
208 | let ty = Ty::from_hir( | 208 | let ty = Ty::from_hir( |
209 | self.db, | 209 | self.db, |
210 | // TODO use right resolver for block | 210 | // FIXME use right resolver for block |
211 | &self.resolver, | 211 | &self.resolver, |
212 | type_ref, | 212 | type_ref, |
213 | ); | 213 | ); |
@@ -407,18 +407,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
407 | 407 | ||
408 | let substs = | 408 | let substs = |
409 | Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable); | 409 | Ty::substs_from_path_segment(self.db, &self.resolver, segment, typable); |
410 | self.db.type_for_def(typable, Namespace::Types).apply_substs(substs) | 410 | self.db.type_for_def(typable, Namespace::Types).subst(&substs) |
411 | } | 411 | } |
412 | Resolution::LocalBinding(_) => { | 412 | Resolution::LocalBinding(_) => { |
413 | // can't have a local binding in an associated item path | 413 | // can't have a local binding in an associated item path |
414 | return None; | 414 | return None; |
415 | } | 415 | } |
416 | Resolution::GenericParam(..) => { | 416 | Resolution::GenericParam(..) => { |
417 | // TODO associated item of generic param | 417 | // FIXME associated item of generic param |
418 | return None; | 418 | return None; |
419 | } | 419 | } |
420 | Resolution::SelfType(_) => { | 420 | Resolution::SelfType(_) => { |
421 | // TODO associated item of self type | 421 | // FIXME associated item of self type |
422 | return None; | 422 | return None; |
423 | } | 423 | } |
424 | }; | 424 | }; |
@@ -446,7 +446,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
446 | } | 446 | } |
447 | } | 447 | } |
448 | 448 | ||
449 | // TODO: Resolve associated types | 449 | // FIXME: Resolve associated types |
450 | crate::ImplItem::TypeAlias(_) => None, | 450 | crate::ImplItem::TypeAlias(_) => None, |
451 | }; | 451 | }; |
452 | match matching_def { | 452 | match matching_def { |
@@ -466,7 +466,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
466 | let typable: Option<TypableDef> = def.into(); | 466 | let typable: Option<TypableDef> = def.into(); |
467 | let typable = typable?; | 467 | let typable = typable?; |
468 | let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); | 468 | let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); |
469 | let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); | 469 | let ty = self.db.type_for_def(typable, Namespace::Values).subst(&substs); |
470 | let ty = self.insert_type_vars(ty); | 470 | let ty = self.insert_type_vars(ty); |
471 | Some(ty) | 471 | Some(ty) |
472 | } | 472 | } |
@@ -504,7 +504,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
504 | return (Ty::Unknown, None); | 504 | return (Ty::Unknown, None); |
505 | } | 505 | } |
506 | Some(Resolution::SelfType(..)) => { | 506 | Some(Resolution::SelfType(..)) => { |
507 | // TODO this is allowed in an impl for a struct, handle this | 507 | // FIXME this is allowed in an impl for a struct, handle this |
508 | return (Ty::Unknown, None); | 508 | return (Ty::Unknown, None); |
509 | } | 509 | } |
510 | None => return (Ty::Unknown, None), | 510 | None => return (Ty::Unknown, None), |
@@ -513,7 +513,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
513 | None => return (Ty::Unknown, None), | 513 | None => return (Ty::Unknown, None), |
514 | Some(it) => it, | 514 | Some(it) => it, |
515 | }; | 515 | }; |
516 | // TODO remove the duplication between here and `Ty::from_path`? | 516 | // FIXME remove the duplication between here and `Ty::from_path`? |
517 | let substs = Ty::substs_from_path(self.db, resolver, path, def); | 517 | let substs = Ty::substs_from_path(self.db, resolver, path, def); |
518 | match def { | 518 | match def { |
519 | TypableDef::Struct(s) => { | 519 | TypableDef::Struct(s) => { |
@@ -590,7 +590,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
590 | | Pat::Struct { .. } | 590 | | Pat::Struct { .. } |
591 | | Pat::Range { .. } | 591 | | Pat::Range { .. } |
592 | | Pat::Slice { .. } => true, | 592 | | Pat::Slice { .. } => true, |
593 | // TODO: Path/Lit might actually evaluate to ref, but inference is unimplemented. | 593 | // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented. |
594 | Pat::Path(..) | Pat::Lit(..) => true, | 594 | Pat::Path(..) | Pat::Lit(..) => true, |
595 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, | 595 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, |
596 | }; | 596 | }; |
@@ -635,7 +635,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
635 | let expectation = match expected.as_reference() { | 635 | let expectation = match expected.as_reference() { |
636 | Some((inner_ty, exp_mut)) => { | 636 | Some((inner_ty, exp_mut)) => { |
637 | if *mutability != exp_mut { | 637 | if *mutability != exp_mut { |
638 | // TODO: emit type error? | 638 | // FIXME: emit type error? |
639 | } | 639 | } |
640 | inner_ty | 640 | inner_ty |
641 | } | 641 | } |
@@ -651,7 +651,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
651 | self.infer_struct_pat(p.as_ref(), fields, expected, default_bm) | 651 | self.infer_struct_pat(p.as_ref(), fields, expected, default_bm) |
652 | } | 652 | } |
653 | Pat::Path(path) => { | 653 | Pat::Path(path) => { |
654 | // TODO use correct resolver for the surrounding expression | 654 | // FIXME use correct resolver for the surrounding expression |
655 | let resolver = self.resolver.clone(); | 655 | let resolver = self.resolver.clone(); |
656 | self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) | 656 | self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) |
657 | } | 657 | } |
@@ -741,7 +741,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
741 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), | 741 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
742 | Expr::Loop { body } => { | 742 | Expr::Loop { body } => { |
743 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 743 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
744 | // TODO handle break with value | 744 | // FIXME handle break with value |
745 | Ty::simple(TypeCtor::Never) | 745 | Ty::simple(TypeCtor::Never) |
746 | } | 746 | } |
747 | Expr::While { condition, body } => { | 747 | Expr::While { condition, body } => { |
@@ -769,7 +769,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
769 | self.infer_pat(*arg_pat, &expected, BindingMode::default()); | 769 | self.infer_pat(*arg_pat, &expected, BindingMode::default()); |
770 | } | 770 | } |
771 | 771 | ||
772 | // TODO: infer lambda type etc. | 772 | // FIXME: infer lambda type etc. |
773 | let _body_ty = self.infer_expr(*body, &Expectation::none()); | 773 | let _body_ty = self.infer_expr(*body, &Expectation::none()); |
774 | Ty::Unknown | 774 | Ty::Unknown |
775 | } | 775 | } |
@@ -795,7 +795,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
795 | }, | 795 | }, |
796 | _ => { | 796 | _ => { |
797 | // not callable | 797 | // not callable |
798 | // TODO report an error? | 798 | // FIXME report an error? |
799 | (Vec::new(), Ty::Unknown) | 799 | (Vec::new(), Ty::Unknown) |
800 | } | 800 | } |
801 | }; | 801 | }; |
@@ -894,14 +894,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
894 | expected.ty | 894 | expected.ty |
895 | } | 895 | } |
896 | Expr::Path(p) => { | 896 | Expr::Path(p) => { |
897 | // TODO this could be more efficient... | 897 | // FIXME this could be more efficient... |
898 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); | 898 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); |
899 | self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 899 | self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
900 | } | 900 | } |
901 | Expr::Continue => Ty::simple(TypeCtor::Never), | 901 | Expr::Continue => Ty::simple(TypeCtor::Never), |
902 | Expr::Break { expr } => { | 902 | Expr::Break { expr } => { |
903 | if let Some(expr) = expr { | 903 | if let Some(expr) = expr { |
904 | // TODO handle break with value | 904 | // FIXME handle break with value |
905 | self.infer_expr(*expr, &Expectation::none()); | 905 | self.infer_expr(*expr, &Expectation::none()); |
906 | } | 906 | } |
907 | Ty::simple(TypeCtor::Never) | 907 | Ty::simple(TypeCtor::Never) |
@@ -957,21 +957,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
957 | Expr::Cast { expr, type_ref } => { | 957 | Expr::Cast { expr, type_ref } => { |
958 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); | 958 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); |
959 | let cast_ty = self.make_ty(type_ref); | 959 | let cast_ty = self.make_ty(type_ref); |
960 | // TODO check the cast... | 960 | // FIXME check the cast... |
961 | cast_ty | 961 | cast_ty |
962 | } | 962 | } |
963 | Expr::Ref { expr, mutability } => { | 963 | Expr::Ref { expr, mutability } => { |
964 | let expectation = | 964 | let expectation = |
965 | if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { | 965 | if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { |
966 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 966 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { |
967 | // TODO: throw type error - expected mut reference but found shared ref, | 967 | // FIXME: throw type error - expected mut reference but found shared ref, |
968 | // which cannot be coerced | 968 | // which cannot be coerced |
969 | } | 969 | } |
970 | Expectation::has_type(Ty::clone(exp_inner)) | 970 | Expectation::has_type(Ty::clone(exp_inner)) |
971 | } else { | 971 | } else { |
972 | Expectation::none() | 972 | Expectation::none() |
973 | }; | 973 | }; |
974 | // TODO reference coercions etc. | 974 | // FIXME reference coercions etc. |
975 | let inner_ty = self.infer_expr(*expr, &expectation); | 975 | let inner_ty = self.infer_expr(*expr, &expectation); |
976 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 976 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
977 | } | 977 | } |
@@ -982,7 +982,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
982 | if let Some(derefed_ty) = inner_ty.builtin_deref() { | 982 | if let Some(derefed_ty) = inner_ty.builtin_deref() { |
983 | derefed_ty | 983 | derefed_ty |
984 | } else { | 984 | } else { |
985 | // TODO Deref::deref | 985 | // FIXME Deref::deref |
986 | Ty::Unknown | 986 | Ty::Unknown |
987 | } | 987 | } |
988 | } | 988 | } |
@@ -1002,7 +1002,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1002 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { | 1002 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { |
1003 | inner_ty | 1003 | inner_ty |
1004 | } | 1004 | } |
1005 | // TODO: resolve ops::Neg trait | 1005 | // FIXME: resolve ops::Neg trait |
1006 | _ => Ty::Unknown, | 1006 | _ => Ty::Unknown, |
1007 | } | 1007 | } |
1008 | } | 1008 | } |
@@ -1013,7 +1013,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1013 | _ => Ty::Unknown, | 1013 | _ => Ty::Unknown, |
1014 | }, | 1014 | }, |
1015 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 1015 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
1016 | // TODO: resolve ops::Not trait for inner_ty | 1016 | // FIXME: resolve ops::Not trait for inner_ty |
1017 | _ => Ty::Unknown, | 1017 | _ => Ty::Unknown, |
1018 | } | 1018 | } |
1019 | } | 1019 | } |
@@ -1028,12 +1028,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1028 | _ => Expectation::none(), | 1028 | _ => Expectation::none(), |
1029 | }; | 1029 | }; |
1030 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 1030 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
1031 | // TODO: find implementation of trait corresponding to operation | 1031 | // FIXME: find implementation of trait corresponding to operation |
1032 | // symbol and resolve associated `Output` type | 1032 | // symbol and resolve associated `Output` type |
1033 | let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty); | 1033 | let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty); |
1034 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); | 1034 | let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); |
1035 | 1035 | ||
1036 | // TODO: similar as above, return ty is often associated trait type | 1036 | // FIXME: similar as above, return ty is often associated trait type |
1037 | op::binary_op_return_ty(*op, rhs_ty) | 1037 | op::binary_op_return_ty(*op, rhs_ty) |
1038 | } | 1038 | } |
1039 | _ => Ty::Unknown, | 1039 | _ => Ty::Unknown, |
@@ -1227,7 +1227,7 @@ impl InferTy { | |||
1227 | #[derive(Clone, PartialEq, Eq, Debug)] | 1227 | #[derive(Clone, PartialEq, Eq, Debug)] |
1228 | struct Expectation { | 1228 | struct Expectation { |
1229 | ty: Ty, | 1229 | ty: Ty, |
1230 | // TODO: In some cases, we need to be aware whether the expectation is that | 1230 | // FIXME: In some cases, we need to be aware whether the expectation is that |
1231 | // the type match exactly what we passed, or whether it just needs to be | 1231 | // the type match exactly what we passed, or whether it just needs to be |
1232 | // coercible to the expected type. See Expectation::rvalue_hint in rustc. | 1232 | // coercible to the expected type. See Expectation::rvalue_hint in rustc. |
1233 | } | 1233 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 7f9af307b..003a89f0d 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -60,7 +60,7 @@ impl Ty { | |||
60 | 60 | ||
61 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { | 61 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { |
62 | if let Some(name) = path.as_ident() { | 62 | if let Some(name) = path.as_ident() { |
63 | // TODO handle primitive type names in resolver as well? | 63 | // FIXME handle primitive type names in resolver as well? |
64 | if let Some(int_ty) = primitive::IntTy::from_type_name(name) { | 64 | if let Some(int_ty) = primitive::IntTy::from_type_name(name) { |
65 | return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty))); | 65 | return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty))); |
66 | } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) { | 66 | } else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) { |
@@ -87,7 +87,7 @@ impl Ty { | |||
87 | Some(Resolution::GenericParam(idx)) => { | 87 | Some(Resolution::GenericParam(idx)) => { |
88 | return Ty::Param { | 88 | return Ty::Param { |
89 | idx, | 89 | idx, |
90 | // TODO: maybe return name in resolution? | 90 | // FIXME: maybe return name in resolution? |
91 | name: path | 91 | name: path |
92 | .as_ident() | 92 | .as_ident() |
93 | .expect("generic param should be single-segment path") | 93 | .expect("generic param should be single-segment path") |
@@ -139,7 +139,7 @@ impl Ty { | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | // add placeholders for args that were not provided | 141 | // add placeholders for args that were not provided |
142 | // TODO: handle defaults | 142 | // FIXME: handle defaults |
143 | let supplied_params = substs.len(); | 143 | let supplied_params = substs.len(); |
144 | for _ in supplied_params..def_generics.count_params_including_parent() { | 144 | for _ in supplied_params..def_generics.count_params_including_parent() { |
145 | substs.push(Ty::Unknown); | 145 | substs.push(Ty::Unknown); |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index ed75bfaee..b1684acf9 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -120,7 +120,7 @@ fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { | |||
120 | } | 120 | } |
121 | 121 | ||
122 | impl Ty { | 122 | impl Ty { |
123 | // TODO: cache this as a query? | 123 | // FIXME: cache this as a query? |
124 | // - if so, what signature? (TyFingerprint, Name)? | 124 | // - if so, what signature? (TyFingerprint, Name)? |
125 | // - or maybe cache all names and def_ids of methods per fingerprint? | 125 | // - or maybe cache all names and def_ids of methods per fingerprint? |
126 | /// Look up the method with the given name, returning the actual autoderefed | 126 | /// Look up the method with the given name, returning the actual autoderefed |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 0f2172ddf..5d8ad4aa7 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1792,6 +1792,29 @@ fn test<R>(query_response: Canonical<QueryResponse<R>>) { | |||
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | #[test] | 1794 | #[test] |
1795 | fn bug_1030() { | ||
1796 | assert_snapshot_matches!(infer(r#" | ||
1797 | struct HashSet<T, H>; | ||
1798 | struct FxHasher; | ||
1799 | type FxHashSet<T> = HashSet<T, FxHasher>; | ||
1800 | |||
1801 | impl<T, H> HashSet<T, H> { | ||
1802 | fn default() -> HashSet<T, H> {} | ||
1803 | } | ||
1804 | |||
1805 | pub fn main_loop() { | ||
1806 | FxHashSet::default(); | ||
1807 | } | ||
1808 | "#), | ||
1809 | @r###" | ||
1810 | [144; 146) '{}': () | ||
1811 | [169; 198) '{ ...t(); }': () | ||
1812 | [175; 193) 'FxHash...efault': fn default<{unknown}, {unknown}>() -> HashSet<T, H> | ||
1813 | [175; 195) 'FxHash...ault()': HashSet<{unknown}, {unknown}>"### | ||
1814 | ); | ||
1815 | } | ||
1816 | |||
1817 | #[test] | ||
1795 | fn cross_crate_associated_method_call() { | 1818 | fn cross_crate_associated_method_call() { |
1796 | let (mut db, pos) = MockDatabase::with_position( | 1819 | let (mut db, pos) = MockDatabase::with_position( |
1797 | r#" | 1820 | r#" |
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs index d02762d20..e35adcb2f 100644 --- a/crates/ra_hir/src/type_alias.rs +++ b/crates/ra_hir/src/type_alias.rs | |||
@@ -2,12 +2,9 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use crate::{TypeAlias, db::PersistentHirDatabase, type_ref::TypeRef}; | 5 | use crate::{TypeAlias, db::DefDatabase, type_ref::TypeRef}; |
6 | 6 | ||
7 | pub(crate) fn type_alias_ref_query( | 7 | pub(crate) fn type_alias_ref_query(db: &impl DefDatabase, typ: TypeAlias) -> Arc<TypeRef> { |
8 | db: &impl PersistentHirDatabase, | ||
9 | typ: TypeAlias, | ||
10 | ) -> Arc<TypeRef> { | ||
11 | let (_, node) = typ.source(db); | 8 | let (_, node) = typ.source(db); |
12 | Arc::new(TypeRef::from_ast_opt(node.type_ref())) | 9 | Arc::new(TypeRef::from_ast_opt(node.type_ref())) |
13 | } | 10 | } |
diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml index ac8c8057b..c64226801 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide_api/Cargo.toml | |||
@@ -10,7 +10,7 @@ join_to_string = "0.1.3" | |||
10 | log = "0.4.5" | 10 | log = "0.4.5" |
11 | relative-path = "0.4.0" | 11 | relative-path = "0.4.0" |
12 | rayon = "1.0.2" | 12 | rayon = "1.0.2" |
13 | fst = "0.3.1" | 13 | fst = { version = "0.3.1", default-features = false } |
14 | rustc-hash = "1.0" | 14 | rustc-hash = "1.0" |
15 | parking_lot = "0.7.0" | 15 | parking_lot = "0.7.0" |
16 | unicase = "2.2.0" | 16 | unicase = "2.2.0" |
@@ -23,13 +23,19 @@ ra_syntax = { path = "../ra_syntax" } | |||
23 | ra_ide_api_light = { path = "../ra_ide_api_light" } | 23 | ra_ide_api_light = { path = "../ra_ide_api_light" } |
24 | ra_text_edit = { path = "../ra_text_edit" } | 24 | ra_text_edit = { path = "../ra_text_edit" } |
25 | ra_db = { path = "../ra_db" } | 25 | ra_db = { path = "../ra_db" } |
26 | ra_fmt = { path = "../ra_fmt" } | ||
26 | hir = { path = "../ra_hir", package = "ra_hir" } | 27 | hir = { path = "../ra_hir", package = "ra_hir" } |
27 | test_utils = { path = "../test_utils" } | 28 | test_utils = { path = "../test_utils" } |
28 | ra_assists = { path = "../ra_assists" } | 29 | ra_assists = { path = "../ra_assists" } |
29 | 30 | ||
30 | [dev-dependencies] | 31 | [dev-dependencies] |
31 | insta = "0.7.0" | 32 | insta = "0.7.0" |
32 | proptest = "0.9.0" | 33 | |
34 | [dev-dependencies.proptest] | ||
35 | version = "0.9.0" | ||
36 | # Disable `fork` feature to allow compiling on webassembly | ||
37 | default-features = false | ||
38 | features = ["std", "bit-set", "break-dead-code"] | ||
33 | 39 | ||
34 | [features] | 40 | [features] |
35 | jemalloc = [ "jemallocator", "jemalloc-ctl" ] | 41 | jemalloc = [ "jemallocator", "jemalloc-ctl" ] |
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 31d5374ba..f54a02d1d 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -30,7 +30,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) | |||
30 | acc.add_field(ctx, field, &a_ty.parameters); | 30 | acc.add_field(ctx, field, &a_ty.parameters); |
31 | } | 31 | } |
32 | } | 32 | } |
33 | // TODO unions | 33 | // FIXME unions |
34 | TypeCtor::Tuple => { | 34 | TypeCtor::Tuple => { |
35 | for (i, ty) in a_ty.parameters.iter().enumerate() { | 35 | for (i, ty) in a_ty.parameters.iter().enumerate() { |
36 | acc.add_pos_field(ctx, i, ty); | 36 | acc.add_pos_field(ctx, i, ty); |
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs index 3cf79c080..7abcd019b 100644 --- a/crates/ra_ide_api/src/completion/complete_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_pattern.rs | |||
@@ -5,7 +5,7 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
5 | if !ctx.is_pat_binding { | 5 | if !ctx.is_pat_binding { |
6 | return; | 6 | return; |
7 | } | 7 | } |
8 | // TODO: ideally, we should look at the type we are matching against and | 8 | // FIXME: ideally, we should look at the type we are matching against and |
9 | // suggest variants + auto-imports | 9 | // suggest variants + auto-imports |
10 | let names = ctx.resolver.all_names(ctx.db); | 10 | let names = ctx.resolver.all_names(ctx.db); |
11 | for (name, res) in names.into_iter() { | 11 | for (name, res) in names.into_iter() { |
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs index b75526282..f58bcd03e 100644 --- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs | |||
@@ -26,7 +26,7 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon | |||
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
29 | // TODO unions | 29 | // FIXME unions |
30 | AdtDef::Enum(_) => (), | 30 | AdtDef::Enum(_) => (), |
31 | }; | 31 | }; |
32 | } | 32 | } |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 00f4bdfd2..ea4255d35 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -15,7 +15,7 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; | |||
15 | LineIndexDatabaseStorage, | 15 | LineIndexDatabaseStorage, |
16 | symbol_index::SymbolsDatabaseStorage, | 16 | symbol_index::SymbolsDatabaseStorage, |
17 | hir::db::HirDatabaseStorage, | 17 | hir::db::HirDatabaseStorage, |
18 | hir::db::PersistentHirDatabaseStorage | 18 | hir::db::DefDatabaseStorage |
19 | )] | 19 | )] |
20 | #[derive(Debug)] | 20 | #[derive(Debug)] |
21 | pub(crate) struct RootDatabase { | 21 | pub(crate) struct RootDatabase { |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 069092528..b9dc424c6 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use itertools::Itertools; | 1 | use itertools::Itertools; |
2 | use hir::{Problem, source_binder}; | 2 | use hir::{Problem, source_binder}; |
3 | use ra_ide_api_light::Severity; | ||
4 | use ra_db::SourceDatabase; | 3 | use ra_db::SourceDatabase; |
5 | use ra_syntax::{ | 4 | use ra_syntax::{ |
6 | Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, | 5 | Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, |
@@ -11,6 +10,12 @@ use ra_text_edit::{TextEdit, TextEditBuilder}; | |||
11 | 10 | ||
12 | use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase}; | 11 | use crate::{Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit, db::RootDatabase}; |
13 | 12 | ||
13 | #[derive(Debug, Copy, Clone)] | ||
14 | pub enum Severity { | ||
15 | Error, | ||
16 | WeakWarning, | ||
17 | } | ||
18 | |||
14 | pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> { | 19 | pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> { |
15 | let source_file = db.parse(file_id); | 20 | let source_file = db.parse(file_id); |
16 | let mut res = Vec::new(); | 21 | let mut res = Vec::new(); |
@@ -152,27 +157,6 @@ fn check_module( | |||
152 | fix: Some(fix), | 157 | fix: Some(fix), |
153 | } | 158 | } |
154 | } | 159 | } |
155 | Problem::NotDirOwner { move_to, candidate } => { | ||
156 | let move_file = FileSystemEdit::MoveFile { | ||
157 | src: file_id, | ||
158 | dst_source_root: source_root, | ||
159 | dst_path: move_to.clone(), | ||
160 | }; | ||
161 | let create_file = | ||
162 | FileSystemEdit::CreateFile { source_root, path: move_to.join(candidate) }; | ||
163 | let fix = SourceChange { | ||
164 | label: "move file and create module".to_string(), | ||
165 | source_file_edits: Vec::new(), | ||
166 | file_system_edits: vec![move_file, create_file], | ||
167 | cursor_position: None, | ||
168 | }; | ||
169 | Diagnostic { | ||
170 | range: name_node.range(), | ||
171 | message: "can't declare module at this location".to_string(), | ||
172 | severity: Severity::Error, | ||
173 | fix: Some(fix), | ||
174 | } | ||
175 | } | ||
176 | }; | 160 | }; |
177 | acc.push(diag) | 161 | acc.push(diag) |
178 | } | 162 | } |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index f94487d94..660b43cfa 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -117,7 +117,7 @@ pub(crate) fn reference_definition( | |||
117 | return Exact(nav); | 117 | return Exact(nav); |
118 | } | 118 | } |
119 | Some(Resolution::GenericParam(..)) => { | 119 | Some(Resolution::GenericParam(..)) => { |
120 | // TODO: go to the generic param def | 120 | // FIXME: go to the generic param def |
121 | } | 121 | } |
122 | Some(Resolution::SelfType(impl_block)) => { | 122 | Some(Resolution::SelfType(impl_block)) => { |
123 | let ty = impl_block.target_ty(db); | 123 | let ty = impl_block.target_ty(db); |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index f6443580d..3206e68b9 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -204,7 +204,7 @@ impl NavigationTarget { | |||
204 | /// | 204 | /// |
205 | /// e.g. `struct Name`, `enum Name`, `fn Name` | 205 | /// e.g. `struct Name`, `enum Name`, `fn Name` |
206 | fn description(&self, db: &RootDatabase) -> Option<String> { | 206 | fn description(&self, db: &RootDatabase) -> Option<String> { |
207 | // TODO: After type inference is done, add type information to improve the output | 207 | // FIXME: After type inference is done, add type information to improve the output |
208 | let node = self.node(db)?; | 208 | let node = self.node(db)?; |
209 | 209 | ||
210 | fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> | 210 | fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String> |
diff --git a/crates/ra_ide_api_light/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs index b5bcd62fb..8fb3eaa06 100644 --- a/crates/ra_ide_api_light/src/join_lines.rs +++ b/crates/ra_ide_api/src/join_lines.rs | |||
@@ -9,22 +9,14 @@ use ra_syntax::{ | |||
9 | use ra_fmt::{ | 9 | use ra_fmt::{ |
10 | compute_ws, extract_trivial_expression | 10 | compute_ws, extract_trivial_expression |
11 | }; | 11 | }; |
12 | use crate::{ | 12 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
13 | LocalEdit, TextEditBuilder, | ||
14 | }; | ||
15 | 13 | ||
16 | pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit { | 14 | pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { |
17 | let range = if range.is_empty() { | 15 | let range = if range.is_empty() { |
18 | let syntax = file.syntax(); | 16 | let syntax = file.syntax(); |
19 | let text = syntax.text().slice(range.start()..); | 17 | let text = syntax.text().slice(range.start()..); |
20 | let pos = match text.find('\n') { | 18 | let pos = match text.find('\n') { |
21 | None => { | 19 | None => return TextEditBuilder::default().finish(), |
22 | return LocalEdit { | ||
23 | label: "join lines".to_string(), | ||
24 | edit: TextEditBuilder::default().finish(), | ||
25 | cursor_position: None, | ||
26 | }; | ||
27 | } | ||
28 | Some(pos) => pos, | 20 | Some(pos) => pos, |
29 | }; | 21 | }; |
30 | TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n')) | 22 | TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n')) |
@@ -52,7 +44,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit { | |||
52 | } | 44 | } |
53 | } | 45 | } |
54 | 46 | ||
55 | LocalEdit { label: "join lines".to_string(), edit: edit.finish(), cursor_position: None } | 47 | edit.finish() |
56 | } | 48 | } |
57 | 49 | ||
58 | fn remove_newline( | 50 | fn remove_newline( |
@@ -514,7 +506,7 @@ fn foo() { | |||
514 | let (sel, before) = extract_range(before); | 506 | let (sel, before) = extract_range(before); |
515 | let file = SourceFile::parse(&before); | 507 | let file = SourceFile::parse(&before); |
516 | let result = join_lines(&file, sel); | 508 | let result = join_lines(&file, sel); |
517 | let actual = result.edit.apply(&before); | 509 | let actual = result.apply(&before); |
518 | assert_eq_text!(after, &actual); | 510 | assert_eq_text!(after, &actual); |
519 | } | 511 | } |
520 | 512 | ||
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index d6f63490d..99f18b6b8 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -36,9 +36,14 @@ mod syntax_tree; | |||
36 | mod line_index; | 36 | mod line_index; |
37 | mod folding_ranges; | 37 | mod folding_ranges; |
38 | mod line_index_utils; | 38 | mod line_index_utils; |
39 | mod join_lines; | ||
40 | mod typing; | ||
41 | mod matching_brace; | ||
39 | 42 | ||
40 | #[cfg(test)] | 43 | #[cfg(test)] |
41 | mod marks; | 44 | mod marks; |
45 | #[cfg(test)] | ||
46 | mod test_utils; | ||
42 | 47 | ||
43 | use std::sync::Arc; | 48 | use std::sync::Arc; |
44 | 49 | ||
@@ -66,10 +71,10 @@ pub use crate::{ | |||
66 | line_index::{LineIndex, LineCol}, | 71 | line_index::{LineIndex, LineCol}, |
67 | line_index_utils::translate_offset_with_edit, | 72 | line_index_utils::translate_offset_with_edit, |
68 | folding_ranges::{Fold, FoldKind}, | 73 | folding_ranges::{Fold, FoldKind}, |
74 | syntax_highlighting::HighlightedRange, | ||
75 | diagnostics::Severity, | ||
69 | }; | 76 | }; |
70 | pub use ra_ide_api_light::{ | 77 | pub use ra_ide_api_light::StructureNode; |
71 | HighlightedRange, Severity, StructureNode, LocalEdit, | ||
72 | }; | ||
73 | pub use ra_db::{ | 78 | pub use ra_db::{ |
74 | Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId, | 79 | Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId, |
75 | Edition | 80 | Edition |
@@ -263,7 +268,7 @@ impl Analysis { | |||
263 | /// supported). | 268 | /// supported). |
264 | pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { | 269 | pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { |
265 | let file = self.db.parse(position.file_id); | 270 | let file = self.db.parse(position.file_id); |
266 | ra_ide_api_light::matching_brace(&file, position.offset) | 271 | matching_brace::matching_brace(&file, position.offset) |
267 | } | 272 | } |
268 | 273 | ||
269 | /// Returns a syntax tree represented as `String`, for debug purposes. | 274 | /// Returns a syntax tree represented as `String`, for debug purposes. |
@@ -276,18 +281,22 @@ impl Analysis { | |||
276 | /// stuff like trailing commas. | 281 | /// stuff like trailing commas. |
277 | pub fn join_lines(&self, frange: FileRange) -> SourceChange { | 282 | pub fn join_lines(&self, frange: FileRange) -> SourceChange { |
278 | let file = self.db.parse(frange.file_id); | 283 | let file = self.db.parse(frange.file_id); |
279 | SourceChange::from_local_edit( | 284 | let file_edit = SourceFileEdit { |
280 | frange.file_id, | 285 | file_id: frange.file_id, |
281 | ra_ide_api_light::join_lines(&file, frange.range), | 286 | edit: join_lines::join_lines(&file, frange.range), |
282 | ) | 287 | }; |
288 | SourceChange { | ||
289 | label: "join lines".to_string(), | ||
290 | source_file_edits: vec![file_edit], | ||
291 | file_system_edits: vec![], | ||
292 | cursor_position: None, | ||
293 | } | ||
283 | } | 294 | } |
284 | 295 | ||
285 | /// Returns an edit which should be applied when opening a new line, fixing | 296 | /// Returns an edit which should be applied when opening a new line, fixing |
286 | /// up minor stuff like continuing the comment. | 297 | /// up minor stuff like continuing the comment. |
287 | pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { | 298 | pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { |
288 | let file = self.db.parse(position.file_id); | 299 | typing::on_enter(&self.db, position) |
289 | let edit = ra_ide_api_light::on_enter(&file, position.offset)?; | ||
290 | Some(SourceChange::from_local_edit(position.file_id, edit)) | ||
291 | } | 300 | } |
292 | 301 | ||
293 | /// Returns an edit which should be applied after `=` was typed. Primarily, | 302 | /// Returns an edit which should be applied after `=` was typed. Primarily, |
@@ -295,15 +304,18 @@ impl Analysis { | |||
295 | // FIXME: use a snippet completion instead of this hack here. | 304 | // FIXME: use a snippet completion instead of this hack here. |
296 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { | 305 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { |
297 | let file = self.db.parse(position.file_id); | 306 | let file = self.db.parse(position.file_id); |
298 | let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?; | 307 | let edit = typing::on_eq_typed(&file, position.offset)?; |
299 | Some(SourceChange::from_local_edit(position.file_id, edit)) | 308 | Some(SourceChange { |
309 | label: "add semicolon".to_string(), | ||
310 | source_file_edits: vec![SourceFileEdit { edit, file_id: position.file_id }], | ||
311 | file_system_edits: vec![], | ||
312 | cursor_position: None, | ||
313 | }) | ||
300 | } | 314 | } |
301 | 315 | ||
302 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. | 316 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. |
303 | pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { | 317 | pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { |
304 | let file = self.db.parse(position.file_id); | 318 | typing::on_dot_typed(&self.db, position) |
305 | let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?; | ||
306 | Some(SourceChange::from_local_edit(position.file_id, edit)) | ||
307 | } | 319 | } |
308 | 320 | ||
309 | /// Returns a tree representation of symbols in the file. Useful to draw a | 321 | /// Returns a tree representation of symbols in the file. Useful to draw a |
@@ -425,18 +437,6 @@ impl Analysis { | |||
425 | } | 437 | } |
426 | } | 438 | } |
427 | 439 | ||
428 | impl SourceChange { | ||
429 | pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange { | ||
430 | let file_edit = SourceFileEdit { file_id, edit: edit.edit }; | ||
431 | SourceChange { | ||
432 | label: edit.label, | ||
433 | source_file_edits: vec![file_edit], | ||
434 | file_system_edits: vec![], | ||
435 | cursor_position: edit.cursor_position.map(|offset| FilePosition { offset, file_id }), | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | #[test] | 440 | #[test] |
441 | fn analysis_is_send() { | 441 | fn analysis_is_send() { |
442 | fn is_send<T: Send>() {} | 442 | fn is_send<T: Send>() {} |
diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide_api/src/line_index.rs index bf004c33a..fd33d6767 100644 --- a/crates/ra_ide_api/src/line_index.rs +++ b/crates/ra_ide_api/src/line_index.rs | |||
@@ -77,7 +77,7 @@ impl LineIndex { | |||
77 | } | 77 | } |
78 | 78 | ||
79 | pub fn offset(&self, line_col: LineCol) -> TextUnit { | 79 | pub fn offset(&self, line_col: LineCol) -> TextUnit { |
80 | //TODO: return Result | 80 | //FIXME: return Result |
81 | let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16); | 81 | let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16); |
82 | self.newlines[line_col.line as usize] + col | 82 | self.newlines[line_col.line as usize] + col |
83 | } | 83 | } |
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs new file mode 100644 index 000000000..d1405f14f --- /dev/null +++ b/crates/ra_ide_api/src/matching_brace.rs | |||
@@ -0,0 +1,45 @@ | |||
1 | use ra_syntax::{ | ||
2 | SourceFile, TextUnit, | ||
3 | algo::find_leaf_at_offset, | ||
4 | SyntaxKind::{self, *}, | ||
5 | ast::AstNode, | ||
6 | }; | ||
7 | |||
8 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | ||
9 | const BRACES: &[SyntaxKind] = | ||
10 | &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE]; | ||
11 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) | ||
12 | .filter_map(|node| { | ||
13 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; | ||
14 | Some((node, idx)) | ||
15 | }) | ||
16 | .next()?; | ||
17 | let parent = brace_node.parent()?; | ||
18 | let matching_kind = BRACES[brace_idx ^ 1]; | ||
19 | let matching_node = parent.children().find(|node| node.kind() == matching_kind)?; | ||
20 | Some(matching_node.range().start()) | ||
21 | } | ||
22 | |||
23 | #[cfg(test)] | ||
24 | mod tests { | ||
25 | use test_utils::{add_cursor, assert_eq_text, extract_offset}; | ||
26 | |||
27 | use super::*; | ||
28 | |||
29 | #[test] | ||
30 | fn test_matching_brace() { | ||
31 | fn do_check(before: &str, after: &str) { | ||
32 | let (pos, before) = extract_offset(before); | ||
33 | let file = SourceFile::parse(&before); | ||
34 | let new_pos = match matching_brace(&file, pos) { | ||
35 | None => pos, | ||
36 | Some(pos) => pos, | ||
37 | }; | ||
38 | let actual = add_cursor(&before, new_pos); | ||
39 | assert_eq_text!(after, &actual); | ||
40 | } | ||
41 | |||
42 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); | ||
43 | } | ||
44 | |||
45 | } | ||
diff --git a/crates/ra_ide_api/src/snapshots/tests__highlighting.snap b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap new file mode 100644 index 000000000..72029e0ed --- /dev/null +++ b/crates/ra_ide_api/src/snapshots/tests__highlighting.snap | |||
@@ -0,0 +1,34 @@ | |||
1 | --- | ||
2 | created: "2019-03-23T16:20:31.394314144Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_ide_api/src/syntax_highlighting.rs | ||
5 | expression: result | ||
6 | --- | ||
7 | Ok( | ||
8 | [ | ||
9 | HighlightedRange { | ||
10 | range: [1; 11), | ||
11 | tag: "comment" | ||
12 | }, | ||
13 | HighlightedRange { | ||
14 | range: [12; 14), | ||
15 | tag: "keyword" | ||
16 | }, | ||
17 | HighlightedRange { | ||
18 | range: [15; 19), | ||
19 | tag: "function" | ||
20 | }, | ||
21 | HighlightedRange { | ||
22 | range: [29; 37), | ||
23 | tag: "macro" | ||
24 | }, | ||
25 | HighlightedRange { | ||
26 | range: [38; 50), | ||
27 | tag: "string" | ||
28 | }, | ||
29 | HighlightedRange { | ||
30 | range: [52; 54), | ||
31 | tag: "literal" | ||
32 | } | ||
33 | ] | ||
34 | ) | ||
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 23c743bef..0978d164a 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -68,7 +68,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> | |||
68 | 68 | ||
69 | let symbols = source_file_to_file_symbols(&source_file, file_id); | 69 | let symbols = source_file_to_file_symbols(&source_file, file_id); |
70 | 70 | ||
71 | // TODO: add macros here | 71 | // FIXME: add macros here |
72 | 72 | ||
73 | Arc::new(SymbolIndex::new(symbols)) | 73 | Arc::new(SymbolIndex::new(symbols)) |
74 | } | 74 | } |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index fdd87bcff..a0c5e78ad 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -1,12 +1,81 @@ | |||
1 | use ra_syntax::AstNode; | 1 | use rustc_hash::FxHashSet; |
2 | |||
3 | use ra_syntax::{ast, AstNode, TextRange, Direction, SyntaxKind::*}; | ||
2 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
3 | 5 | ||
4 | use crate::{ | 6 | use crate::{FileId, db::RootDatabase}; |
5 | FileId, HighlightedRange, | 7 | |
6 | db::RootDatabase, | 8 | #[derive(Debug)] |
7 | }; | 9 | pub struct HighlightedRange { |
10 | pub range: TextRange, | ||
11 | pub tag: &'static str, | ||
12 | } | ||
8 | 13 | ||
9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 14 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { |
10 | let source_file = db.parse(file_id); | 15 | let source_file = db.parse(file_id); |
11 | ra_ide_api_light::highlight(source_file.syntax()) | 16 | |
17 | // Visited nodes to handle highlighting priorities | ||
18 | let mut highlighted = FxHashSet::default(); | ||
19 | let mut res = Vec::new(); | ||
20 | for node in source_file.syntax().descendants() { | ||
21 | if highlighted.contains(&node) { | ||
22 | continue; | ||
23 | } | ||
24 | let tag = match node.kind() { | ||
25 | COMMENT => "comment", | ||
26 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | ||
27 | ATTR => "attribute", | ||
28 | NAME_REF => "text", | ||
29 | NAME => "function", | ||
30 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | ||
31 | LIFETIME => "parameter", | ||
32 | k if k.is_keyword() => "keyword", | ||
33 | _ => { | ||
34 | if let Some(macro_call) = ast::MacroCall::cast(node) { | ||
35 | if let Some(path) = macro_call.path() { | ||
36 | if let Some(segment) = path.segment() { | ||
37 | if let Some(name_ref) = segment.name_ref() { | ||
38 | highlighted.insert(name_ref.syntax()); | ||
39 | let range_start = name_ref.syntax().range().start(); | ||
40 | let mut range_end = name_ref.syntax().range().end(); | ||
41 | for sibling in path.syntax().siblings(Direction::Next) { | ||
42 | match sibling.kind() { | ||
43 | EXCL | IDENT => range_end = sibling.range().end(), | ||
44 | _ => (), | ||
45 | } | ||
46 | } | ||
47 | res.push(HighlightedRange { | ||
48 | range: TextRange::from_to(range_start, range_end), | ||
49 | tag: "macro", | ||
50 | }) | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | continue; | ||
56 | } | ||
57 | }; | ||
58 | res.push(HighlightedRange { range: node.range(), tag }) | ||
59 | } | ||
60 | res | ||
61 | } | ||
62 | |||
63 | #[cfg(test)] | ||
64 | mod tests { | ||
65 | use insta::assert_debug_snapshot_matches; | ||
66 | |||
67 | use crate::mock_analysis::single_file; | ||
68 | |||
69 | #[test] | ||
70 | fn test_highlighting() { | ||
71 | let (analysis, file_id) = single_file( | ||
72 | r#" | ||
73 | // comment | ||
74 | fn main() {} | ||
75 | println!("Hello, {}!", 92); | ||
76 | "#, | ||
77 | ); | ||
78 | let result = analysis.highlight(file_id); | ||
79 | assert_debug_snapshot_matches!("highlighting", result); | ||
80 | } | ||
12 | } | 81 | } |
diff --git a/crates/ra_ide_api_light/src/test_utils.rs b/crates/ra_ide_api/src/test_utils.rs index bfac0fce3..d0bd3a1e4 100644 --- a/crates/ra_ide_api_light/src/test_utils.rs +++ b/crates/ra_ide_api/src/test_utils.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use ra_syntax::{SourceFile, TextUnit}; | 1 | use ra_syntax::{SourceFile, TextUnit}; |
2 | use ra_text_edit::TextEdit; | ||
2 | 3 | ||
3 | use crate::LocalEdit; | ||
4 | pub use test_utils::*; | 4 | pub use test_utils::*; |
5 | 5 | ||
6 | pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<LocalEdit>>( | 6 | pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<TextEdit>>( |
7 | before: &str, | 7 | before: &str, |
8 | after: &str, | 8 | after: &str, |
9 | f: F, | 9 | f: F, |
@@ -11,14 +11,9 @@ pub fn check_action<F: Fn(&SourceFile, TextUnit) -> Option<LocalEdit>>( | |||
11 | let (before_cursor_pos, before) = extract_offset(before); | 11 | let (before_cursor_pos, before) = extract_offset(before); |
12 | let file = SourceFile::parse(&before); | 12 | let file = SourceFile::parse(&before); |
13 | let result = f(&file, before_cursor_pos).expect("code action is not applicable"); | 13 | let result = f(&file, before_cursor_pos).expect("code action is not applicable"); |
14 | let actual = result.edit.apply(&before); | 14 | let actual = result.apply(&before); |
15 | let actual_cursor_pos = match result.cursor_position { | 15 | let actual_cursor_pos = |
16 | None => result | 16 | result.apply_to_offset(before_cursor_pos).expect("cursor position is affected by the edit"); |
17 | .edit | ||
18 | .apply_to_offset(before_cursor_pos) | ||
19 | .expect("cursor position is affected by the edit"), | ||
20 | Some(off) => off, | ||
21 | }; | ||
22 | let actual = add_cursor(&actual, actual_cursor_pos); | 17 | let actual = add_cursor(&actual, actual_cursor_pos); |
23 | assert_eq_text!(after, &actual); | 18 | assert_eq_text!(after, &actual); |
24 | } | 19 | } |
diff --git a/crates/ra_ide_api_light/src/typing.rs b/crates/ra_ide_api/src/typing.rs index 9dd9f1c1d..94b228466 100644 --- a/crates/ra_ide_api_light/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs | |||
@@ -5,30 +5,37 @@ use ra_syntax::{ | |||
5 | ast::{self, AstToken}, | 5 | ast::{self, AstToken}, |
6 | }; | 6 | }; |
7 | use ra_fmt::leading_indent; | 7 | use ra_fmt::leading_indent; |
8 | use crate::{LocalEdit, TextEditBuilder}; | 8 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
9 | use ra_db::{FilePosition, SourceDatabase}; | ||
10 | use crate::{db::RootDatabase, SourceChange, SourceFileEdit}; | ||
9 | 11 | ||
10 | pub fn on_enter(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> { | 12 | pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { |
11 | let comment = | 13 | let file = db.parse(position.file_id); |
12 | find_leaf_at_offset(file.syntax(), offset).left_biased().and_then(ast::Comment::cast)?; | 14 | let comment = find_leaf_at_offset(file.syntax(), position.offset) |
15 | .left_biased() | ||
16 | .and_then(ast::Comment::cast)?; | ||
13 | 17 | ||
14 | if let ast::CommentFlavor::Multiline = comment.flavor() { | 18 | if let ast::CommentFlavor::Multiline = comment.flavor() { |
15 | return None; | 19 | return None; |
16 | } | 20 | } |
17 | 21 | ||
18 | let prefix = comment.prefix(); | 22 | let prefix = comment.prefix(); |
19 | if offset < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) { | 23 | if position.offset |
24 | < comment.syntax().range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) | ||
25 | { | ||
20 | return None; | 26 | return None; |
21 | } | 27 | } |
22 | 28 | ||
23 | let indent = node_indent(file, comment.syntax())?; | 29 | let indent = node_indent(&file, comment.syntax())?; |
24 | let inserted = format!("\n{}{} ", indent, prefix); | 30 | let inserted = format!("\n{}{} ", indent, prefix); |
25 | let cursor_position = offset + TextUnit::of_str(&inserted); | 31 | let cursor_position = position.offset + TextUnit::of_str(&inserted); |
26 | let mut edit = TextEditBuilder::default(); | 32 | let mut edit = TextEditBuilder::default(); |
27 | edit.insert(offset, inserted); | 33 | edit.insert(position.offset, inserted); |
28 | Some(LocalEdit { | 34 | Some(SourceChange { |
29 | label: "on enter".to_string(), | 35 | label: "on enter".to_string(), |
30 | edit: edit.finish(), | 36 | source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }], |
31 | cursor_position: Some(cursor_position), | 37 | file_system_edits: vec![], |
38 | cursor_position: Some(FilePosition { offset: cursor_position, file_id: position.file_id }), | ||
32 | }) | 39 | }) |
33 | } | 40 | } |
34 | 41 | ||
@@ -52,7 +59,7 @@ fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> { | |||
52 | Some(&text[pos..]) | 59 | Some(&text[pos..]) |
53 | } | 60 | } |
54 | 61 | ||
55 | pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<LocalEdit> { | 62 | pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> { |
56 | assert_eq!(file.syntax().text().char_at(eq_offset), Some('=')); | 63 | assert_eq!(file.syntax().text().char_at(eq_offset), Some('=')); |
57 | let let_stmt: &ast::LetStmt = find_node_at_offset(file.syntax(), eq_offset)?; | 64 | let let_stmt: &ast::LetStmt = find_node_at_offset(file.syntax(), eq_offset)?; |
58 | if let_stmt.has_semi() { | 65 | if let_stmt.has_semi() { |
@@ -72,17 +79,14 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<LocalEdit> | |||
72 | let offset = let_stmt.syntax().range().end(); | 79 | let offset = let_stmt.syntax().range().end(); |
73 | let mut edit = TextEditBuilder::default(); | 80 | let mut edit = TextEditBuilder::default(); |
74 | edit.insert(offset, ";".to_string()); | 81 | edit.insert(offset, ";".to_string()); |
75 | Some(LocalEdit { | 82 | Some(edit.finish()) |
76 | label: "add semicolon".to_string(), | ||
77 | edit: edit.finish(), | ||
78 | cursor_position: None, | ||
79 | }) | ||
80 | } | 83 | } |
81 | 84 | ||
82 | pub fn on_dot_typed(file: &SourceFile, dot_offset: TextUnit) -> Option<LocalEdit> { | 85 | pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { |
83 | assert_eq!(file.syntax().text().char_at(dot_offset), Some('.')); | 86 | let file = db.parse(position.file_id); |
87 | assert_eq!(file.syntax().text().char_at(position.offset), Some('.')); | ||
84 | 88 | ||
85 | let whitespace = find_leaf_at_offset(file.syntax(), dot_offset) | 89 | let whitespace = find_leaf_at_offset(file.syntax(), position.offset) |
86 | .left_biased() | 90 | .left_biased() |
87 | .and_then(ast::Whitespace::cast)?; | 91 | .and_then(ast::Whitespace::cast)?; |
88 | 92 | ||
@@ -103,22 +107,27 @@ pub fn on_dot_typed(file: &SourceFile, dot_offset: TextUnit) -> Option<LocalEdit | |||
103 | } | 107 | } |
104 | let mut edit = TextEditBuilder::default(); | 108 | let mut edit = TextEditBuilder::default(); |
105 | edit.replace( | 109 | edit.replace( |
106 | TextRange::from_to(dot_offset - current_indent_len, dot_offset), | 110 | TextRange::from_to(position.offset - current_indent_len, position.offset), |
107 | target_indent.into(), | 111 | target_indent.into(), |
108 | ); | 112 | ); |
109 | let res = LocalEdit { | 113 | let res = SourceChange { |
110 | label: "reindent dot".to_string(), | 114 | label: "reindent dot".to_string(), |
111 | edit: edit.finish(), | 115 | source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }], |
112 | cursor_position: Some( | 116 | file_system_edits: vec![], |
113 | dot_offset + target_indent_len - current_indent_len + TextUnit::of_char('.'), | 117 | cursor_position: Some(FilePosition { |
114 | ), | 118 | offset: position.offset + target_indent_len - current_indent_len |
119 | + TextUnit::of_char('.'), | ||
120 | file_id: position.file_id, | ||
121 | }), | ||
115 | }; | 122 | }; |
116 | Some(res) | 123 | Some(res) |
117 | } | 124 | } |
118 | 125 | ||
119 | #[cfg(test)] | 126 | #[cfg(test)] |
120 | mod tests { | 127 | mod tests { |
121 | use crate::test_utils::{add_cursor, assert_eq_text, extract_offset}; | 128 | use test_utils::{add_cursor, assert_eq_text, extract_offset}; |
129 | |||
130 | use crate::mock_analysis::single_file; | ||
122 | 131 | ||
123 | use super::*; | 132 | use super::*; |
124 | 133 | ||
@@ -131,7 +140,7 @@ mod tests { | |||
131 | let before = edit.finish().apply(&before); | 140 | let before = edit.finish().apply(&before); |
132 | let file = SourceFile::parse(&before); | 141 | let file = SourceFile::parse(&before); |
133 | if let Some(result) = on_eq_typed(&file, offset) { | 142 | if let Some(result) = on_eq_typed(&file, offset) { |
134 | let actual = result.edit.apply(&before); | 143 | let actual = result.apply(&before); |
135 | assert_eq_text!(after, &actual); | 144 | assert_eq_text!(after, &actual); |
136 | } else { | 145 | } else { |
137 | assert_eq_text!(&before, after) | 146 | assert_eq_text!(&before, after) |
@@ -177,9 +186,10 @@ fn foo() { | |||
177 | let mut edit = TextEditBuilder::default(); | 186 | let mut edit = TextEditBuilder::default(); |
178 | edit.insert(offset, ".".to_string()); | 187 | edit.insert(offset, ".".to_string()); |
179 | let before = edit.finish().apply(&before); | 188 | let before = edit.finish().apply(&before); |
180 | let file = SourceFile::parse(&before); | 189 | let (analysis, file_id) = single_file(&before); |
181 | if let Some(result) = on_dot_typed(&file, offset) { | 190 | if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }) { |
182 | let actual = result.edit.apply(&before); | 191 | assert_eq!(result.source_file_edits.len(), 1); |
192 | let actual = result.source_file_edits[0].edit.apply(&before); | ||
183 | assert_eq_text!(after, &actual); | 193 | assert_eq_text!(after, &actual); |
184 | } else { | 194 | } else { |
185 | assert_eq_text!(&before, after) | 195 | assert_eq_text!(&before, after) |
@@ -358,10 +368,12 @@ fn foo() { | |||
358 | fn test_on_enter() { | 368 | fn test_on_enter() { |
359 | fn apply_on_enter(before: &str) -> Option<String> { | 369 | fn apply_on_enter(before: &str) -> Option<String> { |
360 | let (offset, before) = extract_offset(before); | 370 | let (offset, before) = extract_offset(before); |
361 | let file = SourceFile::parse(&before); | 371 | let (analysis, file_id) = single_file(&before); |
362 | let result = on_enter(&file, offset)?; | 372 | let result = analysis.on_enter(FilePosition { offset, file_id })?; |
363 | let actual = result.edit.apply(&before); | 373 | |
364 | let actual = add_cursor(&actual, result.cursor_position.unwrap()); | 374 | assert_eq!(result.source_file_edits.len(), 1); |
375 | let actual = result.source_file_edits[0].edit.apply(&before); | ||
376 | let actual = add_cursor(&actual, result.cursor_position.unwrap().offset); | ||
365 | Some(actual) | 377 | Some(actual) |
366 | } | 378 | } |
367 | 379 | ||
diff --git a/crates/ra_ide_api_light/Cargo.toml b/crates/ra_ide_api_light/Cargo.toml index a30833dc3..4e69f5325 100644 --- a/crates/ra_ide_api_light/Cargo.toml +++ b/crates/ra_ide_api_light/Cargo.toml | |||
@@ -17,5 +17,10 @@ ra_fmt = { path = "../ra_fmt" } | |||
17 | 17 | ||
18 | [dev-dependencies] | 18 | [dev-dependencies] |
19 | test_utils = { path = "../test_utils" } | 19 | test_utils = { path = "../test_utils" } |
20 | proptest = "0.9.0" | ||
21 | insta = "0.7.0" | 20 | insta = "0.7.0" |
21 | |||
22 | [dev-dependencies.proptest] | ||
23 | version = "0.9.0" | ||
24 | # Disable `fork` feature to allow compiling on webassembly | ||
25 | default-features = false | ||
26 | features = ["std", "bit-set", "break-dead-code"] | ||
diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs index 4036a598e..df7f144b6 100644 --- a/crates/ra_ide_api_light/src/lib.rs +++ b/crates/ra_ide_api_light/src/lib.rs | |||
@@ -4,151 +4,9 @@ | |||
4 | //! an edit or some auxiliary info. | 4 | //! an edit or some auxiliary info. |
5 | 5 | ||
6 | mod structure; | 6 | mod structure; |
7 | #[cfg(test)] | ||
8 | mod test_utils; | ||
9 | mod join_lines; | ||
10 | mod typing; | ||
11 | 7 | ||
12 | use rustc_hash::FxHashSet; | 8 | use ra_syntax::TextRange; |
13 | use ra_text_edit::TextEditBuilder; | ||
14 | use ra_syntax::{ | ||
15 | SourceFile, SyntaxNode, TextRange, TextUnit, Direction, | ||
16 | algo::find_leaf_at_offset, | ||
17 | SyntaxKind::{self, *}, | ||
18 | ast::{self, AstNode}, | ||
19 | }; | ||
20 | 9 | ||
21 | pub use crate::{ | 10 | pub use crate::{ |
22 | structure::{file_structure, StructureNode}, | 11 | structure::{file_structure, StructureNode}, |
23 | join_lines::join_lines, | ||
24 | typing::{on_enter, on_dot_typed, on_eq_typed}, | ||
25 | }; | 12 | }; |
26 | |||
27 | #[derive(Debug)] | ||
28 | pub struct LocalEdit { | ||
29 | pub label: String, | ||
30 | pub edit: ra_text_edit::TextEdit, | ||
31 | pub cursor_position: Option<TextUnit>, | ||
32 | } | ||
33 | |||
34 | #[derive(Debug)] | ||
35 | pub struct HighlightedRange { | ||
36 | pub range: TextRange, | ||
37 | pub tag: &'static str, | ||
38 | } | ||
39 | |||
40 | #[derive(Debug, Copy, Clone)] | ||
41 | pub enum Severity { | ||
42 | Error, | ||
43 | WeakWarning, | ||
44 | } | ||
45 | |||
46 | #[derive(Debug)] | ||
47 | pub struct Diagnostic { | ||
48 | pub range: TextRange, | ||
49 | pub msg: String, | ||
50 | pub severity: Severity, | ||
51 | pub fix: Option<LocalEdit>, | ||
52 | } | ||
53 | |||
54 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | ||
55 | const BRACES: &[SyntaxKind] = | ||
56 | &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE]; | ||
57 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) | ||
58 | .filter_map(|node| { | ||
59 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; | ||
60 | Some((node, idx)) | ||
61 | }) | ||
62 | .next()?; | ||
63 | let parent = brace_node.parent()?; | ||
64 | let matching_kind = BRACES[brace_idx ^ 1]; | ||
65 | let matching_node = parent.children().find(|node| node.kind() == matching_kind)?; | ||
66 | Some(matching_node.range().start()) | ||
67 | } | ||
68 | |||
69 | pub fn highlight(root: &SyntaxNode) -> Vec<HighlightedRange> { | ||
70 | // Visited nodes to handle highlighting priorities | ||
71 | let mut highlighted = FxHashSet::default(); | ||
72 | let mut res = Vec::new(); | ||
73 | for node in root.descendants() { | ||
74 | if highlighted.contains(&node) { | ||
75 | continue; | ||
76 | } | ||
77 | let tag = match node.kind() { | ||
78 | COMMENT => "comment", | ||
79 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | ||
80 | ATTR => "attribute", | ||
81 | NAME_REF => "text", | ||
82 | NAME => "function", | ||
83 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | ||
84 | LIFETIME => "parameter", | ||
85 | k if k.is_keyword() => "keyword", | ||
86 | _ => { | ||
87 | if let Some(macro_call) = ast::MacroCall::cast(node) { | ||
88 | if let Some(path) = macro_call.path() { | ||
89 | if let Some(segment) = path.segment() { | ||
90 | if let Some(name_ref) = segment.name_ref() { | ||
91 | highlighted.insert(name_ref.syntax()); | ||
92 | let range_start = name_ref.syntax().range().start(); | ||
93 | let mut range_end = name_ref.syntax().range().end(); | ||
94 | for sibling in path.syntax().siblings(Direction::Next) { | ||
95 | match sibling.kind() { | ||
96 | EXCL | IDENT => range_end = sibling.range().end(), | ||
97 | _ => (), | ||
98 | } | ||
99 | } | ||
100 | res.push(HighlightedRange { | ||
101 | range: TextRange::from_to(range_start, range_end), | ||
102 | tag: "macro", | ||
103 | }) | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | continue; | ||
109 | } | ||
110 | }; | ||
111 | res.push(HighlightedRange { range: node.range(), tag }) | ||
112 | } | ||
113 | res | ||
114 | } | ||
115 | |||
116 | #[cfg(test)] | ||
117 | mod tests { | ||
118 | use ra_syntax::AstNode; | ||
119 | use insta::assert_debug_snapshot_matches; | ||
120 | |||
121 | use crate::test_utils::{add_cursor, assert_eq_text, extract_offset}; | ||
122 | |||
123 | use super::*; | ||
124 | |||
125 | #[test] | ||
126 | fn test_highlighting() { | ||
127 | let file = SourceFile::parse( | ||
128 | r#" | ||
129 | // comment | ||
130 | fn main() {} | ||
131 | println!("Hello, {}!", 92); | ||
132 | "#, | ||
133 | ); | ||
134 | let hls = highlight(file.syntax()); | ||
135 | assert_debug_snapshot_matches!("highlighting", hls); | ||
136 | } | ||
137 | |||
138 | #[test] | ||
139 | fn test_matching_brace() { | ||
140 | fn do_check(before: &str, after: &str) { | ||
141 | let (pos, before) = extract_offset(before); | ||
142 | let file = SourceFile::parse(&before); | ||
143 | let new_pos = match matching_brace(&file, pos) { | ||
144 | None => pos, | ||
145 | Some(pos) => pos, | ||
146 | }; | ||
147 | let actual = add_cursor(&before, new_pos); | ||
148 | assert_eq_text!(after, &actual); | ||
149 | } | ||
150 | |||
151 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); | ||
152 | } | ||
153 | |||
154 | } | ||
diff --git a/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap b/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap deleted file mode 100644 index ef306a7a0..000000000 --- a/crates/ra_ide_api_light/src/snapshots/tests__highlighting.snap +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | --- | ||
2 | created: "2019-01-22T14:45:01.959724300+00:00" | ||
3 | creator: [email protected] | ||
4 | expression: hls | ||
5 | source: "crates\\ra_ide_api_light\\src\\lib.rs" | ||
6 | --- | ||
7 | [ | ||
8 | HighlightedRange { | ||
9 | range: [1; 11), | ||
10 | tag: "comment" | ||
11 | }, | ||
12 | HighlightedRange { | ||
13 | range: [12; 14), | ||
14 | tag: "keyword" | ||
15 | }, | ||
16 | HighlightedRange { | ||
17 | range: [15; 19), | ||
18 | tag: "function" | ||
19 | }, | ||
20 | HighlightedRange { | ||
21 | range: [29; 37), | ||
22 | tag: "macro" | ||
23 | }, | ||
24 | HighlightedRange { | ||
25 | range: [38; 50), | ||
26 | tag: "string" | ||
27 | }, | ||
28 | HighlightedRange { | ||
29 | range: [52; 54), | ||
30 | tag: "literal" | ||
31 | } | ||
32 | ] | ||
diff --git a/crates/ra_parser/src/grammar/items/consts.rs b/crates/ra_parser/src/grammar/items/consts.rs index e6e6011c6..1f802246f 100644 --- a/crates/ra_parser/src/grammar/items/consts.rs +++ b/crates/ra_parser/src/grammar/items/consts.rs | |||
@@ -11,7 +11,7 @@ pub(super) fn const_def(p: &mut Parser, m: Marker) { | |||
11 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { | 11 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { |
12 | assert!(p.at(kw)); | 12 | assert!(p.at(kw)); |
13 | p.bump(); | 13 | p.bump(); |
14 | p.eat(MUT_KW); // TODO: validator to forbid const mut | 14 | p.eat(MUT_KW); // FIXME: validator to forbid const mut |
15 | name(p); | 15 | name(p); |
16 | types::ascription(p); | 16 | types::ascription(p); |
17 | if p.eat(EQ) { | 17 | if p.eat(EQ) { |
diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/nominal.rs index a3579eebd..e93bd76b8 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/nominal.rs | |||
@@ -15,7 +15,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { | |||
15 | } | 15 | } |
16 | L_CURLY => named_field_def_list(p), | 16 | L_CURLY => named_field_def_list(p), |
17 | _ => { | 17 | _ => { |
18 | //TODO: special case `(` error message | 18 | //FIXME: special case `(` error message |
19 | p.error("expected `;` or `{`"); | 19 | p.error("expected `;` or `{`"); |
20 | } | 20 | } |
21 | } | 21 | } |
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs index d5a8ccd98..f49615f6b 100644 --- a/crates/ra_parser/src/grammar/items/traits.rs +++ b/crates/ra_parser/src/grammar/items/traits.rs | |||
@@ -49,7 +49,7 @@ pub(super) fn impl_block(p: &mut Parser) { | |||
49 | type_params::opt_type_param_list(p); | 49 | type_params::opt_type_param_list(p); |
50 | } | 50 | } |
51 | 51 | ||
52 | // TODO: never type | 52 | // FIXME: never type |
53 | // impl ! {} | 53 | // impl ! {} |
54 | 54 | ||
55 | // test impl_block_neg | 55 | // test impl_block_neg |
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs index ea2f94604..908493789 100644 --- a/crates/ra_parser/src/grammar/items/use_item.rs +++ b/crates/ra_parser/src/grammar/items/use_item.rs | |||
@@ -21,7 +21,7 @@ fn use_tree(p: &mut Parser) { | |||
21 | // This does not handle cases such as `use some::path::*` | 21 | // This does not handle cases such as `use some::path::*` |
22 | // N.B. in Rust 2015 `use *;` imports all from crate root | 22 | // N.B. in Rust 2015 `use *;` imports all from crate root |
23 | // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates') | 23 | // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates') |
24 | // TODO: Add this error (if not out of scope) | 24 | // FIXME: Add this error (if not out of scope) |
25 | 25 | ||
26 | // test use_star | 26 | // test use_star |
27 | // use *; | 27 | // use *; |
@@ -33,7 +33,7 @@ fn use_tree(p: &mut Parser) { | |||
33 | // Parse `use ::*;`, which imports all from the crate root in Rust 2015 | 33 | // Parse `use ::*;`, which imports all from the crate root in Rust 2015 |
34 | // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) | 34 | // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) |
35 | // but still parses and errors later: ('crate root in paths can only be used in start position') | 35 | // but still parses and errors later: ('crate root in paths can only be used in start position') |
36 | // TODO: Add this error (if not out of scope) | 36 | // FIXME: Add this error (if not out of scope) |
37 | // In Rust 2018, it is always invalid (see above) | 37 | // In Rust 2018, it is always invalid (see above) |
38 | p.bump(); | 38 | p.bump(); |
39 | p.bump(); | 39 | p.bump(); |
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index adc189a29..fdd4f2c52 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -202,12 +202,15 @@ pub(super) fn for_binder(p: &mut Parser) { | |||
202 | 202 | ||
203 | // test for_type | 203 | // test for_type |
204 | // type A = for<'a> fn() -> (); | 204 | // type A = for<'a> fn() -> (); |
205 | // fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} | ||
206 | // fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} | ||
205 | pub(super) fn for_type(p: &mut Parser) { | 207 | pub(super) fn for_type(p: &mut Parser) { |
206 | assert!(p.at(FOR_KW)); | 208 | assert!(p.at(FOR_KW)); |
207 | let m = p.start(); | 209 | let m = p.start(); |
208 | for_binder(p); | 210 | for_binder(p); |
209 | match p.current() { | 211 | match p.current() { |
210 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), | 212 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), |
213 | AMP => reference_type(p), | ||
211 | _ if paths::is_path_start(p) => path_type_(p, false), | 214 | _ if paths::is_path_start(p) => path_type_(p, false), |
212 | _ => p.error("expected a path"), | 215 | _ => p.error("expected a path"), |
213 | } | 216 | } |
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs index 3c326452b..56f8b7126 100644 --- a/crates/ra_parser/src/parser.rs +++ b/crates/ra_parser/src/parser.rs | |||
@@ -121,7 +121,7 @@ impl<'t> Parser<'t> { | |||
121 | /// final tree. | 121 | /// final tree. |
122 | pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { | 122 | pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { |
123 | if self.nth(0) == EOF { | 123 | if self.nth(0) == EOF { |
124 | // TODO: panic!? | 124 | // FIXME: panic!? |
125 | return; | 125 | return; |
126 | } | 126 | } |
127 | self.do_bump(kind, 1); | 127 | self.do_bump(kind, 1); |
@@ -135,7 +135,7 @@ impl<'t> Parser<'t> { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | /// Emit error with the `message` | 137 | /// Emit error with the `message` |
138 | /// TODO: this should be much more fancy and support | 138 | /// FIXME: this should be much more fancy and support |
139 | /// structured errors with spans and notes, like rustc | 139 | /// structured errors with spans and notes, like rustc |
140 | /// does. | 140 | /// does. |
141 | pub(crate) fn error<T: Into<String>>(&mut self, message: T) { | 141 | pub(crate) fn error<T: Into<String>>(&mut self, message: T) { |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 6f46a2d43..3bad4f8d3 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -23,7 +23,7 @@ pub use crate::{ | |||
23 | sysroot::Sysroot, | 23 | sysroot::Sysroot, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | // TODO use proper error enum | 26 | // FIXME use proper error enum |
27 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 27 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
28 | 28 | ||
29 | #[derive(Debug, Clone)] | 29 | #[derive(Debug, Clone)] |
diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs index 3169ed590..c874e5d08 100644 --- a/crates/ra_syntax/src/validation/char.rs +++ b/crates/ra_syntax/src/validation/char.rs | |||
@@ -85,7 +85,7 @@ pub(super) fn is_ascii_escape(code: char) -> bool { | |||
85 | fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { | 85 | fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) { |
86 | // An AsciiCodeEscape has 4 chars, example: `\xDD` | 86 | // An AsciiCodeEscape has 4 chars, example: `\xDD` |
87 | if !text.is_ascii() { | 87 | if !text.is_ascii() { |
88 | // TODO: Give a more precise error message (say what the invalid character was) | 88 | // FIXME: Give a more precise error message (say what the invalid character was) |
89 | errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range)); | 89 | errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range)); |
90 | } else if text.chars().count() < 4 { | 90 | } else if text.chars().count() < 4 { |
91 | errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range)); | 91 | errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range)); |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs index 4d6a18c6b..7cde5c532 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.rs | |||
@@ -1 +1,3 @@ | |||
1 | type A = for<'a> fn() -> (); | 1 | type A = for<'a> fn() -> (); |
2 | fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} | ||
3 | fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt index 6e7e6bda1..568f61fb2 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0081_for_type.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | SOURCE_FILE@[0; 29) | 1 | SOURCE_FILE@[0; 135) |
2 | TYPE_ALIAS_DEF@[0; 28) | 2 | TYPE_ALIAS_DEF@[0; 28) |
3 | TYPE_KW@[0; 4) | 3 | TYPE_KW@[0; 4) |
4 | WHITESPACE@[4; 5) | 4 | WHITESPACE@[4; 5) |
@@ -29,3 +29,127 @@ SOURCE_FILE@[0; 29) | |||
29 | R_PAREN@[26; 27) | 29 | R_PAREN@[26; 27) |
30 | SEMI@[27; 28) | 30 | SEMI@[27; 28) |
31 | WHITESPACE@[28; 29) | 31 | WHITESPACE@[28; 29) |
32 | FN_DEF@[29; 79) | ||
33 | FN_KW@[29; 31) | ||
34 | WHITESPACE@[31; 32) | ||
35 | NAME@[32; 35) | ||
36 | IDENT@[32; 35) "foo" | ||
37 | TYPE_PARAM_LIST@[35; 38) | ||
38 | L_ANGLE@[35; 36) | ||
39 | TYPE_PARAM@[36; 37) | ||
40 | NAME@[36; 37) | ||
41 | IDENT@[36; 37) "T" | ||
42 | R_ANGLE@[37; 38) | ||
43 | PARAM_LIST@[38; 46) | ||
44 | L_PAREN@[38; 39) | ||
45 | PARAM@[39; 45) | ||
46 | BIND_PAT@[39; 41) | ||
47 | NAME@[39; 41) | ||
48 | IDENT@[39; 41) "_t" | ||
49 | COLON@[41; 42) | ||
50 | WHITESPACE@[42; 43) | ||
51 | REFERENCE_TYPE@[43; 45) | ||
52 | AMP@[43; 44) | ||
53 | PATH_TYPE@[44; 45) | ||
54 | PATH@[44; 45) | ||
55 | PATH_SEGMENT@[44; 45) | ||
56 | NAME_REF@[44; 45) | ||
57 | IDENT@[44; 45) "T" | ||
58 | R_PAREN@[45; 46) | ||
59 | WHITESPACE@[46; 47) | ||
60 | WHERE_CLAUSE@[47; 76) | ||
61 | WHERE_KW@[47; 52) | ||
62 | WHITESPACE@[52; 53) | ||
63 | WHERE_PRED@[53; 76) | ||
64 | FOR_TYPE@[53; 66) | ||
65 | FOR_KW@[53; 56) | ||
66 | TYPE_PARAM_LIST@[56; 60) | ||
67 | L_ANGLE@[56; 57) | ||
68 | LIFETIME_PARAM@[57; 59) | ||
69 | LIFETIME@[57; 59) "'a" | ||
70 | R_ANGLE@[59; 60) | ||
71 | WHITESPACE@[60; 61) | ||
72 | REFERENCE_TYPE@[61; 66) | ||
73 | AMP@[61; 62) | ||
74 | LIFETIME@[62; 64) "'a" | ||
75 | WHITESPACE@[64; 65) | ||
76 | PATH_TYPE@[65; 66) | ||
77 | PATH@[65; 66) | ||
78 | PATH_SEGMENT@[65; 66) | ||
79 | NAME_REF@[65; 66) | ||
80 | IDENT@[65; 66) "T" | ||
81 | COLON@[66; 67) | ||
82 | WHITESPACE@[67; 68) | ||
83 | PATH_TYPE@[68; 76) | ||
84 | PATH@[68; 76) | ||
85 | PATH_SEGMENT@[68; 76) | ||
86 | NAME_REF@[68; 76) | ||
87 | IDENT@[68; 76) "Iterator" | ||
88 | WHITESPACE@[76; 77) | ||
89 | BLOCK@[77; 79) | ||
90 | L_CURLY@[77; 78) | ||
91 | R_CURLY@[78; 79) | ||
92 | WHITESPACE@[79; 80) | ||
93 | FN_DEF@[80; 134) | ||
94 | FN_KW@[80; 82) | ||
95 | WHITESPACE@[82; 83) | ||
96 | NAME@[83; 86) | ||
97 | IDENT@[83; 86) "bar" | ||
98 | TYPE_PARAM_LIST@[86; 89) | ||
99 | L_ANGLE@[86; 87) | ||
100 | TYPE_PARAM@[87; 88) | ||
101 | NAME@[87; 88) | ||
102 | IDENT@[87; 88) "T" | ||
103 | R_ANGLE@[88; 89) | ||
104 | PARAM_LIST@[89; 97) | ||
105 | L_PAREN@[89; 90) | ||
106 | PARAM@[90; 96) | ||
107 | BIND_PAT@[90; 92) | ||
108 | NAME@[90; 92) | ||
109 | IDENT@[90; 92) "_t" | ||
110 | COLON@[92; 93) | ||
111 | WHITESPACE@[93; 94) | ||
112 | REFERENCE_TYPE@[94; 96) | ||
113 | AMP@[94; 95) | ||
114 | PATH_TYPE@[95; 96) | ||
115 | PATH@[95; 96) | ||
116 | PATH_SEGMENT@[95; 96) | ||
117 | NAME_REF@[95; 96) | ||
118 | IDENT@[95; 96) "T" | ||
119 | R_PAREN@[96; 97) | ||
120 | WHITESPACE@[97; 98) | ||
121 | WHERE_CLAUSE@[98; 131) | ||
122 | WHERE_KW@[98; 103) | ||
123 | WHITESPACE@[103; 104) | ||
124 | WHERE_PRED@[104; 131) | ||
125 | FOR_TYPE@[104; 121) | ||
126 | FOR_KW@[104; 107) | ||
127 | TYPE_PARAM_LIST@[107; 111) | ||
128 | L_ANGLE@[107; 108) | ||
129 | LIFETIME_PARAM@[108; 110) | ||
130 | LIFETIME@[108; 110) "'a" | ||
131 | R_ANGLE@[110; 111) | ||
132 | WHITESPACE@[111; 112) | ||
133 | REFERENCE_TYPE@[112; 121) | ||
134 | AMP@[112; 113) | ||
135 | LIFETIME@[113; 115) "'a" | ||
136 | WHITESPACE@[115; 116) | ||
137 | MUT_KW@[116; 119) | ||
138 | WHITESPACE@[119; 120) | ||
139 | PATH_TYPE@[120; 121) | ||
140 | PATH@[120; 121) | ||
141 | PATH_SEGMENT@[120; 121) | ||
142 | NAME_REF@[120; 121) | ||
143 | IDENT@[120; 121) "T" | ||
144 | COLON@[121; 122) | ||
145 | WHITESPACE@[122; 123) | ||
146 | PATH_TYPE@[123; 131) | ||
147 | PATH@[123; 131) | ||
148 | PATH_SEGMENT@[123; 131) | ||
149 | NAME_REF@[123; 131) | ||
150 | IDENT@[123; 131) "Iterator" | ||
151 | WHITESPACE@[131; 132) | ||
152 | BLOCK@[132; 134) | ||
153 | L_CURLY@[132; 133) | ||
154 | R_CURLY@[133; 134) | ||
155 | WHITESPACE@[134; 135) | ||
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs index 537b01368..276756c85 100644 --- a/crates/ra_syntax/tests/test.rs +++ b/crates/ra_syntax/tests/test.rs | |||
@@ -61,7 +61,7 @@ fn reparse_fuzz_tests() { | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /// Test that Rust-analyzer can parse and validate the rust-analyser | 63 | /// Test that Rust-analyzer can parse and validate the rust-analyser |
64 | /// TODO: Use this as a benchmark | 64 | /// FIXME: Use this as a benchmark |
65 | #[test] | 65 | #[test] |
66 | fn self_hosting_parsing() { | 66 | fn self_hosting_parsing() { |
67 | use std::ffi::OsStr; | 67 | use std::ffi::OsStr; |
diff --git a/crates/ra_text_edit/Cargo.toml b/crates/ra_text_edit/Cargo.toml index 5769940df..b40026004 100644 --- a/crates/ra_text_edit/Cargo.toml +++ b/crates/ra_text_edit/Cargo.toml | |||
@@ -7,7 +7,12 @@ publish = false | |||
7 | 7 | ||
8 | [dependencies] | 8 | [dependencies] |
9 | text_unit = "0.1.6" | 9 | text_unit = "0.1.6" |
10 | proptest = "0.9.0" | 10 | |
11 | [dependencies.proptest] | ||
12 | version = "0.9.0" | ||
13 | # Disable `fork` feature to allow compiling on webassembly | ||
14 | default-features = false | ||
15 | features = ["std", "bit-set", "break-dead-code"] | ||
11 | 16 | ||
12 | [dev-dependencies] | 17 | [dev-dependencies] |
13 | test_utils = { path = "../test_utils" } | 18 | test_utils = { path = "../test_utils" } |
diff --git a/crates/tools/tests/cli.rs b/crates/tools/tests/cli.rs index aab52a4aa..6f82ae61d 100644 --- a/crates/tools/tests/cli.rs +++ b/crates/tools/tests/cli.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | use tools::{generate, gen_tests, run_rustfmt, Verify}; | 1 | use walkdir::WalkDir; |
2 | |||
3 | use tools::{generate, gen_tests, run_rustfmt, Verify, project_root}; | ||
2 | 4 | ||
3 | #[test] | 5 | #[test] |
4 | fn generated_grammar_is_fresh() { | 6 | fn generated_grammar_is_fresh() { |
@@ -20,3 +22,25 @@ fn check_code_formatting() { | |||
20 | panic!("{}. Please format the code by running `cargo format`", error); | 22 | panic!("{}. Please format the code by running `cargo format`", error); |
21 | } | 23 | } |
22 | } | 24 | } |
25 | |||
26 | #[test] | ||
27 | fn no_todo() { | ||
28 | WalkDir::new(project_root().join("crates")).into_iter().for_each(|e| { | ||
29 | let e = e.unwrap(); | ||
30 | if e.path().extension().map(|it| it != "rs").unwrap_or(true) { | ||
31 | return; | ||
32 | } | ||
33 | if e.path().ends_with("tests/cli.rs") { | ||
34 | return; | ||
35 | } | ||
36 | let text = std::fs::read_to_string(e.path()).unwrap(); | ||
37 | if text.contains("TODO") { | ||
38 | panic!( | ||
39 | "\nTODO markers should not be commited to the master branch,\n\ | ||
40 | use FIXME instead\n\ | ||
41 | {}\n", | ||
42 | e.path().display(), | ||
43 | ) | ||
44 | } | ||
45 | }) | ||
46 | } | ||