diff options
29 files changed, 650 insertions, 324 deletions
diff --git a/Cargo.lock b/Cargo.lock index 4476d188b..31a850797 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -844,9 +844,9 @@ dependencies = [ | |||
844 | 844 | ||
845 | [[package]] | 845 | [[package]] |
846 | name = "lsp-types" | 846 | name = "lsp-types" |
847 | version = "0.85.0" | 847 | version = "0.86.0" |
848 | source = "registry+https://github.com/rust-lang/crates.io-index" | 848 | source = "registry+https://github.com/rust-lang/crates.io-index" |
849 | checksum = "857650f3e83fb62f89d15410414e0ed7d0735445020da398d37f65d20a5423b9" | 849 | checksum = "f2a5c40d566f2704dac30859bca152217583fc94fd5b178d8baba915e1abd382" |
850 | dependencies = [ | 850 | dependencies = [ |
851 | "base64", | 851 | "base64", |
852 | "bitflags", | 852 | "bitflags", |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 9bfcd215a..f17734e41 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -267,7 +267,12 @@ impl ModuleDef { | |||
267 | _ => return, | 267 | _ => return, |
268 | }; | 268 | }; |
269 | 269 | ||
270 | hir_ty::diagnostics::validate_module_item(db, id, sink) | 270 | let module = match self.module(db) { |
271 | Some(it) => it, | ||
272 | None => return, | ||
273 | }; | ||
274 | |||
275 | hir_ty::diagnostics::validate_module_item(db, module.id.krate, id, sink) | ||
271 | } | 276 | } |
272 | } | 277 | } |
273 | 278 | ||
@@ -397,9 +402,9 @@ impl Module { | |||
397 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() | 402 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() |
398 | } | 403 | } |
399 | 404 | ||
400 | pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<ImplDef> { | 405 | pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> { |
401 | let def_map = db.crate_def_map(self.id.krate); | 406 | let def_map = db.crate_def_map(self.id.krate); |
402 | def_map[self.id.local_id].scope.impls().map(ImplDef::from).collect() | 407 | def_map[self.id.local_id].scope.impls().map(Impl::from).collect() |
403 | } | 408 | } |
404 | 409 | ||
405 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { | 410 | pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { |
@@ -780,8 +785,9 @@ impl Function { | |||
780 | } | 785 | } |
781 | 786 | ||
782 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 787 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
788 | let krate = self.module(db).id.krate; | ||
783 | hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink); | 789 | hir_def::diagnostics::validate_body(db.upcast(), self.id.into(), sink); |
784 | hir_ty::diagnostics::validate_module_item(db, self.id.into(), sink); | 790 | hir_ty::diagnostics::validate_module_item(db, krate, self.id.into(), sink); |
785 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink); | 791 | hir_ty::diagnostics::validate_body(db, self.id.into(), sink); |
786 | } | 792 | } |
787 | 793 | ||
@@ -1001,7 +1007,7 @@ pub enum AssocItem { | |||
1001 | } | 1007 | } |
1002 | pub enum AssocItemContainer { | 1008 | pub enum AssocItemContainer { |
1003 | Trait(Trait), | 1009 | Trait(Trait), |
1004 | ImplDef(ImplDef), | 1010 | Impl(Impl), |
1005 | } | 1011 | } |
1006 | pub trait AsAssocItem { | 1012 | pub trait AsAssocItem { |
1007 | fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>; | 1013 | fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem>; |
@@ -1058,7 +1064,7 @@ impl AssocItem { | |||
1058 | }; | 1064 | }; |
1059 | match container { | 1065 | match container { |
1060 | AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), | 1066 | AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), |
1061 | AssocContainerId::ImplId(id) => AssocItemContainer::ImplDef(id.into()), | 1067 | AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()), |
1062 | AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"), | 1068 | AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"), |
1063 | } | 1069 | } |
1064 | } | 1070 | } |
@@ -1080,7 +1086,7 @@ pub enum GenericDef { | |||
1080 | Adt(Adt), | 1086 | Adt(Adt), |
1081 | Trait(Trait), | 1087 | Trait(Trait), |
1082 | TypeAlias(TypeAlias), | 1088 | TypeAlias(TypeAlias), |
1083 | ImplDef(ImplDef), | 1089 | Impl(Impl), |
1084 | // enum variants cannot have generics themselves, but their parent enums | 1090 | // enum variants cannot have generics themselves, but their parent enums |
1085 | // can, and this makes some code easier to write | 1091 | // can, and this makes some code easier to write |
1086 | EnumVariant(EnumVariant), | 1092 | EnumVariant(EnumVariant), |
@@ -1092,7 +1098,7 @@ impl_from!( | |||
1092 | Adt(Struct, Enum, Union), | 1098 | Adt(Struct, Enum, Union), |
1093 | Trait, | 1099 | Trait, |
1094 | TypeAlias, | 1100 | TypeAlias, |
1095 | ImplDef, | 1101 | Impl, |
1096 | EnumVariant, | 1102 | EnumVariant, |
1097 | Const | 1103 | Const |
1098 | for GenericDef | 1104 | for GenericDef |
@@ -1262,30 +1268,28 @@ impl LifetimeParam { | |||
1262 | 1268 | ||
1263 | // FIXME: rename from `ImplDef` to `Impl` | 1269 | // FIXME: rename from `ImplDef` to `Impl` |
1264 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1270 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
1265 | pub struct ImplDef { | 1271 | pub struct Impl { |
1266 | pub(crate) id: ImplId, | 1272 | pub(crate) id: ImplId, |
1267 | } | 1273 | } |
1268 | 1274 | ||
1269 | impl ImplDef { | 1275 | impl Impl { |
1270 | pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<ImplDef> { | 1276 | pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> { |
1271 | let inherent = db.inherent_impls_in_crate(krate.id); | 1277 | let inherent = db.inherent_impls_in_crate(krate.id); |
1272 | let trait_ = db.trait_impls_in_crate(krate.id); | 1278 | let trait_ = db.trait_impls_in_crate(krate.id); |
1273 | 1279 | ||
1274 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() | 1280 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() |
1275 | } | 1281 | } |
1276 | pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplDef> { | 1282 | pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { |
1277 | let impls = db.trait_impls_in_crate(krate.id); | 1283 | let impls = db.trait_impls_in_crate(krate.id); |
1278 | impls.for_trait(trait_.id).map(Self::from).collect() | 1284 | impls.for_trait(trait_.id).map(Self::from).collect() |
1279 | } | 1285 | } |
1280 | 1286 | ||
1287 | // FIXME: the return type is wrong. This should be a hir version of | ||
1288 | // `TraitRef` (ie, resolved `TypeRef`). | ||
1281 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1289 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1282 | db.impl_data(self.id).target_trait.clone() | 1290 | db.impl_data(self.id).target_trait.clone() |
1283 | } | 1291 | } |
1284 | 1292 | ||
1285 | pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef { | ||
1286 | db.impl_data(self.id).target_type.clone() | ||
1287 | } | ||
1288 | |||
1289 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { | 1293 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { |
1290 | let impl_data = db.impl_data(self.id); | 1294 | let impl_data = db.impl_data(self.id); |
1291 | let resolver = self.id.resolver(db.upcast()); | 1295 | let resolver = self.id.resolver(db.upcast()); |
@@ -1319,6 +1323,7 @@ impl ImplDef { | |||
1319 | let item = src.file_id.is_builtin_derive(db.upcast())?; | 1323 | let item = src.file_id.is_builtin_derive(db.upcast())?; |
1320 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); | 1324 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); |
1321 | 1325 | ||
1326 | // FIXME: handle `cfg_attr` | ||
1322 | let attr = item | 1327 | let attr = item |
1323 | .value | 1328 | .value |
1324 | .attrs() | 1329 | .attrs() |
@@ -1898,7 +1903,7 @@ pub enum ScopeDef { | |||
1898 | ModuleDef(ModuleDef), | 1903 | ModuleDef(ModuleDef), |
1899 | MacroDef(MacroDef), | 1904 | MacroDef(MacroDef), |
1900 | GenericParam(TypeParam), | 1905 | GenericParam(TypeParam), |
1901 | ImplSelfType(ImplDef), | 1906 | ImplSelfType(Impl), |
1902 | AdtSelfType(Adt), | 1907 | AdtSelfType(Adt), |
1903 | Local(Local), | 1908 | Local(Local), |
1904 | Unknown, | 1909 | Unknown, |
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index dd3fcfe4a..8d0f84508 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs | |||
@@ -39,7 +39,7 @@ from_id![ | |||
39 | (hir_def::StaticId, crate::Static), | 39 | (hir_def::StaticId, crate::Static), |
40 | (hir_def::ConstId, crate::Const), | 40 | (hir_def::ConstId, crate::Const), |
41 | (hir_def::FunctionId, crate::Function), | 41 | (hir_def::FunctionId, crate::Function), |
42 | (hir_def::ImplId, crate::ImplDef), | 42 | (hir_def::ImplId, crate::Impl), |
43 | (hir_def::TypeParamId, crate::TypeParam), | 43 | (hir_def::TypeParamId, crate::TypeParam), |
44 | (hir_def::LifetimeParamId, crate::LifetimeParam), | 44 | (hir_def::LifetimeParamId, crate::LifetimeParam), |
45 | (hir_expand::MacroDefId, crate::MacroDef) | 45 | (hir_expand::MacroDefId, crate::MacroDef) |
@@ -146,7 +146,7 @@ impl From<GenericDef> for GenericDefId { | |||
146 | GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), | 146 | GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), |
147 | GenericDef::Trait(it) => GenericDefId::TraitId(it.id), | 147 | GenericDef::Trait(it) => GenericDefId::TraitId(it.id), |
148 | GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), | 148 | GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), |
149 | GenericDef::ImplDef(it) => GenericDefId::ImplId(it.id), | 149 | GenericDef::Impl(it) => GenericDefId::ImplId(it.id), |
150 | GenericDef::EnumVariant(it) => { | 150 | GenericDef::EnumVariant(it) => { |
151 | GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) | 151 | GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id }) |
152 | } | 152 | } |
@@ -162,7 +162,7 @@ impl From<GenericDefId> for GenericDef { | |||
162 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), | 162 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), |
163 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), | 163 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), |
164 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | 164 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), |
165 | GenericDefId::ImplId(it) => GenericDef::ImplDef(it.into()), | 165 | GenericDefId::ImplId(it) => GenericDef::Impl(it.into()), |
166 | GenericDefId::EnumVariantId(it) => { | 166 | GenericDefId::EnumVariantId(it) => { |
167 | GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) | 167 | GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) |
168 | } | 168 | } |
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 11ae63c31..c5b81b252 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -10,8 +10,8 @@ use hir_expand::InFile; | |||
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, | 13 | db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, Impl, LifetimeParam, |
14 | LifetimeParam, MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, | 14 | MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait HasSource { | 17 | pub trait HasSource { |
@@ -118,7 +118,7 @@ impl HasSource for MacroDef { | |||
118 | } | 118 | } |
119 | } | 119 | } |
120 | } | 120 | } |
121 | impl HasSource for ImplDef { | 121 | impl HasSource for Impl { |
122 | type Ast = ast::Impl; | 122 | type Ast = ast::Impl; |
123 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> { | 123 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::Impl> { |
124 | self.id.lookup(db.upcast()).source(db.upcast()) | 124 | self.id.lookup(db.upcast()).source(db.upcast()) |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 0f399a2c6..3f4f8d8e4 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -35,7 +35,7 @@ pub use crate::{ | |||
35 | code_model::{ | 35 | code_model::{ |
36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, | 36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, |
37 | Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, | 37 | Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, |
38 | GenericDef, HasVisibility, ImplDef, LifetimeParam, Local, MacroDef, Module, ModuleDef, | 38 | GenericDef, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, |
39 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, | 39 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, |
40 | }, | 40 | }, |
41 | has_source::HasSource, | 41 | has_source::HasSource, |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index ee2074602..83ec91f58 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -25,7 +25,7 @@ use crate::{ | |||
25 | diagnostics::Diagnostic, | 25 | diagnostics::Diagnostic, |
26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
28 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local, | 28 | AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local, |
29 | MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, | 29 | MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, |
30 | VariantDef, | 30 | VariantDef, |
31 | }; | 31 | }; |
@@ -38,7 +38,7 @@ pub enum PathResolution { | |||
38 | Local(Local), | 38 | Local(Local), |
39 | /// A generic parameter | 39 | /// A generic parameter |
40 | TypeParam(TypeParam), | 40 | TypeParam(TypeParam), |
41 | SelfType(ImplDef), | 41 | SelfType(Impl), |
42 | Macro(MacroDef), | 42 | Macro(MacroDef), |
43 | AssocItem(AssocItem), | 43 | AssocItem(AssocItem), |
44 | } | 44 | } |
@@ -708,7 +708,7 @@ to_def_impls![ | |||
708 | (crate::Enum, ast::Enum, enum_to_def), | 708 | (crate::Enum, ast::Enum, enum_to_def), |
709 | (crate::Union, ast::Union, union_to_def), | 709 | (crate::Union, ast::Union, union_to_def), |
710 | (crate::Trait, ast::Trait, trait_to_def), | 710 | (crate::Trait, ast::Trait, trait_to_def), |
711 | (crate::ImplDef, ast::Impl, impl_to_def), | 711 | (crate::Impl, ast::Impl, impl_to_def), |
712 | (crate::TypeAlias, ast::TypeAlias, type_alias_to_def), | 712 | (crate::TypeAlias, ast::TypeAlias, type_alias_to_def), |
713 | (crate::Const, ast::Const, const_to_def), | 713 | (crate::Const, ast::Const, const_to_def), |
714 | (crate::Static, ast::Static, static_to_def), | 714 | (crate::Static, ast::Static, static_to_def), |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index c64b78445..45313f335 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -104,7 +104,7 @@ impl Attrs { | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | pub fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { | 107 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { |
108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | 108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); |
109 | Attrs::new(owner.value, &hygiene) | 109 | Attrs::new(owner.value, &hygiene) |
110 | } | 110 | } |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 7e2199a9c..ba09a9126 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -425,6 +425,16 @@ impl HasModule for AdtId { | |||
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
428 | impl HasModule for VariantId { | ||
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | ||
430 | match self { | ||
431 | VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), | ||
432 | VariantId::StructId(it) => it.lookup(db).container.module(db), | ||
433 | VariantId::UnionId(it) => it.lookup(db).container.module(db), | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | |||
428 | impl HasModule for DefWithBodyId { | 438 | impl HasModule for DefWithBodyId { |
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | 439 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { |
430 | match self { | 440 | match self { |
@@ -465,6 +475,26 @@ impl HasModule for StaticLoc { | |||
465 | } | 475 | } |
466 | } | 476 | } |
467 | 477 | ||
478 | impl AttrDefId { | ||
479 | pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { | ||
480 | match self { | ||
481 | AttrDefId::ModuleId(it) => it.krate, | ||
482 | AttrDefId::FieldId(it) => it.parent.module(db).krate, | ||
483 | AttrDefId::AdtId(it) => it.module(db).krate, | ||
484 | AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, | ||
485 | AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate, | ||
486 | AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, | ||
487 | AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, | ||
488 | AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate, | ||
489 | AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, | ||
490 | AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate, | ||
491 | // FIXME: `MacroDefId` should store the defining module, then this can implement | ||
492 | // `HasModule` | ||
493 | AttrDefId::MacroDefId(it) => it.krate, | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
468 | /// A helper trait for converting to MacroCallId | 498 | /// A helper trait for converting to MacroCallId |
469 | pub trait AsMacroCall { | 499 | pub trait AsMacroCall { |
470 | fn as_call_id( | 500 | fn as_call_id( |
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 1c72f766e..14e18f5a1 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
@@ -6,6 +6,7 @@ mod decl_check; | |||
6 | 6 | ||
7 | use std::{any::Any, fmt}; | 7 | use std::{any::Any, fmt}; |
8 | 8 | ||
9 | use base_db::CrateId; | ||
9 | use hir_def::{DefWithBodyId, ModuleDefId}; | 10 | use hir_def::{DefWithBodyId, ModuleDefId}; |
10 | use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink}; | 11 | use hir_expand::diagnostics::{Diagnostic, DiagnosticCode, DiagnosticSink}; |
11 | use hir_expand::{name::Name, HirFileId, InFile}; | 12 | use hir_expand::{name::Name, HirFileId, InFile}; |
@@ -18,12 +19,13 @@ pub use crate::diagnostics::expr::{record_literal_missing_fields, record_pattern | |||
18 | 19 | ||
19 | pub fn validate_module_item( | 20 | pub fn validate_module_item( |
20 | db: &dyn HirDatabase, | 21 | db: &dyn HirDatabase, |
22 | krate: CrateId, | ||
21 | owner: ModuleDefId, | 23 | owner: ModuleDefId, |
22 | sink: &mut DiagnosticSink<'_>, | 24 | sink: &mut DiagnosticSink<'_>, |
23 | ) { | 25 | ) { |
24 | let _p = profile::span("validate_module_item"); | 26 | let _p = profile::span("validate_module_item"); |
25 | let mut validator = decl_check::DeclValidator::new(owner, sink); | 27 | let mut validator = decl_check::DeclValidator::new(db, krate, sink); |
26 | validator.validate_item(db); | 28 | validator.validate_item(owner); |
27 | } | 29 | } |
28 | 30 | ||
29 | pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { | 31 | pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) { |
@@ -407,7 +409,7 @@ mod tests { | |||
407 | for (module_id, _) in crate_def_map.modules.iter() { | 409 | for (module_id, _) in crate_def_map.modules.iter() { |
408 | for decl in crate_def_map[module_id].scope.declarations() { | 410 | for decl in crate_def_map[module_id].scope.declarations() { |
409 | let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); | 411 | let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); |
410 | validate_module_item(self, decl, &mut sink); | 412 | validate_module_item(self, krate, decl, &mut sink); |
411 | 413 | ||
412 | if let ModuleDefId::FunctionId(f) = decl { | 414 | if let ModuleDefId::FunctionId(f) = decl { |
413 | fns.push(f) | 415 | fns.push(f) |
@@ -419,7 +421,12 @@ mod tests { | |||
419 | for item in impl_data.items.iter() { | 421 | for item in impl_data.items.iter() { |
420 | if let AssocItemId::FunctionId(f) = item { | 422 | if let AssocItemId::FunctionId(f) = item { |
421 | let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); | 423 | let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); |
422 | validate_module_item(self, ModuleDefId::FunctionId(*f), &mut sink); | 424 | validate_module_item( |
425 | self, | ||
426 | krate, | ||
427 | ModuleDefId::FunctionId(*f), | ||
428 | &mut sink, | ||
429 | ); | ||
423 | fns.push(*f) | 430 | fns.push(*f) |
424 | } | 431 | } |
425 | } | 432 | } |
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 25587e116..eaeb6899f 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | mod case_conv; | 13 | mod case_conv; |
14 | 14 | ||
15 | use base_db::CrateId; | ||
15 | use hir_def::{ | 16 | use hir_def::{ |
16 | adt::VariantData, | 17 | adt::VariantData, |
17 | expr::{Pat, PatId}, | 18 | expr::{Pat, PatId}, |
@@ -40,7 +41,8 @@ mod allow { | |||
40 | } | 41 | } |
41 | 42 | ||
42 | pub(super) struct DeclValidator<'a, 'b: 'a> { | 43 | pub(super) struct DeclValidator<'a, 'b: 'a> { |
43 | owner: ModuleDefId, | 44 | db: &'a dyn HirDatabase, |
45 | krate: CrateId, | ||
44 | sink: &'a mut DiagnosticSink<'b>, | 46 | sink: &'a mut DiagnosticSink<'b>, |
45 | } | 47 | } |
46 | 48 | ||
@@ -53,26 +55,27 @@ struct Replacement { | |||
53 | 55 | ||
54 | impl<'a, 'b> DeclValidator<'a, 'b> { | 56 | impl<'a, 'b> DeclValidator<'a, 'b> { |
55 | pub(super) fn new( | 57 | pub(super) fn new( |
56 | owner: ModuleDefId, | 58 | db: &'a dyn HirDatabase, |
59 | krate: CrateId, | ||
57 | sink: &'a mut DiagnosticSink<'b>, | 60 | sink: &'a mut DiagnosticSink<'b>, |
58 | ) -> DeclValidator<'a, 'b> { | 61 | ) -> DeclValidator<'a, 'b> { |
59 | DeclValidator { owner, sink } | 62 | DeclValidator { db, krate, sink } |
60 | } | 63 | } |
61 | 64 | ||
62 | pub(super) fn validate_item(&mut self, db: &dyn HirDatabase) { | 65 | pub(super) fn validate_item(&mut self, item: ModuleDefId) { |
63 | match self.owner { | 66 | match item { |
64 | ModuleDefId::FunctionId(func) => self.validate_func(db, func), | 67 | ModuleDefId::FunctionId(func) => self.validate_func(func), |
65 | ModuleDefId::AdtId(adt) => self.validate_adt(db, adt), | 68 | ModuleDefId::AdtId(adt) => self.validate_adt(adt), |
66 | ModuleDefId::ConstId(const_id) => self.validate_const(db, const_id), | 69 | ModuleDefId::ConstId(const_id) => self.validate_const(const_id), |
67 | ModuleDefId::StaticId(static_id) => self.validate_static(db, static_id), | 70 | ModuleDefId::StaticId(static_id) => self.validate_static(static_id), |
68 | _ => return, | 71 | _ => return, |
69 | } | 72 | } |
70 | } | 73 | } |
71 | 74 | ||
72 | fn validate_adt(&mut self, db: &dyn HirDatabase, adt: AdtId) { | 75 | fn validate_adt(&mut self, adt: AdtId) { |
73 | match adt { | 76 | match adt { |
74 | AdtId::StructId(struct_id) => self.validate_struct(db, struct_id), | 77 | AdtId::StructId(struct_id) => self.validate_struct(struct_id), |
75 | AdtId::EnumId(enum_id) => self.validate_enum(db, enum_id), | 78 | AdtId::EnumId(enum_id) => self.validate_enum(enum_id), |
76 | AdtId::UnionId(_) => { | 79 | AdtId::UnionId(_) => { |
77 | // Unions aren't yet supported by this validator. | 80 | // Unions aren't yet supported by this validator. |
78 | } | 81 | } |
@@ -82,27 +85,27 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
82 | /// Checks whether not following the convention is allowed for this item. | 85 | /// Checks whether not following the convention is allowed for this item. |
83 | /// | 86 | /// |
84 | /// Currently this method doesn't check parent attributes. | 87 | /// Currently this method doesn't check parent attributes. |
85 | fn allowed(&self, db: &dyn HirDatabase, id: AttrDefId, allow_name: &str) -> bool { | 88 | fn allowed(&self, id: AttrDefId, allow_name: &str) -> bool { |
86 | db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) | 89 | self.db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) |
87 | } | 90 | } |
88 | 91 | ||
89 | fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { | 92 | fn validate_func(&mut self, func: FunctionId) { |
90 | let data = db.function_data(func); | 93 | let data = self.db.function_data(func); |
91 | if data.is_extern { | 94 | if data.is_extern { |
92 | mark::hit!(extern_func_incorrect_case_ignored); | 95 | mark::hit!(extern_func_incorrect_case_ignored); |
93 | return; | 96 | return; |
94 | } | 97 | } |
95 | 98 | ||
96 | let body = db.body(func.into()); | 99 | let body = self.db.body(func.into()); |
97 | 100 | ||
98 | // Recursively validate inner scope items, such as static variables and constants. | 101 | // Recursively validate inner scope items, such as static variables and constants. |
99 | for (item_id, _) in body.item_scope.values() { | 102 | for (item_id, _) in body.item_scope.values() { |
100 | let mut validator = DeclValidator::new(item_id, self.sink); | 103 | let mut validator = DeclValidator::new(self.db, self.krate, self.sink); |
101 | validator.validate_item(db); | 104 | validator.validate_item(item_id); |
102 | } | 105 | } |
103 | 106 | ||
104 | // Check whether non-snake case identifiers are allowed for this function. | 107 | // Check whether non-snake case identifiers are allowed for this function. |
105 | if self.allowed(db, func.into(), allow::NON_SNAKE_CASE) { | 108 | if self.allowed(func.into(), allow::NON_SNAKE_CASE) { |
106 | return; | 109 | return; |
107 | } | 110 | } |
108 | 111 | ||
@@ -169,11 +172,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
169 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 172 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
170 | self.create_incorrect_case_diagnostic_for_func( | 173 | self.create_incorrect_case_diagnostic_for_func( |
171 | func, | 174 | func, |
172 | db, | ||
173 | fn_name_replacement, | 175 | fn_name_replacement, |
174 | fn_param_replacements, | 176 | fn_param_replacements, |
175 | ); | 177 | ); |
176 | self.create_incorrect_case_diagnostic_for_variables(func, db, pats_replacements); | 178 | self.create_incorrect_case_diagnostic_for_variables(func, pats_replacements); |
177 | } | 179 | } |
178 | 180 | ||
179 | /// Given the information about incorrect names in the function declaration, looks up into the source code | 181 | /// Given the information about incorrect names in the function declaration, looks up into the source code |
@@ -181,7 +183,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
181 | fn create_incorrect_case_diagnostic_for_func( | 183 | fn create_incorrect_case_diagnostic_for_func( |
182 | &mut self, | 184 | &mut self, |
183 | func: FunctionId, | 185 | func: FunctionId, |
184 | db: &dyn HirDatabase, | ||
185 | fn_name_replacement: Option<Replacement>, | 186 | fn_name_replacement: Option<Replacement>, |
186 | fn_param_replacements: Vec<Replacement>, | 187 | fn_param_replacements: Vec<Replacement>, |
187 | ) { | 188 | ) { |
@@ -190,8 +191,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
190 | return; | 191 | return; |
191 | } | 192 | } |
192 | 193 | ||
193 | let fn_loc = func.lookup(db.upcast()); | 194 | let fn_loc = func.lookup(self.db.upcast()); |
194 | let fn_src = fn_loc.source(db.upcast()); | 195 | let fn_src = fn_loc.source(self.db.upcast()); |
195 | 196 | ||
196 | // Diagnostic for function name. | 197 | // Diagnostic for function name. |
197 | if let Some(replacement) = fn_name_replacement { | 198 | if let Some(replacement) = fn_name_replacement { |
@@ -282,7 +283,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
282 | fn create_incorrect_case_diagnostic_for_variables( | 283 | fn create_incorrect_case_diagnostic_for_variables( |
283 | &mut self, | 284 | &mut self, |
284 | func: FunctionId, | 285 | func: FunctionId, |
285 | db: &dyn HirDatabase, | ||
286 | pats_replacements: Vec<(PatId, Replacement)>, | 286 | pats_replacements: Vec<(PatId, Replacement)>, |
287 | ) { | 287 | ) { |
288 | // XXX: only look at source_map if we do have missing fields | 288 | // XXX: only look at source_map if we do have missing fields |
@@ -290,12 +290,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
290 | return; | 290 | return; |
291 | } | 291 | } |
292 | 292 | ||
293 | let (_, source_map) = db.body_with_source_map(func.into()); | 293 | let (_, source_map) = self.db.body_with_source_map(func.into()); |
294 | 294 | ||
295 | for (id, replacement) in pats_replacements { | 295 | for (id, replacement) in pats_replacements { |
296 | if let Ok(source_ptr) = source_map.pat_syntax(id) { | 296 | if let Ok(source_ptr) = source_map.pat_syntax(id) { |
297 | if let Some(expr) = source_ptr.value.as_ref().left() { | 297 | if let Some(expr) = source_ptr.value.as_ref().left() { |
298 | let root = source_ptr.file_syntax(db.upcast()); | 298 | let root = source_ptr.file_syntax(self.db.upcast()); |
299 | if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) { | 299 | if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) { |
300 | let parent = match ident_pat.syntax().parent() { | 300 | let parent = match ident_pat.syntax().parent() { |
301 | Some(parent) => parent, | 301 | Some(parent) => parent, |
@@ -333,12 +333,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
333 | } | 333 | } |
334 | } | 334 | } |
335 | 335 | ||
336 | fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { | 336 | fn validate_struct(&mut self, struct_id: StructId) { |
337 | let data = db.struct_data(struct_id); | 337 | let data = self.db.struct_data(struct_id); |
338 | 338 | ||
339 | let non_camel_case_allowed = | 339 | let non_camel_case_allowed = self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES); |
340 | self.allowed(db, struct_id.into(), allow::NON_CAMEL_CASE_TYPES); | 340 | let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE); |
341 | let non_snake_case_allowed = self.allowed(db, struct_id.into(), allow::NON_SNAKE_CASE); | ||
342 | 341 | ||
343 | // Check the structure name. | 342 | // Check the structure name. |
344 | let struct_name = data.name.to_string(); | 343 | let struct_name = data.name.to_string(); |
@@ -379,7 +378,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
379 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 378 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
380 | self.create_incorrect_case_diagnostic_for_struct( | 379 | self.create_incorrect_case_diagnostic_for_struct( |
381 | struct_id, | 380 | struct_id, |
382 | db, | ||
383 | struct_name_replacement, | 381 | struct_name_replacement, |
384 | struct_fields_replacements, | 382 | struct_fields_replacements, |
385 | ); | 383 | ); |
@@ -390,7 +388,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
390 | fn create_incorrect_case_diagnostic_for_struct( | 388 | fn create_incorrect_case_diagnostic_for_struct( |
391 | &mut self, | 389 | &mut self, |
392 | struct_id: StructId, | 390 | struct_id: StructId, |
393 | db: &dyn HirDatabase, | ||
394 | struct_name_replacement: Option<Replacement>, | 391 | struct_name_replacement: Option<Replacement>, |
395 | struct_fields_replacements: Vec<Replacement>, | 392 | struct_fields_replacements: Vec<Replacement>, |
396 | ) { | 393 | ) { |
@@ -399,8 +396,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
399 | return; | 396 | return; |
400 | } | 397 | } |
401 | 398 | ||
402 | let struct_loc = struct_id.lookup(db.upcast()); | 399 | let struct_loc = struct_id.lookup(self.db.upcast()); |
403 | let struct_src = struct_loc.source(db.upcast()); | 400 | let struct_src = struct_loc.source(self.db.upcast()); |
404 | 401 | ||
405 | if let Some(replacement) = struct_name_replacement { | 402 | if let Some(replacement) = struct_name_replacement { |
406 | let ast_ptr = match struct_src.value.name() { | 403 | let ast_ptr = match struct_src.value.name() { |
@@ -473,11 +470,11 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
473 | } | 470 | } |
474 | } | 471 | } |
475 | 472 | ||
476 | fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { | 473 | fn validate_enum(&mut self, enum_id: EnumId) { |
477 | let data = db.enum_data(enum_id); | 474 | let data = self.db.enum_data(enum_id); |
478 | 475 | ||
479 | // Check whether non-camel case names are allowed for this enum. | 476 | // Check whether non-camel case names are allowed for this enum. |
480 | if self.allowed(db, enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { | 477 | if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { |
481 | return; | 478 | return; |
482 | } | 479 | } |
483 | 480 | ||
@@ -512,7 +509,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
512 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. | 509 | // If there is at least one element to spawn a warning on, go to the source map and generate a warning. |
513 | self.create_incorrect_case_diagnostic_for_enum( | 510 | self.create_incorrect_case_diagnostic_for_enum( |
514 | enum_id, | 511 | enum_id, |
515 | db, | ||
516 | enum_name_replacement, | 512 | enum_name_replacement, |
517 | enum_fields_replacements, | 513 | enum_fields_replacements, |
518 | ) | 514 | ) |
@@ -523,7 +519,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
523 | fn create_incorrect_case_diagnostic_for_enum( | 519 | fn create_incorrect_case_diagnostic_for_enum( |
524 | &mut self, | 520 | &mut self, |
525 | enum_id: EnumId, | 521 | enum_id: EnumId, |
526 | db: &dyn HirDatabase, | ||
527 | enum_name_replacement: Option<Replacement>, | 522 | enum_name_replacement: Option<Replacement>, |
528 | enum_variants_replacements: Vec<Replacement>, | 523 | enum_variants_replacements: Vec<Replacement>, |
529 | ) { | 524 | ) { |
@@ -532,8 +527,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
532 | return; | 527 | return; |
533 | } | 528 | } |
534 | 529 | ||
535 | let enum_loc = enum_id.lookup(db.upcast()); | 530 | let enum_loc = enum_id.lookup(self.db.upcast()); |
536 | let enum_src = enum_loc.source(db.upcast()); | 531 | let enum_src = enum_loc.source(self.db.upcast()); |
537 | 532 | ||
538 | if let Some(replacement) = enum_name_replacement { | 533 | if let Some(replacement) = enum_name_replacement { |
539 | let ast_ptr = match enum_src.value.name() { | 534 | let ast_ptr = match enum_src.value.name() { |
@@ -608,10 +603,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
608 | } | 603 | } |
609 | } | 604 | } |
610 | 605 | ||
611 | fn validate_const(&mut self, db: &dyn HirDatabase, const_id: ConstId) { | 606 | fn validate_const(&mut self, const_id: ConstId) { |
612 | let data = db.const_data(const_id); | 607 | let data = self.db.const_data(const_id); |
613 | 608 | ||
614 | if self.allowed(db, const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { | 609 | if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { |
615 | return; | 610 | return; |
616 | } | 611 | } |
617 | 612 | ||
@@ -632,8 +627,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
632 | return; | 627 | return; |
633 | }; | 628 | }; |
634 | 629 | ||
635 | let const_loc = const_id.lookup(db.upcast()); | 630 | let const_loc = const_id.lookup(self.db.upcast()); |
636 | let const_src = const_loc.source(db.upcast()); | 631 | let const_src = const_loc.source(self.db.upcast()); |
637 | 632 | ||
638 | let ast_ptr = match const_src.value.name() { | 633 | let ast_ptr = match const_src.value.name() { |
639 | Some(name) => name, | 634 | Some(name) => name, |
@@ -652,14 +647,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
652 | self.sink.push(diagnostic); | 647 | self.sink.push(diagnostic); |
653 | } | 648 | } |
654 | 649 | ||
655 | fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { | 650 | fn validate_static(&mut self, static_id: StaticId) { |
656 | let data = db.static_data(static_id); | 651 | let data = self.db.static_data(static_id); |
657 | if data.is_extern { | 652 | if data.is_extern { |
658 | mark::hit!(extern_static_incorrect_case_ignored); | 653 | mark::hit!(extern_static_incorrect_case_ignored); |
659 | return; | 654 | return; |
660 | } | 655 | } |
661 | 656 | ||
662 | if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { | 657 | if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { |
663 | return; | 658 | return; |
664 | } | 659 | } |
665 | 660 | ||
@@ -680,8 +675,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
680 | return; | 675 | return; |
681 | }; | 676 | }; |
682 | 677 | ||
683 | let static_loc = static_id.lookup(db.upcast()); | 678 | let static_loc = static_id.lookup(self.db.upcast()); |
684 | let static_src = static_loc.source(db.upcast()); | 679 | let static_src = static_loc.source(self.db.upcast()); |
685 | 680 | ||
686 | let ast_ptr = match static_src.value.name() { | 681 | let ast_ptr = match static_src.value.name() { |
687 | Some(name) => name, | 682 | Some(name) => name, |
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 234f80a3a..522607cb7 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -1,15 +1,13 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use either::Either; | 3 | use either::Either; |
4 | use hir::{ | 4 | use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource}; |
5 | AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirFileId, InFile, ModuleSource, | ||
6 | }; | ||
7 | use ide_db::base_db::{FileId, SourceDatabase}; | 5 | use ide_db::base_db::{FileId, SourceDatabase}; |
8 | use ide_db::{defs::Definition, RootDatabase}; | 6 | use ide_db::{defs::Definition, RootDatabase}; |
9 | use syntax::{ | 7 | use syntax::{ |
10 | ast::{self, NameOwner}, | 8 | ast::{self, NameOwner}, |
11 | match_ast, AstNode, SmolStr, | 9 | match_ast, AstNode, SmolStr, |
12 | SyntaxKind::{self, IDENT_PAT, TYPE_PARAM}, | 10 | SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM}, |
13 | TextRange, | 11 | TextRange, |
14 | }; | 12 | }; |
15 | 13 | ||
@@ -119,25 +117,6 @@ impl NavigationTarget { | |||
119 | ) | 117 | ) |
120 | } | 118 | } |
121 | 119 | ||
122 | /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner` | ||
123 | pub(crate) fn from_doc_commented( | ||
124 | db: &RootDatabase, | ||
125 | named: InFile<&dyn ast::NameOwner>, | ||
126 | node: InFile<&dyn ast::DocCommentsOwner>, | ||
127 | ) -> NavigationTarget { | ||
128 | let name = | ||
129 | named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); | ||
130 | let frange = node.map(|it| it.syntax()).original_file_range(db); | ||
131 | |||
132 | NavigationTarget::from_syntax( | ||
133 | frange.file_id, | ||
134 | name, | ||
135 | None, | ||
136 | frange.range, | ||
137 | node.value.syntax().kind(), | ||
138 | ) | ||
139 | } | ||
140 | |||
141 | fn from_syntax( | 120 | fn from_syntax( |
142 | file_id: FileId, | 121 | file_id: FileId, |
143 | name: SmolStr, | 122 | name: SmolStr, |
@@ -168,7 +147,7 @@ impl ToNav for FileSymbol { | |||
168 | focus_range: self.name_range, | 147 | focus_range: self.name_range, |
169 | container_name: self.container_name.clone(), | 148 | container_name: self.container_name.clone(), |
170 | description: description_from_symbol(db, self), | 149 | description: description_from_symbol(db, self), |
171 | docs: docs_from_symbol(db, self), | 150 | docs: None, |
172 | } | 151 | } |
173 | } | 152 | } |
174 | } | 153 | } |
@@ -182,6 +161,7 @@ impl TryToNav for Definition { | |||
182 | Definition::SelfType(it) => Some(it.to_nav(db)), | 161 | Definition::SelfType(it) => Some(it.to_nav(db)), |
183 | Definition::Local(it) => Some(it.to_nav(db)), | 162 | Definition::Local(it) => Some(it.to_nav(db)), |
184 | Definition::TypeParam(it) => Some(it.to_nav(db)), | 163 | Definition::TypeParam(it) => Some(it.to_nav(db)), |
164 | Definition::LifetimeParam(it) => Some(it.to_nav(db)), | ||
185 | } | 165 | } |
186 | } | 166 | } |
187 | } | 167 | } |
@@ -244,7 +224,7 @@ impl ToNav for hir::Module { | |||
244 | } | 224 | } |
245 | } | 225 | } |
246 | 226 | ||
247 | impl ToNav for hir::ImplDef { | 227 | impl ToNav for hir::Impl { |
248 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 228 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
249 | let src = self.source(db); | 229 | let src = self.source(db); |
250 | let derive_attr = self.is_builtin_derive(db); | 230 | let derive_attr = self.is_builtin_derive(db); |
@@ -376,28 +356,21 @@ impl ToNav for hir::TypeParam { | |||
376 | } | 356 | } |
377 | } | 357 | } |
378 | 358 | ||
379 | pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<Documentation> { | 359 | impl ToNav for hir::LifetimeParam { |
380 | let parse = db.parse(symbol.file_id); | 360 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
381 | let node = symbol.ptr.to_node(parse.tree().syntax()); | 361 | let src = self.source(db); |
382 | let file_id = HirFileId::from(symbol.file_id); | 362 | let full_range = src.value.syntax().text_range(); |
383 | 363 | NavigationTarget { | |
384 | let it = match_ast! { | 364 | file_id: src.file_id.original_file(db), |
385 | match node { | 365 | name: self.name(db).to_string().into(), |
386 | ast::Fn(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 366 | kind: LIFETIME_PARAM, |
387 | ast::Struct(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 367 | full_range, |
388 | ast::Enum(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 368 | focus_range: Some(full_range), |
389 | ast::Trait(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 369 | container_name: None, |
390 | ast::Module(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 370 | description: None, |
391 | ast::TypeAlias(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | 371 | docs: None, |
392 | ast::Const(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
393 | ast::Static(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
394 | ast::RecordField(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
395 | ast::Variant(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
396 | ast::MacroCall(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)), | ||
397 | _ => return None, | ||
398 | } | 372 | } |
399 | }; | 373 | } |
400 | it.docs() | ||
401 | } | 374 | } |
402 | 375 | ||
403 | /// Get a description of a symbol. | 376 | /// Get a description of a symbol. |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 10263537a..79c081cac 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -112,7 +112,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { | |||
112 | .as_assoc_item(db) | 112 | .as_assoc_item(db) |
113 | .and_then(|assoc| match assoc.container(db) { | 113 | .and_then(|assoc| match assoc.container(db) { |
114 | AssocItemContainer::Trait(t) => Some(t.into()), | 114 | AssocItemContainer::Trait(t) => Some(t.into()), |
115 | AssocItemContainer::ImplDef(impld) => { | 115 | AssocItemContainer::Impl(impld) => { |
116 | impld.target_ty(db).as_adt().map(|adt| adt.into()) | 116 | impld.target_ty(db).as_adt().map(|adt| adt.into()) |
117 | } | 117 | } |
118 | }) | 118 | }) |
@@ -190,7 +190,10 @@ fn rewrite_intra_doc_link( | |||
190 | }, | 190 | }, |
191 | Definition::Macro(it) => it.resolve_doc_path(db, link, ns), | 191 | Definition::Macro(it) => it.resolve_doc_path(db, link, ns), |
192 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | 192 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), |
193 | Definition::SelfType(_) | Definition::Local(_) | Definition::TypeParam(_) => return None, | 193 | Definition::SelfType(_) |
194 | | Definition::Local(_) | ||
195 | | Definition::TypeParam(_) | ||
196 | | Definition::LifetimeParam(_) => return None, | ||
194 | }?; | 197 | }?; |
195 | let krate = resolved.module(db)?.krate(); | 198 | let krate = resolved.module(db)?.krate(); |
196 | let canonical_path = resolved.canonical_path(db)?; | 199 | let canonical_path = resolved.canonical_path(db)?; |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index b9810457f..173509b08 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -1,3 +1,4 @@ | |||
1 | use either::Either; | ||
1 | use hir::Semantics; | 2 | use hir::Semantics; |
2 | use ide_db::{ | 3 | use ide_db::{ |
3 | base_db::FileId, | 4 | base_db::FileId, |
@@ -33,7 +34,7 @@ pub(crate) fn goto_definition( | |||
33 | let nav_targets = match_ast! { | 34 | let nav_targets = match_ast! { |
34 | match parent { | 35 | match parent { |
35 | ast::NameRef(name_ref) => { | 36 | ast::NameRef(name_ref) => { |
36 | reference_definition(&sema, &name_ref).to_vec() | 37 | reference_definition(&sema, Either::Right(&name_ref)).to_vec() |
37 | }, | 38 | }, |
38 | ast::Name(name) => { | 39 | ast::Name(name) => { |
39 | let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db); | 40 | let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db); |
@@ -53,6 +54,13 @@ pub(crate) fn goto_definition( | |||
53 | let self_param = func.param_list()?.self_param()?; | 54 | let self_param = func.param_list()?.self_param()?; |
54 | vec![self_to_nav_target(self_param, position.file_id)?] | 55 | vec![self_to_nav_target(self_param, position.file_id)?] |
55 | }, | 56 | }, |
57 | ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) { | ||
58 | let def = name_class.referenced_or_defined(sema.db); | ||
59 | let nav = def.try_to_nav(sema.db)?; | ||
60 | vec![nav] | ||
61 | } else { | ||
62 | reference_definition(&sema, Either::Left(<)).to_vec() | ||
63 | }, | ||
56 | _ => return None, | 64 | _ => return None, |
57 | } | 65 | } |
58 | }; | 66 | }; |
@@ -64,7 +72,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | |||
64 | return tokens.max_by_key(priority); | 72 | return tokens.max_by_key(priority); |
65 | fn priority(n: &SyntaxToken) -> usize { | 73 | fn priority(n: &SyntaxToken) -> usize { |
66 | match n.kind() { | 74 | match n.kind() { |
67 | IDENT | INT_NUMBER | T![self] => 2, | 75 | IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2, |
68 | kind if kind.is_trivia() => 0, | 76 | kind if kind.is_trivia() => 0, |
69 | _ => 1, | 77 | _ => 1, |
70 | } | 78 | } |
@@ -102,9 +110,12 @@ impl ReferenceResult { | |||
102 | 110 | ||
103 | pub(crate) fn reference_definition( | 111 | pub(crate) fn reference_definition( |
104 | sema: &Semantics<RootDatabase>, | 112 | sema: &Semantics<RootDatabase>, |
105 | name_ref: &ast::NameRef, | 113 | name_ref: Either<&ast::Lifetime, &ast::NameRef>, |
106 | ) -> ReferenceResult { | 114 | ) -> ReferenceResult { |
107 | let name_kind = NameRefClass::classify(sema, name_ref); | 115 | let name_kind = name_ref.either( |
116 | |lifetime| NameRefClass::classify_lifetime(sema, lifetime), | ||
117 | |name_ref| NameRefClass::classify(sema, name_ref), | ||
118 | ); | ||
108 | if let Some(def) = name_kind { | 119 | if let Some(def) = name_kind { |
109 | let def = def.referenced(sema.db); | 120 | let def = def.referenced(sema.db); |
110 | return match def.try_to_nav(sema.db) { | 121 | return match def.try_to_nav(sema.db) { |
@@ -114,10 +125,9 @@ pub(crate) fn reference_definition( | |||
114 | } | 125 | } |
115 | 126 | ||
116 | // Fallback index based approach: | 127 | // Fallback index based approach: |
117 | let navs = symbol_index::index_resolve(sema.db, name_ref) | 128 | let name = name_ref.either(ast::Lifetime::text, ast::NameRef::text); |
118 | .into_iter() | 129 | let navs = |
119 | .map(|s| s.to_nav(sema.db)) | 130 | symbol_index::index_resolve(sema.db, name).into_iter().map(|s| s.to_nav(sema.db)).collect(); |
120 | .collect(); | ||
121 | ReferenceResult::Approximate(navs) | 131 | ReferenceResult::Approximate(navs) |
122 | } | 132 | } |
123 | 133 | ||
@@ -1036,4 +1046,35 @@ impl Foo { | |||
1036 | }"#, | 1046 | }"#, |
1037 | ) | 1047 | ) |
1038 | } | 1048 | } |
1049 | |||
1050 | #[test] | ||
1051 | fn goto_lifetime_param_on_decl() { | ||
1052 | check( | ||
1053 | r#" | ||
1054 | fn foo<'foobar<|>>(_: &'foobar ()) { | ||
1055 | //^^^^^^^ | ||
1056 | }"#, | ||
1057 | ) | ||
1058 | } | ||
1059 | |||
1060 | #[test] | ||
1061 | fn goto_lifetime_param_decl() { | ||
1062 | check( | ||
1063 | r#" | ||
1064 | fn foo<'foobar>(_: &'foobar<|> ()) { | ||
1065 | //^^^^^^^ | ||
1066 | }"#, | ||
1067 | ) | ||
1068 | } | ||
1069 | |||
1070 | #[test] | ||
1071 | fn goto_lifetime_param_decl_nested() { | ||
1072 | check( | ||
1073 | r#" | ||
1074 | fn foo<'foobar>(_: &'foobar ()) { | ||
1075 | fn foo<'foobar>(_: &'foobar<|> ()) {} | ||
1076 | //^^^^^^^ | ||
1077 | }"#, | ||
1078 | ) | ||
1079 | } | ||
1039 | } | 1080 | } |
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 68c628d31..6eac39639 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::{Crate, ImplDef, Semantics}; | 1 | use hir::{Crate, Impl, Semantics}; |
2 | use ide_db::RootDatabase; | 2 | use ide_db::RootDatabase; |
3 | use syntax::{algo::find_node_at_offset, ast, AstNode}; | 3 | use syntax::{algo::find_node_at_offset, ast, AstNode}; |
4 | 4 | ||
@@ -49,7 +49,7 @@ fn impls_for_def( | |||
49 | ast::AdtDef::Union(def) => sema.to_def(def)?.ty(sema.db), | 49 | ast::AdtDef::Union(def) => sema.to_def(def)?.ty(sema.db), |
50 | }; | 50 | }; |
51 | 51 | ||
52 | let impls = ImplDef::all_in_crate(sema.db, krate); | 52 | let impls = Impl::all_in_crate(sema.db, krate); |
53 | 53 | ||
54 | Some( | 54 | Some( |
55 | impls | 55 | impls |
@@ -67,7 +67,7 @@ fn impls_for_trait( | |||
67 | ) -> Option<Vec<NavigationTarget>> { | 67 | ) -> Option<Vec<NavigationTarget>> { |
68 | let tr = sema.to_def(node)?; | 68 | let tr = sema.to_def(node)?; |
69 | 69 | ||
70 | let impls = ImplDef::for_trait(sema.db, krate, tr); | 70 | let impls = Impl::for_trait(sema.db, krate, tr); |
71 | 71 | ||
72 | Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect()) | 72 | Some(impls.into_iter().map(|imp| imp.to_nav(sema.db)).collect()) |
73 | } | 73 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index ab017d2ad..e82aad6d5 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -295,7 +295,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String> | |||
295 | Definition::ModuleDef(md) => match md { | 295 | Definition::ModuleDef(md) => match md { |
296 | ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) { | 296 | ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) { |
297 | AssocItemContainer::Trait(t) => Some(t.name(db)), | 297 | AssocItemContainer::Trait(t) => Some(t.name(db)), |
298 | AssocItemContainer::ImplDef(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), | 298 | AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)), |
299 | }, | 299 | }, |
300 | ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), | 300 | ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), |
301 | _ => None, | 301 | _ => None, |
@@ -364,7 +364,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
364 | Adt::Enum(it) => from_def_source(db, it, mod_path), | 364 | Adt::Enum(it) => from_def_source(db, it, mod_path), |
365 | }) | 365 | }) |
366 | } | 366 | } |
367 | Definition::TypeParam(_) => { | 367 | Definition::TypeParam(_) | Definition::LifetimeParam(_) => { |
368 | // FIXME: Hover for generic param | 368 | // FIXME: Hover for generic param |
369 | None | 369 | None |
370 | } | 370 | } |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 71068cac2..c5c652cda 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -528,6 +528,13 @@ impl Analysis { | |||
528 | self.with_db(|db| references::rename::rename(db, position, new_name)) | 528 | self.with_db(|db| references::rename::rename(db, position, new_name)) |
529 | } | 529 | } |
530 | 530 | ||
531 | pub fn prepare_rename( | ||
532 | &self, | ||
533 | position: FilePosition, | ||
534 | ) -> Cancelable<Result<RangeInfo<()>, RenameError>> { | ||
535 | self.with_db(|db| references::rename::prepare_rename(db, position)) | ||
536 | } | ||
537 | |||
531 | pub fn structural_search_replace( | 538 | pub fn structural_search_replace( |
532 | &self, | 539 | &self, |
533 | query: &str, | 540 | query: &str, |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 675957fff..98190a86b 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -130,6 +130,8 @@ pub(crate) fn find_all_refs( | |||
130 | kind = ReferenceKind::FieldShorthandForLocal; | 130 | kind = ReferenceKind::FieldShorthandForLocal; |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } else if let Definition::LifetimeParam(_) = def { | ||
134 | kind = ReferenceKind::Lifetime; | ||
133 | }; | 135 | }; |
134 | 136 | ||
135 | let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) }; | 137 | let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) }; |
@@ -148,11 +150,29 @@ fn find_name( | |||
148 | let range = name.syntax().text_range(); | 150 | let range = name.syntax().text_range(); |
149 | return Some(RangeInfo::new(range, def)); | 151 | return Some(RangeInfo::new(range, def)); |
150 | } | 152 | } |
151 | let name_ref = | 153 | |
152 | sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?; | 154 | let (text_range, def) = if let Some(lifetime) = |
153 | let def = NameRefClass::classify(sema, &name_ref)?.referenced(sema.db); | 155 | sema.find_node_at_offset_with_descend::<ast::Lifetime>(&syntax, position.offset) |
154 | let range = name_ref.syntax().text_range(); | 156 | { |
155 | Some(RangeInfo::new(range, def)) | 157 | if let Some(def) = NameRefClass::classify_lifetime(sema, &lifetime) |
158 | .map(|class| NameRefClass::referenced(class, sema.db)) | ||
159 | { | ||
160 | (lifetime.syntax().text_range(), def) | ||
161 | } else { | ||
162 | ( | ||
163 | lifetime.syntax().text_range(), | ||
164 | NameClass::classify_lifetime(sema, &lifetime)?.referenced_or_defined(sema.db), | ||
165 | ) | ||
166 | } | ||
167 | } else { | ||
168 | let name_ref = | ||
169 | sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?; | ||
170 | ( | ||
171 | name_ref.syntax().text_range(), | ||
172 | NameRefClass::classify(sema, &name_ref)?.referenced(sema.db), | ||
173 | ) | ||
174 | }; | ||
175 | Some(RangeInfo::new(text_range, def)) | ||
156 | } | 176 | } |
157 | 177 | ||
158 | fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> { | 178 | fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> { |
@@ -1005,4 +1025,65 @@ impl Foo { | |||
1005 | } | 1025 | } |
1006 | expect.assert_eq(&actual) | 1026 | expect.assert_eq(&actual) |
1007 | } | 1027 | } |
1028 | |||
1029 | #[test] | ||
1030 | fn test_find_lifetimes_function() { | ||
1031 | check( | ||
1032 | r#" | ||
1033 | trait Foo<'a> {} | ||
1034 | impl<'a> Foo<'a> for &'a () {} | ||
1035 | fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> { | ||
1036 | fn bar<'a>(_: &'a ()) {} | ||
1037 | x | ||
1038 | } | ||
1039 | "#, | ||
1040 | expect![[r#" | ||
1041 | 'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime | ||
1042 | |||
1043 | FileId(0) 63..65 Lifetime | ||
1044 | FileId(0) 71..73 Lifetime | ||
1045 | FileId(0) 82..84 Lifetime | ||
1046 | FileId(0) 95..97 Lifetime | ||
1047 | FileId(0) 106..108 Lifetime | ||
1048 | "#]], | ||
1049 | ); | ||
1050 | } | ||
1051 | |||
1052 | #[test] | ||
1053 | fn test_find_lifetimes_type_alias() { | ||
1054 | check( | ||
1055 | r#" | ||
1056 | type Foo<'a, T> where T: 'a<|> = &'a T; | ||
1057 | "#, | ||
1058 | expect![[r#" | ||
1059 | 'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime | ||
1060 | |||
1061 | FileId(0) 25..27 Lifetime | ||
1062 | FileId(0) 31..33 Lifetime | ||
1063 | "#]], | ||
1064 | ); | ||
1065 | } | ||
1066 | |||
1067 | #[test] | ||
1068 | fn test_find_lifetimes_trait_impl() { | ||
1069 | check( | ||
1070 | r#" | ||
1071 | trait Foo<'a> { | ||
1072 | fn foo() -> &'a (); | ||
1073 | } | ||
1074 | impl<'a> Foo<'a> for &'a () { | ||
1075 | fn foo() -> &'a<|> () { | ||
1076 | unimplemented!() | ||
1077 | } | ||
1078 | } | ||
1079 | "#, | ||
1080 | expect![[r#" | ||
1081 | 'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime | ||
1082 | |||
1083 | FileId(0) 55..57 Lifetime | ||
1084 | FileId(0) 64..66 Lifetime | ||
1085 | FileId(0) 89..91 Lifetime | ||
1086 | "#]], | ||
1087 | ); | ||
1088 | } | ||
1008 | } | 1089 | } |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 44081f210..56e923841 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -35,6 +35,29 @@ impl fmt::Display for RenameError { | |||
35 | 35 | ||
36 | impl Error for RenameError {} | 36 | impl Error for RenameError {} |
37 | 37 | ||
38 | pub(crate) fn prepare_rename( | ||
39 | db: &RootDatabase, | ||
40 | position: FilePosition, | ||
41 | ) -> Result<RangeInfo<()>, RenameError> { | ||
42 | let sema = Semantics::new(db); | ||
43 | let source_file = sema.parse(position.file_id); | ||
44 | let syntax = source_file.syntax(); | ||
45 | if let Some(module) = find_module_at_offset(&sema, position, syntax) { | ||
46 | rename_mod(&sema, position, module, "dummy") | ||
47 | } else if let Some(self_token) = | ||
48 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) | ||
49 | { | ||
50 | rename_self_to_param(&sema, position, self_token, "dummy") | ||
51 | } else { | ||
52 | let range = match find_all_refs(&sema, position, None) { | ||
53 | Some(RangeInfo { range, .. }) => range, | ||
54 | None => return Err(RenameError("No references found at position".to_string())), | ||
55 | }; | ||
56 | Ok(RangeInfo::new(range, SourceChange::from(vec![]))) | ||
57 | } | ||
58 | .map(|info| RangeInfo::new(info.range, ())) | ||
59 | } | ||
60 | |||
38 | pub(crate) fn rename( | 61 | pub(crate) fn rename( |
39 | db: &RootDatabase, | 62 | db: &RootDatabase, |
40 | position: FilePosition, | 63 | position: FilePosition, |
@@ -49,11 +72,18 @@ pub(crate) fn rename_with_semantics( | |||
49 | position: FilePosition, | 72 | position: FilePosition, |
50 | new_name: &str, | 73 | new_name: &str, |
51 | ) -> Result<RangeInfo<SourceChange>, RenameError> { | 74 | ) -> Result<RangeInfo<SourceChange>, RenameError> { |
52 | match lex_single_syntax_kind(new_name) { | 75 | let is_lifetime_name = match lex_single_syntax_kind(new_name) { |
53 | Some(res) => match res { | 76 | Some(res) => match res { |
54 | (SyntaxKind::IDENT, _) => (), | 77 | (SyntaxKind::IDENT, _) => false, |
55 | (SyntaxKind::UNDERSCORE, _) => (), | 78 | (SyntaxKind::UNDERSCORE, _) => false, |
56 | (SyntaxKind::SELF_KW, _) => return rename_to_self(&sema, position), | 79 | (SyntaxKind::SELF_KW, _) => return rename_to_self(&sema, position), |
80 | (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => true, | ||
81 | (SyntaxKind::LIFETIME_IDENT, _) => { | ||
82 | return Err(RenameError(format!( | ||
83 | "Invalid name `{0}`: Cannot rename lifetime to {0}", | ||
84 | new_name | ||
85 | ))) | ||
86 | } | ||
57 | (_, Some(syntax_error)) => { | 87 | (_, Some(syntax_error)) => { |
58 | return Err(RenameError(format!("Invalid name `{}`: {}", new_name, syntax_error))) | 88 | return Err(RenameError(format!("Invalid name `{}`: {}", new_name, syntax_error))) |
59 | } | 89 | } |
@@ -62,18 +92,21 @@ pub(crate) fn rename_with_semantics( | |||
62 | } | 92 | } |
63 | }, | 93 | }, |
64 | None => return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))), | 94 | None => return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))), |
65 | } | 95 | }; |
66 | 96 | ||
67 | let source_file = sema.parse(position.file_id); | 97 | let source_file = sema.parse(position.file_id); |
68 | let syntax = source_file.syntax(); | 98 | let syntax = source_file.syntax(); |
69 | if let Some(module) = find_module_at_offset(&sema, position, syntax) { | 99 | // this is here to prevent lifetime renames from happening on modules and self |
100 | if is_lifetime_name { | ||
101 | rename_reference(&sema, position, new_name, is_lifetime_name) | ||
102 | } else if let Some(module) = find_module_at_offset(&sema, position, syntax) { | ||
70 | rename_mod(&sema, position, module, new_name) | 103 | rename_mod(&sema, position, module, new_name) |
71 | } else if let Some(self_token) = | 104 | } else if let Some(self_token) = |
72 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) | 105 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) |
73 | { | 106 | { |
74 | rename_self_to_param(&sema, position, self_token, new_name) | 107 | rename_self_to_param(&sema, position, self_token, new_name) |
75 | } else { | 108 | } else { |
76 | rename_reference(&sema, position, new_name) | 109 | rename_reference(&sema, position, new_name, is_lifetime_name) |
77 | } | 110 | } |
78 | } | 111 | } |
79 | 112 | ||
@@ -355,12 +388,26 @@ fn rename_reference( | |||
355 | sema: &Semantics<RootDatabase>, | 388 | sema: &Semantics<RootDatabase>, |
356 | position: FilePosition, | 389 | position: FilePosition, |
357 | new_name: &str, | 390 | new_name: &str, |
391 | is_lifetime_name: bool, | ||
358 | ) -> Result<RangeInfo<SourceChange>, RenameError> { | 392 | ) -> Result<RangeInfo<SourceChange>, RenameError> { |
359 | let RangeInfo { range, info: refs } = match find_all_refs(sema, position, None) { | 393 | let RangeInfo { range, info: refs } = match find_all_refs(sema, position, None) { |
360 | Some(range_info) => range_info, | 394 | Some(range_info) => range_info, |
361 | None => return Err(RenameError("No references found at position".to_string())), | 395 | None => return Err(RenameError("No references found at position".to_string())), |
362 | }; | 396 | }; |
363 | 397 | ||
398 | match (refs.declaration.kind == ReferenceKind::Lifetime, is_lifetime_name) { | ||
399 | (true, false) => { | ||
400 | return Err(RenameError(format!( | ||
401 | "Invalid name `{}`: not a lifetime identifier", | ||
402 | new_name | ||
403 | ))) | ||
404 | } | ||
405 | (false, true) => { | ||
406 | return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) | ||
407 | } | ||
408 | _ => (), | ||
409 | } | ||
410 | |||
364 | let edit = refs | 411 | let edit = refs |
365 | .into_iter() | 412 | .into_iter() |
366 | .map(|reference| source_edit_from_reference(sema, reference, new_name)) | 413 | .map(|reference| source_edit_from_reference(sema, reference, new_name)) |
@@ -465,6 +512,24 @@ mod tests { | |||
465 | } | 512 | } |
466 | 513 | ||
467 | #[test] | 514 | #[test] |
515 | fn test_rename_to_invalid_identifier_lifetime() { | ||
516 | check( | ||
517 | "'foo", | ||
518 | r#"fn main() { let i<|> = 1; }"#, | ||
519 | "error: Invalid name `'foo`: not an identifier", | ||
520 | ); | ||
521 | } | ||
522 | |||
523 | #[test] | ||
524 | fn test_rename_to_invalid_identifier_lifetime2() { | ||
525 | check( | ||
526 | "foo", | ||
527 | r#"fn main<'a>(_: &'a<|> ()) {}"#, | ||
528 | "error: Invalid name `foo`: not a lifetime identifier", | ||
529 | ); | ||
530 | } | ||
531 | |||
532 | #[test] | ||
468 | fn test_rename_for_local() { | 533 | fn test_rename_for_local() { |
469 | check( | 534 | check( |
470 | "k", | 535 | "k", |
@@ -1396,4 +1461,31 @@ fn foo(Foo { i: bar }: foo) -> i32 { | |||
1396 | "#, | 1461 | "#, |
1397 | ) | 1462 | ) |
1398 | } | 1463 | } |
1464 | |||
1465 | #[test] | ||
1466 | fn test_rename_lifetimes() { | ||
1467 | check( | ||
1468 | "'yeeee", | ||
1469 | r#" | ||
1470 | trait Foo<'a> { | ||
1471 | fn foo() -> &'a (); | ||
1472 | } | ||
1473 | impl<'a> Foo<'a> for &'a () { | ||
1474 | fn foo() -> &'a<|> () { | ||
1475 | unimplemented!() | ||
1476 | } | ||
1477 | } | ||
1478 | "#, | ||
1479 | r#" | ||
1480 | trait Foo<'a> { | ||
1481 | fn foo() -> &'a (); | ||
1482 | } | ||
1483 | impl<'yeeee> Foo<'yeeee> for &'yeeee () { | ||
1484 | fn foo() -> &'yeeee () { | ||
1485 | unimplemented!() | ||
1486 | } | ||
1487 | } | ||
1488 | "#, | ||
1489 | ) | ||
1490 | } | ||
1399 | } | 1491 | } |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 646f63704..2f465c195 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -2,7 +2,7 @@ use std::fmt; | |||
2 | 2 | ||
3 | use assists::utils::test_related_attribute; | 3 | use assists::utils::test_related_attribute; |
4 | use cfg::CfgExpr; | 4 | use cfg::CfgExpr; |
5 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; | 5 | use hir::{AsAssocItem, HasAttrs, InFile, Semantics}; |
6 | use ide_db::RootDatabase; | 6 | use ide_db::RootDatabase; |
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use syntax::{ | 8 | use syntax::{ |
@@ -10,7 +10,10 @@ use syntax::{ | |||
10 | match_ast, SyntaxNode, | 10 | match_ast, SyntaxNode, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | use crate::{display::ToNav, FileId, NavigationTarget}; | 13 | use crate::{ |
14 | display::{ToNav, TryToNav}, | ||
15 | FileId, NavigationTarget, | ||
16 | }; | ||
14 | 17 | ||
15 | #[derive(Debug, Clone)] | 18 | #[derive(Debug, Clone)] |
16 | pub struct Runnable { | 19 | pub struct Runnable { |
@@ -101,124 +104,109 @@ pub(crate) fn runnable( | |||
101 | item: SyntaxNode, | 104 | item: SyntaxNode, |
102 | file_id: FileId, | 105 | file_id: FileId, |
103 | ) -> Option<Runnable> { | 106 | ) -> Option<Runnable> { |
104 | match_ast! { | 107 | let runnable_item = match_ast! { |
105 | match item { | 108 | match (item.clone()) { |
106 | ast::Struct(it) => runnable_struct(sema, it, file_id), | ||
107 | ast::Fn(it) => runnable_fn(sema, it, file_id), | 109 | ast::Fn(it) => runnable_fn(sema, it, file_id), |
108 | ast::Module(it) => runnable_mod(sema, it, file_id), | 110 | ast::Module(it) => runnable_mod(sema, it), |
109 | _ => None, | 111 | _ => None, |
110 | } | 112 | } |
111 | } | 113 | }; |
114 | runnable_item.or_else(|| runnable_doctest(sema, item)) | ||
112 | } | 115 | } |
113 | 116 | ||
114 | fn runnable_fn( | 117 | fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> { |
115 | sema: &Semantics<RootDatabase>, | 118 | let def = sema.to_def(&func)?; |
116 | fn_def: ast::Fn, | 119 | let name_string = func.name()?.text().to_string(); |
117 | file_id: FileId, | ||
118 | ) -> Option<Runnable> { | ||
119 | let name_string = fn_def.name()?.text().to_string(); | ||
120 | 120 | ||
121 | let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &fn_def)); | ||
122 | let kind = if name_string == "main" { | 121 | let kind = if name_string == "main" { |
123 | RunnableKind::Bin | 122 | RunnableKind::Bin |
124 | } else { | 123 | } else { |
125 | let test_id = match sema.to_def(&fn_def).map(|def| def.module(sema.db)) { | 124 | let canonical_path = sema.to_def(&func).and_then(|def| { |
126 | Some(module) => { | 125 | let def: hir::ModuleDef = def.into(); |
127 | let def = sema.to_def(&fn_def)?; | 126 | def.canonical_path(sema.db) |
128 | let impl_trait_name = def.as_assoc_item(sema.db).and_then(|assoc_item| { | 127 | }); |
129 | match assoc_item.container(sema.db) { | 128 | let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string)); |
130 | hir::AssocItemContainer::Trait(trait_item) => { | 129 | |
131 | Some(trait_item.name(sema.db).to_string()) | 130 | if test_related_attribute(&func).is_some() { |
132 | } | 131 | let attr = TestAttr::from_fn(&func); |
133 | hir::AssocItemContainer::ImplDef(impl_def) => impl_def | ||
134 | .target_ty(sema.db) | ||
135 | .as_adt() | ||
136 | .map(|adt| adt.name(sema.db).to_string()), | ||
137 | } | ||
138 | }); | ||
139 | |||
140 | let path_iter = module | ||
141 | .path_to_root(sema.db) | ||
142 | .into_iter() | ||
143 | .rev() | ||
144 | .filter_map(|it| it.name(sema.db)) | ||
145 | .map(|name| name.to_string()); | ||
146 | |||
147 | let path = if let Some(impl_trait_name) = impl_trait_name { | ||
148 | path_iter | ||
149 | .chain(std::iter::once(impl_trait_name)) | ||
150 | .chain(std::iter::once(name_string)) | ||
151 | .join("::") | ||
152 | } else { | ||
153 | path_iter.chain(std::iter::once(name_string)).join("::") | ||
154 | }; | ||
155 | |||
156 | TestId::Path(path) | ||
157 | } | ||
158 | None => TestId::Name(name_string), | ||
159 | }; | ||
160 | |||
161 | if test_related_attribute(&fn_def).is_some() { | ||
162 | let attr = TestAttr::from_fn(&fn_def); | ||
163 | RunnableKind::Test { test_id, attr } | 132 | RunnableKind::Test { test_id, attr } |
164 | } else if fn_def.has_atom_attr("bench") { | 133 | } else if func.has_atom_attr("bench") { |
165 | RunnableKind::Bench { test_id } | 134 | RunnableKind::Bench { test_id } |
166 | } else if has_runnable_doc_test(&attrs) { | ||
167 | RunnableKind::DocTest { test_id } | ||
168 | } else { | 135 | } else { |
169 | return None; | 136 | return None; |
170 | } | 137 | } |
171 | }; | 138 | }; |
172 | 139 | ||
173 | let cfg = attrs.cfg(); | 140 | let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &func)); |
174 | 141 | let cfg = def.attrs(sema.db).cfg(); | |
175 | let nav = if let RunnableKind::DocTest { .. } = kind { | ||
176 | NavigationTarget::from_doc_commented( | ||
177 | sema.db, | ||
178 | InFile::new(file_id.into(), &fn_def), | ||
179 | InFile::new(file_id.into(), &fn_def), | ||
180 | ) | ||
181 | } else { | ||
182 | NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)) | ||
183 | }; | ||
184 | Some(Runnable { nav, kind, cfg }) | 142 | Some(Runnable { nav, kind, cfg }) |
185 | } | 143 | } |
186 | 144 | ||
187 | fn runnable_struct( | 145 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
188 | sema: &Semantics<RootDatabase>, | 146 | match_ast! { |
189 | struct_def: ast::Struct, | 147 | match item { |
190 | file_id: FileId, | 148 | ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
191 | ) -> Option<Runnable> { | 149 | ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
192 | let name_string = struct_def.name()?.text().to_string(); | 150 | ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), |
151 | ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
152 | ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
153 | ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
154 | ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
155 | ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | ||
156 | _ => None, | ||
157 | } | ||
158 | } | ||
159 | } | ||
193 | 160 | ||
194 | let attrs = | 161 | fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> { |
195 | Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def)); | 162 | let attrs = match def { |
163 | hir::ModuleDef::Module(it) => it.attrs(sema.db), | ||
164 | hir::ModuleDef::Function(it) => it.attrs(sema.db), | ||
165 | hir::ModuleDef::Adt(it) => it.attrs(sema.db), | ||
166 | hir::ModuleDef::EnumVariant(it) => it.attrs(sema.db), | ||
167 | hir::ModuleDef::Const(it) => it.attrs(sema.db), | ||
168 | hir::ModuleDef::Static(it) => it.attrs(sema.db), | ||
169 | hir::ModuleDef::Trait(it) => it.attrs(sema.db), | ||
170 | hir::ModuleDef::TypeAlias(it) => it.attrs(sema.db), | ||
171 | hir::ModuleDef::BuiltinType(_) => return None, | ||
172 | }; | ||
196 | if !has_runnable_doc_test(&attrs) { | 173 | if !has_runnable_doc_test(&attrs) { |
197 | return None; | 174 | return None; |
198 | } | 175 | } |
199 | let cfg = attrs.cfg(); | 176 | let def_name = def.name(sema.db).map(|it| it.to_string()); |
200 | 177 | let test_id = def | |
201 | let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) { | 178 | .canonical_path(sema.db) |
202 | Some(module) => { | 179 | // This probably belongs to canonical path? |
203 | let path_iter = module | 180 | .map(|path| { |
204 | .path_to_root(sema.db) | 181 | let assoc_def = match def { |
205 | .into_iter() | 182 | hir::ModuleDef::Function(it) => it.as_assoc_item(sema.db), |
206 | .rev() | 183 | hir::ModuleDef::Const(it) => it.as_assoc_item(sema.db), |
207 | .filter_map(|it| it.name(sema.db)) | 184 | hir::ModuleDef::TypeAlias(it) => it.as_assoc_item(sema.db), |
208 | .map(|name| name.to_string()); | 185 | _ => None, |
209 | let path = path_iter.chain(std::iter::once(name_string)).join("::"); | 186 | }; |
210 | 187 | // FIXME: this also looks very wrong | |
211 | TestId::Path(path) | 188 | if let Some(assoc_def) = assoc_def { |
212 | } | 189 | if let hir::AssocItemContainer::Impl(imp) = assoc_def.container(sema.db) { |
213 | None => TestId::Name(name_string), | 190 | if let Some(adt) = imp.target_ty(sema.db).as_adt() { |
214 | }; | 191 | let name = adt.name(sema.db).to_string(); |
215 | 192 | let idx = path.rfind(':').unwrap_or(0); | |
216 | let nav = NavigationTarget::from_doc_commented( | 193 | let (prefix, suffix) = path.split_at(idx); |
217 | sema.db, | 194 | return format!("{}{}::{}", prefix, name, suffix); |
218 | InFile::new(file_id.into(), &struct_def), | 195 | } |
219 | InFile::new(file_id.into(), &struct_def), | 196 | } |
220 | ); | 197 | } |
221 | Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg }) | 198 | path |
199 | }) | ||
200 | .map(TestId::Path) | ||
201 | .or_else(|| def_name.clone().map(TestId::Name))?; | ||
202 | |||
203 | let mut nav = def.try_to_nav(sema.db)?; | ||
204 | nav.focus_range = None; | ||
205 | nav.description = None; | ||
206 | nav.docs = None; | ||
207 | nav.kind = syntax::SyntaxKind::COMMENT; | ||
208 | let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() }; | ||
209 | Some(res) | ||
222 | } | 210 | } |
223 | 211 | ||
224 | #[derive(Debug, Copy, Clone)] | 212 | #[derive(Debug, Copy, Clone)] |
@@ -262,11 +250,7 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool { | |||
262 | }) | 250 | }) |
263 | } | 251 | } |
264 | 252 | ||
265 | fn runnable_mod( | 253 | fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> { |
266 | sema: &Semantics<RootDatabase>, | ||
267 | module: ast::Module, | ||
268 | file_id: FileId, | ||
269 | ) -> Option<Runnable> { | ||
270 | if !has_test_function_or_multiple_test_submodules(&module) { | 254 | if !has_test_function_or_multiple_test_submodules(&module) { |
271 | return None; | 255 | return None; |
272 | } | 256 | } |
@@ -279,7 +263,8 @@ fn runnable_mod( | |||
279 | .filter_map(|it| it.name(sema.db)) | 263 | .filter_map(|it| it.name(sema.db)) |
280 | .join("::"); | 264 | .join("::"); |
281 | 265 | ||
282 | let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &module)); | 266 | let def = sema.to_def(&module)?; |
267 | let attrs = def.attrs(sema.db); | ||
283 | let cfg = attrs.cfg(); | 268 | let cfg = attrs.cfg(); |
284 | let nav = module_def.to_nav(sema.db); | 269 | let nav = module_def.to_nav(sema.db); |
285 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | 270 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) |
@@ -319,7 +304,7 @@ mod tests { | |||
319 | 304 | ||
320 | use crate::fixture; | 305 | use crate::fixture; |
321 | 306 | ||
322 | use super::{RunnableAction, BENCH, BIN, DOCTEST, TEST}; | 307 | use super::*; |
323 | 308 | ||
324 | fn check( | 309 | fn check( |
325 | ra_fixture: &str, | 310 | ra_fixture: &str, |
@@ -548,7 +533,7 @@ struct StructWithRunnable(String); | |||
548 | full_range: 15..74, | 533 | full_range: 15..74, |
549 | focus_range: None, | 534 | focus_range: None, |
550 | name: "should_have_runnable", | 535 | name: "should_have_runnable", |
551 | kind: FN, | 536 | kind: COMMENT, |
552 | container_name: None, | 537 | container_name: None, |
553 | description: None, | 538 | description: None, |
554 | docs: None, | 539 | docs: None, |
@@ -568,7 +553,7 @@ struct StructWithRunnable(String); | |||
568 | full_range: 76..148, | 553 | full_range: 76..148, |
569 | focus_range: None, | 554 | focus_range: None, |
570 | name: "should_have_runnable_1", | 555 | name: "should_have_runnable_1", |
571 | kind: FN, | 556 | kind: COMMENT, |
572 | container_name: None, | 557 | container_name: None, |
573 | description: None, | 558 | description: None, |
574 | docs: None, | 559 | docs: None, |
@@ -588,7 +573,7 @@ struct StructWithRunnable(String); | |||
588 | full_range: 150..254, | 573 | full_range: 150..254, |
589 | focus_range: None, | 574 | focus_range: None, |
590 | name: "should_have_runnable_2", | 575 | name: "should_have_runnable_2", |
591 | kind: FN, | 576 | kind: COMMENT, |
592 | container_name: None, | 577 | container_name: None, |
593 | description: None, | 578 | description: None, |
594 | docs: None, | 579 | docs: None, |
@@ -608,7 +593,7 @@ struct StructWithRunnable(String); | |||
608 | full_range: 756..821, | 593 | full_range: 756..821, |
609 | focus_range: None, | 594 | focus_range: None, |
610 | name: "StructWithRunnable", | 595 | name: "StructWithRunnable", |
611 | kind: STRUCT, | 596 | kind: COMMENT, |
612 | container_name: None, | 597 | container_name: None, |
613 | description: None, | 598 | description: None, |
614 | docs: None, | 599 | docs: None, |
@@ -670,7 +655,7 @@ impl Data { | |||
670 | full_range: 44..98, | 655 | full_range: 44..98, |
671 | focus_range: None, | 656 | focus_range: None, |
672 | name: "foo", | 657 | name: "foo", |
673 | kind: FN, | 658 | kind: COMMENT, |
674 | container_name: None, | 659 | container_name: None, |
675 | description: None, | 660 | description: None, |
676 | docs: None, | 661 | docs: None, |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 990b0f7d9..488969f1a 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -806,6 +806,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
806 | } | 806 | } |
807 | return h; | 807 | return h; |
808 | } | 808 | } |
809 | Definition::LifetimeParam(_) => HighlightTag::Lifetime, | ||
809 | } | 810 | } |
810 | .into() | 811 | .into() |
811 | } | 812 | } |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index d4a774261..bd2afc887 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -6,12 +6,12 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | db::HirDatabase, Crate, Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, | 9 | db::HirDatabase, Crate, Field, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, |
10 | Name, PathResolution, Semantics, TypeParam, Visibility, | 10 | ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, |
11 | }; | 11 | }; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode}, | 13 | ast::{self, AstNode}, |
14 | match_ast, SyntaxNode, | 14 | match_ast, SyntaxKind, SyntaxNode, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | use crate::RootDatabase; | 17 | use crate::RootDatabase; |
@@ -22,9 +22,11 @@ pub enum Definition { | |||
22 | Macro(MacroDef), | 22 | Macro(MacroDef), |
23 | Field(Field), | 23 | Field(Field), |
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
25 | SelfType(ImplDef), | 25 | SelfType(Impl), |
26 | Local(Local), | 26 | Local(Local), |
27 | TypeParam(TypeParam), | 27 | TypeParam(TypeParam), |
28 | LifetimeParam(LifetimeParam), | ||
29 | // FIXME: Label | ||
28 | } | 30 | } |
29 | 31 | ||
30 | impl Definition { | 32 | impl Definition { |
@@ -36,6 +38,7 @@ impl Definition { | |||
36 | Definition::SelfType(it) => Some(it.module(db)), | 38 | Definition::SelfType(it) => Some(it.module(db)), |
37 | Definition::Local(it) => Some(it.module(db)), | 39 | Definition::Local(it) => Some(it.module(db)), |
38 | Definition::TypeParam(it) => Some(it.module(db)), | 40 | Definition::TypeParam(it) => Some(it.module(db)), |
41 | Definition::LifetimeParam(it) => Some(it.module(db)), | ||
39 | } | 42 | } |
40 | } | 43 | } |
41 | 44 | ||
@@ -47,6 +50,7 @@ impl Definition { | |||
47 | Definition::SelfType(_) => None, | 50 | Definition::SelfType(_) => None, |
48 | Definition::Local(_) => None, | 51 | Definition::Local(_) => None, |
49 | Definition::TypeParam(_) => None, | 52 | Definition::TypeParam(_) => None, |
53 | Definition::LifetimeParam(_) => None, | ||
50 | } | 54 | } |
51 | } | 55 | } |
52 | 56 | ||
@@ -72,6 +76,7 @@ impl Definition { | |||
72 | Definition::SelfType(_) => return None, | 76 | Definition::SelfType(_) => return None, |
73 | Definition::Local(it) => it.name(db)?, | 77 | Definition::Local(it) => it.name(db)?, |
74 | Definition::TypeParam(it) => it.name(db), | 78 | Definition::TypeParam(it) => it.name(db), |
79 | Definition::LifetimeParam(it) => it.name(db), | ||
75 | }; | 80 | }; |
76 | Some(name) | 81 | Some(name) |
77 | } | 82 | } |
@@ -229,6 +234,25 @@ impl NameClass { | |||
229 | } | 234 | } |
230 | } | 235 | } |
231 | } | 236 | } |
237 | |||
238 | pub fn classify_lifetime( | ||
239 | sema: &Semantics<RootDatabase>, | ||
240 | lifetime: &ast::Lifetime, | ||
241 | ) -> Option<NameClass> { | ||
242 | let _p = profile::span("classify_lifetime").detail(|| lifetime.to_string()); | ||
243 | let parent = lifetime.syntax().parent()?; | ||
244 | |||
245 | match_ast! { | ||
246 | match parent { | ||
247 | ast::LifetimeParam(it) => { | ||
248 | let def = sema.to_def(&it)?; | ||
249 | Some(NameClass::Definition(Definition::LifetimeParam(def))) | ||
250 | }, | ||
251 | ast::Label(_it) => None, | ||
252 | _ => None, | ||
253 | } | ||
254 | } | ||
255 | } | ||
232 | } | 256 | } |
233 | 257 | ||
234 | #[derive(Debug)] | 258 | #[derive(Debug)] |
@@ -338,6 +362,35 @@ impl NameRefClass { | |||
338 | let resolved = sema.resolve_extern_crate(&extern_crate)?; | 362 | let resolved = sema.resolve_extern_crate(&extern_crate)?; |
339 | Some(NameRefClass::ExternCrate(resolved)) | 363 | Some(NameRefClass::ExternCrate(resolved)) |
340 | } | 364 | } |
365 | |||
366 | pub fn classify_lifetime( | ||
367 | sema: &Semantics<RootDatabase>, | ||
368 | lifetime: &ast::Lifetime, | ||
369 | ) -> Option<NameRefClass> { | ||
370 | let _p = profile::span("classify_lifetime_ref").detail(|| lifetime.to_string()); | ||
371 | let parent = lifetime.syntax().parent()?; | ||
372 | match parent.kind() { | ||
373 | SyntaxKind::LIFETIME_ARG | ||
374 | | SyntaxKind::SELF_PARAM | ||
375 | | SyntaxKind::TYPE_BOUND | ||
376 | | SyntaxKind::WHERE_PRED | ||
377 | | SyntaxKind::REF_TYPE => sema | ||
378 | .resolve_lifetime_param(lifetime) | ||
379 | .map(Definition::LifetimeParam) | ||
380 | .map(NameRefClass::Definition), | ||
381 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check | ||
382 | // if our lifetime is in a LifetimeParam without being the constrained lifetime | ||
383 | _ if ast::LifetimeParam::cast(parent).and_then(|param| param.lifetime()).as_ref() | ||
384 | != Some(lifetime) => | ||
385 | { | ||
386 | sema.resolve_lifetime_param(lifetime) | ||
387 | .map(Definition::LifetimeParam) | ||
388 | .map(NameRefClass::Definition) | ||
389 | } | ||
390 | SyntaxKind::BREAK_EXPR | SyntaxKind::CONTINUE_EXPR => None, | ||
391 | _ => None, | ||
392 | } | ||
393 | } | ||
341 | } | 394 | } |
342 | 395 | ||
343 | impl From<PathResolution> for Definition { | 396 | impl From<PathResolution> for Definition { |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 3936c7390..525c8a41f 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -33,6 +33,7 @@ pub enum ReferenceKind { | |||
33 | RecordFieldExprOrPat, | 33 | RecordFieldExprOrPat, |
34 | SelfKw, | 34 | SelfKw, |
35 | EnumLiteral, | 35 | EnumLiteral, |
36 | Lifetime, | ||
36 | Other, | 37 | Other, |
37 | } | 38 | } |
38 | 39 | ||
@@ -129,6 +130,25 @@ impl Definition { | |||
129 | return SearchScope::new(res); | 130 | return SearchScope::new(res); |
130 | } | 131 | } |
131 | 132 | ||
133 | if let Definition::LifetimeParam(param) = self { | ||
134 | let range = match param.parent(db) { | ||
135 | hir::GenericDef::Function(it) => it.source(db).value.syntax().text_range(), | ||
136 | hir::GenericDef::Adt(it) => match it { | ||
137 | hir::Adt::Struct(it) => it.source(db).value.syntax().text_range(), | ||
138 | hir::Adt::Union(it) => it.source(db).value.syntax().text_range(), | ||
139 | hir::Adt::Enum(it) => it.source(db).value.syntax().text_range(), | ||
140 | }, | ||
141 | hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(), | ||
142 | hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(), | ||
143 | hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(), | ||
144 | hir::GenericDef::EnumVariant(it) => it.source(db).value.syntax().text_range(), | ||
145 | hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(), | ||
146 | }; | ||
147 | let mut res = FxHashMap::default(); | ||
148 | res.insert(file_id, Some(range)); | ||
149 | return SearchScope::new(res); | ||
150 | } | ||
151 | |||
132 | let vis = self.visibility(db); | 152 | let vis = self.visibility(db); |
133 | 153 | ||
134 | if let Some(Visibility::Module(module)) = vis.and_then(|it| it.into()) { | 154 | if let Some(Visibility::Module(module)) = vis.and_then(|it| it.into()) { |
@@ -255,25 +275,42 @@ impl<'a> FindUsages<'a> { | |||
255 | continue; | 275 | continue; |
256 | } | 276 | } |
257 | 277 | ||
258 | match sema.find_node_at_offset_with_descend(&tree, offset) { | 278 | if let Some(name_ref) = sema.find_node_at_offset_with_descend(&tree, offset) { |
259 | Some(name_ref) => { | 279 | if self.found_name_ref(&name_ref, sink) { |
260 | if self.found_name_ref(&name_ref, sink) { | 280 | return; |
261 | return; | 281 | } |
262 | } | 282 | } else if let Some(name) = sema.find_node_at_offset_with_descend(&tree, offset) { |
283 | if self.found_name(&name, sink) { | ||
284 | return; | ||
285 | } | ||
286 | } else if let Some(lifetime) = sema.find_node_at_offset_with_descend(&tree, offset) | ||
287 | { | ||
288 | if self.found_lifetime(&lifetime, sink) { | ||
289 | return; | ||
263 | } | 290 | } |
264 | None => match sema.find_node_at_offset_with_descend(&tree, offset) { | ||
265 | Some(name) => { | ||
266 | if self.found_name(&name, sink) { | ||
267 | return; | ||
268 | } | ||
269 | } | ||
270 | None => {} | ||
271 | }, | ||
272 | } | 291 | } |
273 | } | 292 | } |
274 | } | 293 | } |
275 | } | 294 | } |
276 | 295 | ||
296 | fn found_lifetime( | ||
297 | &self, | ||
298 | lifetime: &ast::Lifetime, | ||
299 | sink: &mut dyn FnMut(Reference) -> bool, | ||
300 | ) -> bool { | ||
301 | match NameRefClass::classify_lifetime(self.sema, lifetime) { | ||
302 | Some(NameRefClass::Definition(def)) if &def == self.def => { | ||
303 | let reference = Reference { | ||
304 | file_range: self.sema.original_range(lifetime.syntax()), | ||
305 | kind: ReferenceKind::Lifetime, | ||
306 | access: None, | ||
307 | }; | ||
308 | sink(reference) | ||
309 | } | ||
310 | _ => false, // not a usage | ||
311 | } | ||
312 | } | ||
313 | |||
277 | fn found_name_ref( | 314 | fn found_name_ref( |
278 | &self, | 315 | &self, |
279 | name_ref: &ast::NameRef, | 316 | name_ref: &ast::NameRef, |
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 121063aea..ca455fa03 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs | |||
@@ -209,8 +209,7 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<Fil | |||
209 | query.search(&buf) | 209 | query.search(&buf) |
210 | } | 210 | } |
211 | 211 | ||
212 | pub fn index_resolve(db: &RootDatabase, name_ref: &ast::NameRef) -> Vec<FileSymbol> { | 212 | pub fn index_resolve(db: &RootDatabase, name: &SmolStr) -> Vec<FileSymbol> { |
213 | let name = name_ref.text(); | ||
214 | let mut query = Query::new(name.to_string()); | 213 | let mut query = Query::new(name.to_string()); |
215 | query.exact(); | 214 | query.exact(); |
216 | query.limit(4); | 215 | query.limit(4); |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 039976e4b..0b4d3f4eb 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -21,7 +21,7 @@ env_logger = { version = "0.8.1", default-features = false } | |||
21 | itertools = "0.9.0" | 21 | itertools = "0.9.0" |
22 | jod-thread = "0.1.0" | 22 | jod-thread = "0.1.0" |
23 | log = "0.4.8" | 23 | log = "0.4.8" |
24 | lsp-types = { version = "0.85.0", features = ["proposed"] } | 24 | lsp-types = { version = "0.86.0", features = ["proposed"] } |
25 | parking_lot = "0.11.0" | 25 | parking_lot = "0.11.0" |
26 | pico-args = "0.3.1" | 26 | pico-args = "0.3.1" |
27 | oorandom = "11.1.2" | 27 | oorandom = "11.1.2" |
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 5e4c22bc5..de5eb93b5 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -64,7 +64,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
64 | prepare_provider: Some(true), | 64 | prepare_provider: Some(true), |
65 | work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, | 65 | work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, |
66 | })), | 66 | })), |
67 | on_type_rename_provider: None, | 67 | linked_editing_range_provider: None, |
68 | document_link_provider: None, | 68 | document_link_provider: None, |
69 | color_provider: None, | 69 | color_provider: None, |
70 | execute_command_provider: None, | 70 | execute_command_provider: None, |
@@ -83,6 +83,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
83 | } | 83 | } |
84 | .into(), | 84 | .into(), |
85 | ), | 85 | ), |
86 | moniker_provider: None, | ||
86 | experimental: Some(json!({ | 87 | experimental: Some(json!({ |
87 | "joinLines": true, | 88 | "joinLines": true, |
88 | "ssr": true, | 89 | "ssr": true, |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 94e2bfa1b..af226c109 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -733,7 +733,7 @@ pub(crate) fn handle_prepare_rename( | |||
733 | let _p = profile::span("handle_prepare_rename"); | 733 | let _p = profile::span("handle_prepare_rename"); |
734 | let position = from_proto::file_position(&snap, params)?; | 734 | let position = from_proto::file_position(&snap, params)?; |
735 | 735 | ||
736 | let change = snap.analysis.rename(position, "dummy")??; | 736 | let change = snap.analysis.prepare_rename(position)??; |
737 | let line_index = snap.analysis.file_line_index(position.file_id)?; | 737 | let line_index = snap.analysis.file_line_index(position.file_id)?; |
738 | let range = to_proto::range(&line_index, change.range); | 738 | let range = to_proto::range(&line_index, change.range); |
739 | Ok(Some(PrepareRenameResponse::Range(range))) | 739 | Ok(Some(PrepareRenameResponse::Range(range))) |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 715f8927a..72f77a016 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -633,7 +633,7 @@ pub(crate) fn resource_op( | |||
633 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { | 633 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { |
634 | uri, | 634 | uri, |
635 | options: None, | 635 | options: None, |
636 | annotation: None, | 636 | annotation_id: None, |
637 | }) | 637 | }) |
638 | } | 638 | } |
639 | FileSystemEdit::MoveFile { src, dst } => { | 639 | FileSystemEdit::MoveFile { src, dst } => { |
@@ -643,7 +643,7 @@ pub(crate) fn resource_op( | |||
643 | old_uri, | 643 | old_uri, |
644 | new_uri, | 644 | new_uri, |
645 | options: None, | 645 | options: None, |
646 | annotation: None, | 646 | annotation_id: None, |
647 | }) | 647 | }) |
648 | } | 648 | } |
649 | } | 649 | } |
@@ -708,6 +708,7 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { | |||
708 | .collect(), | 708 | .collect(), |
709 | ) | 709 | ) |
710 | }), | 710 | }), |
711 | change_annotations: None, | ||
711 | } | 712 | } |
712 | } | 713 | } |
713 | } | 714 | } |
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index e83b116a7..2d717e366 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json | |||
@@ -195,9 +195,9 @@ | |||
195 | } | 195 | } |
196 | }, | 196 | }, |
197 | "@types/vscode": { | 197 | "@types/vscode": { |
198 | "version": "1.51.0", | 198 | "version": "1.52.0", |
199 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.51.0.tgz", | 199 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.52.0.tgz", |
200 | "integrity": "sha512-C/jZ35OT5k/rsJyAK8mS1kM++vMcm89oSWegkzxRCvHllIq0cToZAkIDs6eCY4SKrvik3nrhELizyLcM0onbQA==", | 200 | "integrity": "sha512-Kt3bvWzAvvF/WH9YEcrCICDp0Z7aHhJGhLJ1BxeyNP6yRjonWqWnAIh35/pXAjswAnWOABrYlF7SwXR9+1nnLA==", |
201 | "dev": true | 201 | "dev": true |
202 | }, | 202 | }, |
203 | "@typescript-eslint/eslint-plugin": { | 203 | "@typescript-eslint/eslint-plugin": { |
@@ -455,8 +455,7 @@ | |||
455 | "balanced-match": { | 455 | "balanced-match": { |
456 | "version": "1.0.0", | 456 | "version": "1.0.0", |
457 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", | 457 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", |
458 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", | 458 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" |
459 | "dev": true | ||
460 | }, | 459 | }, |
461 | "binary-extensions": { | 460 | "binary-extensions": { |
462 | "version": "2.1.0", | 461 | "version": "2.1.0", |
@@ -474,7 +473,6 @@ | |||
474 | "version": "1.1.11", | 473 | "version": "1.1.11", |
475 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | 474 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |
476 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | 475 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", |
477 | "dev": true, | ||
478 | "requires": { | 476 | "requires": { |
479 | "balanced-match": "^1.0.0", | 477 | "balanced-match": "^1.0.0", |
480 | "concat-map": "0.0.1" | 478 | "concat-map": "0.0.1" |
@@ -673,8 +671,7 @@ | |||
673 | "concat-map": { | 671 | "concat-map": { |
674 | "version": "0.0.1", | 672 | "version": "0.0.1", |
675 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | 673 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |
676 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", | 674 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" |
677 | "dev": true | ||
678 | }, | 675 | }, |
679 | "cross-spawn": { | 676 | "cross-spawn": { |
680 | "version": "7.0.3", | 677 | "version": "7.0.3", |
@@ -1622,7 +1619,6 @@ | |||
1622 | "version": "3.0.4", | 1619 | "version": "3.0.4", |
1623 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | 1620 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", |
1624 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", | 1621 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", |
1625 | "dev": true, | ||
1626 | "requires": { | 1622 | "requires": { |
1627 | "brace-expansion": "^1.1.7" | 1623 | "brace-expansion": "^1.1.7" |
1628 | } | 1624 | } |
@@ -2021,9 +2017,27 @@ | |||
2021 | "dev": true | 2017 | "dev": true |
2022 | }, | 2018 | }, |
2023 | "semver": { | 2019 | "semver": { |
2024 | "version": "6.3.0", | 2020 | "version": "7.3.4", |
2025 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", | 2021 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", |
2026 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" | 2022 | "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", |
2023 | "requires": { | ||
2024 | "lru-cache": "^6.0.0" | ||
2025 | }, | ||
2026 | "dependencies": { | ||
2027 | "lru-cache": { | ||
2028 | "version": "6.0.0", | ||
2029 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", | ||
2030 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", | ||
2031 | "requires": { | ||
2032 | "yallist": "^4.0.0" | ||
2033 | } | ||
2034 | }, | ||
2035 | "yallist": { | ||
2036 | "version": "4.0.0", | ||
2037 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | ||
2038 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" | ||
2039 | } | ||
2040 | } | ||
2027 | }, | 2041 | }, |
2028 | "serialize-javascript": { | 2042 | "serialize-javascript": { |
2029 | "version": "5.0.1", | 2043 | "version": "5.0.1", |
@@ -2350,32 +2364,33 @@ | |||
2350 | } | 2364 | } |
2351 | }, | 2365 | }, |
2352 | "vscode-jsonrpc": { | 2366 | "vscode-jsonrpc": { |
2353 | "version": "6.0.0-next.7", | 2367 | "version": "6.0.0", |
2354 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.7.tgz", | 2368 | "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", |
2355 | "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug==" | 2369 | "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==" |
2356 | }, | 2370 | }, |
2357 | "vscode-languageclient": { | 2371 | "vscode-languageclient": { |
2358 | "version": "7.0.0-next.14", | 2372 | "version": "7.0.0", |
2359 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0-next.14.tgz", | 2373 | "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", |
2360 | "integrity": "sha512-QUccfXK2F6AXXRFR8QJCaIz7N2BhJK6ok8E1aO8LHq2IBU33+5hTSJBXs7nEqrqZ/cY2VlDDbMWtMvCxz+/y1w==", | 2374 | "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", |
2361 | "requires": { | 2375 | "requires": { |
2362 | "semver": "^6.3.0", | 2376 | "minimatch": "^3.0.4", |
2363 | "vscode-languageserver-protocol": "3.16.0-next.11" | 2377 | "semver": "^7.3.4", |
2378 | "vscode-languageserver-protocol": "3.16.0" | ||
2364 | } | 2379 | } |
2365 | }, | 2380 | }, |
2366 | "vscode-languageserver-protocol": { | 2381 | "vscode-languageserver-protocol": { |
2367 | "version": "3.16.0-next.11", | 2382 | "version": "3.16.0", |
2368 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.11.tgz", | 2383 | "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", |
2369 | "integrity": "sha512-31FmupmSmfznuMuGp7qN6h3d/hKUbexbvcwTvrUE/igqRlzFU542s8MtGICx1ERbVuDOLGp96W2Z92qbUbmBPA==", | 2384 | "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", |
2370 | "requires": { | 2385 | "requires": { |
2371 | "vscode-jsonrpc": "6.0.0-next.7", | 2386 | "vscode-jsonrpc": "6.0.0", |
2372 | "vscode-languageserver-types": "3.16.0-next.5" | 2387 | "vscode-languageserver-types": "3.16.0" |
2373 | } | 2388 | } |
2374 | }, | 2389 | }, |
2375 | "vscode-languageserver-types": { | 2390 | "vscode-languageserver-types": { |
2376 | "version": "3.16.0-next.5", | 2391 | "version": "3.16.0", |
2377 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.5.tgz", | 2392 | "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", |
2378 | "integrity": "sha512-lf8Y1XXMtF1r2oDDAmJe+drizNXkybSRXAQQk5dPy2rYJsY9SPXYNO074L3THu9zNYepzV5fRJZUPo/V/TLBRQ==" | 2393 | "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" |
2379 | }, | 2394 | }, |
2380 | "vscode-test": { | 2395 | "vscode-test": { |
2381 | "version": "1.4.1", | 2396 | "version": "1.4.1", |
diff --git a/editors/code/package.json b/editors/code/package.json index 160a62e46..ad01fea7b 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -21,7 +21,7 @@ | |||
21 | "Programming Languages" | 21 | "Programming Languages" |
22 | ], | 22 | ], |
23 | "engines": { | 23 | "engines": { |
24 | "vscode": "^1.51.0" | 24 | "vscode": "^1.52.0" |
25 | }, | 25 | }, |
26 | "enableProposedApi": true, | 26 | "enableProposedApi": true, |
27 | "scripts": { | 27 | "scripts": { |
@@ -36,7 +36,7 @@ | |||
36 | }, | 36 | }, |
37 | "dependencies": { | 37 | "dependencies": { |
38 | "node-fetch": "^2.6.1", | 38 | "node-fetch": "^2.6.1", |
39 | "vscode-languageclient": "7.0.0-next.14" | 39 | "vscode-languageclient": "7.0.0" |
40 | }, | 40 | }, |
41 | "devDependencies": { | 41 | "devDependencies": { |
42 | "@rollup/plugin-commonjs": "^17.0.0", | 42 | "@rollup/plugin-commonjs": "^17.0.0", |
@@ -45,7 +45,7 @@ | |||
45 | "@types/mocha": "^8.0.4", | 45 | "@types/mocha": "^8.0.4", |
46 | "@types/node": "~12.12.6", | 46 | "@types/node": "~12.12.6", |
47 | "@types/node-fetch": "^2.5.7", | 47 | "@types/node-fetch": "^2.5.7", |
48 | "@types/vscode": "^1.51.0", | 48 | "@types/vscode": "^1.52.0", |
49 | "@typescript-eslint/eslint-plugin": "^4.9.0", | 49 | "@typescript-eslint/eslint-plugin": "^4.9.0", |
50 | "@typescript-eslint/parser": "^4.9.0", | 50 | "@typescript-eslint/parser": "^4.9.0", |
51 | "eslint": "^7.15.0", | 51 | "eslint": "^7.15.0", |