diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/code_model.rs | 12 | ||||
-rw-r--r-- | crates/hir_def/src/attr.rs | 56 | ||||
-rw-r--r-- | crates/hir_def/src/db.rs | 11 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 5 | ||||
-rw-r--r-- | crates/ssr/src/parsing.rs | 16 | ||||
-rw-r--r-- | crates/ssr/src/tests.rs | 47 |
6 files changed, 129 insertions, 18 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 071e553a8..1a4aa78fb 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -743,6 +743,18 @@ impl Function { | |||
743 | db.function_data(self.id).name.clone() | 743 | db.function_data(self.id).name.clone() |
744 | } | 744 | } |
745 | 745 | ||
746 | /// Get this function's return type | ||
747 | pub fn ret_type(self, db: &dyn HirDatabase) -> Type { | ||
748 | let resolver = self.id.resolver(db.upcast()); | ||
749 | let ret_type = &db.function_data(self.id).ret_type; | ||
750 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | ||
751 | let environment = TraitEnvironment::lower(db, &resolver); | ||
752 | Type { | ||
753 | krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate, | ||
754 | ty: InEnvironment { value: Ty::from_hir_ext(&ctx, ret_type).0, environment }, | ||
755 | } | ||
756 | } | ||
757 | |||
746 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 758 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
747 | if !db.function_data(self.id).has_self_param { | 759 | if !db.function_data(self.id).has_self_param { |
748 | return None; | 760 | return None; |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 6b79e7bad..9e6426b31 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use arena::map::ArenaMap; | ||
5 | use base_db::CrateId; | 6 | use base_db::CrateId; |
6 | use cfg::{CfgExpr, CfgOptions}; | 7 | use cfg::{CfgExpr, CfgOptions}; |
7 | use either::Either; | 8 | use either::Either; |
@@ -21,7 +22,8 @@ use crate::{ | |||
21 | nameres::ModuleSource, | 22 | nameres::ModuleSource, |
22 | path::{ModPath, PathKind}, | 23 | path::{ModPath, PathKind}, |
23 | src::HasChildSource, | 24 | src::HasChildSource, |
24 | AdtId, AttrDefId, GenericParamId, Lookup, | 25 | AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, |
26 | VariantId, | ||
25 | }; | 27 | }; |
26 | 28 | ||
27 | /// Holds documentation | 29 | /// Holds documentation |
@@ -210,16 +212,10 @@ impl Attrs { | |||
210 | } | 212 | } |
211 | } | 213 | } |
212 | AttrDefId::FieldId(it) => { | 214 | AttrDefId::FieldId(it) => { |
213 | let src = it.parent.child_source(db); | 215 | return db.fields_attrs(it.parent)[it.local_id].clone(); |
214 | match &src.value[it.local_id] { | ||
215 | Either::Left(_tuple) => RawAttrs::default(), | ||
216 | Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)), | ||
217 | } | ||
218 | } | 216 | } |
219 | AttrDefId::EnumVariantId(var_id) => { | 217 | AttrDefId::EnumVariantId(it) => { |
220 | let src = var_id.parent.child_source(db); | 218 | return db.variants_attrs(it.parent)[it.local_id].clone(); |
221 | let src = src.as_ref().map(|it| &it[var_id.local_id]); | ||
222 | RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) | ||
223 | } | 219 | } |
224 | AttrDefId::AdtId(it) => match it { | 220 | AttrDefId::AdtId(it) => match it { |
225 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 221 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
@@ -259,6 +255,46 @@ impl Attrs { | |||
259 | raw_attrs.filter(db, def.krate(db)) | 255 | raw_attrs.filter(db, def.krate(db)) |
260 | } | 256 | } |
261 | 257 | ||
258 | pub(crate) fn variants_attrs_query( | ||
259 | db: &dyn DefDatabase, | ||
260 | e: EnumId, | ||
261 | ) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> { | ||
262 | let krate = e.lookup(db).container.module(db).krate; | ||
263 | let src = e.child_source(db); | ||
264 | let mut res = ArenaMap::default(); | ||
265 | |||
266 | for (id, var) in src.value.iter() { | ||
267 | let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn AttrsOwner)) | ||
268 | .filter(db, krate); | ||
269 | |||
270 | res.insert(id, attrs) | ||
271 | } | ||
272 | |||
273 | Arc::new(res) | ||
274 | } | ||
275 | |||
276 | pub(crate) fn fields_attrs_query( | ||
277 | db: &dyn DefDatabase, | ||
278 | v: VariantId, | ||
279 | ) -> Arc<ArenaMap<LocalFieldId, Attrs>> { | ||
280 | let krate = v.module(db).krate; | ||
281 | let src = v.child_source(db); | ||
282 | let mut res = ArenaMap::default(); | ||
283 | |||
284 | for (id, fld) in src.value.iter() { | ||
285 | let attrs = match fld { | ||
286 | Either::Left(_tuple) => Attrs::default(), | ||
287 | Either::Right(record) => { | ||
288 | RawAttrs::from_attrs_owner(db, src.with_value(record)).filter(db, krate) | ||
289 | } | ||
290 | }; | ||
291 | |||
292 | res.insert(id, attrs); | ||
293 | } | ||
294 | |||
295 | Arc::new(res) | ||
296 | } | ||
297 | |||
262 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { | 298 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { |
263 | AttrQuery { attrs: self, key } | 299 | AttrQuery { attrs: self, key } |
264 | } | 300 | } |
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index d1a459066..d3bf5b34c 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! Defines database & queries for name resolution. | 1 | //! Defines database & queries for name resolution. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use arena::map::ArenaMap; | ||
4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; | 5 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; |
5 | use hir_expand::{db::AstDatabase, HirFileId}; | 6 | use hir_expand::{db::AstDatabase, HirFileId}; |
6 | use syntax::SmolStr; | 7 | use syntax::SmolStr; |
@@ -16,8 +17,8 @@ use crate::{ | |||
16 | lang_item::{LangItemTarget, LangItems}, | 17 | lang_item::{LangItemTarget, LangItems}, |
17 | nameres::CrateDefMap, | 18 | nameres::CrateDefMap, |
18 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, | 19 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, |
19 | GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, | 20 | GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, StaticLoc, StructId, |
20 | TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, | 21 | StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId, |
21 | }; | 22 | }; |
22 | 23 | ||
23 | #[salsa::query_group(InternDatabaseStorage)] | 24 | #[salsa::query_group(InternDatabaseStorage)] |
@@ -92,6 +93,12 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
92 | #[salsa::invoke(GenericParams::generic_params_query)] | 93 | #[salsa::invoke(GenericParams::generic_params_query)] |
93 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; | 94 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; |
94 | 95 | ||
96 | #[salsa::invoke(Attrs::variants_attrs_query)] | ||
97 | fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>; | ||
98 | |||
99 | #[salsa::invoke(Attrs::fields_attrs_query)] | ||
100 | fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>; | ||
101 | |||
95 | #[salsa::invoke(Attrs::attrs_query)] | 102 | #[salsa::invoke(Attrs::attrs_query)] |
96 | fn attrs(&self, def: AttrDefId) -> Attrs; | 103 | fn attrs(&self, def: AttrDefId) -> Attrs; |
97 | 104 | ||
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 685a9fdf0..a5b1d90b1 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -777,9 +777,8 @@ fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String { | |||
777 | fields | 777 | fields |
778 | .iter() | 778 | .iter() |
779 | .map(|(field, _ty, doc, default)| { | 779 | .map(|(field, _ty, doc, default)| { |
780 | let name = field.replace("_", "."); | 780 | let name = format!("rust-analyzer.{}", field.replace("_", ".")); |
781 | let name = format!("rust-analyzer.{} (default: `{}`)", name, default); | 781 | format!("[[{}]]{} (default: `{}`)::\n{}\n", name, name, default, doc.join(" ")) |
782 | format!("{}::\n{}\n", name, doc.join(" ")) | ||
783 | }) | 782 | }) |
784 | .collect::<String>() | 783 | .collect::<String>() |
785 | } | 784 | } |
diff --git a/crates/ssr/src/parsing.rs b/crates/ssr/src/parsing.rs index 289affe90..3d5e4feb7 100644 --- a/crates/ssr/src/parsing.rs +++ b/crates/ssr/src/parsing.rs | |||
@@ -73,12 +73,18 @@ impl ParsedRule { | |||
73 | placeholders_by_stand_in: pattern.placeholders_by_stand_in(), | 73 | placeholders_by_stand_in: pattern.placeholders_by_stand_in(), |
74 | rules: Vec::new(), | 74 | rules: Vec::new(), |
75 | }; | 75 | }; |
76 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template.map(ast::Expr::parse)); | 76 | |
77 | let raw_template_stmt = raw_template.map(ast::Stmt::parse); | ||
78 | if let raw_template_expr @ Some(Ok(_)) = raw_template.map(ast::Expr::parse) { | ||
79 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_expr); | ||
80 | } else { | ||
81 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_stmt.clone()); | ||
82 | } | ||
77 | builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); | 83 | builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); |
78 | builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); | 84 | builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); |
79 | builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); | 85 | builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); |
80 | builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); | 86 | builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); |
81 | builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template.map(ast::Stmt::parse)); | 87 | builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template_stmt); |
82 | builder.build() | 88 | builder.build() |
83 | } | 89 | } |
84 | } | 90 | } |
@@ -89,7 +95,11 @@ struct RuleBuilder { | |||
89 | } | 95 | } |
90 | 96 | ||
91 | impl RuleBuilder { | 97 | impl RuleBuilder { |
92 | fn try_add<T: AstNode>(&mut self, pattern: Result<T, ()>, template: Option<Result<T, ()>>) { | 98 | fn try_add<T: AstNode, T2: AstNode>( |
99 | &mut self, | ||
100 | pattern: Result<T, ()>, | ||
101 | template: Option<Result<T2, ()>>, | ||
102 | ) { | ||
93 | match (pattern, template) { | 103 | match (pattern, template) { |
94 | (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { | 104 | (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { |
95 | placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), | 105 | placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), |
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs index c4149a849..db9cb8ca1 100644 --- a/crates/ssr/src/tests.rs +++ b/crates/ssr/src/tests.rs | |||
@@ -204,6 +204,53 @@ fn ssr_let_stmt_replace_expr() { | |||
204 | } | 204 | } |
205 | 205 | ||
206 | #[test] | 206 | #[test] |
207 | fn ssr_blockexpr_replace_stmt_with_stmt() { | ||
208 | assert_ssr_transform( | ||
209 | "if $a() {$b;} ==>> $b;", | ||
210 | "{ | ||
211 | if foo() { | ||
212 | bar(); | ||
213 | } | ||
214 | Ok(()) | ||
215 | }", | ||
216 | expect![[r#"{ | ||
217 | bar(); | ||
218 | Ok(()) | ||
219 | }"#]], | ||
220 | ); | ||
221 | } | ||
222 | |||
223 | #[test] | ||
224 | fn ssr_blockexpr_match_trailing_expr() { | ||
225 | assert_matches( | ||
226 | "if $a() {$b;}", | ||
227 | "{ | ||
228 | if foo() { | ||
229 | bar(); | ||
230 | } | ||
231 | }", | ||
232 | &["if foo() { | ||
233 | bar(); | ||
234 | }"], | ||
235 | ); | ||
236 | } | ||
237 | |||
238 | #[test] | ||
239 | fn ssr_blockexpr_replace_trailing_expr_with_stmt() { | ||
240 | assert_ssr_transform( | ||
241 | "if $a() {$b;} ==>> $b;", | ||
242 | "{ | ||
243 | if foo() { | ||
244 | bar(); | ||
245 | } | ||
246 | }", | ||
247 | expect![["{ | ||
248 | bar(); | ||
249 | }"]], | ||
250 | ); | ||
251 | } | ||
252 | |||
253 | #[test] | ||
207 | fn ssr_function_to_method() { | 254 | fn ssr_function_to_method() { |
208 | assert_ssr_transform( | 255 | assert_ssr_transform( |
209 | "my_function($a, $b) ==>> ($a).my_method($b)", | 256 | "my_function($a, $b) ==>> ($a).my_method($b)", |