1use std::fmt::{self, Display};
8
9use crate::def::DefKind;
10use crate::{Item, ItemKind, TraitItem, TraitItemKind, hir};
11
12#[derive(Copy, Clone, PartialEq, Debug)]
13pub enum GenericParamKind {
14 Type,
15 Lifetime,
16 Const,
17}
18
19#[derive(Copy, Clone, PartialEq, Debug)]
20pub enum MethodKind {
21 Trait { body: bool },
22 Inherent,
23}
24
25#[derive(Copy, Clone, PartialEq, Debug)]
26pub enum Target {
27 ExternCrate,
28 Use,
29 Static,
30 Const,
31 Fn,
32 Closure,
33 Mod,
34 ForeignMod,
35 GlobalAsm,
36 TyAlias,
37 Enum,
38 Variant,
39 Struct,
40 Field,
41 Union,
42 Trait,
43 TraitAlias,
44 Impl { of_trait: bool },
45 Expression,
46 Statement,
47 Arm,
48 AssocConst,
49 Method(MethodKind),
50 AssocTy,
51 ForeignFn,
52 ForeignStatic,
53 ForeignTy,
54 GenericParam { kind: GenericParamKind, has_default: bool },
55 MacroDef,
56 Param,
57 PatField,
58 ExprField,
59 WherePredicate,
60}
61
62impl Display for Target {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "{}", Self::name(*self))
65 }
66}
67
68impl Target {
69 pub fn is_associated_item(self) -> bool {
70 match self {
71 Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
72 Target::ExternCrate
73 | Target::Use
74 | Target::Static
75 | Target::Const
76 | Target::Fn
77 | Target::Closure
78 | Target::Mod
79 | Target::ForeignMod
80 | Target::GlobalAsm
81 | Target::TyAlias
82 | Target::Enum
83 | Target::Variant
84 | Target::Struct
85 | Target::Field
86 | Target::Union
87 | Target::Trait
88 | Target::TraitAlias
89 | Target::Impl { .. }
90 | Target::Expression
91 | Target::Statement
92 | Target::Arm
93 | Target::ForeignFn
94 | Target::ForeignStatic
95 | Target::ForeignTy
96 | Target::GenericParam { .. }
97 | Target::MacroDef
98 | Target::Param
99 | Target::PatField
100 | Target::ExprField
101 | Target::WherePredicate => false,
102 }
103 }
104
105 pub fn from_item(item: &Item<'_>) -> Target {
106 match item.kind {
107 ItemKind::ExternCrate(..) => Target::ExternCrate,
108 ItemKind::Use(..) => Target::Use,
109 ItemKind::Static { .. } => Target::Static,
110 ItemKind::Const(..) => Target::Const,
111 ItemKind::Fn { .. } => Target::Fn,
112 ItemKind::Macro(..) => Target::MacroDef,
113 ItemKind::Mod(..) => Target::Mod,
114 ItemKind::ForeignMod { .. } => Target::ForeignMod,
115 ItemKind::GlobalAsm { .. } => Target::GlobalAsm,
116 ItemKind::TyAlias(..) => Target::TyAlias,
117 ItemKind::Enum(..) => Target::Enum,
118 ItemKind::Struct(..) => Target::Struct,
119 ItemKind::Union(..) => Target::Union,
120 ItemKind::Trait(..) => Target::Trait,
121 ItemKind::TraitAlias(..) => Target::TraitAlias,
122 ItemKind::Impl(imp_) => Target::Impl { of_trait: imp_.of_trait.is_some() },
123 }
124 }
125
126 pub fn from_def_kind(def_kind: DefKind) -> Target {
128 match def_kind {
129 DefKind::ExternCrate => Target::ExternCrate,
130 DefKind::Use => Target::Use,
131 DefKind::Static { .. } => Target::Static,
132 DefKind::Const => Target::Const,
133 DefKind::Fn => Target::Fn,
134 DefKind::Macro(..) => Target::MacroDef,
135 DefKind::Mod => Target::Mod,
136 DefKind::ForeignMod => Target::ForeignMod,
137 DefKind::GlobalAsm => Target::GlobalAsm,
138 DefKind::TyAlias => Target::TyAlias,
139 DefKind::Enum => Target::Enum,
140 DefKind::Struct => Target::Struct,
141 DefKind::Union => Target::Union,
142 DefKind::Trait => Target::Trait,
143 DefKind::TraitAlias => Target::TraitAlias,
144 DefKind::Impl { of_trait } => Target::Impl { of_trait },
145 _ => panic!("impossible case reached"),
146 }
147 }
148
149 pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
150 match trait_item.kind {
151 TraitItemKind::Const(..) => Target::AssocConst,
152 TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => {
153 Target::Method(MethodKind::Trait { body: false })
154 }
155 TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => {
156 Target::Method(MethodKind::Trait { body: true })
157 }
158 TraitItemKind::Type(..) => Target::AssocTy,
159 }
160 }
161
162 pub fn from_foreign_item(foreign_item: &hir::ForeignItem<'_>) -> Target {
163 match foreign_item.kind {
164 hir::ForeignItemKind::Fn(..) => Target::ForeignFn,
165 hir::ForeignItemKind::Static(..) => Target::ForeignStatic,
166 hir::ForeignItemKind::Type => Target::ForeignTy,
167 }
168 }
169
170 pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
171 match generic_param.kind {
172 hir::GenericParamKind::Type { default, .. } => Target::GenericParam {
173 kind: GenericParamKind::Type,
174 has_default: default.is_some(),
175 },
176 hir::GenericParamKind::Lifetime { .. } => {
177 Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: false }
178 }
179 hir::GenericParamKind::Const { default, .. } => Target::GenericParam {
180 kind: GenericParamKind::Const,
181 has_default: default.is_some(),
182 },
183 }
184 }
185
186 pub fn name(self) -> &'static str {
187 match self {
188 Target::ExternCrate => "extern crate",
189 Target::Use => "use",
190 Target::Static => "static item",
191 Target::Const => "constant item",
192 Target::Fn => "function",
193 Target::Closure => "closure",
194 Target::Mod => "module",
195 Target::ForeignMod => "foreign module",
196 Target::GlobalAsm => "global asm",
197 Target::TyAlias => "type alias",
198 Target::Enum => "enum",
199 Target::Variant => "enum variant",
200 Target::Struct => "struct",
201 Target::Field => "struct field",
202 Target::Union => "union",
203 Target::Trait => "trait",
204 Target::TraitAlias => "trait alias",
205 Target::Impl { of_trait: false } => "inherent implementation block",
206 Target::Impl { of_trait: true } => "trait implementation block",
207 Target::Expression => "expression",
208 Target::Statement => "statement",
209 Target::Arm => "match arm",
210 Target::AssocConst => "associated const",
211 Target::Method(kind) => match kind {
212 MethodKind::Inherent => "inherent method",
213 MethodKind::Trait { body: false } => "required trait method",
214 MethodKind::Trait { body: true } => "provided trait method",
215 },
216 Target::AssocTy => "associated type",
217 Target::ForeignFn => "foreign function",
218 Target::ForeignStatic => "foreign static item",
219 Target::ForeignTy => "foreign type",
220 Target::GenericParam { kind, has_default: _ } => match kind {
221 GenericParamKind::Type => "type parameter",
222 GenericParamKind::Lifetime => "lifetime parameter",
223 GenericParamKind::Const => "const parameter",
224 },
225 Target::MacroDef => "macro def",
226 Target::Param => "function param",
227 Target::PatField => "pattern field",
228 Target::ExprField => "struct field",
229 Target::WherePredicate => "where predicate",
230 }
231 }
232}