diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 26 |
3 files changed, 45 insertions, 4 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 76d8f85f1..488f74cfb 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -118,7 +118,7 @@ impl_froms!( | |||
118 | BuiltinType | 118 | BuiltinType |
119 | ); | 119 | ); |
120 | 120 | ||
121 | pub use hir_def::attr::Attrs; | 121 | pub use hir_def::{attr::Attrs, visibility::Visibility}; |
122 | 122 | ||
123 | impl Module { | 123 | impl Module { |
124 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 124 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -255,6 +255,15 @@ impl StructField { | |||
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | impl HasVisibility for StructField { | ||
259 | fn visibility(&self, db: &impl HirDatabase) -> Visibility { | ||
260 | let variant_data = self.parent.variant_data(db); | ||
261 | let visibility = &variant_data.fields()[self.id].visibility; | ||
262 | let parent_id: hir_def::VariantId = self.parent.into(); | ||
263 | visibility.resolve(db, &parent_id.resolver(db)) | ||
264 | } | ||
265 | } | ||
266 | |||
258 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 267 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
259 | pub struct Struct { | 268 | pub struct Struct { |
260 | pub(crate) id: StructId, | 269 | pub(crate) id: StructId, |
@@ -1041,3 +1050,11 @@ impl<T: Into<AttrDef> + Copy> Docs for T { | |||
1041 | db.documentation(def.into()) | 1050 | db.documentation(def.into()) |
1042 | } | 1051 | } |
1043 | } | 1052 | } |
1053 | |||
1054 | pub trait HasVisibility { | ||
1055 | fn visibility(&self, db: &impl HirDatabase) -> Visibility; | ||
1056 | fn is_visible_from(&self, db: &impl HirDatabase, module: Module) -> bool { | ||
1057 | let vis = self.visibility(db); | ||
1058 | vis.is_visible_from(db, module.id) | ||
1059 | } | ||
1060 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 0008a8858..3d13978d4 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -40,8 +40,8 @@ mod from_source; | |||
40 | pub use crate::{ | 40 | pub use crate::{ |
41 | code_model::{ | 41 | code_model::{ |
42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, | 42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, |
43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef, | 43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, HasVisibility, ImplBlock, Local, |
44 | Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, | 44 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, |
45 | TypeParam, Union, VariantDef, | 45 | TypeParam, Union, VariantDef, |
46 | }, | 46 | }, |
47 | from_source::FromSource, | 47 | from_source::FromSource, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 85b378483..2c422af8b 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -215,8 +215,32 @@ impl SourceAnalyzer { | |||
215 | self.body_source_map.as_ref()?.node_pat(src) | 215 | self.body_source_map.as_ref()?.node_pat(src) |
216 | } | 216 | } |
217 | 217 | ||
218 | fn expand_expr( | ||
219 | &self, | ||
220 | db: &impl HirDatabase, | ||
221 | expr: InFile<&ast::Expr>, | ||
222 | ) -> Option<InFile<ast::Expr>> { | ||
223 | let macro_call = ast::MacroCall::cast(expr.value.syntax().clone())?; | ||
224 | let macro_file = | ||
225 | self.body_source_map.as_ref()?.node_macro_file(expr.with_value(¯o_call))?; | ||
226 | let expanded = db.parse_or_expand(macro_file)?; | ||
227 | let kind = expanded.kind(); | ||
228 | let expr = InFile::new(macro_file, ast::Expr::cast(expanded)?); | ||
229 | |||
230 | if ast::MacroCall::can_cast(kind) { | ||
231 | self.expand_expr(db, expr.as_ref()) | ||
232 | } else { | ||
233 | Some(expr) | ||
234 | } | ||
235 | } | ||
236 | |||
218 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { | 237 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { |
219 | let expr_id = self.expr_id(expr)?; | 238 | let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) { |
239 | self.body_source_map.as_ref()?.node_expr(expr.as_ref())? | ||
240 | } else { | ||
241 | self.expr_id(expr)? | ||
242 | }; | ||
243 | |||
220 | let ty = self.infer.as_ref()?[expr_id].clone(); | 244 | let ty = self.infer.as_ref()?[expr_id].clone(); |
221 | let environment = TraitEnvironment::lower(db, &self.resolver); | 245 | let environment = TraitEnvironment::lower(db, &self.resolver); |
222 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | 246 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) |