diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir/src/semantics.rs | 35 |
3 files changed, 87 insertions, 2 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 0555a0de7..266c4cff3 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -12,6 +12,8 @@ log = "0.4.8" | |||
12 | rustc-hash = "1.1.0" | 12 | rustc-hash = "1.1.0" |
13 | either = "1.5.3" | 13 | either = "1.5.3" |
14 | 14 | ||
15 | itertools = "0.8.2" | ||
16 | |||
15 | ra_syntax = { path = "../ra_syntax" } | 17 | ra_syntax = { path = "../ra_syntax" } |
16 | ra_db = { path = "../ra_db" } | 18 | ra_db = { path = "../ra_db" } |
17 | ra_prof = { path = "../ra_prof" } | 19 | ra_prof = { path = "../ra_prof" } |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9685d6982..78c444037 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -207,10 +207,26 @@ impl Module { | |||
207 | } | 207 | } |
208 | 208 | ||
209 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 209 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
210 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { | 210 | pub fn scope( |
211 | self, | ||
212 | db: &impl HirDatabase, | ||
213 | visible_from: Option<Module>, | ||
214 | ) -> Vec<(Name, ScopeDef)> { | ||
211 | db.crate_def_map(self.id.krate)[self.id.local_id] | 215 | db.crate_def_map(self.id.krate)[self.id.local_id] |
212 | .scope | 216 | .scope |
213 | .entries() | 217 | .entries() |
218 | .filter_map(|(name, def)| { | ||
219 | if let Some(m) = visible_from { | ||
220 | let filtered = def.filter_visibility(|vis| vis.is_visible_from(db, m.id)); | ||
221 | if filtered.is_none() && !def.is_none() { | ||
222 | None | ||
223 | } else { | ||
224 | Some((name, filtered)) | ||
225 | } | ||
226 | } else { | ||
227 | Some((name, def)) | ||
228 | } | ||
229 | }) | ||
214 | .map(|(name, def)| (name.clone(), def.into())) | 230 | .map(|(name, def)| (name.clone(), def.into())) |
215 | .collect() | 231 | .collect() |
216 | } | 232 | } |
@@ -598,6 +614,14 @@ impl Function { | |||
598 | } | 614 | } |
599 | } | 615 | } |
600 | 616 | ||
617 | impl HasVisibility for Function { | ||
618 | fn visibility(&self, db: &impl HirDatabase) -> Visibility { | ||
619 | let function_data = db.function_data(self.id); | ||
620 | let visibility = &function_data.visibility; | ||
621 | visibility.resolve(db, &self.id.resolver(db)) | ||
622 | } | ||
623 | } | ||
624 | |||
601 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 625 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
602 | pub struct Const { | 626 | pub struct Const { |
603 | pub(crate) id: ConstId, | 627 | pub(crate) id: ConstId, |
@@ -617,6 +641,14 @@ impl Const { | |||
617 | } | 641 | } |
618 | } | 642 | } |
619 | 643 | ||
644 | impl HasVisibility for Const { | ||
645 | fn visibility(&self, db: &impl HirDatabase) -> Visibility { | ||
646 | let function_data = db.const_data(self.id); | ||
647 | let visibility = &function_data.visibility; | ||
648 | visibility.resolve(db, &self.id.resolver(db)) | ||
649 | } | ||
650 | } | ||
651 | |||
620 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 652 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
621 | pub struct Static { | 653 | pub struct Static { |
622 | pub(crate) id: StaticId, | 654 | pub(crate) id: StaticId, |
@@ -691,6 +723,14 @@ impl TypeAlias { | |||
691 | } | 723 | } |
692 | } | 724 | } |
693 | 725 | ||
726 | impl HasVisibility for TypeAlias { | ||
727 | fn visibility(&self, db: &impl HirDatabase) -> Visibility { | ||
728 | let function_data = db.type_alias_data(self.id); | ||
729 | let visibility = &function_data.visibility; | ||
730 | visibility.resolve(db, &self.id.resolver(db)) | ||
731 | } | ||
732 | } | ||
733 | |||
694 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 734 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
695 | pub struct MacroDef { | 735 | pub struct MacroDef { |
696 | pub(crate) id: MacroDefId, | 736 | pub(crate) id: MacroDefId, |
@@ -778,6 +818,16 @@ impl AssocItem { | |||
778 | } | 818 | } |
779 | } | 819 | } |
780 | 820 | ||
821 | impl HasVisibility for AssocItem { | ||
822 | fn visibility(&self, db: &impl HirDatabase) -> Visibility { | ||
823 | match self { | ||
824 | AssocItem::Function(f) => f.visibility(db), | ||
825 | AssocItem::Const(c) => c.visibility(db), | ||
826 | AssocItem::TypeAlias(t) => t.visibility(db), | ||
827 | } | ||
828 | } | ||
829 | } | ||
830 | |||
781 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 831 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
782 | pub enum GenericDef { | 832 | pub enum GenericDef { |
783 | Function(Function), | 833 | Function(Function), |
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 965d185a4..3782a9984 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs | |||
@@ -6,7 +6,7 @@ use std::{cell::RefCell, fmt, iter::successors}; | |||
6 | 6 | ||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | resolver::{self, HasResolver, Resolver}, | 8 | resolver::{self, HasResolver, Resolver}, |
9 | TraitId, | 9 | AsMacroCall, TraitId, |
10 | }; | 10 | }; |
11 | use hir_expand::ExpansionInfo; | 11 | use hir_expand::ExpansionInfo; |
12 | use ra_db::{FileId, FileRange}; | 12 | use ra_db::{FileId, FileRange}; |
@@ -70,6 +70,20 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
70 | Some(node) | 70 | Some(node) |
71 | } | 71 | } |
72 | 72 | ||
73 | pub fn expand_hypothetical( | ||
74 | &self, | ||
75 | actual_macro_call: &ast::MacroCall, | ||
76 | hypothetical_args: &ast::TokenTree, | ||
77 | token_to_map: SyntaxToken, | ||
78 | ) -> Option<(SyntaxNode, SyntaxToken)> { | ||
79 | let macro_call = | ||
80 | self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); | ||
81 | let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); | ||
82 | let macro_call_id = macro_call | ||
83 | .as_call_id(self.db, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; | ||
84 | hir_expand::db::expand_hypothetical(self.db, macro_call_id, hypothetical_args, token_to_map) | ||
85 | } | ||
86 | |||
73 | pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { | 87 | pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { |
74 | let parent = token.parent(); | 88 | let parent = token.parent(); |
75 | let parent = self.find_file(parent); | 89 | let parent = self.find_file(parent); |
@@ -104,6 +118,25 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
104 | node.ancestors_with_macros(self.db).map(|it| it.value) | 118 | node.ancestors_with_macros(self.db).map(|it| it.value) |
105 | } | 119 | } |
106 | 120 | ||
121 | pub fn ancestors_at_offset_with_macros( | ||
122 | &self, | ||
123 | node: &SyntaxNode, | ||
124 | offset: TextUnit, | ||
125 | ) -> impl Iterator<Item = SyntaxNode> + '_ { | ||
126 | use itertools::Itertools; | ||
127 | node.token_at_offset(offset) | ||
128 | .map(|token| self.ancestors_with_macros(token.parent())) | ||
129 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) | ||
130 | } | ||
131 | |||
132 | pub fn find_node_at_offset_with_macros<N: AstNode>( | ||
133 | &self, | ||
134 | node: &SyntaxNode, | ||
135 | offset: TextUnit, | ||
136 | ) -> Option<N> { | ||
137 | self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast) | ||
138 | } | ||
139 | |||
107 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 140 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
108 | self.analyze(expr.syntax()).type_of(self.db, &expr) | 141 | self.analyze(expr.syntax()).type_of(self.db, &expr) |
109 | } | 142 | } |