aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/code_model.rs47
-rw-r--r--crates/hir/src/lib.rs9
-rw-r--r--crates/hir/src/semantics.rs46
-rw-r--r--crates/hir/src/source_analyzer.rs2
4 files changed, 70 insertions, 34 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 9a1e9ba49..fcc42c6bb 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -19,8 +19,9 @@ use hir_def::{
19 src::HasSource as _, 19 src::HasSource as _,
20 type_ref::{Mutability, TypeRef}, 20 type_ref::{Mutability, TypeRef},
21 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId, 21 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId,
22 FunctionId, GenericDefId, HasModule, ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, 22 FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId,
23 Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 23 LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
24 UnionId,
24}; 25};
25use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility}; 26use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility};
26use hir_expand::{ 27use hir_expand::{
@@ -831,7 +832,7 @@ impl SelfParam {
831 .params 832 .params
832 .first() 833 .first()
833 .map(|param| match *param { 834 .map(|param| match *param {
834 TypeRef::Reference(_, mutability) => mutability.into(), 835 TypeRef::Reference(.., mutability) => mutability.into(),
835 _ => Access::Owned, 836 _ => Access::Owned,
836 }) 837 })
837 .unwrap_or(Access::Owned) 838 .unwrap_or(Access::Owned)
@@ -1098,8 +1099,25 @@ impl_from!(
1098); 1099);
1099 1100
1100impl GenericDef { 1101impl GenericDef {
1101 pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeParam> { 1102 pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
1102 let generics: Arc<hir_def::generics::GenericParams> = db.generic_params(self.into()); 1103 let generics = db.generic_params(self.into());
1104 let ty_params = generics
1105 .types
1106 .iter()
1107 .map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1108 .map(GenericParam::TypeParam);
1109 let lt_params = generics
1110 .lifetimes
1111 .iter()
1112 .map(|(local_id, _)| LifetimeParam {
1113 id: LifetimeParamId { parent: self.into(), local_id },
1114 })
1115 .map(GenericParam::LifetimeParam);
1116 ty_params.chain(lt_params).collect()
1117 }
1118
1119 pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
1120 let generics = db.generic_params(self.into());
1103 generics 1121 generics
1104 .types 1122 .types
1105 .iter() 1123 .iter()
@@ -1176,6 +1194,13 @@ impl Local {
1176} 1194}
1177 1195
1178#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1196#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1197pub enum GenericParam {
1198 TypeParam(TypeParam),
1199 LifetimeParam(LifetimeParam),
1200}
1201impl_from!(TypeParam, LifetimeParam for GenericParam);
1202
1203#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1179pub struct TypeParam { 1204pub struct TypeParam {
1180 pub(crate) id: TypeParamId, 1205 pub(crate) id: TypeParamId,
1181} 1206}
@@ -1215,6 +1240,18 @@ impl TypeParam {
1215 } 1240 }
1216} 1241}
1217 1242
1243#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1244pub struct LifetimeParam {
1245 pub(crate) id: LifetimeParamId,
1246}
1247
1248impl LifetimeParam {
1249 pub fn name(self, db: &dyn HirDatabase) -> Name {
1250 let params = db.generic_params(self.id.parent);
1251 params.lifetimes[self.id.local_id].name.clone()
1252 }
1253}
1254
1218// FIXME: rename from `ImplDef` to `Impl` 1255// FIXME: rename from `ImplDef` to `Impl`
1219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1220pub struct ImplDef { 1257pub struct ImplDef {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 302a52491..0f399a2c6 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -35,8 +35,8 @@ pub use crate::{
35 code_model::{ 35 code_model::{
36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, 36 Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, 37 Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
38 GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, 38 GenericDef, HasVisibility, ImplDef, LifetimeParam, Local, MacroDef, Module, ModuleDef,
39 Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, 39 ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
40 }, 40 },
41 has_source::HasSource, 41 has_source::HasSource,
42 semantics::{PathResolution, Semantics, SemanticsScope}, 42 semantics::{PathResolution, Semantics, SemanticsScope},
@@ -56,8 +56,9 @@ pub use hir_def::{
56 visibility::Visibility, 56 visibility::Visibility,
57}; 57};
58pub use hir_expand::{ 58pub use hir_expand::{
59 name::known, name::AsName, name::Name, ExpandResult, HirFileId, InFile, MacroCallId, 59 name::{known, AsName, Name},
60 MacroCallLoc, /* FIXME */ MacroDefId, MacroFile, Origin, 60 ExpandResult, HirFileId, InFile, MacroCallId, MacroCallLoc, /* FIXME */ MacroDefId,
61 MacroFile, Origin,
61}; 62};
62pub use hir_ty::display::HirDisplay; 63pub use hir_ty::display::HirDisplay;
63 64
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 4315ad48b..4bd22ed27 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -294,9 +294,8 @@ impl<'db> SemanticsImpl<'db> {
294 } 294 }
295 295
296 fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { 296 fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
297 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); 297 let sa = self.analyze(macro_call.syntax());
298 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); 298 let file_id = sa.expand(self.db, InFile::new(sa.file_id, macro_call))?;
299 let file_id = sa.expand(self.db, macro_call)?;
300 let node = self.db.parse_or_expand(file_id)?; 299 let node = self.db.parse_or_expand(file_id)?;
301 self.cache(node.clone(), file_id); 300 self.cache(node.clone(), file_id);
302 Some(node) 301 Some(node)
@@ -308,9 +307,8 @@ impl<'db> SemanticsImpl<'db> {
308 hypothetical_args: &ast::TokenTree, 307 hypothetical_args: &ast::TokenTree,
309 token_to_map: SyntaxToken, 308 token_to_map: SyntaxToken,
310 ) -> Option<(SyntaxNode, SyntaxToken)> { 309 ) -> Option<(SyntaxNode, SyntaxToken)> {
311 let macro_call = 310 let sa = self.analyze(actual_macro_call.syntax());
312 self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); 311 let macro_call = InFile::new(sa.file_id, actual_macro_call);
313 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None);
314 let krate = sa.resolver.krate()?; 312 let krate = sa.resolver.krate()?;
315 let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { 313 let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
316 sa.resolver.resolve_path_as_macro(self.db.upcast(), &path) 314 sa.resolver.resolve_path_as_macro(self.db.upcast(), &path)
@@ -326,10 +324,9 @@ impl<'db> SemanticsImpl<'db> {
326 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { 324 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
327 let _p = profile::span("descend_into_macros"); 325 let _p = profile::span("descend_into_macros");
328 let parent = token.parent(); 326 let parent = token.parent();
329 let parent = self.find_file(parent); 327 let sa = self.analyze(&parent);
330 let sa = self.analyze2(parent.as_ref(), None);
331 328
332 let token = successors(Some(parent.with_value(token)), |token| { 329 let token = successors(Some(InFile::new(sa.file_id, token)), |token| {
333 self.db.check_canceled(); 330 self.db.check_canceled();
334 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 331 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
335 let tt = macro_call.token_tree()?; 332 let tt = macro_call.token_tree()?;
@@ -486,15 +483,13 @@ impl<'db> SemanticsImpl<'db> {
486 } 483 }
487 484
488 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { 485 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
489 let node = self.find_file(node.clone()); 486 let sa = self.analyze(node);
490 let resolver = self.analyze2(node.as_ref(), None).resolver; 487 SemanticsScope { db: self.db, file_id: sa.file_id, resolver: sa.resolver }
491 SemanticsScope { db: self.db, file_id: node.file_id, resolver }
492 } 488 }
493 489
494 fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { 490 fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
495 let node = self.find_file(node.clone()); 491 let sa = self.analyze_with_offset(node, offset);
496 let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver; 492 SemanticsScope { db: self.db, file_id: sa.file_id, resolver: sa.resolver }
497 SemanticsScope { db: self.db, file_id: node.file_id, resolver }
498 } 493 }
499 494
500 fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { 495 fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
@@ -504,21 +499,24 @@ impl<'db> SemanticsImpl<'db> {
504 } 499 }
505 500
506 fn analyze(&self, node: &SyntaxNode) -> SourceAnalyzer { 501 fn analyze(&self, node: &SyntaxNode) -> SourceAnalyzer {
507 let src = self.find_file(node.clone()); 502 self.analyze_impl(node, None)
508 self.analyze2(src.as_ref(), None)
509 } 503 }
504 fn analyze_with_offset(&self, node: &SyntaxNode, offset: TextSize) -> SourceAnalyzer {
505 self.analyze_impl(node, Some(offset))
506 }
507 fn analyze_impl(&self, node: &SyntaxNode, offset: Option<TextSize>) -> SourceAnalyzer {
508 let _p = profile::span("Semantics::analyze_impl");
509 let node = self.find_file(node.clone());
510 let node = node.as_ref();
510 511
511 fn analyze2(&self, src: InFile<&SyntaxNode>, offset: Option<TextSize>) -> SourceAnalyzer { 512 let container = match self.with_ctx(|ctx| ctx.find_container(node)) {
512 let _p = profile::span("Semantics::analyze2");
513
514 let container = match self.with_ctx(|ctx| ctx.find_container(src)) {
515 Some(it) => it, 513 Some(it) => it,
516 None => return SourceAnalyzer::new_for_resolver(Resolver::default(), src), 514 None => return SourceAnalyzer::new_for_resolver(Resolver::default(), node),
517 }; 515 };
518 516
519 let resolver = match container { 517 let resolver = match container {
520 ChildContainer::DefWithBodyId(def) => { 518 ChildContainer::DefWithBodyId(def) => {
521 return SourceAnalyzer::new_for_body(self.db, def, src, offset) 519 return SourceAnalyzer::new_for_body(self.db, def, node, offset)
522 } 520 }
523 ChildContainer::TraitId(it) => it.resolver(self.db.upcast()), 521 ChildContainer::TraitId(it) => it.resolver(self.db.upcast()),
524 ChildContainer::ImplId(it) => it.resolver(self.db.upcast()), 522 ChildContainer::ImplId(it) => it.resolver(self.db.upcast()),
@@ -528,7 +526,7 @@ impl<'db> SemanticsImpl<'db> {
528 ChildContainer::TypeAliasId(it) => it.resolver(self.db.upcast()), 526 ChildContainer::TypeAliasId(it) => it.resolver(self.db.upcast()),
529 ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()), 527 ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()),
530 }; 528 };
531 SourceAnalyzer::new_for_resolver(resolver, src) 529 SourceAnalyzer::new_for_resolver(resolver, node)
532 } 530 }
533 531
534 fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) { 532 fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 1aef0f33f..bf0c959fe 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -37,7 +37,7 @@ use base_db::CrateId;
37/// original source files. It should not be used inside the HIR itself. 37/// original source files. It should not be used inside the HIR itself.
38#[derive(Debug)] 38#[derive(Debug)]
39pub(crate) struct SourceAnalyzer { 39pub(crate) struct SourceAnalyzer {
40 file_id: HirFileId, 40 pub(crate) file_id: HirFileId,
41 pub(crate) resolver: Resolver, 41 pub(crate) resolver: Resolver,
42 body: Option<Arc<Body>>, 42 body: Option<Arc<Body>>,
43 body_source_map: Option<Arc<BodySourceMap>>, 43 body_source_map: Option<Arc<BodySourceMap>>,