aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-25 17:05:16 +0000
committerFlorian Diebold <[email protected]>2019-12-26 15:23:40 +0000
commit21359c3ab5fc497d11b2c0f0435c7635336a726e (patch)
treead438e045f50be776a9245ceb367598e7b60f8f9 /crates/ra_hir_def/src/nameres/collector.rs
parent8ac25f119eb45d425370d9f7f093bc206e6c4a9f (diff)
Take visibility into account for glob imports
Diffstat (limited to 'crates/ra_hir_def/src/nameres/collector.rs')
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs80
1 files changed, 56 insertions, 24 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 5b8478037..51df44d2f 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -109,7 +109,7 @@ struct MacroDirective {
109struct DefCollector<'a, DB> { 109struct DefCollector<'a, DB> {
110 db: &'a DB, 110 db: &'a DB,
111 def_map: CrateDefMap, 111 def_map: CrateDefMap,
112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::Import)>>, 112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, ResolvedVisibility)>>,
113 unresolved_imports: Vec<ImportDirective>, 113 unresolved_imports: Vec<ImportDirective>,
114 resolved_imports: Vec<ImportDirective>, 114 resolved_imports: Vec<ImportDirective>,
115 unexpanded_macros: Vec<MacroDirective>, 115 unexpanded_macros: Vec<MacroDirective>,
@@ -218,6 +218,7 @@ where
218 self.update( 218 self.update(
219 self.def_map.root, 219 self.def_map.root,
220 &[(name, PerNs::macros(macro_, ResolvedVisibility::Public))], 220 &[(name, PerNs::macros(macro_, ResolvedVisibility::Public))],
221 ResolvedVisibility::Public,
221 ); 222 );
222 } 223 }
223 } 224 }
@@ -352,7 +353,6 @@ where
352 353
353 fn record_resolved_import(&mut self, directive: &ImportDirective) { 354 fn record_resolved_import(&mut self, directive: &ImportDirective) {
354 let module_id = directive.module_id; 355 let module_id = directive.module_id;
355 let import_id = directive.import_id;
356 let import = &directive.import; 356 let import = &directive.import;
357 let def = directive.status.namespaces(); 357 let def = directive.status.namespaces();
358 let vis = self 358 let vis = self
@@ -373,28 +373,48 @@ where
373 let item_map = self.db.crate_def_map(m.krate); 373 let item_map = self.db.crate_def_map(m.krate);
374 let scope = &item_map[m.local_id].scope; 374 let scope = &item_map[m.local_id].scope;
375 375
376 // TODO: only use names we can see
377
378 // Module scoped macros is included 376 // Module scoped macros is included
379 let items = scope.collect_resolutions_with_vis(vis); 377 let items = scope
380 378 .resolutions()
381 self.update(module_id, &items); 379 // only keep visible names...
380 .map(|(n, res)| {
381 (
382 n,
383 res.filter_visibility(|v| {
384 v.visible_from_def_map(&self.def_map, module_id)
385 }),
386 )
387 })
388 .filter(|(_, res)| !res.is_none())
389 .collect::<Vec<_>>();
390
391 self.update(module_id, &items, vis);
382 } else { 392 } else {
383 // glob import from same crate => we do an initial 393 // glob import from same crate => we do an initial
384 // import, and then need to propagate any further 394 // import, and then need to propagate any further
385 // additions 395 // additions
386 let scope = &self.def_map[m.local_id].scope; 396 let scope = &self.def_map[m.local_id].scope;
387 397
388 // TODO: only use names we can see
389
390 // Module scoped macros is included 398 // Module scoped macros is included
391 let items = scope.collect_resolutions_with_vis(vis); 399 let items = scope
392 400 .resolutions()
393 self.update(module_id, &items); 401 // only keep visible names...
402 .map(|(n, res)| {
403 (
404 n,
405 res.filter_visibility(|v| {
406 v.visible_from_def_map(&self.def_map, module_id)
407 }),
408 )
409 })
410 .filter(|(_, res)| !res.is_none())
411 .collect::<Vec<_>>();
412
413 self.update(module_id, &items, vis);
394 // record the glob import in case we add further items 414 // record the glob import in case we add further items
395 let glob = self.glob_imports.entry(m.local_id).or_default(); 415 let glob = self.glob_imports.entry(m.local_id).or_default();
396 if !glob.iter().any(|it| *it == (module_id, import_id)) { 416 if !glob.iter().any(|(mid, _)| *mid == module_id) {
397 glob.push((module_id, import_id)); 417 glob.push((module_id, vis));
398 } 418 }
399 } 419 }
400 } 420 }
@@ -412,7 +432,7 @@ where
412 (name, res) 432 (name, res)
413 }) 433 })
414 .collect::<Vec<_>>(); 434 .collect::<Vec<_>>();
415 self.update(module_id, &resolutions); 435 self.update(module_id, &resolutions, vis);
416 } 436 }
417 Some(d) => { 437 Some(d) => {
418 log::debug!("glob import {:?} from non-module/enum {:?}", import, d); 438 log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -434,21 +454,29 @@ where
434 } 454 }
435 } 455 }
436 456
437 self.update(module_id, &[(name, def.with_visibility(vis))]); 457 self.update(module_id, &[(name, def)], vis);
438 } 458 }
439 None => tested_by!(bogus_paths), 459 None => tested_by!(bogus_paths),
440 } 460 }
441 } 461 }
442 } 462 }
443 463
444 fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, PerNs)]) { 464 fn update(
445 self.update_recursive(module_id, resolutions, 0) 465 &mut self,
466 module_id: LocalModuleId,
467 resolutions: &[(Name, PerNs)],
468 vis: ResolvedVisibility,
469 ) {
470 self.update_recursive(module_id, resolutions, vis, 0)
446 } 471 }
447 472
448 fn update_recursive( 473 fn update_recursive(
449 &mut self, 474 &mut self,
450 module_id: LocalModuleId, 475 module_id: LocalModuleId,
451 resolutions: &[(Name, PerNs)], 476 resolutions: &[(Name, PerNs)],
477 // All resolutions are imported with this visibility; the visibilies in
478 // the `PerNs` values are ignored and overwritten
479 vis: ResolvedVisibility,
452 depth: usize, 480 depth: usize,
453 ) { 481 ) {
454 if depth > 100 { 482 if depth > 100 {
@@ -458,7 +486,7 @@ where
458 let scope = &mut self.def_map.modules[module_id].scope; 486 let scope = &mut self.def_map.modules[module_id].scope;
459 let mut changed = false; 487 let mut changed = false;
460 for (name, res) in resolutions { 488 for (name, res) in resolutions {
461 changed |= scope.push_res(name.clone(), *res); 489 changed |= scope.push_res(name.clone(), res.with_visibility(vis));
462 } 490 }
463 491
464 if !changed { 492 if !changed {
@@ -471,9 +499,13 @@ where
471 .flat_map(|v| v.iter()) 499 .flat_map(|v| v.iter())
472 .cloned() 500 .cloned()
473 .collect::<Vec<_>>(); 501 .collect::<Vec<_>>();
474 for (glob_importing_module, _glob_import) in glob_imports { 502 for (glob_importing_module, glob_import_vis) in glob_imports {
475 // We pass the glob import so that the tracked import in those modules is that glob import 503 // we know all resolutions have the same visibility (`vis`), so we
476 self.update_recursive(glob_importing_module, resolutions, depth + 1); 504 // just need to check that once
505 if !vis.visible_from_def_map(&self.def_map, glob_importing_module) {
506 continue;
507 }
508 self.update_recursive(glob_importing_module, resolutions, glob_import_vis, depth + 1);
477 } 509 }
478 } 510 }
479 511
@@ -715,7 +747,7 @@ where
715 let def: ModuleDefId = module.into(); 747 let def: ModuleDefId = module.into();
716 let vis = ResolvedVisibility::Public; // TODO handle module visibility 748 let vis = ResolvedVisibility::Public; // TODO handle module visibility
717 self.def_collector.def_map.modules[self.module_id].scope.define_def(def); 749 self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
718 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis))]); 750 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis))], vis);
719 res 751 res
720 } 752 }
721 753
@@ -780,7 +812,7 @@ where
780 .def_map 812 .def_map
781 .resolve_visibility(self.def_collector.db, self.module_id, vis) 813 .resolve_visibility(self.def_collector.db, self.module_id, vis)
782 .unwrap_or(ResolvedVisibility::Public); 814 .unwrap_or(ResolvedVisibility::Public);
783 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis))]) 815 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis))], vis)
784 } 816 }
785 817
786 fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { 818 fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {