aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/code_model.rs12
-rw-r--r--crates/hir_def/src/attr.rs56
-rw-r--r--crates/hir_def/src/db.rs11
-rw-r--r--crates/rust-analyzer/src/config.rs5
-rw-r--r--crates/ssr/src/parsing.rs16
-rw-r--r--crates/ssr/src/tests.rs47
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
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use arena::map::ArenaMap;
5use base_db::CrateId; 6use base_db::CrateId;
6use cfg::{CfgExpr, CfgOptions}; 7use cfg::{CfgExpr, CfgOptions};
7use either::Either; 8use 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.
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use arena::map::ArenaMap;
4use base_db::{salsa, CrateId, SourceDatabase, Upcast}; 5use base_db::{salsa, CrateId, SourceDatabase, Upcast};
5use hir_expand::{db::AstDatabase, HirFileId}; 6use hir_expand::{db::AstDatabase, HirFileId};
6use syntax::SmolStr; 7use 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
91impl RuleBuilder { 97impl 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]
207fn 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]
224fn 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]
239fn 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]
207fn ssr_function_to_method() { 254fn 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)",