diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 29 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide/src/references/search_scope.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide_db/src/defs.rs | 80 |
4 files changed, 84 insertions, 60 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 1bdcda069..efc3502d0 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -30,6 +30,7 @@ use ra_syntax::{ | |||
30 | ast::{self, AttrsOwner}, | 30 | ast::{self, AttrsOwner}, |
31 | AstNode, | 31 | AstNode, |
32 | }; | 32 | }; |
33 | use rustc_hash::FxHashSet; | ||
33 | 34 | ||
34 | use crate::{ | 35 | use crate::{ |
35 | db::{DefDatabase, HirDatabase}, | 36 | db::{DefDatabase, HirDatabase}, |
@@ -123,10 +124,25 @@ impl_froms!( | |||
123 | BuiltinType | 124 | BuiltinType |
124 | ); | 125 | ); |
125 | 126 | ||
127 | impl ModuleDef { | ||
128 | pub fn module(self, db: &impl HirDatabase) -> Option<Module> { | ||
129 | match self { | ||
130 | ModuleDef::Module(it) => it.parent(db), | ||
131 | ModuleDef::Function(it) => Some(it.module(db)), | ||
132 | ModuleDef::Adt(it) => Some(it.module(db)), | ||
133 | ModuleDef::EnumVariant(it) => Some(it.module(db)), | ||
134 | ModuleDef::Const(it) => Some(it.module(db)), | ||
135 | ModuleDef::Static(it) => Some(it.module(db)), | ||
136 | ModuleDef::Trait(it) => Some(it.module(db)), | ||
137 | ModuleDef::TypeAlias(it) => Some(it.module(db)), | ||
138 | ModuleDef::BuiltinType(_) => None, | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
126 | pub use hir_def::{ | 143 | pub use hir_def::{ |
127 | attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, | 144 | attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, |
128 | }; | 145 | }; |
129 | use rustc_hash::FxHashSet; | ||
130 | 146 | ||
131 | impl Module { | 147 | impl Module { |
132 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 148 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -649,6 +665,17 @@ pub struct MacroDef { | |||
649 | pub(crate) id: MacroDefId, | 665 | pub(crate) id: MacroDefId, |
650 | } | 666 | } |
651 | 667 | ||
668 | impl MacroDef { | ||
669 | /// FIXME: right now, this just returns the root module of the crate that | ||
670 | /// defines this macro. The reasons for this is that macros are expanded | ||
671 | /// early, in `ra_hir_expand`, where modules simply do not exist yet. | ||
672 | pub fn module(self, db: &impl HirDatabase) -> Option<Module> { | ||
673 | let krate = self.id.krate?; | ||
674 | let module_id = db.crate_def_map(krate).root; | ||
675 | Some(Module::new(Crate { id: krate }, module_id)) | ||
676 | } | ||
677 | } | ||
678 | |||
652 | /// Invariant: `inner.as_assoc_item(db).is_some()` | 679 | /// Invariant: `inner.as_assoc_item(db).is_some()` |
653 | /// We do not actively enforce this invariant. | 680 | /// We do not actively enforce this invariant. |
654 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 681 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index d0f03d8a8..2394e68d1 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs | |||
@@ -22,7 +22,7 @@ pub(crate) fn classify_name_ref( | |||
22 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { | 22 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { |
23 | tested_by!(goto_def_for_methods); | 23 | tested_by!(goto_def_for_methods); |
24 | if let Some(func) = analyzer.resolve_method_call(&method_call) { | 24 | if let Some(func) = analyzer.resolve_method_call(&method_call) { |
25 | return Some(from_module_def(sb.db, func.into(), None)); | 25 | return Some(from_module_def(sb.db, func.into())); |
26 | } | 26 | } |
27 | } | 27 | } |
28 | 28 | ||
@@ -43,7 +43,6 @@ pub(crate) fn classify_name_ref( | |||
43 | 43 | ||
44 | // FIXME: find correct container and visibility for each case | 44 | // FIXME: find correct container and visibility for each case |
45 | let visibility = None; | 45 | let visibility = None; |
46 | let container = sb.to_module_def(name_ref.file_id.original_file(sb.db))?; | ||
47 | 46 | ||
48 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 47 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
49 | tested_by!(goto_def_for_macros); | 48 | tested_by!(goto_def_for_macros); |
@@ -51,40 +50,37 @@ pub(crate) fn classify_name_ref( | |||
51 | analyzer.resolve_macro_call(sb.db, name_ref.with_value(¯o_call)) | 50 | analyzer.resolve_macro_call(sb.db, name_ref.with_value(¯o_call)) |
52 | { | 51 | { |
53 | let kind = NameKind::Macro(macro_def); | 52 | let kind = NameKind::Macro(macro_def); |
54 | return Some(NameDefinition { kind, container, visibility }); | 53 | return Some(NameDefinition { kind, visibility }); |
55 | } | 54 | } |
56 | } | 55 | } |
57 | 56 | ||
58 | let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; | 57 | let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?; |
59 | let resolved = analyzer.resolve_path(sb.db, &path)?; | 58 | let resolved = analyzer.resolve_path(sb.db, &path)?; |
60 | let res = match resolved { | 59 | let res = match resolved { |
61 | PathResolution::Def(def) => from_module_def(sb.db, def, Some(container)), | 60 | PathResolution::Def(def) => from_module_def(sb.db, def), |
62 | PathResolution::AssocItem(item) => { | 61 | PathResolution::AssocItem(item) => { |
63 | let def = match item { | 62 | let def = match item { |
64 | hir::AssocItem::Function(it) => it.into(), | 63 | hir::AssocItem::Function(it) => it.into(), |
65 | hir::AssocItem::Const(it) => it.into(), | 64 | hir::AssocItem::Const(it) => it.into(), |
66 | hir::AssocItem::TypeAlias(it) => it.into(), | 65 | hir::AssocItem::TypeAlias(it) => it.into(), |
67 | }; | 66 | }; |
68 | from_module_def(sb.db, def, Some(container)) | 67 | from_module_def(sb.db, def) |
69 | } | 68 | } |
70 | PathResolution::Local(local) => { | 69 | PathResolution::Local(local) => { |
71 | let kind = NameKind::Local(local); | 70 | let kind = NameKind::Local(local); |
72 | let container = local.module(sb.db); | 71 | NameDefinition { kind, visibility: None } |
73 | NameDefinition { kind, container, visibility: None } | ||
74 | } | 72 | } |
75 | PathResolution::TypeParam(par) => { | 73 | PathResolution::TypeParam(par) => { |
76 | let kind = NameKind::TypeParam(par); | 74 | let kind = NameKind::TypeParam(par); |
77 | let container = par.module(sb.db); | 75 | NameDefinition { kind, visibility } |
78 | NameDefinition { kind, container, visibility } | ||
79 | } | 76 | } |
80 | PathResolution::Macro(def) => { | 77 | PathResolution::Macro(def) => { |
81 | let kind = NameKind::Macro(def); | 78 | let kind = NameKind::Macro(def); |
82 | NameDefinition { kind, container, visibility } | 79 | NameDefinition { kind, visibility } |
83 | } | 80 | } |
84 | PathResolution::SelfType(impl_block) => { | 81 | PathResolution::SelfType(impl_block) => { |
85 | let kind = NameKind::SelfType(impl_block); | 82 | let kind = NameKind::SelfType(impl_block); |
86 | let container = impl_block.module(sb.db); | 83 | NameDefinition { kind, visibility } |
87 | NameDefinition { kind, container, visibility } | ||
88 | } | 84 | } |
89 | }; | 85 | }; |
90 | Some(res) | 86 | Some(res) |
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs index 279f57be0..f9bbe64a4 100644 --- a/crates/ra_ide/src/references/search_scope.rs +++ b/crates/ra_ide/src/references/search_scope.rs | |||
@@ -19,10 +19,17 @@ pub struct SearchScope { | |||
19 | } | 19 | } |
20 | 20 | ||
21 | impl SearchScope { | 21 | impl SearchScope { |
22 | fn empty() -> SearchScope { | ||
23 | SearchScope { entries: FxHashMap::default() } | ||
24 | } | ||
25 | |||
22 | pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope { | 26 | pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope { |
23 | let _p = profile("search_scope"); | 27 | let _p = profile("search_scope"); |
24 | 28 | let module = match def.module(db) { | |
25 | let module_src = def.container.definition_source(db); | 29 | Some(it) => it, |
30 | None => return SearchScope::empty(), | ||
31 | }; | ||
32 | let module_src = module.definition_source(db); | ||
26 | let file_id = module_src.file_id.original_file(db); | 33 | let file_id = module_src.file_id.original_file(db); |
27 | 34 | ||
28 | if let NameKind::Local(var) = def.kind { | 35 | if let NameKind::Local(var) = def.kind { |
@@ -39,7 +46,7 @@ impl SearchScope { | |||
39 | let vis = def.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); | 46 | let vis = def.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); |
40 | 47 | ||
41 | if vis.as_str() == "pub(super)" { | 48 | if vis.as_str() == "pub(super)" { |
42 | if let Some(parent_module) = def.container.parent(db) { | 49 | if let Some(parent_module) = module.parent(db) { |
43 | let mut res = FxHashMap::default(); | 50 | let mut res = FxHashMap::default(); |
44 | let parent_src = parent_module.definition_source(db); | 51 | let parent_src = parent_module.definition_source(db); |
45 | let file_id = parent_src.file_id.original_file(db); | 52 | let file_id = parent_src.file_id.original_file(db); |
@@ -72,7 +79,7 @@ impl SearchScope { | |||
72 | return SearchScope::new(res); | 79 | return SearchScope::new(res); |
73 | } | 80 | } |
74 | if vis.as_str() == "pub" { | 81 | if vis.as_str() == "pub" { |
75 | let krate = def.container.krate(); | 82 | let krate = module.krate(); |
76 | for rev_dep in krate.reverse_dependencies(db) { | 83 | for rev_dep in krate.reverse_dependencies(db) { |
77 | let root_file = rev_dep.root_file(db); | 84 | let root_file = rev_dep.root_file(db); |
78 | let source_root_id = db.file_source_root(root_file); | 85 | let source_root_id = db.file_source_root(root_file); |
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 030f44f86..cc772de51 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -32,10 +32,22 @@ pub struct NameDefinition { | |||
32 | pub visibility: Option<ast::Visibility>, | 32 | pub visibility: Option<ast::Visibility>, |
33 | /// FIXME: this doesn't really make sense. For example, builtin types don't | 33 | /// FIXME: this doesn't really make sense. For example, builtin types don't |
34 | /// really have a module. | 34 | /// really have a module. |
35 | pub container: Module, | ||
36 | pub kind: NameKind, | 35 | pub kind: NameKind, |
37 | } | 36 | } |
38 | 37 | ||
38 | impl NameDefinition { | ||
39 | pub fn module(&self, db: &RootDatabase) -> Option<Module> { | ||
40 | match self.kind { | ||
41 | NameKind::Macro(it) => it.module(db), | ||
42 | NameKind::StructField(it) => Some(it.parent_def(db).module(db)), | ||
43 | NameKind::ModuleDef(it) => it.module(db), | ||
44 | NameKind::SelfType(it) => Some(it.module(db)), | ||
45 | NameKind::Local(it) => Some(it.module(db)), | ||
46 | NameKind::TypeParam(it) => Some(it.module(db)), | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
39 | pub fn classify_name( | 51 | pub fn classify_name( |
40 | sb: &mut SourceBinder<RootDatabase>, | 52 | sb: &mut SourceBinder<RootDatabase>, |
41 | name: InFile<&ast::Name>, | 53 | name: InFile<&ast::Name>, |
@@ -50,7 +62,6 @@ pub fn classify_name( | |||
50 | let local = sb.to_def(src)?; | 62 | let local = sb.to_def(src)?; |
51 | Some(NameDefinition { | 63 | Some(NameDefinition { |
52 | visibility: None, | 64 | visibility: None, |
53 | container: local.module(sb.db), | ||
54 | kind: NameKind::Local(local), | 65 | kind: NameKind::Local(local), |
55 | }) | 66 | }) |
56 | }, | 67 | }, |
@@ -61,57 +72,54 @@ pub fn classify_name( | |||
61 | }, | 72 | }, |
62 | ast::Module(it) => { | 73 | ast::Module(it) => { |
63 | let def = sb.to_def(name.with_value(it))?; | 74 | let def = sb.to_def(name.with_value(it))?; |
64 | Some(from_module_def(sb.db, def.into(), None)) | 75 | Some(from_module_def(sb.db, def.into())) |
65 | }, | 76 | }, |
66 | ast::StructDef(it) => { | 77 | ast::StructDef(it) => { |
67 | let src = name.with_value(it); | 78 | let src = name.with_value(it); |
68 | let def: hir::Struct = sb.to_def(src)?; | 79 | let def: hir::Struct = sb.to_def(src)?; |
69 | Some(from_module_def(sb.db, def.into(), None)) | 80 | Some(from_module_def(sb.db, def.into())) |
70 | }, | 81 | }, |
71 | ast::EnumDef(it) => { | 82 | ast::EnumDef(it) => { |
72 | let src = name.with_value(it); | 83 | let src = name.with_value(it); |
73 | let def: hir::Enum = sb.to_def(src)?; | 84 | let def: hir::Enum = sb.to_def(src)?; |
74 | Some(from_module_def(sb.db, def.into(), None)) | 85 | Some(from_module_def(sb.db, def.into())) |
75 | }, | 86 | }, |
76 | ast::TraitDef(it) => { | 87 | ast::TraitDef(it) => { |
77 | let src = name.with_value(it); | 88 | let src = name.with_value(it); |
78 | let def: hir::Trait = sb.to_def(src)?; | 89 | let def: hir::Trait = sb.to_def(src)?; |
79 | Some(from_module_def(sb.db, def.into(), None)) | 90 | Some(from_module_def(sb.db, def.into())) |
80 | }, | 91 | }, |
81 | ast::StaticDef(it) => { | 92 | ast::StaticDef(it) => { |
82 | let src = name.with_value(it); | 93 | let src = name.with_value(it); |
83 | let def: hir::Static = sb.to_def(src)?; | 94 | let def: hir::Static = sb.to_def(src)?; |
84 | Some(from_module_def(sb.db, def.into(), None)) | 95 | Some(from_module_def(sb.db, def.into())) |
85 | }, | 96 | }, |
86 | ast::EnumVariant(it) => { | 97 | ast::EnumVariant(it) => { |
87 | let src = name.with_value(it); | 98 | let src = name.with_value(it); |
88 | let def: hir::EnumVariant = sb.to_def(src)?; | 99 | let def: hir::EnumVariant = sb.to_def(src)?; |
89 | Some(from_module_def(sb.db, def.into(), None)) | 100 | Some(from_module_def(sb.db, def.into())) |
90 | }, | 101 | }, |
91 | ast::FnDef(it) => { | 102 | ast::FnDef(it) => { |
92 | let src = name.with_value(it); | 103 | let src = name.with_value(it); |
93 | let def: hir::Function = sb.to_def(src)?; | 104 | let def: hir::Function = sb.to_def(src)?; |
94 | Some(from_module_def(sb.db, def.into(), None)) | 105 | Some(from_module_def(sb.db, def.into())) |
95 | }, | 106 | }, |
96 | ast::ConstDef(it) => { | 107 | ast::ConstDef(it) => { |
97 | let src = name.with_value(it); | 108 | let src = name.with_value(it); |
98 | let def: hir::Const = sb.to_def(src)?; | 109 | let def: hir::Const = sb.to_def(src)?; |
99 | Some(from_module_def(sb.db, def.into(), None)) | 110 | Some(from_module_def(sb.db, def.into())) |
100 | }, | 111 | }, |
101 | ast::TypeAliasDef(it) => { | 112 | ast::TypeAliasDef(it) => { |
102 | let src = name.with_value(it); | 113 | let src = name.with_value(it); |
103 | let def: hir::TypeAlias = sb.to_def(src)?; | 114 | let def: hir::TypeAlias = sb.to_def(src)?; |
104 | Some(from_module_def(sb.db, def.into(), None)) | 115 | Some(from_module_def(sb.db, def.into())) |
105 | }, | 116 | }, |
106 | ast::MacroCall(it) => { | 117 | ast::MacroCall(it) => { |
107 | let src = name.with_value(it); | 118 | let src = name.with_value(it); |
108 | let def = sb.to_def(src.clone())?; | 119 | let def = sb.to_def(src.clone())?; |
109 | 120 | ||
110 | let module = sb.to_module_def(src.file_id.original_file(sb.db))?; | ||
111 | |||
112 | Some(NameDefinition { | 121 | Some(NameDefinition { |
113 | visibility: None, | 122 | visibility: None, |
114 | container: module, | ||
115 | kind: NameKind::Macro(def), | 123 | kind: NameKind::Macro(def), |
116 | }) | 124 | }) |
117 | }, | 125 | }, |
@@ -120,7 +128,6 @@ pub fn classify_name( | |||
120 | let def = sb.to_def(src)?; | 128 | let def = sb.to_def(src)?; |
121 | Some(NameDefinition { | 129 | Some(NameDefinition { |
122 | visibility: None, | 130 | visibility: None, |
123 | container: def.module(sb.db), | ||
124 | kind: NameKind::TypeParam(def), | 131 | kind: NameKind::TypeParam(def), |
125 | }) | 132 | }) |
126 | }, | 133 | }, |
@@ -132,41 +139,28 @@ pub fn classify_name( | |||
132 | pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { | 139 | pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition { |
133 | let kind = NameKind::StructField(field); | 140 | let kind = NameKind::StructField(field); |
134 | let parent = field.parent_def(db); | 141 | let parent = field.parent_def(db); |
135 | let container = parent.module(db); | ||
136 | let visibility = match parent { | 142 | let visibility = match parent { |
137 | VariantDef::Struct(s) => s.source(db).value.visibility(), | 143 | VariantDef::Struct(s) => s.source(db).value.visibility(), |
138 | VariantDef::Union(e) => e.source(db).value.visibility(), | 144 | VariantDef::Union(e) => e.source(db).value.visibility(), |
139 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), | 145 | VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), |
140 | }; | 146 | }; |
141 | NameDefinition { kind, container, visibility } | 147 | NameDefinition { kind, visibility } |
142 | } | 148 | } |
143 | 149 | ||
144 | pub fn from_module_def( | 150 | pub fn from_module_def(db: &RootDatabase, def: ModuleDef) -> NameDefinition { |
145 | db: &RootDatabase, | ||
146 | def: ModuleDef, | ||
147 | module: Option<Module>, | ||
148 | ) -> NameDefinition { | ||
149 | let kind = NameKind::ModuleDef(def); | 151 | let kind = NameKind::ModuleDef(def); |
150 | let (container, visibility) = match def { | 152 | let visibility = match def { |
151 | ModuleDef::Module(it) => { | 153 | ModuleDef::Module(it) => it.declaration_source(db).and_then(|s| s.value.visibility()), |
152 | let container = it.parent(db).or_else(|| Some(it)).unwrap(); | 154 | ModuleDef::EnumVariant(it) => it.source(db).value.parent_enum().visibility(), |
153 | let visibility = it.declaration_source(db).and_then(|s| s.value.visibility()); | 155 | ModuleDef::Function(it) => it.source(db).value.visibility(), |
154 | (container, visibility) | 156 | ModuleDef::Const(it) => it.source(db).value.visibility(), |
155 | } | 157 | ModuleDef::Static(it) => it.source(db).value.visibility(), |
156 | ModuleDef::EnumVariant(it) => { | 158 | ModuleDef::Trait(it) => it.source(db).value.visibility(), |
157 | let container = it.module(db); | 159 | ModuleDef::TypeAlias(it) => it.source(db).value.visibility(), |
158 | let visibility = it.source(db).value.parent_enum().visibility(); | 160 | ModuleDef::Adt(Adt::Struct(it)) => it.source(db).value.visibility(), |
159 | (container, visibility) | 161 | ModuleDef::Adt(Adt::Union(it)) => it.source(db).value.visibility(), |
160 | } | 162 | ModuleDef::Adt(Adt::Enum(it)) => it.source(db).value.visibility(), |
161 | ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()), | 163 | ModuleDef::BuiltinType(..) => None, |
162 | ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()), | ||
163 | ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()), | ||
164 | ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()), | ||
165 | ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()), | ||
166 | ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()), | ||
167 | ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()), | ||
168 | ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()), | ||
169 | ModuleDef::BuiltinType(..) => (module.unwrap(), None), | ||
170 | }; | 164 | }; |
171 | NameDefinition { kind, container, visibility } | 165 | NameDefinition { kind, visibility } |
172 | } | 166 | } |