diff options
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r-- | crates/hir/src/semantics.rs | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 4bd22ed27..e4fc21ced 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -13,7 +13,11 @@ use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; | |||
13 | use hir_ty::associated_type_shorthand_candidates; | 13 | use hir_ty::associated_type_shorthand_candidates; |
14 | use itertools::Itertools; | 14 | use itertools::Itertools; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode, SyntaxToken, TextSize}; | 16 | use syntax::{ |
17 | algo::find_node_at_offset, | ||
18 | ast::{self, GenericParamsOwner}, | ||
19 | match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, | ||
20 | }; | ||
17 | 21 | ||
18 | use crate::{ | 22 | use crate::{ |
19 | code_model::Access, | 23 | code_model::Access, |
@@ -21,8 +25,9 @@ use crate::{ | |||
21 | diagnostics::Diagnostic, | 25 | diagnostics::Diagnostic, |
22 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
23 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
24 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, | 28 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local, |
25 | Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, | 29 | MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, |
30 | VariantDef, | ||
26 | }; | 31 | }; |
27 | 32 | ||
28 | #[derive(Debug, Clone, PartialEq, Eq)] | 33 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -173,6 +178,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
173 | self.imp.descend_node_at_offset(node, offset).find_map(N::cast) | 178 | self.imp.descend_node_at_offset(node, offset).find_map(N::cast) |
174 | } | 179 | } |
175 | 180 | ||
181 | // FIXME: Replace the SyntaxToken with a typed ast Node/Token | ||
182 | pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { | ||
183 | self.imp.resolve_lifetime_param(lifetime_token) | ||
184 | } | ||
185 | |||
176 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 186 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
177 | self.imp.type_of_expr(expr) | 187 | self.imp.type_of_expr(expr) |
178 | } | 188 | } |
@@ -392,16 +402,44 @@ impl<'db> SemanticsImpl<'db> { | |||
392 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) | 402 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) |
393 | } | 403 | } |
394 | 404 | ||
405 | // FIXME: Replace the SyntaxToken with a typed ast Node/Token | ||
406 | fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { | ||
407 | if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME { | ||
408 | return None; | ||
409 | } | ||
410 | let lifetime_text = lifetime_token.text(); | ||
411 | let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| { | ||
412 | let gpl = match_ast! { | ||
413 | match syn { | ||
414 | ast::Fn(it) => it.generic_param_list()?, | ||
415 | ast::TypeAlias(it) => it.generic_param_list()?, | ||
416 | ast::Struct(it) => it.generic_param_list()?, | ||
417 | ast::Enum(it) => it.generic_param_list()?, | ||
418 | ast::Union(it) => it.generic_param_list()?, | ||
419 | ast::Trait(it) => it.generic_param_list()?, | ||
420 | ast::Impl(it) => it.generic_param_list()?, | ||
421 | ast::WherePred(it) => it.generic_param_list()?, | ||
422 | ast::ForType(it) => it.generic_param_list()?, | ||
423 | _ => return None, | ||
424 | } | ||
425 | }; | ||
426 | gpl.lifetime_params() | ||
427 | .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text)) | ||
428 | })?; | ||
429 | let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); | ||
430 | ToDef::to_def(self, src) | ||
431 | } | ||
432 | |||
395 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 433 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
396 | self.analyze(expr.syntax()).type_of_expr(self.db, &expr) | 434 | self.analyze(expr.syntax()).type_of_expr(self.db, expr) |
397 | } | 435 | } |
398 | 436 | ||
399 | fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { | 437 | fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { |
400 | self.analyze(pat.syntax()).type_of_pat(self.db, &pat) | 438 | self.analyze(pat.syntax()).type_of_pat(self.db, pat) |
401 | } | 439 | } |
402 | 440 | ||
403 | fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { | 441 | fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { |
404 | self.analyze(param.syntax()).type_of_self(self.db, ¶m) | 442 | self.analyze(param.syntax()).type_of_self(self.db, param) |
405 | } | 443 | } |
406 | 444 | ||
407 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { | 445 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { |
@@ -684,6 +722,7 @@ to_def_impls![ | |||
684 | (crate::Field, ast::TupleField, tuple_field_to_def), | 722 | (crate::Field, ast::TupleField, tuple_field_to_def), |
685 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), | 723 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), |
686 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 724 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
725 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | ||
687 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros | 726 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros |
688 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 727 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
689 | ]; | 728 | ]; |