diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir/src/source_binder.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 213 |
1 files changed, 90 insertions, 123 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 76c493f1a..85b378483 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -7,19 +7,26 @@ | |||
7 | //! purely for "IDE needs". | 7 | //! purely for "IDE needs". |
8 | use std::sync::Arc; | 8 | use std::sync::Arc; |
9 | 9 | ||
10 | use either::Either; | ||
10 | use hir_def::{ | 11 | use hir_def::{ |
11 | body::{ | 12 | body::{ |
12 | scope::{ExprScopes, ScopeId}, | 13 | scope::{ExprScopes, ScopeId}, |
13 | BodySourceMap, | 14 | BodySourceMap, |
14 | }, | 15 | }, |
15 | expr::{ExprId, PatId}, | 16 | expr::{ExprId, PatId}, |
16 | path::known, | 17 | nameres::ModuleSource, |
18 | path::path, | ||
17 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 19 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
18 | AssocItemId, DefWithBodyId, | 20 | AssocItemId, DefWithBodyId, |
19 | }; | 21 | }; |
20 | use hir_expand::{ | 22 | use hir_expand::{ |
21 | hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, | 23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
22 | }; | 24 | }; |
25 | use hir_ty::{ | ||
26 | method_resolution::{self, implements_trait}, | ||
27 | Canonical, InEnvironment, InferenceResult, TraitEnvironment, Ty, | ||
28 | }; | ||
29 | use ra_prof::profile; | ||
23 | use ra_syntax::{ | 30 | use ra_syntax::{ |
24 | ast::{self, AstNode}, | 31 | ast::{self, AstNode}, |
25 | match_ast, AstPtr, | 32 | match_ast, AstPtr, |
@@ -28,16 +35,12 @@ use ra_syntax::{ | |||
28 | }; | 35 | }; |
29 | 36 | ||
30 | use crate::{ | 37 | use crate::{ |
31 | db::HirDatabase, | 38 | db::HirDatabase, Adt, AssocItem, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, |
32 | ty::{ | 39 | ImplBlock, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, |
33 | method_resolution::{self, implements_trait}, | 40 | TypeParam, |
34 | InEnvironment, TraitEnvironment, Ty, | ||
35 | }, | ||
36 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | ||
37 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 43 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> { |
41 | match_ast! { | 44 | match_ast! { |
42 | match (node.value) { | 45 | match (node.value) { |
43 | ast::Module(it) => { | 46 | ast::Module(it) => { |
@@ -45,7 +48,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
45 | Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) | 48 | Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) |
46 | }, | 49 | }, |
47 | ast::SourceFile(it) => { | 50 | ast::SourceFile(it) => { |
48 | let src = node.with_value(crate::ModuleSource::SourceFile(it)); | 51 | let src = node.with_value(ModuleSource::SourceFile(it)); |
49 | Some(crate::Module::from_definition(db, src)?.id.resolver(db)) | 52 | Some(crate::Module::from_definition(db, src)?.id.resolver(db)) |
50 | }, | 53 | }, |
51 | ast::StructDef(it) => { | 54 | ast::StructDef(it) => { |
@@ -56,6 +59,14 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
56 | let src = node.with_value(it); | 59 | let src = node.with_value(it); |
57 | Some(Enum::from_source(db, src)?.id.resolver(db)) | 60 | Some(Enum::from_source(db, src)?.id.resolver(db)) |
58 | }, | 61 | }, |
62 | ast::ImplBlock(it) => { | ||
63 | let src = node.with_value(it); | ||
64 | Some(ImplBlock::from_source(db, src)?.id.resolver(db)) | ||
65 | }, | ||
66 | ast::TraitDef(it) => { | ||
67 | let src = node.with_value(it); | ||
68 | Some(Trait::from_source(db, src)?.id.resolver(db)) | ||
69 | }, | ||
59 | _ => match node.value.kind() { | 70 | _ => match node.value.kind() { |
60 | FN_DEF | CONST_DEF | STATIC_DEF => { | 71 | FN_DEF | CONST_DEF | STATIC_DEF => { |
61 | let def = def_with_body_from_child_node(db, node)?; | 72 | let def = def_with_body_from_child_node(db, node)?; |
@@ -71,14 +82,16 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - | |||
71 | 82 | ||
72 | fn def_with_body_from_child_node( | 83 | fn def_with_body_from_child_node( |
73 | db: &impl HirDatabase, | 84 | db: &impl HirDatabase, |
74 | child: Source<&SyntaxNode>, | 85 | child: InFile<&SyntaxNode>, |
75 | ) -> Option<DefWithBody> { | 86 | ) -> Option<DefWithBody> { |
76 | child.value.ancestors().find_map(|node| { | 87 | let _p = profile("def_with_body_from_child_node"); |
88 | child.cloned().ancestors_with_macros(db).find_map(|node| { | ||
89 | let n = &node.value; | ||
77 | match_ast! { | 90 | match_ast! { |
78 | match node { | 91 | match n { |
79 | ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 92 | ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
80 | ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 93 | ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
81 | ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); }, | 94 | ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); }, |
82 | _ => { None }, | 95 | _ => { None }, |
83 | } | 96 | } |
84 | } | 97 | } |
@@ -93,7 +106,7 @@ pub struct SourceAnalyzer { | |||
93 | resolver: Resolver, | 106 | resolver: Resolver, |
94 | body_owner: Option<DefWithBody>, | 107 | body_owner: Option<DefWithBody>, |
95 | body_source_map: Option<Arc<BodySourceMap>>, | 108 | body_source_map: Option<Arc<BodySourceMap>>, |
96 | infer: Option<Arc<crate::ty::InferenceResult>>, | 109 | infer: Option<Arc<InferenceResult>>, |
97 | scopes: Option<Arc<ExprScopes>>, | 110 | scopes: Option<Arc<ExprScopes>>, |
98 | } | 111 | } |
99 | 112 | ||
@@ -104,7 +117,7 @@ pub enum PathResolution { | |||
104 | /// A local binding (only value namespace) | 117 | /// A local binding (only value namespace) |
105 | Local(Local), | 118 | Local(Local), |
106 | /// A generic parameter | 119 | /// A generic parameter |
107 | GenericParam(GenericParam), | 120 | TypeParam(TypeParam), |
108 | SelfType(crate::ImplBlock), | 121 | SelfType(crate::ImplBlock), |
109 | Macro(MacroDef), | 122 | Macro(MacroDef), |
110 | AssocItem(crate::AssocItem), | 123 | AssocItem(crate::AssocItem), |
@@ -132,8 +145,8 @@ pub struct ReferenceDescriptor { | |||
132 | pub name: String, | 145 | pub name: String, |
133 | } | 146 | } |
134 | 147 | ||
148 | #[derive(Debug)] | ||
135 | pub struct Expansion { | 149 | pub struct Expansion { |
136 | macro_file_kind: MacroFileKind, | ||
137 | macro_call_id: MacroCallId, | 150 | macro_call_id: MacroCallId, |
138 | } | 151 | } |
139 | 152 | ||
@@ -141,23 +154,24 @@ impl Expansion { | |||
141 | pub fn map_token_down( | 154 | pub fn map_token_down( |
142 | &self, | 155 | &self, |
143 | db: &impl HirDatabase, | 156 | db: &impl HirDatabase, |
144 | token: Source<&SyntaxToken>, | 157 | token: InFile<&SyntaxToken>, |
145 | ) -> Option<Source<SyntaxToken>> { | 158 | ) -> Option<InFile<SyntaxToken>> { |
146 | let exp_info = self.file_id().expansion_info(db)?; | 159 | let exp_info = self.file_id().expansion_info(db)?; |
147 | exp_info.map_token_down(token) | 160 | exp_info.map_token_down(token) |
148 | } | 161 | } |
149 | 162 | ||
150 | pub fn file_id(&self) -> HirFileId { | 163 | pub fn file_id(&self) -> HirFileId { |
151 | self.macro_call_id.as_file(self.macro_file_kind) | 164 | self.macro_call_id.as_file() |
152 | } | 165 | } |
153 | } | 166 | } |
154 | 167 | ||
155 | impl SourceAnalyzer { | 168 | impl SourceAnalyzer { |
156 | pub fn new( | 169 | pub fn new( |
157 | db: &impl HirDatabase, | 170 | db: &impl HirDatabase, |
158 | node: Source<&SyntaxNode>, | 171 | node: InFile<&SyntaxNode>, |
159 | offset: Option<TextUnit>, | 172 | offset: Option<TextUnit>, |
160 | ) -> SourceAnalyzer { | 173 | ) -> SourceAnalyzer { |
174 | let _p = profile("SourceAnalyzer::new"); | ||
161 | let def_with_body = def_with_body_from_child_node(db, node); | 175 | let def_with_body = def_with_body_from_child_node(db, node); |
162 | if let Some(def) = def_with_body { | 176 | if let Some(def) = def_with_body { |
163 | let (_body, source_map) = db.body_with_source_map(def.into()); | 177 | let (_body, source_map) = db.body_with_source_map(def.into()); |
@@ -192,12 +206,12 @@ impl SourceAnalyzer { | |||
192 | } | 206 | } |
193 | 207 | ||
194 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { | 208 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { |
195 | let src = Source { file_id: self.file_id, value: expr }; | 209 | let src = InFile { file_id: self.file_id, value: expr }; |
196 | self.body_source_map.as_ref()?.node_expr(src) | 210 | self.body_source_map.as_ref()?.node_expr(src) |
197 | } | 211 | } |
198 | 212 | ||
199 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { | 213 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { |
200 | let src = Source { file_id: self.file_id, value: pat }; | 214 | let src = InFile { file_id: self.file_id, value: pat }; |
201 | self.body_source_map.as_ref()?.node_pat(src) | 215 | self.body_source_map.as_ref()?.node_pat(src) |
202 | } | 216 | } |
203 | 217 | ||
@@ -226,7 +240,13 @@ impl SourceAnalyzer { | |||
226 | } | 240 | } |
227 | 241 | ||
228 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | 242 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { |
229 | let expr_id = self.expr_id(&field.expr()?)?; | 243 | let expr_id = match field.expr() { |
244 | Some(it) => self.expr_id(&it)?, | ||
245 | None => { | ||
246 | let src = InFile { file_id: self.file_id, value: field }; | ||
247 | self.body_source_map.as_ref()?.field_init_shorthand_expr(src)? | ||
248 | } | ||
249 | }; | ||
230 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) | 250 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) |
231 | } | 251 | } |
232 | 252 | ||
@@ -243,11 +263,11 @@ impl SourceAnalyzer { | |||
243 | pub fn resolve_macro_call( | 263 | pub fn resolve_macro_call( |
244 | &self, | 264 | &self, |
245 | db: &impl HirDatabase, | 265 | db: &impl HirDatabase, |
246 | macro_call: Source<&ast::MacroCall>, | 266 | macro_call: InFile<&ast::MacroCall>, |
247 | ) -> Option<MacroDef> { | 267 | ) -> Option<MacroDef> { |
248 | let hygiene = Hygiene::new(db, macro_call.file_id); | 268 | let hygiene = Hygiene::new(db, macro_call.file_id); |
249 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; | 269 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; |
250 | self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) | 270 | self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) |
251 | } | 271 | } |
252 | 272 | ||
253 | pub fn resolve_hir_path( | 273 | pub fn resolve_hir_path( |
@@ -255,43 +275,42 @@ impl SourceAnalyzer { | |||
255 | db: &impl HirDatabase, | 275 | db: &impl HirDatabase, |
256 | path: &crate::Path, | 276 | path: &crate::Path, |
257 | ) -> Option<PathResolution> { | 277 | ) -> Option<PathResolution> { |
258 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 278 | let types = |
259 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 279 | self.resolver.resolve_path_in_type_ns_fully(db, path.mod_path()).map(|ty| match ty { |
260 | TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { | 280 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
261 | parent: self.resolver.generic_def().unwrap(), | 281 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
262 | idx, | 282 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
263 | }), | 283 | PathResolution::Def(Adt::from(it).into()) |
264 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | ||
265 | PathResolution::Def(Adt::from(it).into()) | ||
266 | } | ||
267 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
268 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | ||
269 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | ||
270 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | ||
271 | }); | ||
272 | let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { | ||
273 | let res = match val { | ||
274 | ValueNs::LocalBinding(pat_id) => { | ||
275 | let var = Local { parent: self.body_owner?, pat_id }; | ||
276 | PathResolution::Local(var) | ||
277 | } | 284 | } |
278 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), | 285 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), |
279 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | 286 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
280 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | 287 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
281 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | 288 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
282 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 289 | }); |
283 | }; | 290 | let values = |
284 | Some(res) | 291 | self.resolver.resolve_path_in_value_ns_fully(db, path.mod_path()).and_then(|val| { |
285 | }); | 292 | let res = match val { |
293 | ValueNs::LocalBinding(pat_id) => { | ||
294 | let var = Local { parent: self.body_owner?, pat_id }; | ||
295 | PathResolution::Local(var) | ||
296 | } | ||
297 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), | ||
298 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | ||
299 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | ||
300 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | ||
301 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
302 | }; | ||
303 | Some(res) | ||
304 | }); | ||
286 | 305 | ||
287 | let items = self | 306 | let items = self |
288 | .resolver | 307 | .resolver |
289 | .resolve_module_path(db, &path) | 308 | .resolve_module_path_in_items(db, path.mod_path()) |
290 | .take_types() | 309 | .take_types() |
291 | .map(|it| PathResolution::Def(it.into())); | 310 | .map(|it| PathResolution::Def(it.into())); |
292 | types.or(values).or(items).or_else(|| { | 311 | types.or(values).or(items).or_else(|| { |
293 | self.resolver | 312 | self.resolver |
294 | .resolve_path_as_macro(db, &path) | 313 | .resolve_path_as_macro(db, path.mod_path()) |
295 | .map(|def| PathResolution::Macro(def.into())) | 314 | .map(|def| PathResolution::Macro(def.into())) |
296 | }) | 315 | }) |
297 | } | 316 | } |
@@ -318,7 +337,7 @@ impl SourceAnalyzer { | |||
318 | let name = name_ref.as_name(); | 337 | let name = name_ref.as_name(); |
319 | let source_map = self.body_source_map.as_ref()?; | 338 | let source_map = self.body_source_map.as_ref()?; |
320 | let scopes = self.scopes.as_ref()?; | 339 | let scopes = self.scopes.as_ref()?; |
321 | let scope = scope_for(scopes, source_map, Source::new(self.file_id, name_ref.syntax()))?; | 340 | let scope = scope_for(scopes, source_map, InFile::new(self.file_id, name_ref.syntax()))?; |
322 | let entry = scopes.resolve_name_in_scope(scope, &name)?; | 341 | let entry = scopes.resolve_name_in_scope(scope, &name)?; |
323 | Some(ScopeEntryWithSyntax { | 342 | Some(ScopeEntryWithSyntax { |
324 | name: entry.name().clone(), | 343 | name: entry.name().clone(), |
@@ -332,10 +351,7 @@ impl SourceAnalyzer { | |||
332 | resolver::ScopeDef::PerNs(it) => it.into(), | 351 | resolver::ScopeDef::PerNs(it) => it.into(), |
333 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | 352 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), |
334 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | 353 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), |
335 | resolver::ScopeDef::GenericParam(idx) => { | 354 | resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), |
336 | let parent = self.resolver.generic_def().unwrap(); | ||
337 | ScopeDef::GenericParam(GenericParam { parent, idx }) | ||
338 | } | ||
339 | resolver::ScopeDef::Local(pat_id) => { | 355 | resolver::ScopeDef::Local(pat_id) => { |
340 | let parent = self.resolver.body_owner().unwrap().into(); | 356 | let parent = self.resolver.body_owner().unwrap().into(); |
341 | ScopeDef::Local(Local { parent, pat_id }) | 357 | ScopeDef::Local(Local { parent, pat_id }) |
@@ -349,7 +365,7 @@ impl SourceAnalyzer { | |||
349 | // should switch to general reference search infra there. | 365 | // should switch to general reference search infra there. |
350 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 366 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
351 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 367 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
352 | let ptr = Either::A(AstPtr::new(&ast::Pat::from(pat.clone()))); | 368 | let ptr = Either::Left(AstPtr::new(&ast::Pat::from(pat.clone()))); |
353 | fn_def | 369 | fn_def |
354 | .syntax() | 370 | .syntax() |
355 | .descendants() | 371 | .descendants() |
@@ -375,7 +391,7 @@ impl SourceAnalyzer { | |||
375 | // There should be no inference vars in types passed here | 391 | // There should be no inference vars in types passed here |
376 | // FIXME check that? | 392 | // FIXME check that? |
377 | // FIXME replace Unknown by bound vars here | 393 | // FIXME replace Unknown by bound vars here |
378 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 394 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
379 | method_resolution::iterate_method_candidates( | 395 | method_resolution::iterate_method_candidates( |
380 | &canonical, | 396 | &canonical, |
381 | db, | 397 | db, |
@@ -399,7 +415,7 @@ impl SourceAnalyzer { | |||
399 | // There should be no inference vars in types passed here | 415 | // There should be no inference vars in types passed here |
400 | // FIXME check that? | 416 | // FIXME check that? |
401 | // FIXME replace Unknown by bound vars here | 417 | // FIXME replace Unknown by bound vars here |
402 | let canonical = crate::ty::Canonical { value: ty.ty.value.clone(), num_vars: 0 }; | 418 | let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 }; |
403 | method_resolution::iterate_method_candidates( | 419 | method_resolution::iterate_method_candidates( |
404 | &canonical, | 420 | &canonical, |
405 | db, | 421 | db, |
@@ -410,24 +426,10 @@ impl SourceAnalyzer { | |||
410 | ) | 426 | ) |
411 | } | 427 | } |
412 | 428 | ||
413 | // pub fn autoderef<'a>( | ||
414 | // &'a self, | ||
415 | // db: &'a impl HirDatabase, | ||
416 | // ty: Ty, | ||
417 | // ) -> impl Iterator<Item = Ty> + 'a { | ||
418 | // // There should be no inference vars in types passed here | ||
419 | // // FIXME check that? | ||
420 | // let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; | ||
421 | // let krate = self.resolver.krate(); | ||
422 | // let environment = TraitEnvironment::lower(db, &self.resolver); | ||
423 | // let ty = crate::ty::InEnvironment { value: canonical, environment }; | ||
424 | // crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value) | ||
425 | // } | ||
426 | |||
427 | /// Checks that particular type `ty` implements `std::future::Future`. | 429 | /// Checks that particular type `ty` implements `std::future::Future`. |
428 | /// This function is used in `.await` syntax completion. | 430 | /// This function is used in `.await` syntax completion. |
429 | pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { | 431 | pub fn impls_future(&self, db: &impl HirDatabase, ty: Type) -> bool { |
430 | let std_future_path = known::std_future_future(); | 432 | let std_future_path = path![std::future::Future]; |
431 | 433 | ||
432 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { | 434 | let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { |
433 | Some(it) => it.into(), | 435 | Some(it) => it.into(), |
@@ -439,43 +441,40 @@ impl SourceAnalyzer { | |||
439 | _ => return false, | 441 | _ => return false, |
440 | }; | 442 | }; |
441 | 443 | ||
442 | let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; | 444 | let canonical_ty = Canonical { value: ty.ty.value, num_vars: 0 }; |
443 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) | 445 | implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) |
444 | } | 446 | } |
445 | 447 | ||
446 | pub fn expand( | 448 | pub fn expand( |
447 | &self, | 449 | &self, |
448 | db: &impl HirDatabase, | 450 | db: &impl HirDatabase, |
449 | macro_call: Source<&ast::MacroCall>, | 451 | macro_call: InFile<&ast::MacroCall>, |
450 | ) -> Option<Expansion> { | 452 | ) -> Option<Expansion> { |
451 | let def = self.resolve_macro_call(db, macro_call)?.id; | 453 | let def = self.resolve_macro_call(db, macro_call)?.id; |
452 | let ast_id = AstId::new( | 454 | let ast_id = AstId::new( |
453 | macro_call.file_id, | 455 | macro_call.file_id, |
454 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 456 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
455 | ); | 457 | ); |
456 | Some(Expansion { | 458 | Some(Expansion { macro_call_id: def.as_call_id(db, MacroCallKind::FnLike(ast_id)) }) |
457 | macro_call_id: def.as_call_id(db, ast_id), | ||
458 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
459 | }) | ||
460 | } | 459 | } |
461 | } | 460 | } |
462 | 461 | ||
463 | fn scope_for( | 462 | fn scope_for( |
464 | scopes: &ExprScopes, | 463 | scopes: &ExprScopes, |
465 | source_map: &BodySourceMap, | 464 | source_map: &BodySourceMap, |
466 | node: Source<&SyntaxNode>, | 465 | node: InFile<&SyntaxNode>, |
467 | ) -> Option<ScopeId> { | 466 | ) -> Option<ScopeId> { |
468 | node.value | 467 | node.value |
469 | .ancestors() | 468 | .ancestors() |
470 | .filter_map(ast::Expr::cast) | 469 | .filter_map(ast::Expr::cast) |
471 | .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) | 470 | .filter_map(|it| source_map.node_expr(InFile::new(node.file_id, &it))) |
472 | .find_map(|it| scopes.scope_for(it)) | 471 | .find_map(|it| scopes.scope_for(it)) |
473 | } | 472 | } |
474 | 473 | ||
475 | fn scope_for_offset( | 474 | fn scope_for_offset( |
476 | scopes: &ExprScopes, | 475 | scopes: &ExprScopes, |
477 | source_map: &BodySourceMap, | 476 | source_map: &BodySourceMap, |
478 | offset: Source<TextUnit>, | 477 | offset: InFile<TextUnit>, |
479 | ) -> Option<ScopeId> { | 478 | ) -> Option<ScopeId> { |
480 | scopes | 479 | scopes |
481 | .scope_by_expr() | 480 | .scope_by_expr() |
@@ -540,35 +539,3 @@ fn adjust( | |||
540 | }) | 539 | }) |
541 | .map(|(_ptr, scope)| *scope) | 540 | .map(|(_ptr, scope)| *scope) |
542 | } | 541 | } |
543 | |||
544 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
545 | /// FIXME: Not completed | ||
546 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
547 | let syn = macro_call.syntax(); | ||
548 | let parent = match syn.parent() { | ||
549 | Some(it) => it, | ||
550 | None => { | ||
551 | // FIXME: | ||
552 | // If it is root, which means the parent HirFile | ||
553 | // MacroKindFile must be non-items | ||
554 | // return expr now. | ||
555 | return MacroFileKind::Expr; | ||
556 | } | ||
557 | }; | ||
558 | |||
559 | match parent.kind() { | ||
560 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
561 | LET_STMT => { | ||
562 | // FIXME: Handle Pattern | ||
563 | MacroFileKind::Expr | ||
564 | } | ||
565 | EXPR_STMT => MacroFileKind::Statements, | ||
566 | BLOCK => MacroFileKind::Statements, | ||
567 | ARG_LIST => MacroFileKind::Expr, | ||
568 | TRY_EXPR => MacroFileKind::Expr, | ||
569 | _ => { | ||
570 | // Unknown , Just guess it is `Items` | ||
571 | MacroFileKind::Items | ||
572 | } | ||
573 | } | ||
574 | } | ||