aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/Cargo.toml2
-rw-r--r--crates/ra_hir/src/code_model.rs52
-rw-r--r--crates/ra_hir/src/semantics.rs35
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"
12rustc-hash = "1.1.0" 12rustc-hash = "1.1.0"
13either = "1.5.3" 13either = "1.5.3"
14 14
15itertools = "0.8.2"
16
15ra_syntax = { path = "../ra_syntax" } 17ra_syntax = { path = "../ra_syntax" }
16ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
17ra_prof = { path = "../ra_prof" } 19ra_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
617impl 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)]
602pub struct Const { 626pub struct Const {
603 pub(crate) id: ConstId, 627 pub(crate) id: ConstId,
@@ -617,6 +641,14 @@ impl Const {
617 } 641 }
618} 642}
619 643
644impl 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)]
621pub struct Static { 653pub struct Static {
622 pub(crate) id: StaticId, 654 pub(crate) id: StaticId,
@@ -691,6 +723,14 @@ impl TypeAlias {
691 } 723 }
692} 724}
693 725
726impl 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)]
695pub struct MacroDef { 735pub struct MacroDef {
696 pub(crate) id: MacroDefId, 736 pub(crate) id: MacroDefId,
@@ -778,6 +818,16 @@ impl AssocItem {
778 } 818 }
779} 819}
780 820
821impl 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)]
782pub enum GenericDef { 832pub 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
7use hir_def::{ 7use hir_def::{
8 resolver::{self, HasResolver, Resolver}, 8 resolver::{self, HasResolver, Resolver},
9 TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::ExpansionInfo;
12use ra_db::{FileId, FileRange}; 12use 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 }