diff options
Diffstat (limited to 'crates/ra_hir/src/source_analyzer.rs')
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 44 |
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 | } |