aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r--crates/ra_hir/src/adt.rs109
1 files changed, 42 insertions, 67 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index ab1c428db..6b13b464d 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -3,25 +3,35 @@
3 3
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use ra_syntax::{ 6use ra_syntax::ast::{self, NameOwner, StructFlavor};
7 SyntaxNode,
8 ast::{self, NameOwner, StructFlavor, AstNode}
9};
10 7
11use crate::{ 8use crate::{
12 DefId, DefLoc, Name, AsName, Struct, Enum, EnumVariant, 9 Name, AsName, Struct, Enum, EnumVariant, Crate,
13 HirDatabase, DefKind, 10 HirDatabase,
14 SourceItemId,
15 type_ref::TypeRef, 11 type_ref::TypeRef,
12 ids::LocationCtx,
16}; 13};
17 14
18impl Struct { 15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
19 pub(crate) fn new(def_id: DefId) -> Self { 16pub enum AdtDef {
20 Struct { def_id } 17 Struct(Struct),
18 Enum(Enum),
19}
20impl_froms!(AdtDef: Struct, Enum);
21
22impl AdtDef {
23 pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
24 match self {
25 AdtDef::Struct(s) => s.module(db),
26 AdtDef::Enum(e) => e.module(db),
27 }
28 .krate(db)
21 } 29 }
30}
22 31
32impl Struct {
23 pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> { 33 pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
24 db.struct_data(self.def_id).variant_data.clone() 34 db.struct_data((*self).into()).variant_data.clone()
25 } 35 }
26} 36}
27 37
@@ -39,38 +49,12 @@ impl StructData {
39 StructData { name, variant_data } 49 StructData { name, variant_data }
40 } 50 }
41 51
42 pub(crate) fn struct_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<StructData> { 52 pub(crate) fn struct_data_query(db: &impl HirDatabase, struct_: Struct) -> Arc<StructData> {
43 let def_loc = def_id.loc(db); 53 let (_, struct_def) = struct_.source(db);
44 assert!(def_loc.kind == DefKind::Struct); 54 Arc::new(StructData::new(&*struct_def))
45 let syntax = db.file_item(def_loc.source_item_id);
46 let struct_def =
47 ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
48 Arc::new(StructData::new(struct_def))
49 } 55 }
50} 56}
51 57
52fn get_def_id(
53 db: &impl HirDatabase,
54 same_file_loc: &DefLoc,
55 node: &SyntaxNode,
56 expected_kind: DefKind,
57) -> DefId {
58 let file_id = same_file_loc.source_item_id.file_id;
59 let file_items = db.file_items(file_id);
60
61 let item_id = file_items.id_of(file_id, node);
62 let source_item_id = SourceItemId {
63 item_id: Some(item_id),
64 ..same_file_loc.source_item_id
65 };
66 let loc = DefLoc {
67 kind: expected_kind,
68 source_item_id,
69 ..*same_file_loc
70 };
71 loc.id(db)
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)] 58#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct EnumData { 59pub struct EnumData {
76 pub(crate) name: Option<Name>, 60 pub(crate) name: Option<Name>,
@@ -83,27 +67,24 @@ impl EnumData {
83 EnumData { name, variants } 67 EnumData { name, variants }
84 } 68 }
85 69
86 pub(crate) fn enum_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<EnumData> { 70 pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
87 let def_loc = def_id.loc(db); 71 let (file_id, enum_def) = e.source(db);
88 assert!(def_loc.kind == DefKind::Enum); 72 let module = e.module(db);
89 let syntax = db.file_item(def_loc.source_item_id); 73 let ctx = LocationCtx::new(db, module, file_id);
90 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
91 let variants = if let Some(vl) = enum_def.variant_list() { 74 let variants = if let Some(vl) = enum_def.variant_list() {
92 vl.variants() 75 vl.variants()
93 .filter_map(|variant_def| { 76 .filter_map(|variant_def| {
94 let name = variant_def.name().map(|n| n.as_name()); 77 let name = variant_def.name()?.as_name();
95 78 let var = EnumVariant {
96 name.map(|n| { 79 id: ctx.to_def(variant_def),
97 let def_id = 80 };
98 get_def_id(db, &def_loc, variant_def.syntax(), DefKind::EnumVariant); 81 Some((name, var))
99 (n, EnumVariant::new(def_id))
100 })
101 }) 82 })
102 .collect() 83 .collect()
103 } else { 84 } else {
104 Vec::new() 85 Vec::new()
105 }; 86 };
106 Arc::new(EnumData::new(enum_def, variants)) 87 Arc::new(EnumData::new(&*enum_def, variants))
107 } 88 }
108} 89}
109 90
@@ -128,21 +109,15 @@ impl EnumVariantData {
128 109
129 pub(crate) fn enum_variant_data_query( 110 pub(crate) fn enum_variant_data_query(
130 db: &impl HirDatabase, 111 db: &impl HirDatabase,
131 def_id: DefId, 112 var: EnumVariant,
132 ) -> Arc<EnumVariantData> { 113 ) -> Arc<EnumVariantData> {
133 let def_loc = def_id.loc(db); 114 let (file_id, variant_def) = var.source(db);
134 assert!(def_loc.kind == DefKind::EnumVariant); 115 let enum_def = variant_def.parent_enum();
135 let syntax = db.file_item(def_loc.source_item_id); 116 let ctx = LocationCtx::new(db, var.module(db), file_id);
136 let variant_def = ast::EnumVariant::cast(&syntax) 117 let e = Enum {
137 .expect("enum variant def should point to EnumVariant node"); 118 id: ctx.to_def(enum_def),
138 let enum_node = syntax 119 };
139 .parent() 120 Arc::new(EnumVariantData::new(&*variant_def, e))
140 .expect("enum variant should have enum variant list ancestor")
141 .parent()
142 .expect("enum variant list should have enum ancestor");
143 let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum);
144
145 Arc::new(EnumVariantData::new(variant_def, Enum::new(enum_def_id)))
146 } 121 }
147} 122}
148 123