diff options
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 109 |
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 | ||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use ra_syntax::{ | 6 | use ra_syntax::ast::{self, NameOwner, StructFlavor}; |
7 | SyntaxNode, | ||
8 | ast::{self, NameOwner, StructFlavor, AstNode} | ||
9 | }; | ||
10 | 7 | ||
11 | use crate::{ | 8 | use 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 | ||
18 | impl Struct { | 15 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
19 | pub(crate) fn new(def_id: DefId) -> Self { | 16 | pub enum AdtDef { |
20 | Struct { def_id } | 17 | Struct(Struct), |
18 | Enum(Enum), | ||
19 | } | ||
20 | impl_froms!(AdtDef: Struct, Enum); | ||
21 | |||
22 | impl 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 | ||
32 | impl 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 | ||
52 | fn 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)] |
75 | pub struct EnumData { | 59 | pub 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 | ||