1use std::sync::Arc;
2
3use indexmap::IndexMap;
4use mir_types::Union;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12pub enum Visibility {
13 Public,
14 Protected,
15 Private,
16}
17
18impl Visibility {
19 pub fn is_at_least(&self, required: Visibility) -> bool {
20 *self <= required
21 }
22}
23
24impl std::fmt::Display for Visibility {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 match self {
27 Visibility::Public => write!(f, "public"),
28 Visibility::Protected => write!(f, "protected"),
29 Visibility::Private => write!(f, "private"),
30 }
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
35pub struct TemplateParam {
36 pub name: Arc<str>,
37 pub bound: Option<Union>,
38 pub defining_entity: Arc<str>,
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
43pub struct FnParam {
44 pub name: Arc<str>,
45 pub ty: Option<Union>,
46 pub default: Option<Union>,
47 pub is_variadic: bool,
48 pub is_byref: bool,
49 pub is_optional: bool,
50}
51
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
57pub struct Location {
58 pub file: Arc<str>,
59 pub start: u32,
61 pub end: u32,
62 pub line: u32,
64 pub col: u16,
66}
67
68impl Location {
69 pub fn new(file: Arc<str>, start: u32, end: u32) -> Self {
70 Self {
71 file,
72 start,
73 end,
74 line: 1,
75 col: 0,
76 }
77 }
78
79 pub fn with_line_col(file: Arc<str>, start: u32, end: u32, line: u32, col: u16) -> Self {
80 Self {
81 file,
82 start,
83 end,
84 line,
85 col,
86 }
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
95pub enum AssertionKind {
96 Assert,
97 AssertIfTrue,
98 AssertIfFalse,
99}
100
101#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
102pub struct Assertion {
103 pub kind: AssertionKind,
104 pub param: Arc<str>,
105 pub ty: Union,
106}
107
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub struct MethodStorage {
114 pub name: Arc<str>,
115 pub fqcn: Arc<str>,
116 pub params: Vec<FnParam>,
117 pub return_type: Option<Union>,
119 pub inferred_return_type: Option<Union>,
121 pub visibility: Visibility,
122 pub is_static: bool,
123 pub is_abstract: bool,
124 pub is_final: bool,
125 pub is_constructor: bool,
126 pub template_params: Vec<TemplateParam>,
127 pub assertions: Vec<Assertion>,
128 pub throws: Vec<Arc<str>>,
129 pub is_deprecated: bool,
130 pub is_internal: bool,
131 pub is_pure: bool,
132 pub location: Option<Location>,
133}
134
135impl MethodStorage {
136 pub fn effective_return_type(&self) -> Option<&Union> {
137 self.return_type
138 .as_ref()
139 .or(self.inferred_return_type.as_ref())
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
148pub struct PropertyStorage {
149 pub name: Arc<str>,
150 pub ty: Option<Union>,
151 pub inferred_ty: Option<Union>,
152 pub visibility: Visibility,
153 pub is_static: bool,
154 pub is_readonly: bool,
155 pub default: Option<Union>,
156 pub location: Option<Location>,
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
164pub struct ConstantStorage {
165 pub name: Arc<str>,
166 pub ty: Union,
167 pub visibility: Option<Visibility>,
168 pub location: Option<Location>,
169}
170
171#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
176pub struct ClassStorage {
177 pub fqcn: Arc<str>,
178 pub short_name: Arc<str>,
179 pub parent: Option<Arc<str>>,
180 pub interfaces: Vec<Arc<str>>,
181 pub traits: Vec<Arc<str>>,
182 pub own_methods: IndexMap<Arc<str>, MethodStorage>,
183 pub own_properties: IndexMap<Arc<str>, PropertyStorage>,
184 pub own_constants: IndexMap<Arc<str>, ConstantStorage>,
185 pub template_params: Vec<TemplateParam>,
186 pub is_abstract: bool,
187 pub is_final: bool,
188 pub is_readonly: bool,
189 pub all_methods: IndexMap<Arc<str>, MethodStorage>,
191 pub all_parents: Vec<Arc<str>>,
193 pub is_deprecated: bool,
194 pub is_internal: bool,
195 pub location: Option<Location>,
196}
197
198impl ClassStorage {
199 pub fn get_method(&self, name: &str) -> Option<&MethodStorage> {
200 if let Some(m) = self
203 .all_methods
204 .get(name)
205 .or_else(|| self.own_methods.get(name))
206 {
207 return Some(m);
208 }
209 self.all_methods
211 .iter()
212 .find(|(k, _)| k.as_ref().eq_ignore_ascii_case(name))
213 .map(|(_, v)| v)
214 .or_else(|| {
215 self.own_methods
216 .iter()
217 .find(|(k, _)| k.as_ref().eq_ignore_ascii_case(name))
218 .map(|(_, v)| v)
219 })
220 }
221
222 pub fn get_property(&self, name: &str) -> Option<&PropertyStorage> {
223 self.own_properties.get(name)
224 }
225
226 pub fn implements_or_extends(&self, fqcn: &str) -> bool {
227 self.fqcn.as_ref() == fqcn || self.all_parents.iter().any(|p| p.as_ref() == fqcn)
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
236pub struct InterfaceStorage {
237 pub fqcn: Arc<str>,
238 pub short_name: Arc<str>,
239 pub extends: Vec<Arc<str>>,
240 pub own_methods: IndexMap<Arc<str>, MethodStorage>,
241 pub own_constants: IndexMap<Arc<str>, ConstantStorage>,
242 pub template_params: Vec<TemplateParam>,
243 pub all_parents: Vec<Arc<str>>,
244 pub location: Option<Location>,
245}
246
247#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
252pub struct TraitStorage {
253 pub fqcn: Arc<str>,
254 pub short_name: Arc<str>,
255 pub own_methods: IndexMap<Arc<str>, MethodStorage>,
256 pub own_properties: IndexMap<Arc<str>, PropertyStorage>,
257 pub own_constants: IndexMap<Arc<str>, ConstantStorage>,
258 pub template_params: Vec<TemplateParam>,
259 pub location: Option<Location>,
260}
261
262#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
267pub struct EnumCaseStorage {
268 pub name: Arc<str>,
269 pub value: Option<Union>,
270 pub location: Option<Location>,
271}
272
273#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
274pub struct EnumStorage {
275 pub fqcn: Arc<str>,
276 pub short_name: Arc<str>,
277 pub scalar_type: Option<Union>,
278 pub interfaces: Vec<Arc<str>>,
279 pub cases: IndexMap<Arc<str>, EnumCaseStorage>,
280 pub own_methods: IndexMap<Arc<str>, MethodStorage>,
281 pub own_constants: IndexMap<Arc<str>, ConstantStorage>,
282 pub location: Option<Location>,
283}
284
285#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
290pub struct FunctionStorage {
291 pub fqn: Arc<str>,
292 pub short_name: Arc<str>,
293 pub params: Vec<FnParam>,
294 pub return_type: Option<Union>,
295 pub inferred_return_type: Option<Union>,
296 pub template_params: Vec<TemplateParam>,
297 pub assertions: Vec<Assertion>,
298 pub throws: Vec<Arc<str>>,
299 pub is_deprecated: bool,
300 pub is_pure: bool,
301 pub location: Option<Location>,
302}
303
304impl FunctionStorage {
305 pub fn effective_return_type(&self) -> Option<&Union> {
306 self.return_type
307 .as_ref()
308 .or(self.inferred_return_type.as_ref())
309 }
310}