1use super::*;
2use crate::parser::Position;
3
4pub enum ClassElement {
5 Attribute(Attribute<ClassId>),
6 Method(Method<ClassId>),
7}
8
9#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
12pub struct ClassId(pub usize);
13
14impl Id for ClassId {
15 fn empty() -> Self {
16 Self(0)
17 }
18}
19
20#[derive(Clone)]
23pub struct Class {
24 id: ClassId,
25 name: String,
26 typ: Type,
27 extends: Option<Type>,
28 attributes: Vec<Attribute<ClassId>>,
29 methods: Vec<Method<ClassId>>,
30 position: Option<Position>,
31}
32
33impl Class {
34 pub fn new<S: Into<String>>(
35 name: S,
36 extends: Option<Type>,
37 position: Option<Position>,
38 ) -> Self {
39 let id = ClassId::empty();
40 let name = name.into();
41 Self {
42 id,
43 name,
44 typ: Type::Class(id),
45 extends,
46 attributes: vec![],
47 methods: vec![],
48 position,
49 }
50 }
51
52 pub fn extends(&self) -> &Option<Type> {
55 &self.extends
56 }
57
58 pub fn super_class(&self) -> Option<ClassId> {
59 if let Some(t) = &self.extends {
60 match t {
61 Type::Class(c) => Some(*c),
62 _ => None,
63 }
64 } else {
65 None
66 }
67 }
68
69 pub fn direct_sub_classes(&self, problem: &Problem) -> Vec<ClassId> {
70 problem
71 .classes()
72 .iter()
73 .filter(|c| c.super_class() == Some(self.id()))
74 .map(|c| c.id())
75 .collect()
76 }
77
78 pub fn super_classes(&self, problem: &Problem) -> Vec<ClassId> {
79 if let Some(c) = self.super_class() {
80 let mut v = Vec::new();
81 let mut todo = vec![c];
82
83 while !todo.is_empty() {
84 let c = todo.pop().unwrap();
85 if !v.contains(&c) {
86 v.push(c);
87 if let Some(s) = problem.get(c).unwrap().super_class() {
88 todo.push(s);
89 }
90 }
91 }
92 v
93 } else {
94 vec![]
95 }
96 }
97
98 pub fn sub_classes(&self, problem: &Problem) -> Vec<ClassId> {
99 problem
100 .classes()
101 .iter()
102 .filter(|c| c.super_classes(problem).contains(&self.id()))
103 .map(|c| c.id())
104 .collect()
105 }
106
107 pub fn common_class(&self, problem: &Problem, other: ClassId) -> Option<ClassId> {
108 let mut l1 = self.super_classes(problem);
109 l1.push(self.id());
110 let mut l2 = problem.get(other).unwrap().super_classes(problem);
111 l2.push(other);
112 let mut res = None;
114 for c in l1.iter() {
115 if !l2.contains(c) {
116 return res;
117 }
118 res = Some(*c);
119 }
120 res
121 }
122
123 pub fn add_attribute(&mut self, mut attribute: Attribute<ClassId>) -> AttributeId<ClassId> {
126 let id = AttributeId(self.id(), self.attributes.len());
127 attribute.set_id(id);
128 self.attributes.push(attribute);
129 id
130 }
131
132 pub fn get_attribute(&self, id: AttributeId<ClassId>) -> Option<&Attribute<ClassId>> {
133 let AttributeId(structure_id, n) = id;
134 if self.id != structure_id {
135 None
136 } else {
137 self.attributes.get(n)
138 }
139 }
140
141 pub fn attributes(&self) -> &Vec<Attribute<ClassId>> {
142 &self.attributes
143 }
144
145 pub fn all_attributes(&self, problem: &Problem) -> Vec<AttributeId<ClassId>> {
146 let mut classes = self.super_classes(problem).clone();
147 classes.push(self.id());
148 let mut v = Vec::new();
149 for id in classes.iter() {
150 let c = problem.get(*id).unwrap();
151 v.extend(c.attributes().iter().map(|a| a.id()));
152 }
153 v
154 }
155
156 pub fn find_attribute(&self, name: &str) -> Option<&Attribute<ClassId>> {
157 self.attributes.iter().find(|x| x.name() == name)
158 }
159
160 pub fn find_all_attribute(&self, problem: &Problem, name: &str) -> Option<Attribute<ClassId>> {
161 for x in self.attributes.iter() {
162 if x.name() == name {
163 return Some(x.clone());
164 }
165 }
166 for c in self.super_classes(problem).iter() {
167 let c = problem.get(*c).unwrap();
168 for x in c.attributes.iter() {
169 if x.name() == name {
170 return Some(x.clone());
171 }
172 }
173 }
174 None
175 }
176
177 pub fn add_method(&mut self, mut method: Method<ClassId>) -> MethodId<ClassId> {
180 let id = MethodId(self.id(), self.methods.len());
181 method.set_id(id);
182 self.methods.push(method);
183 id
184 }
185
186 pub fn get_method(&self, id: MethodId<ClassId>) -> Option<&Method<ClassId>> {
187 let MethodId(class_id, n) = id;
188 if self.id != class_id {
189 None
190 } else {
191 self.methods.get(n)
192 }
193 }
194
195 pub fn methods(&self) -> &Vec<Method<ClassId>> {
196 &self.methods
197 }
198
199 pub fn all_methods(&self, problem: &Problem) -> Vec<MethodId<ClassId>> {
200 let mut classes = self.super_classes(problem).clone();
201 classes.push(self.id());
202 let mut v = Vec::new();
203 for id in classes.iter() {
204 let c = problem.get(*id).unwrap();
205 v.extend(c.methods().iter().map(|a| a.id()));
206 }
207 v
208 }
209
210 pub fn find_method(&self, name: &str) -> Option<&Method<ClassId>> {
211 self.methods.iter().find(|x| x.name() == name)
212 }
213
214 pub fn find_all_method(&self, problem: &Problem, name: &str) -> Option<Method<ClassId>> {
215 for x in self.methods.iter() {
216 if x.name() == name {
217 return Some(x.clone());
218 }
219 }
220 for c in self.super_classes(problem).iter() {
221 let c = problem.get(*c).unwrap();
222 for x in c.methods.iter() {
223 if x.name() == name {
224 return Some(x.clone());
225 }
226 }
227 }
228 None
229 }
230
231 pub fn instances(&self, problem: &Problem) -> Vec<InstanceId> {
234 let mut v = Vec::new();
235 for inst in problem.instances().iter() {
236 match inst.typ() {
237 Type::Class(id) => {
238 if *id == self.id() {
239 v.push(inst.id());
240 }
241 }
242 _ => {}
243 }
244 }
245 v
246 }
247
248 pub fn is_empty(&self, problem: &Problem) -> bool {
249 self.all_instances(problem).is_empty()
250 }
251
252 pub fn all_instances(&self, problem: &Problem) -> Vec<InstanceId> {
253 let mut v = self.instances(problem).clone();
254 for c in self.sub_classes(problem).iter() {
255 v.extend(problem.get(*c).unwrap().instances(problem));
256 }
257 v
258 }
259
260 pub fn local_naming(&self, problem: &Problem) -> Vec<Naming> {
263 let mut v = vec![];
264 v.extend(
265 self.all_attributes(problem)
266 .iter()
267 .map(|x| problem.get(*x).unwrap().naming()),
268 );
269 v.extend(
270 self.all_methods(problem)
271 .iter()
272 .map(|x| problem.get(*x).unwrap().naming()),
273 );
274 v
275 }
276
277 pub fn duplicate(&self, problem: &Problem) -> Result<(), Error> {
278 let namings = self.local_naming(problem);
279 check_duplicate(namings)?;
280 for x in self.methods.iter() {
281 x.duplicate()?;
282 }
283 Ok(())
284 }
285
286 pub fn resolve_type_expr(&mut self, entries: &TypeEntries) -> Result<(), Error> {
289 for x in self.attributes.iter_mut() {
291 x.resolve_type(entries)?;
292 x.resolve_type_expr(entries)?;
293 }
294 for x in self.methods.iter_mut() {
296 x.resolve_type(entries)?;
297 x.resolve_type_expr(entries)?;
298 }
299 Ok(())
301 }
302
303 pub fn resolve_expr(&self, problem: &Problem, entries: &Entries) -> Result<Class, Error> {
304 let mut attributes = Vec::new();
306 for x in self.attributes.iter() {
307 let a = x.resolve_expr(problem, &entries)?;
308 attributes.push(a);
309 }
310 let mut methods = Vec::new();
312 for x in self.methods.iter() {
313 let m = x.resolve_expr(problem, &entries)?;
314 methods.push(m);
315 }
316 Ok(Class {
318 id: self.id,
319 name: self.name.clone(),
320 typ: self.typ.clone(),
321 extends: self.extends.clone(),
322 attributes,
323 methods,
324 position: self.position.clone(),
325 })
326 }
327
328 pub fn check_parameter_size(&self, problem: &Problem) -> Result<(), Error> {
331 for x in self.attributes.iter() {
332 x.check_parameter_size(problem)?;
333 }
334 for x in self.methods.iter() {
335 x.check_parameter_size(problem)?;
336 }
337 Ok(())
338 }
339
340 pub fn check_bounded(&self, problem: &Problem) -> Result<(), Error> {
343 for x in self.methods.iter() {
344 x.check_bounded(problem)?;
345 }
346 Ok(())
347 }
348
349 pub fn check_type(&self, problem: &Problem) -> Result<(), Error> {
352 for x in self.attributes.iter() {
353 x.check_type(problem)?;
354 }
355 for x in self.methods.iter() {
356 x.check_type(problem)?;
357 }
358 Ok(())
359 }
360
361 pub fn check_cycle(&self, problem: &Problem) -> Result<(), Error> {
362 let classes = self.super_classes(problem);
363 if classes.contains(&self.id()) {
364 Err(Error::Cyclic { id: self.id() })
365 } else {
366 Ok(())
367 }
368 }
369}
370
371impl WithPosition for Class {
374 fn position(&self) -> &Option<Position> {
375 &self.position
376 }
377}
378
379impl Named<ClassId> for Class {
382 fn id(&self) -> ClassId {
383 self.id
384 }
385
386 fn set_id(&mut self, id: ClassId) {
387 self.id = id;
388 self.typ = Type::Class(id);
389 for (n, x) in self.attributes.iter_mut().enumerate() {
390 let id = AttributeId(id, n);
391 x.set_id(id);
392 }
393 for (n, x) in self.methods.iter_mut().enumerate() {
394 let id = MethodId(id, n);
395 x.set_id(id);
396 }
397 }
398
399 fn name(&self) -> &str {
400 &self.name
401 }
402}
403
404impl WithType for Class {
407 fn typ(&self) -> &Type {
408 &self.typ
409 }
410
411 fn set_type(&mut self, _: Type) {}
412
413 fn resolve_type_children(&mut self, entries: &TypeEntries) -> Result<(), Error> {
414 if let Some(c) = &self.extends {
415 let c = c.resolve_type(entries)?;
416 self.extends = Some(c);
417 }
418 for x in self.attributes.iter_mut() {
419 x.resolve_type(&entries)?;
420 }
421 for x in self.methods.iter_mut() {
422 x.resolve_type(&entries)?;
423 }
424 Ok(())
425 }
426
427 fn check_interval_children(&self, problem: &Problem) -> Result<(), Error> {
428 for x in self.attributes.iter() {
429 x.check_interval(problem)?;
430 }
431 for x in self.methods.iter() {
432 x.check_interval(problem)?;
433 }
434 Ok(())
435 }
436}
437
438impl ToLang for Class {
441 fn to_lang(&self, problem: &Problem) -> String {
442 let mut s = format!("class {}", self.name());
443 if let Some(c) = &self.extends {
445 s.push_str(&format!(" extends {}", c.to_lang(problem)));
446 }
447 s.push_str(" {\n");
448 for x in self.attributes.iter() {
450 s.push_str(&format!("{}\n", &x.to_lang(problem)));
451 }
452 for x in self.methods.iter() {
454 s.push_str(&format!("{}", &x.to_lang(problem)));
455 s.push_str(&format!("// {:?}\n", x.id()));
456 }
457 s.push_str("}\n");
459 s
460 }
461}
462
463impl GetFromId<AttributeId<ClassId>, Attribute<ClassId>> for Class {
466 fn get(&self, id: AttributeId<ClassId>) -> Option<&Attribute<ClassId>> {
467 self.get_attribute(id)
468 }
469}
470
471impl GetFromId<MethodId<ClassId>, Method<ClassId>> for Class {
472 fn get(&self, id: MethodId<ClassId>) -> Option<&Method<ClassId>> {
473 self.get_method(id)
474 }
475}