diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/display.rs | 180 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 36 |
2 files changed, 213 insertions, 3 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index ae08e2584..0640712de 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs | |||
@@ -1,8 +1,9 @@ | |||
1 | //! HirDisplay implementations for various hir types. | 1 | //! HirDisplay implementations for various hir types. |
2 | use hir_def::{ | 2 | use hir_def::{ |
3 | adt::VariantData, | ||
3 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, | 4 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, |
4 | type_ref::{TypeBound, TypeRef}, | 5 | type_ref::{TypeBound, TypeRef}, |
5 | GenericDefId, | 6 | AdtId, GenericDefId, |
6 | }; | 7 | }; |
7 | use hir_ty::display::{ | 8 | use hir_ty::display::{ |
8 | write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, | 9 | write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, |
@@ -10,7 +11,10 @@ use hir_ty::display::{ | |||
10 | }; | 11 | }; |
11 | use syntax::ast::{self, NameOwner}; | 12 | use syntax::ast::{self, NameOwner}; |
12 | 13 | ||
13 | use crate::{Function, HasVisibility, Substs, Type, TypeParam}; | 14 | use crate::{ |
15 | Const, ConstParam, Enum, Field, Function, HasVisibility, Module, Static, Struct, Substs, Trait, | ||
16 | Type, TypeAlias, TypeParam, Union, Variant, | ||
17 | }; | ||
14 | 18 | ||
15 | impl HirDisplay for Function { | 19 | impl HirDisplay for Function { |
16 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 20 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
@@ -116,6 +120,91 @@ impl HirDisplay for Function { | |||
116 | } | 120 | } |
117 | } | 121 | } |
118 | 122 | ||
123 | impl HirDisplay for Struct { | ||
124 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
125 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
126 | write!(f, "struct ")?; | ||
127 | write!(f, "{}", self.name(f.db))?; | ||
128 | let def_id = GenericDefId::AdtId(AdtId::StructId(self.id)); | ||
129 | write_generic_params(def_id, f)?; | ||
130 | write_where_clause(def_id, f)?; | ||
131 | Ok(()) | ||
132 | } | ||
133 | } | ||
134 | |||
135 | impl HirDisplay for Enum { | ||
136 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
137 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
138 | write!(f, "enum ")?; | ||
139 | write!(f, "{}", self.name(f.db))?; | ||
140 | let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id)); | ||
141 | write_generic_params(def_id, f)?; | ||
142 | write_where_clause(def_id, f)?; | ||
143 | Ok(()) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | impl HirDisplay for Union { | ||
148 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
149 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
150 | write!(f, "union ")?; | ||
151 | write!(f, "{}", self.name(f.db))?; | ||
152 | let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id)); | ||
153 | write_generic_params(def_id, f)?; | ||
154 | write_where_clause(def_id, f)?; | ||
155 | Ok(()) | ||
156 | } | ||
157 | } | ||
158 | |||
159 | impl HirDisplay for Field { | ||
160 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
161 | write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?; | ||
162 | write!(f, "{}: ", self.name(f.db))?; | ||
163 | self.signature_ty(f.db).hir_fmt(f) | ||
164 | } | ||
165 | } | ||
166 | |||
167 | impl HirDisplay for Variant { | ||
168 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
169 | write!(f, "{}", self.name(f.db))?; | ||
170 | let data = self.variant_data(f.db); | ||
171 | match &*data { | ||
172 | VariantData::Unit => {} | ||
173 | VariantData::Tuple(fields) => { | ||
174 | write!(f, "(")?; | ||
175 | let mut first = true; | ||
176 | for (_, field) in fields.iter() { | ||
177 | if first { | ||
178 | first = false; | ||
179 | } else { | ||
180 | write!(f, ", ")?; | ||
181 | } | ||
182 | // Enum variant fields must be pub. | ||
183 | field.type_ref.hir_fmt(f)?; | ||
184 | } | ||
185 | write!(f, ")")?; | ||
186 | } | ||
187 | VariantData::Record(fields) => { | ||
188 | write!(f, " {{")?; | ||
189 | let mut first = true; | ||
190 | for (_, field) in fields.iter() { | ||
191 | if first { | ||
192 | first = false; | ||
193 | write!(f, " ")?; | ||
194 | } else { | ||
195 | write!(f, ", ")?; | ||
196 | } | ||
197 | // Enum variant fields must be pub. | ||
198 | write!(f, "{}: ", field.name)?; | ||
199 | field.type_ref.hir_fmt(f)?; | ||
200 | } | ||
201 | write!(f, " }}")?; | ||
202 | } | ||
203 | } | ||
204 | Ok(()) | ||
205 | } | ||
206 | } | ||
207 | |||
119 | impl HirDisplay for Type { | 208 | impl HirDisplay for Type { |
120 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 209 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
121 | self.ty.value.hir_fmt(f) | 210 | self.ty.value.hir_fmt(f) |
@@ -135,6 +224,13 @@ impl HirDisplay for TypeParam { | |||
135 | } | 224 | } |
136 | } | 225 | } |
137 | 226 | ||
227 | impl HirDisplay for ConstParam { | ||
228 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
229 | write!(f, "const {}: ", self.name(f.db))?; | ||
230 | self.ty(f.db).hir_fmt(f) | ||
231 | } | ||
232 | } | ||
233 | |||
138 | fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 234 | fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
139 | let params = f.db.generic_params(def); | 235 | let params = f.db.generic_params(def); |
140 | if params.lifetimes.is_empty() && params.types.is_empty() && params.consts.is_empty() { | 236 | if params.lifetimes.is_empty() && params.types.is_empty() && params.consts.is_empty() { |
@@ -253,3 +349,83 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir | |||
253 | 349 | ||
254 | Ok(()) | 350 | Ok(()) |
255 | } | 351 | } |
352 | |||
353 | impl HirDisplay for Const { | ||
354 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
355 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
356 | let data = f.db.const_data(self.id); | ||
357 | write!(f, "const ")?; | ||
358 | match &data.name { | ||
359 | Some(name) => write!(f, "{}: ", name)?, | ||
360 | None => write!(f, "_: ")?, | ||
361 | } | ||
362 | data.type_ref.hir_fmt(f)?; | ||
363 | Ok(()) | ||
364 | } | ||
365 | } | ||
366 | |||
367 | impl HirDisplay for Static { | ||
368 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
369 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
370 | let data = f.db.static_data(self.id); | ||
371 | write!(f, "static ")?; | ||
372 | if data.mutable { | ||
373 | write!(f, "mut ")?; | ||
374 | } | ||
375 | match &data.name { | ||
376 | Some(name) => write!(f, "{}: ", name)?, | ||
377 | None => write!(f, "_: ")?, | ||
378 | } | ||
379 | data.type_ref.hir_fmt(f)?; | ||
380 | Ok(()) | ||
381 | } | ||
382 | } | ||
383 | |||
384 | impl HirDisplay for Trait { | ||
385 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
386 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
387 | let data = f.db.trait_data(self.id); | ||
388 | if data.is_unsafe { | ||
389 | write!(f, "unsafe ")?; | ||
390 | } | ||
391 | if data.is_auto { | ||
392 | write!(f, "auto ")?; | ||
393 | } | ||
394 | write!(f, "trait {}", data.name)?; | ||
395 | let def_id = GenericDefId::TraitId(self.id); | ||
396 | write_generic_params(def_id, f)?; | ||
397 | if !data.bounds.is_empty() { | ||
398 | write!(f, ": ")?; | ||
399 | f.write_joined(&*data.bounds, " + ")?; | ||
400 | } | ||
401 | write_where_clause(def_id, f)?; | ||
402 | Ok(()) | ||
403 | } | ||
404 | } | ||
405 | |||
406 | impl HirDisplay for TypeAlias { | ||
407 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
408 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
409 | let data = f.db.type_alias_data(self.id); | ||
410 | write!(f, "type {}", data.name)?; | ||
411 | if !data.bounds.is_empty() { | ||
412 | write!(f, ": ")?; | ||
413 | f.write_joined(&data.bounds, " + ")?; | ||
414 | } | ||
415 | if let Some(ty) = &data.type_ref { | ||
416 | write!(f, " = ")?; | ||
417 | ty.hir_fmt(f)?; | ||
418 | } | ||
419 | Ok(()) | ||
420 | } | ||
421 | } | ||
422 | |||
423 | impl HirDisplay for Module { | ||
424 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
425 | // FIXME: Module doesn't have visibility saved in data. | ||
426 | match self.name(f.db) { | ||
427 | Some(name) => write!(f, "mod {}", name), | ||
428 | None => write!(f, "mod {{unnamed}}"), | ||
429 | } | ||
430 | } | ||
431 | } | ||
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 476fdb132..98135602a 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -572,6 +572,12 @@ impl Struct { | |||
572 | } | 572 | } |
573 | } | 573 | } |
574 | 574 | ||
575 | impl HasVisibility for Struct { | ||
576 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
577 | db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
578 | } | ||
579 | } | ||
580 | |||
575 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 581 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
576 | pub struct Union { | 582 | pub struct Union { |
577 | pub(crate) id: UnionId, | 583 | pub(crate) id: UnionId, |
@@ -604,6 +610,12 @@ impl Union { | |||
604 | } | 610 | } |
605 | } | 611 | } |
606 | 612 | ||
613 | impl HasVisibility for Union { | ||
614 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
615 | db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
616 | } | ||
617 | } | ||
618 | |||
607 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 619 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
608 | pub struct Enum { | 620 | pub struct Enum { |
609 | pub(crate) id: EnumId, | 621 | pub(crate) id: EnumId, |
@@ -631,6 +643,12 @@ impl Enum { | |||
631 | } | 643 | } |
632 | } | 644 | } |
633 | 645 | ||
646 | impl HasVisibility for Enum { | ||
647 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
648 | db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
649 | } | ||
650 | } | ||
651 | |||
634 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 652 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
635 | pub struct Variant { | 653 | pub struct Variant { |
636 | pub(crate) parent: Enum, | 654 | pub(crate) parent: Enum, |
@@ -962,6 +980,10 @@ impl Const { | |||
962 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 980 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
963 | db.const_data(self.id).name.clone() | 981 | db.const_data(self.id).name.clone() |
964 | } | 982 | } |
983 | |||
984 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | ||
985 | db.const_data(self.id).type_ref.clone() | ||
986 | } | ||
965 | } | 987 | } |
966 | 988 | ||
967 | impl HasVisibility for Const { | 989 | impl HasVisibility for Const { |
@@ -995,6 +1017,12 @@ impl Static { | |||
995 | } | 1017 | } |
996 | } | 1018 | } |
997 | 1019 | ||
1020 | impl HasVisibility for Static { | ||
1021 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1022 | db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1023 | } | ||
1024 | } | ||
1025 | |||
998 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1026 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
999 | pub struct Trait { | 1027 | pub struct Trait { |
1000 | pub(crate) id: TraitId, | 1028 | pub(crate) id: TraitId, |
@@ -1014,7 +1042,13 @@ impl Trait { | |||
1014 | } | 1042 | } |
1015 | 1043 | ||
1016 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { | 1044 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { |
1017 | db.trait_data(self.id).auto | 1045 | db.trait_data(self.id).is_auto |
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | impl HasVisibility for Trait { | ||
1050 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1051 | db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1018 | } | 1052 | } |
1019 | } | 1053 | } |
1020 | 1054 | ||