aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-31 15:17:08 +0000
committerFlorian Diebold <[email protected]>2020-01-11 22:33:04 +0000
commit4d75430e912491c19fb1a7b1a95ee812f6a8a124 (patch)
tree4ae28c225c8c4032f20fda876796b1e436984a2c /crates/ra_assists
parent460fa71c5528d95d34465a4db6853dc8c992b80b (diff)
Qualify some paths in 'add missing impl members'
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs49
1 files changed, 47 insertions, 2 deletions
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index f0dfe7780..2b0726869 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -139,6 +139,12 @@ fn add_missing_impl_members_inner(
139 139
140 ctx.add_assist(AssistId(assist_id), label, |edit| { 140 ctx.add_assist(AssistId(assist_id), label, |edit| {
141 let n_existing_items = impl_item_list.impl_items().count(); 141 let n_existing_items = impl_item_list.impl_items().count();
142 let module = hir::SourceAnalyzer::new(
143 db,
144 hir::InFile::new(file_id.into(), impl_node.syntax()),
145 None,
146 )
147 .module();
142 let substs = get_syntactic_substs(impl_node).unwrap_or_default(); 148 let substs = get_syntactic_substs(impl_node).unwrap_or_default();
143 let generic_def: hir::GenericDef = trait_.into(); 149 let generic_def: hir::GenericDef = trait_.into();
144 let substs_by_param: HashMap<_, _> = generic_def 150 let substs_by_param: HashMap<_, _> = generic_def
@@ -150,6 +156,10 @@ fn add_missing_impl_members_inner(
150 .collect(); 156 .collect();
151 let items = missing_items 157 let items = missing_items
152 .into_iter() 158 .into_iter()
159 .map(|it| match module {
160 Some(module) => qualify_paths(db, hir::InFile::new(file_id.into(), it), module),
161 None => it,
162 })
153 .map(|it| { 163 .map(|it| {
154 substitute_type_params(db, hir::InFile::new(file_id.into(), it), &substs_by_param) 164 substitute_type_params(db, hir::InFile::new(file_id.into(), it), &substs_by_param)
155 }) 165 })
@@ -227,6 +237,41 @@ fn substitute_type_params<N: AstNode>(
227 } 237 }
228} 238}
229 239
240use hir::PathResolution;
241
242// TODO handle partial paths, with generic args
243// TODO handle value ns?
244
245fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from: hir::Module) -> N {
246 let path_replacements = node
247 .value
248 .syntax()
249 .descendants()
250 .filter_map(ast::Path::cast)
251 .filter_map(|p| {
252 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None);
253 let resolution = analyzer.resolve_path(db, &p)?;
254 match resolution {
255 PathResolution::Def(def) => {
256 let found_path = from.find_path(db, def)?;
257 Some((p, found_path.to_ast()))
258 }
259 PathResolution::Local(_)
260 | PathResolution::TypeParam(_)
261 | PathResolution::SelfType(_) => None,
262 PathResolution::Macro(_) => None,
263 PathResolution::AssocItem(_) => None,
264 }
265 })
266 .collect::<Vec<_>>();
267
268 if path_replacements.is_empty() {
269 node.value
270 } else {
271 edit::replace_descendants(&node.value, path_replacements.into_iter())
272 }
273}
274
230/// Given an `ast::ImplBlock`, resolves the target trait (the one being 275/// Given an `ast::ImplBlock`, resolves the target trait (the one being
231/// implemented) to a `ast::TraitDef`. 276/// implemented) to a `ast::TraitDef`.
232fn resolve_target_trait_def( 277fn resolve_target_trait_def(
@@ -406,14 +451,14 @@ impl Foo for S {
406 add_missing_impl_members, 451 add_missing_impl_members,
407 " 452 "
408mod foo { 453mod foo {
409 struct Bar; 454 pub struct Bar;
410 trait Foo { fn foo(&self, bar: Bar); } 455 trait Foo { fn foo(&self, bar: Bar); }
411} 456}
412struct S; 457struct S;
413impl foo::Foo for S { <|> }", 458impl foo::Foo for S { <|> }",
414 " 459 "
415mod foo { 460mod foo {
416 struct Bar; 461 pub struct Bar;
417 trait Foo { fn foo(&self, bar: Bar); } 462 trait Foo { fn foo(&self, bar: Bar); }
418} 463}
419struct S; 464struct S;