aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/utils.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-17 09:34:08 +0000
committerGitHub <[email protected]>2020-02-17 09:34:08 +0000
commit8d8d542dfa1d3b83088a1f48a91665e95fd008cc (patch)
tree495e3d223f595404e46d5e58b426cda4b0c633bc /crates/ra_assists/src/utils.rs
parent953dbe3e02fa87bab2f12452746e6c50a47ac153 (diff)
parent057d0bee5516dc7cba71479b27227c5ad22140ee (diff)
Merge #3108
3108: Magic Completion for `impl Trait for` Associated Items r=matklad a=kdelorey # Summary This PR adds a set of magic completions to auto complete associated trait items (functions/consts/types). ![Associated Trait Impl](https://user-images.githubusercontent.com/2295721/74493144-d8f1af00-4e96-11ea-93a4-82725bf89646.gif) ## Notes Since the assist and completion share the same logic when figuring out the associated items that are missing, a shared utility was created in the `ra_assists::utils` module. Resolves #1046 As this is my first PR to the rust-analyzer project, I'm new to the codebase, feedback welcomed! Co-authored-by: Kevin DeLorey <[email protected]>
Diffstat (limited to 'crates/ra_assists/src/utils.rs')
-rw-r--r--crates/ra_assists/src/utils.rs75
1 files changed, 73 insertions, 2 deletions
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs
index 0d5722295..6ff44c95c 100644
--- a/crates/ra_assists/src/utils.rs
+++ b/crates/ra_assists/src/utils.rs
@@ -1,10 +1,81 @@
1//! Assorted functions shared by several assists. 1//! Assorted functions shared by several assists.
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 ast::{self, make}, 4 ast::{self, make, NameOwner},
5 T, 5 AstNode, T,
6}; 6};
7 7
8use hir::db::HirDatabase;
9use rustc_hash::FxHashSet;
10
11pub fn get_missing_impl_items(
12 db: &impl HirDatabase,
13 analyzer: &hir::SourceAnalyzer,
14 impl_block: &ast::ImplBlock,
15) -> Vec<hir::AssocItem> {
16 // Names must be unique between constants and functions. However, type aliases
17 // may share the same name as a function or constant.
18 let mut impl_fns_consts = FxHashSet::default();
19 let mut impl_type = FxHashSet::default();
20
21 if let Some(item_list) = impl_block.item_list() {
22 for item in item_list.impl_items() {
23 match item {
24 ast::ImplItem::FnDef(f) => {
25 if let Some(n) = f.name() {
26 impl_fns_consts.insert(n.syntax().to_string());
27 }
28 }
29
30 ast::ImplItem::TypeAliasDef(t) => {
31 if let Some(n) = t.name() {
32 impl_type.insert(n.syntax().to_string());
33 }
34 }
35
36 ast::ImplItem::ConstDef(c) => {
37 if let Some(n) = c.name() {
38 impl_fns_consts.insert(n.syntax().to_string());
39 }
40 }
41 }
42 }
43 }
44
45 resolve_target_trait(db, analyzer, impl_block).map_or(vec![], |target_trait| {
46 target_trait
47 .items(db)
48 .iter()
49 .filter(|i| match i {
50 hir::AssocItem::Function(f) => !impl_fns_consts.contains(&f.name(db).to_string()),
51 hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(db).to_string()),
52 hir::AssocItem::Const(c) => c
53 .name(db)
54 .map(|n| !impl_fns_consts.contains(&n.to_string()))
55 .unwrap_or_default(),
56 })
57 .cloned()
58 .collect()
59 })
60}
61
62pub(crate) fn resolve_target_trait(
63 db: &impl HirDatabase,
64 analyzer: &hir::SourceAnalyzer,
65 impl_block: &ast::ImplBlock,
66) -> Option<hir::Trait> {
67 let ast_path = impl_block
68 .target_trait()
69 .map(|it| it.syntax().clone())
70 .and_then(ast::PathType::cast)?
71 .path()?;
72
73 match analyzer.resolve_path(db, &ast_path) {
74 Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def),
75 _ => None,
76 }
77}
78
8pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr { 79pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
9 if let Some(expr) = invert_special_case(&expr) { 80 if let Some(expr) = invert_special_case(&expr) {
10 return expr; 81 return expr;