aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_analyzer.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-03-25 12:53:15 +0000
committerAleksey Kladov <[email protected]>2020-03-25 12:53:15 +0000
commit2ccfb49baba6a9a0381e8a5be77df5a3c8f46205 (patch)
treeeedee71ea4d2535dddeb2aa56966140652d6d2c1 /crates/ra_hir/src/source_analyzer.rs
parente2dd17f75b1bb5e1185acff66211e74430177592 (diff)
Always expand macros during analysis
Diffstat (limited to 'crates/ra_hir/src/source_analyzer.rs')
-rw-r--r--crates/ra_hir/src/source_analyzer.rs44
1 files changed, 26 insertions, 18 deletions
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 10c12c910..815ca158c 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -78,9 +78,15 @@ impl SourceAnalyzer {
78 } 78 }
79 } 79 }
80 80
81 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { 81 fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<ExprId> {
82 let src = InFile { file_id: self.file_id, value: expr }; 82 let src = match expr {
83 self.body_source_map.as_ref()?.node_expr(src) 83 ast::Expr::MacroCall(call) => {
84 self.expand_expr(db, InFile::new(self.file_id, call.clone()))?
85 }
86 _ => InFile::new(self.file_id, expr.clone()),
87 };
88 let sm = self.body_source_map.as_ref()?;
89 sm.node_expr(src.as_ref())
84 } 90 }
85 91
86 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { 92 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
@@ -104,14 +110,7 @@ impl SourceAnalyzer {
104 } 110 }
105 111
106 pub(crate) fn type_of(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<Type> { 112 pub(crate) fn type_of(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<Type> {
107 let expr_id = match expr { 113 let expr_id = self.expr_id(db, expr)?;
108 ast::Expr::MacroCall(call) => {
109 let expr = self.expand_expr(db, InFile::new(self.file_id, call.clone()))?;
110 self.body_source_map.as_ref()?.node_expr(expr.as_ref())
111 }
112 _ => self.expr_id(expr),
113 }?;
114
115 let ty = self.infer.as_ref()?[expr_id].clone(); 114 let ty = self.infer.as_ref()?[expr_id].clone();
116 Type::new_with_resolver(db, &self.resolver, ty) 115 Type::new_with_resolver(db, &self.resolver, ty)
117 } 116 }
@@ -122,13 +121,21 @@ impl SourceAnalyzer {
122 Type::new_with_resolver(db, &self.resolver, ty) 121 Type::new_with_resolver(db, &self.resolver, ty)
123 } 122 }
124 123
125 pub(crate) fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { 124 pub(crate) fn resolve_method_call(
126 let expr_id = self.expr_id(&call.clone().into())?; 125 &self,
126 db: &dyn HirDatabase,
127 call: &ast::MethodCallExpr,
128 ) -> Option<Function> {
129 let expr_id = self.expr_id(db, &call.clone().into())?;
127 self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) 130 self.infer.as_ref()?.method_resolution(expr_id).map(Function::from)
128 } 131 }
129 132
130 pub(crate) fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { 133 pub(crate) fn resolve_field(
131 let expr_id = self.expr_id(&field.clone().into())?; 134 &self,
135 db: &dyn HirDatabase,
136 field: &ast::FieldExpr,
137 ) -> Option<crate::StructField> {
138 let expr_id = self.expr_id(db, &field.clone().into())?;
132 self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into()) 139 self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into())
133 } 140 }
134 141
@@ -138,7 +145,7 @@ impl SourceAnalyzer {
138 field: &ast::RecordField, 145 field: &ast::RecordField,
139 ) -> Option<(crate::StructField, Option<Local>)> { 146 ) -> Option<(crate::StructField, Option<Local>)> {
140 let (expr_id, local) = match field.expr() { 147 let (expr_id, local) = match field.expr() {
141 Some(it) => (self.expr_id(&it)?, None), 148 Some(it) => (self.expr_id(db, &it)?, None),
142 None => { 149 None => {
143 let src = InFile { file_id: self.file_id, value: field }; 150 let src = InFile { file_id: self.file_id, value: field };
144 let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?; 151 let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?;
@@ -159,9 +166,10 @@ impl SourceAnalyzer {
159 166
160 pub(crate) fn resolve_record_literal( 167 pub(crate) fn resolve_record_literal(
161 &self, 168 &self,
169 db: &dyn HirDatabase,
162 record_lit: &ast::RecordLit, 170 record_lit: &ast::RecordLit,
163 ) -> Option<crate::VariantDef> { 171 ) -> Option<crate::VariantDef> {
164 let expr_id = self.expr_id(&record_lit.clone().into())?; 172 let expr_id = self.expr_id(db, &record_lit.clone().into())?;
165 self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into()) 173 self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into())
166 } 174 }
167 175
@@ -207,7 +215,7 @@ impl SourceAnalyzer {
207 path: &ast::Path, 215 path: &ast::Path,
208 ) -> Option<PathResolution> { 216 ) -> Option<PathResolution> {
209 if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { 217 if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) {
210 let expr_id = self.expr_id(&path_expr.into())?; 218 let expr_id = self.expr_id(db, &path_expr.into())?;
211 if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { 219 if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) {
212 return Some(PathResolution::AssocItem(assoc.into())); 220 return Some(PathResolution::AssocItem(assoc.into()));
213 } 221 }