aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/adt.rs131
-rw-r--r--crates/ra_hir/src/code_model_api.rs98
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/query_definitions.rs20
5 files changed, 131 insertions, 124 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index b75adda84..602e7db74 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -1,93 +1,60 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::Cancelable; 3use ra_db::Cancelable;
4use ra_syntax::ast::{self, NameOwner, StructFlavor}; 4use ra_syntax::ast::{self, NameOwner, StructFlavor, AstNode};
5 5
6use crate::{ 6use crate::{
7 DefId, Name, AsName, 7 DefId, Name, AsName, Struct, Enum, VariantData, StructField, HirDatabase, DefKind,
8 db::HirDatabase,
9 type_ref::TypeRef, 8 type_ref::TypeRef,
10}; 9};
11 10
12pub struct Struct {
13 def_id: DefId,
14}
15
16impl Struct { 11impl Struct {
17 pub(crate) fn new(def_id: DefId) -> Self { 12 pub(crate) fn new(def_id: DefId) -> Self {
18 Struct { def_id } 13 Struct { def_id }
19 } 14 }
20
21 pub fn def_id(&self) -> DefId {
22 self.def_id
23 }
24
25 pub fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> {
26 Ok(db.struct_data(self.def_id)?.variant_data.clone())
27 }
28
29 pub fn struct_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<StructData>> {
30 Ok(db.struct_data(self.def_id)?)
31 }
32
33 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
34 Ok(db.struct_data(self.def_id)?.name.clone())
35 }
36} 15}
37 16
38#[derive(Debug, Clone, PartialEq, Eq)] 17#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct StructData { 18pub struct StructData {
40 name: Option<Name>, 19 pub(crate) name: Option<Name>,
41 variant_data: Arc<VariantData>, 20 pub(crate) variant_data: Arc<VariantData>,
42} 21}
43 22
44impl StructData { 23impl StructData {
45 pub(crate) fn new(struct_def: &ast::StructDef) -> StructData { 24 fn new(struct_def: &ast::StructDef) -> StructData {
46 let name = struct_def.name().map(|n| n.as_name()); 25 let name = struct_def.name().map(|n| n.as_name());
47 let variant_data = VariantData::new(struct_def.flavor()); 26 let variant_data = VariantData::new(struct_def.flavor());
48 let variant_data = Arc::new(variant_data); 27 let variant_data = Arc::new(variant_data);
49 StructData { name, variant_data } 28 StructData { name, variant_data }
50 } 29 }
51 30
52 pub fn name(&self) -> Option<&Name> { 31 pub(crate) fn struct_data_query(
53 self.name.as_ref() 32 db: &impl HirDatabase,
54 } 33 def_id: DefId,
55 34 ) -> Cancelable<Arc<StructData>> {
56 pub fn variant_data(&self) -> &Arc<VariantData> { 35 let def_loc = def_id.loc(db);
57 &self.variant_data 36 assert!(def_loc.kind == DefKind::Struct);
37 let syntax = db.file_item(def_loc.source_item_id);
38 let struct_def =
39 ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
40 Ok(Arc::new(StructData::new(struct_def)))
58 } 41 }
59} 42}
60 43
61pub struct Enum {
62 def_id: DefId,
63}
64
65impl Enum { 44impl Enum {
66 pub(crate) fn new(def_id: DefId) -> Self { 45 pub(crate) fn new(def_id: DefId) -> Self {
67 Enum { def_id } 46 Enum { def_id }
68 } 47 }
69
70 pub fn def_id(&self) -> DefId {
71 self.def_id
72 }
73
74 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
75 Ok(db.enum_data(self.def_id)?.name.clone())
76 }
77
78 pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, Arc<VariantData>)>> {
79 Ok(db.enum_data(self.def_id)?.variants.clone())
80 }
81} 48}
82 49
83#[derive(Debug, Clone, PartialEq, Eq)] 50#[derive(Debug, Clone, PartialEq, Eq)]
84pub struct EnumData { 51pub struct EnumData {
85 name: Option<Name>, 52 pub(crate) name: Option<Name>,
86 variants: Vec<(Name, Arc<VariantData>)>, 53 pub(crate) variants: Vec<(Name, Arc<VariantData>)>,
87} 54}
88 55
89impl EnumData { 56impl EnumData {
90 pub(crate) fn new(enum_def: &ast::EnumDef) -> Self { 57 fn new(enum_def: &ast::EnumDef) -> Self {
91 let name = enum_def.name().map(|n| n.as_name()); 58 let name = enum_def.name().map(|n| n.as_name());
92 let variants = if let Some(evl) = enum_def.variant_list() { 59 let variants = if let Some(evl) = enum_def.variant_list() {
93 evl.variants() 60 evl.variants()
@@ -103,34 +70,21 @@ impl EnumData {
103 }; 70 };
104 EnumData { name, variants } 71 EnumData { name, variants }
105 } 72 }
106}
107
108/// A single field of an enum variant or struct
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub struct StructField {
111 name: Name,
112 type_ref: TypeRef,
113}
114 73
115impl StructField { 74 pub(crate) fn enum_data_query(
116 pub fn name(&self) -> Name { 75 db: &impl HirDatabase,
117 self.name.clone() 76 def_id: DefId,
77 ) -> Cancelable<Arc<EnumData>> {
78 let def_loc = def_id.loc(db);
79 assert!(def_loc.kind == DefKind::Enum);
80 let syntax = db.file_item(def_loc.source_item_id);
81 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
82 Ok(Arc::new(EnumData::new(enum_def)))
118 } 83 }
119 pub fn type_ref(&self) -> &TypeRef {
120 &self.type_ref
121 }
122}
123
124/// Fields of an enum variant or struct
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub enum VariantData {
127 Struct(Vec<StructField>),
128 Tuple(Vec<StructField>),
129 Unit,
130} 84}
131 85
132impl VariantData { 86impl VariantData {
133 pub fn new(flavor: StructFlavor) -> Self { 87 fn new(flavor: StructFlavor) -> Self {
134 match flavor { 88 match flavor {
135 StructFlavor::Tuple(fl) => { 89 StructFlavor::Tuple(fl) => {
136 let fields = fl 90 let fields = fl
@@ -160,32 +114,7 @@ impl VariantData {
160 pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> { 114 pub(crate) fn get_field_type_ref(&self, field_name: &Name) -> Option<&TypeRef> {
161 self.fields() 115 self.fields()
162 .iter() 116 .iter()
163 .find(|f| f.name == *field_name) 117 .find(|f| f.name() == field_name)
164 .map(|f| &f.type_ref) 118 .map(|f| f.type_ref())
165 }
166
167 pub fn fields(&self) -> &[StructField] {
168 match *self {
169 VariantData::Struct(ref fields) | VariantData::Tuple(ref fields) => fields,
170 _ => &[],
171 }
172 }
173 pub fn is_struct(&self) -> bool {
174 match self {
175 VariantData::Struct(..) => true,
176 _ => false,
177 }
178 }
179 pub fn is_tuple(&self) -> bool {
180 match self {
181 VariantData::Tuple(..) => true,
182 _ => false,
183 }
184 }
185 pub fn is_unit(&self) -> bool {
186 match self {
187 VariantData::Unit => true,
188 _ => false,
189 }
190 } 119 }
191} 120}
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 43cddb504..f06f1ae66 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,8 +1,15 @@
1use std::sync::Arc;
2
1use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
2use ra_db::{CrateId, Cancelable, FileId}; 4use ra_db::{CrateId, Cancelable, FileId};
3use ra_syntax::{ast, TreePtr, SyntaxNode}; 5use ra_syntax::{ast, TreePtr, SyntaxNode};
4 6
5use crate::{Name, db::HirDatabase, DefId, Path, PerNs, nameres::ModuleScope}; 7use crate::{
8 Name, DefId, Path, PerNs,
9 type_ref::TypeRef,
10 nameres::ModuleScope,
11 db::HirDatabase,
12};
6 13
7/// hir::Crate describes a single crate. It's the main inteface with which 14/// hir::Crate describes a single crate. It's the main inteface with which
8/// crate's dependencies interact. Mostly, it should be just a proxy for the 15/// crate's dependencies interact. Mostly, it should be just a proxy for the
@@ -111,3 +118,92 @@ impl Module {
111 self.problems_impl(db) 118 self.problems_impl(db)
112 } 119 }
113} 120}
121
122/// A single field of an enum variant or struct
123#[derive(Debug, Clone, PartialEq, Eq)]
124pub struct StructField {
125 pub(crate) name: Name,
126 pub(crate) type_ref: TypeRef,
127}
128
129impl StructField {
130 pub fn name(&self) -> &Name {
131 &self.name
132 }
133 pub fn type_ref(&self) -> &TypeRef {
134 &self.type_ref
135 }
136}
137
138/// Fields of an enum variant or struct
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub enum VariantData {
141 Struct(Vec<StructField>),
142 Tuple(Vec<StructField>),
143 Unit,
144}
145
146impl VariantData {
147 pub fn fields(&self) -> &[StructField] {
148 match self {
149 VariantData::Struct(fields) | VariantData::Tuple(fields) => fields,
150 _ => &[],
151 }
152 }
153 pub fn is_struct(&self) -> bool {
154 match self {
155 VariantData::Struct(..) => true,
156 _ => false,
157 }
158 }
159 pub fn is_tuple(&self) -> bool {
160 match self {
161 VariantData::Tuple(..) => true,
162 _ => false,
163 }
164 }
165 pub fn is_unit(&self) -> bool {
166 match self {
167 VariantData::Unit => true,
168 _ => false,
169 }
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Hash)]
174pub struct Struct {
175 pub(crate) def_id: DefId,
176}
177
178impl Struct {
179 pub fn def_id(&self) -> DefId {
180 self.def_id
181 }
182
183 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
184 Ok(db.struct_data(self.def_id)?.name.clone())
185 }
186
187 pub fn variant_data(&self, db: &impl HirDatabase) -> Cancelable<Arc<VariantData>> {
188 Ok(db.struct_data(self.def_id)?.variant_data.clone())
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Eq, Hash)]
193pub struct Enum {
194 pub(crate) def_id: DefId,
195}
196
197impl Enum {
198 pub fn def_id(&self) -> DefId {
199 self.def_id
200 }
201
202 pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> {
203 Ok(db.enum_data(self.def_id)?.name.clone())
204 }
205
206 pub fn variants(&self, db: &impl HirDatabase) -> Cancelable<Vec<(Name, Arc<VariantData>)>> {
207 Ok(db.enum_data(self.def_id)?.variants.clone())
208 }
209}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 03e65387d..bb4fb3d66 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -38,12 +38,12 @@ pub trait HirDatabase: SyntaxDatabase
38 38
39 fn struct_data(def_id: DefId) -> Cancelable<Arc<StructData>> { 39 fn struct_data(def_id: DefId) -> Cancelable<Arc<StructData>> {
40 type StructDataQuery; 40 type StructDataQuery;
41 use fn query_definitions::struct_data; 41 use fn crate::adt::StructData::struct_data_query;
42 } 42 }
43 43
44 fn enum_data(def_id: DefId) -> Cancelable<Arc<EnumData>> { 44 fn enum_data(def_id: DefId) -> Cancelable<Arc<EnumData>> {
45 type EnumDataQuery; 45 type EnumDataQuery;
46 use fn query_definitions::enum_data; 46 use fn crate::adt::EnumData::enum_data_query;
47 } 47 }
48 48
49 fn infer(def_id: DefId) -> Cancelable<Arc<InferenceResult>> { 49 fn infer(def_id: DefId) -> Cancelable<Arc<InferenceResult>> {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 9f133f174..cd04575d1 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -50,7 +50,6 @@ pub use self::{
50 module_tree::ModuleId, 50 module_tree::ModuleId,
51 nameres::{ItemMap, PerNs, Namespace, Resolution}, 51 nameres::{ItemMap, PerNs, Namespace, Resolution},
52 function::{Function, FnSignature, FnScopes, ScopesWithSyntaxMapping}, 52 function::{Function, FnSignature, FnScopes, ScopesWithSyntaxMapping},
53 adt::{Struct, Enum},
54 ty::Ty, 53 ty::Ty,
55 impl_block::{ImplBlock, ImplItem}, 54 impl_block::{ImplBlock, ImplItem},
56}; 55};
@@ -60,6 +59,7 @@ pub use self::function::FnSignatureInfo;
60pub use self::code_model_api::{ 59pub use self::code_model_api::{
61 Crate, CrateDependency, 60 Crate, CrateDependency,
62 Module, ModuleSource, Problem, 61 Module, ModuleSource, Problem,
62 Struct, Enum, VariantData, StructField,
63}; 63};
64 64
65pub enum Def { 65pub enum Def {
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index 380ea5410..ab4e6e629 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -11,13 +11,12 @@ use ra_syntax::{
11use ra_db::{SourceRootId, Cancelable,}; 11use ra_db::{SourceRootId, Cancelable,};
12 12
13use crate::{ 13use crate::{
14 SourceFileItems, SourceItemId, DefKind, DefId, HirFileId, ModuleSource, 14 SourceFileItems, SourceItemId, DefId, HirFileId, ModuleSource,
15 MacroCallLoc, 15 MacroCallLoc,
16 db::HirDatabase, 16 db::HirDatabase,
17 function::FnScopes, 17 function::FnScopes,
18 module_tree::ModuleId, 18 module_tree::ModuleId,
19 nameres::{InputModuleItems, ItemMap, Resolver}, 19 nameres::{InputModuleItems, ItemMap, Resolver},
20 adt::{StructData, EnumData},
21}; 20};
22 21
23pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<FnScopes>> { 22pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<FnScopes>> {
@@ -26,23 +25,6 @@ pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<
26 Ok(Arc::new(res)) 25 Ok(Arc::new(res))
27} 26}
28 27
29pub(super) fn struct_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<StructData>> {
30 let def_loc = def_id.loc(db);
31 assert!(def_loc.kind == DefKind::Struct);
32 let syntax = db.file_item(def_loc.source_item_id);
33 let struct_def =
34 ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
35 Ok(Arc::new(StructData::new(struct_def)))
36}
37
38pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<EnumData>> {
39 let def_loc = def_id.loc(db);
40 assert!(def_loc.kind == DefKind::Enum);
41 let syntax = db.file_item(def_loc.source_item_id);
42 let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
43 Ok(Arc::new(EnumData::new(enum_def)))
44}
45
46pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> { 28pub(super) fn file_items(db: &impl HirDatabase, file_id: HirFileId) -> Arc<SourceFileItems> {
47 let source_file = db.hir_source_file(file_id); 29 let source_file = db.hir_source_file(file_id);
48 let res = SourceFileItems::new(file_id, &source_file); 30 let res = SourceFileItems::new(file_id, &source_file);