1use std::collections::{HashMap, HashSet};
2use std::fmt::{Display, Formatter};
3use std::ops::Deref;
4use std::ptr;
5use std::sync::atomic::{AtomicI64, Ordering};
6use std::sync::{LazyLock, Mutex};
7use gc::{Finalize, Gc, GcCell, Trace};
8use crate::interpreter::data::{DataObject, DataObjectRef, DataTypeConstraint, DataTypeConstraintError, FunctionPointerObjectRef, LangObjectRef, OptionLangObjectRef, Visibility};
9use crate::interpreter::data::function::{FunctionPointerObject, InternalFunction};
10use crate::interpreter::Interpreter;
11use crate::utils;
12
13static NEXT_CLASS_ID: AtomicI64 = AtomicI64::new(0);
14pub(super) static CLASS_ID_TO_SUPER_CLASS_IDS: LazyLock<Mutex<HashMap<i64, Vec<i64>>>> = LazyLock::new(Default::default);
15
16#[derive(Debug, Trace, Finalize)]
17pub struct LangObjectObject {
18 super_level: usize,
19
20 members: Vec<DataObjectRef>,
21
22 class_base_definition: LangObjectRef,
23
24 initialized: bool,
28}
29
30impl LangObjectObject {
31 pub fn new(
32 super_level: usize,
33 members: Vec<DataObjectRef>,
34 class_base_definition: LangObjectRef,
35 initialized: bool,
36 ) -> Self {
37 Self { super_level, members, class_base_definition, initialized }
38 }
39
40 pub fn super_level(&self) -> usize {
41 self.super_level
42 }
43
44 pub fn members(&self) -> &[DataObjectRef] {
45 &self.members
46 }
47
48 pub fn class_base_definition(&self) -> &LangObjectRef {
49 &self.class_base_definition
50 }
51
52 pub fn initialized(&self) -> bool {
53 self.initialized
54 }
55}
56
57#[derive(Debug, Trace, Finalize)]
58pub struct MemberDefinition {
59 name: Box<str>,
60
61 #[unsafe_ignore_trace]
63 type_constraint: Option<Box<DataTypeConstraint>>,
64
65 final_flag: bool,
66
67 #[unsafe_ignore_trace]
69 member_of_visibility: Visibility,
70 member_of_class: LangObjectRef,
71}
72
73impl MemberDefinition {
74 pub fn new(
75 name: &str,
76 type_constraint: Option<Box<DataTypeConstraint>>,
77 final_flag: bool,
78 member_of_visibility: Visibility,
79 member_of_class: LangObjectRef,
80 ) -> Self {
81 Self {
82 name: Box::from(name),
83 type_constraint,
84 final_flag,
85 member_of_visibility,
86 member_of_class,
87 }
88 }
89
90 pub fn name(&self) -> &str {
91 &self.name
92 }
93
94 pub fn type_constraint(&self) -> Option<&DataTypeConstraint> {
95 self.type_constraint.as_deref()
96 }
97
98 pub fn final_flag(&self) -> bool {
99 self.final_flag
100 }
101
102 pub fn member_of_visibility(&self) -> Visibility {
103 self.member_of_visibility
104 }
105
106 pub fn member_of_class(&self) -> &LangObjectRef {
107 &self.member_of_class
108 }
109}
110
111#[derive(Debug, Trace, Finalize)]
112pub struct LangObjectClass {
113 members: Vec<MemberDefinition>,
114
115 parent_classes: Vec<LangObjectRef>,
120}
121
122impl LangObjectClass {
123 pub fn new(members: Vec<MemberDefinition>, parent_classes: Vec<LangObjectRef>) -> Self {
124 Self { members, parent_classes }
125 }
126
127 pub fn members(&self) -> &[MemberDefinition] {
128 &self.members
129 }
130
131 pub fn parent_classes(&self) -> &[LangObjectRef] {
132 &self.parent_classes
133 }
134}
135
136#[derive(Debug, Trace, Finalize)]
137pub enum LangObjectData {
138 Class(LangObjectClass),
139 Object(LangObjectObject),
140}
141
142#[derive(Debug, Trace, Finalize)]
143pub struct LangObject {
144 pub(super) class_id: i64,
145
146 class_name: Option<Box<str>>,
147
148 static_members: Vec<DataObjectRef>,
149
150 methods: HashMap<Box<str>, FunctionPointerObjectRef>,
151 constructors: FunctionPointerObjectRef,
152
153 data: LangObjectData,
154}
155
156impl LangObject {
157 thread_local! {
159 static DUMMY_CLASS_DEFINITION_CLASS: LangObjectRef = {
160 let constructor = |_interpreter: &mut Interpreter, _: LangObjectRef| {};
161 let constructor = FunctionPointerObject::from(crate::lang_func!(
162 constructor,
163 crate::lang_func_metadata!(
164 name="construct",
165 return_type_constraint(
166 allowed=["VOID"],
167 ),
168 ),
169 ));
170
171 let constructor_visibility = vec![Visibility::Public];
172
173 LangObject::new_class(
174 Some("<class-definition>"), Vec::new(), Vec::new(),
175 HashMap::new(), HashMap::new(), HashMap::new(), constructor, constructor_visibility,
176 Vec::new(),
177 ).unwrap()
178 };
179
180 static OBJECT_CLASS: LangObjectRef = {
181 let mut methods = HashMap::new();
182 let mut method_override_flags = HashMap::new();
183 let mut method_visibility = HashMap::new();
184
185 let get_class_method = |_interpreter: &mut Interpreter, this: LangObjectRef| -> DataObjectRef {
186 let mut class_object = DataObject::new();
187 class_object.set_object(this.borrow().base_definition().unwrap()).unwrap();
188
189 DataObjectRef::new(class_object)
190 };
191 let get_class_method = FunctionPointerObject::from(crate::lang_func!(
192 get_class_method,
193 crate::lang_func_metadata!(
194 name="mp.getClass",
195 return_type_constraint(
196 allowed=["OBJECT"],
197 ),
198 ),
199 ));
200
201 methods.insert(Box::from("mp.getClass"), get_class_method);
202 method_override_flags.insert(Box::from("mp.getClass"), vec![false]);
203 method_visibility.insert(Box::from("mp.getClass"), vec![Visibility::Public]);
204
205 let constructor = |_interpreter: &mut Interpreter, _: LangObjectRef| {};
206 let constructor = FunctionPointerObject::from(crate::lang_func!(
207 constructor,
208 crate::lang_func_metadata!(
209 name="construct",
210 return_type_constraint(
211 allowed=["VOID"],
212 ),
213 ),
214 ));
215
216 let constructor_visibility = vec![Visibility::Public];
217
218 LangObject::new_class_internal(
219 true, Some("&Object"), Vec::new(), Vec::new(),
220 methods, method_override_flags, method_visibility, constructor, constructor_visibility,
221 Vec::new(),
222 ).unwrap()
223 };
224 }
225
226 pub(crate) fn dummy_class_definition_class() -> LangObjectRef {
228 Self::DUMMY_CLASS_DEFINITION_CLASS.with(Clone::clone)
229 }
230
231 pub fn object_class() -> LangObjectRef {
233 Self::OBJECT_CLASS.with(Clone::clone)
234 }
235
236 #[expect(clippy::too_many_arguments)]
237 pub fn new_class(
238 class_name: Option<&str>,
239
240 static_members: Vec<DataObject>,
241
242 members: Vec<MemberDefinition>,
243
244 methods: HashMap<Box<str>, FunctionPointerObject>,
245 method_override_flags: HashMap<Box<str>, Vec<bool>>,
246 method_visibility: HashMap<Box<str>, Vec<Visibility>>,
247
248 constructors: FunctionPointerObject,
249 constructor_visibility: Vec<Visibility>,
250
251 parent_classes: Vec<LangObjectRef>,
252 ) -> Result<LangObjectRef, DataTypeConstraintError> {
253 Self::new_class_internal(
254 false,
255 class_name,
256 static_members,
257 members,
258 methods,
259 method_override_flags,
260 method_visibility,
261 constructors,
262 constructor_visibility,
263 parent_classes,
264 )
265 }
266
267 #[expect(clippy::too_many_arguments)]
268 fn new_class_internal(
269 is_base_object: bool,
270 class_name: Option<&str>,
271
272 static_members: Vec<DataObject>,
273
274 members: Vec<MemberDefinition>,
275
276 methods: HashMap<Box<str>, FunctionPointerObject>,
277 method_override_flags: HashMap<Box<str>, Vec<bool>>,
278 method_visibility: HashMap<Box<str>, Vec<Visibility>>,
279
280 constructors: FunctionPointerObject,
281 constructor_visibility: Vec<Visibility>,
282
283 parent_classes: Vec<LangObjectRef>,
284 ) -> Result<LangObjectRef, DataTypeConstraintError> {
285 let parent_classes = if is_base_object {
286 Vec::new()
287 }else if parent_classes.is_empty() {
288 vec![Self::object_class()]
289 }else {
290 for parent_class in parent_classes.iter() {
291 if !parent_class.borrow().is_class() {
292 return Err(DataTypeConstraintError::with_message(
293 "Parent classes must not be an object",
294 ));
295 }
296 }
297
298 if parent_classes.len() == 1 {
299 parent_classes
300 }else {
301 return Err(DataTypeConstraintError::with_message(
302 "Multi-inheritance is not allowed",
303 ));
304 }
305 };
306
307 for static_member in static_members.iter() {
308 let Some(static_member_name) = static_member.variable_name() else {
309 return Err(DataTypeConstraintError::with_message(
310 "Variable name must not be None for static member",
311 ));
312 };
313
314 for parent_class in parent_classes.iter() {
315 let static_members = &parent_class.borrow().static_members;
316
317 for super_static_member in static_members {
318 if let Some(super_static_member_name) = &super_static_member.borrow().variable_name
319 && **super_static_member_name == *static_member_name {
320 return Err(DataTypeConstraintError::with_message(format!(
321 "Super class static member must not be shadowed (For static member \"{static_member_name}\")",
322 )));
323 }
324 }
325 }
326 }
327
328 let class_id = NEXT_CLASS_ID.fetch_add(1, Ordering::Relaxed);
329 {
330 let mut class_id_to_super_class_ids = CLASS_ID_TO_SUPER_CLASS_IDS.lock().unwrap();
331
332 let mut super_class_ids = HashSet::new();
333 super_class_ids.insert(class_id);
334 for parent_class in &parent_classes {
335 let parent_class_id = parent_class.borrow().class_id;
336
337 for class_id in &class_id_to_super_class_ids[&parent_class_id] {
338 super_class_ids.insert(*class_id);
339 }
340 }
341
342 class_id_to_super_class_ids.insert(class_id, Vec::from_iter(super_class_ids));
343 }
344
345 let new_value = Gc::new(GcCell::new(Self {
346 class_id,
347
348 class_name: class_name.map(Box::from),
349
350 static_members: Vec::new(),
351
352 methods: HashMap::new(),
353 constructors: Gc::new(FunctionPointerObject::new_dummy_definition()),
354
355 data: LangObjectData::Class(LangObjectClass::new(
356 Vec::new(),
357 parent_classes.clone(),
358 )),
359 }));
360
361 let mut static_members = static_members;
362 for static_member in static_members.iter_mut() {
363 static_member.set_member_of_class(Some(new_value.clone()));
364
365 if let Some(function_pointer) = static_member.function_pointer_value() {
366 let func = function_pointer.copy_with_mapped_functions(|function| {
367 if let Some(member_of_class) = function.member_of_class()
368 && ptr::eq(member_of_class.borrow().deref(), Self::dummy_class_definition_class().borrow().deref()) {
369 return InternalFunction::copy_with_class_member_attributes(
370 function,
371 new_value.clone(),
372 Visibility::Public,
373 );
374 }
375
376 function.clone()
377 });
378
379 static_member.set_function_pointer(Gc::new(func))?;
380 }
381 }
382
383 let mut static_members = static_members.into_iter().
384 map(DataObjectRef::new).
385 collect::<Vec<_>>();
386
387 for parent_class in parent_classes.iter() {
389 for super_static_member in &parent_class.borrow().static_members {
390 static_members.push(super_static_member.clone());
392 }
393 }
394
395 for member in members.iter() {
396 for parent_class in parent_classes.iter() {
397 let static_members = &parent_class.borrow().static_members;
398 for super_static_member in static_members {
399 if let Some(super_static_member_name) = &super_static_member.borrow().variable_name
400 && *super_static_member_name == member.name {
401 return Err(DataTypeConstraintError::with_message(format!(
402 "Super class static member must not be shadowed (For member \"{}\")",
403 member.name,
404 )));
405 }
406 }
407
408 let parent_class = parent_class.borrow();
409 let members = parent_class.member_definitions().unwrap();
410 for super_member in members {
411 let super_member_name = &super_member.name;
412 if *super_member_name == member.name {
413 return Err(DataTypeConstraintError::with_message(format!(
414 "Super class member must not be shadowed (For member \"{}\")",
415 member.name,
416 )));
417 }
418 }
419 }
420
421 for static_member in static_members.iter() {
422 if let Some(static_member_name) = &static_member.borrow().variable_name
423 && *static_member_name == member.name {
424 return Err(DataTypeConstraintError::with_message(format!(
425 "Static members must not be shadowed (For member \"{}\")",
426 member.name,
427 )));
428 }
429 }
430 }
431
432 let mut members_new = Vec::new();
434 for member in members.iter() {
435 members_new.push(MemberDefinition::new(
436 &member.name,
437 member.type_constraint.clone(),
438 member.final_flag,
439 member.member_of_visibility,
440 new_value.clone(),
441 ));
442 }
443
444 for parent_class in parent_classes.iter() {
445 for member in parent_class.borrow().member_definitions().unwrap() {
446 members_new.push(MemberDefinition::new(
447 &member.name,
448 member.type_constraint.clone(),
449 member.final_flag,
450 member.member_of_visibility,
451 parent_class.clone(),
452 ));
453 }
454 }
455
456 let mut methods_new = methods;
457 for (method_name, overloaded_functions) in methods_new.iter_mut() {
458 if overloaded_functions.get_overloaded_function_count() == 0 {
459 return Err(DataTypeConstraintError::with_message(format!(
460 "No method present for method (For method \"{method_name}\")",
461 )));
462 }
463
464 let Some(overloaded_method_override_flags) = method_override_flags.get(method_name) else {
465 return Err(DataTypeConstraintError::with_message(format!(
466 "Missing method override flags (For method \"{method_name}\")",
467 )));
468 };
469
470 if overloaded_method_override_flags.len() != overloaded_functions.get_overloaded_function_count() {
471 return Err(DataTypeConstraintError::with_message(format!(
472 "Count of method override flags does not match overloaded function count (For method \"{method_name}\")",
473 )));
474 }
475
476 let Some(overloaded_method_visibility) = method_visibility.get(method_name) else {
477 return Err(DataTypeConstraintError::with_message(format!(
478 "Missing method visibility (For method \"{method_name}\")",
479 )));
480 };
481
482 if overloaded_method_visibility.len() != overloaded_functions.get_overloaded_function_count() {
483 return Err(DataTypeConstraintError::with_message(format!(
484 "Count of method visibility does not match overloaded function count (For method \"{method_name}\")",
485 )));
486 }
487
488 let functions = overloaded_functions.functions_mut();
490 for (i, function) in functions.iter_mut().enumerate() {
491 *function = function.copy_with_class_member_attributes(
492 new_value.clone(),
493 overloaded_method_visibility[i],
494 ).copy_with_super_level(0);
495 }
496
497 let function_signatures = functions.iter().
499 map(|internal_function| internal_function.function()).
500 collect::<Vec<_>>();
501
502 for func_a in function_signatures.iter() {
503 for func_b in function_signatures.iter() {
504 if ptr::eq(*func_a, *func_b) {
506 continue;
507 }
508
509 if utils::are_function_signatures_equals(func_a, func_b) {
510 return Err(DataTypeConstraintError::with_message(format!(
511 "Duplicated function signatures: \"{method_name}{}\" and \"{method_name}{}\"",
512 func_a.to_function_signature_string(),
513 func_b.to_function_signature_string(),
514 )));
515 }
516 }
517 }
518 }
519
520 for method_name in methods_new.keys() {
521 let function_var_name = "fp.".to_string() + &method_name[3..];
522
523 for parent_class in parent_classes.iter() {
524 let static_members = &parent_class.borrow().static_members;
525 for super_static_member in static_members {
526 if let Some(super_static_member_name) = &super_static_member.borrow().variable_name
527 && **super_static_member_name == *function_var_name {
528 return Err(DataTypeConstraintError::with_message(format!(
529 "\"fp.\" static members of a super class must not be shadowed by method (For method \"{}\" and member \"{}\")",
530 method_name, function_var_name,
531 )));
532 }
533 }
534
535 let parent_class = parent_class.borrow();
536 let members = parent_class.member_definitions().unwrap();
537 for super_member in members {
538 let super_member_name = &super_member.name;
539 if **super_member_name == function_var_name {
540 return Err(DataTypeConstraintError::with_message(format!(
541 "\"fp.\" members of a super class not be shadowed by method (For method \"{}\" and member \"{}\")",
542 method_name, function_var_name,
543 )));
544 }
545 }
546 }
547
548 for static_member in static_members.iter() {
549 if let Some(static_member_name) = &static_member.borrow().variable_name
550 && **static_member_name == function_var_name {
551 return Err(DataTypeConstraintError::with_message(format!(
552 "\"fp.\" static members must not be shadowed by method (For method \"{}\" and member \"{}\")",
553 method_name, function_var_name,
554 )));
555 }
556 }
557
558 for member in members.iter() {
559 let super_static_member_name = &member.name;
560 if **super_static_member_name == function_var_name {
561 return Err(DataTypeConstraintError::with_message(format!(
562 "\"fp.\" members must not be shadowed by method (For method \"{}\" and member \"{}\")",
563 method_name, function_var_name,
564 )));
565 }
566 }
567 }
568
569 {
571 for parent_class in parent_classes.iter() {
572 for (method_name, super_overloaded_methods) in &parent_class.borrow().methods {
573 let overloaded_methods = methods_new.get_mut(method_name);
574 let Some(overloaded_methods) = overloaded_methods else {
575 methods_new.insert(
576 method_name.clone(),
577 super_overloaded_methods.copy_with_mapped_functions(|internal_function|
578 internal_function.copy_with_super_level(internal_function.super_level().unwrap() + 1)),
579 );
580
581 continue;
582 };
583
584 let override_flags = &method_override_flags[method_name];
586 let function_signatures = overloaded_methods.functions().iter().
587 map(|internal_function| internal_function.function()).
588 collect::<Vec<_>>();
589
590 let super_function_signatures = super_overloaded_methods.functions().iter().
591 map(|internal_function| internal_function.function()).
592 collect::<Vec<_>>();
593
594 for (i, func_a) in function_signatures.into_iter().enumerate() {
595 let mut is_any_equals = false;
596 for func_b in &super_function_signatures {
597 if utils::are_function_signatures_equals(func_a, func_b) {
598 is_any_equals = true;
599 break;
600 }
601 }
602
603 if override_flags[i] {
604 if !is_any_equals {
605 return Err(DataTypeConstraintError::with_message(format!(
606 "No method for override was found for function signature: \"{method_name}{}\"",
607 func_a.to_function_signature_string(),
608 )));
609 }
610 }else if is_any_equals {
611 return Err(DataTypeConstraintError::with_message(format!(
612 "Method was not declared as override for function signature: \"{method_name}{}\"",
613 func_a.to_function_signature_string(),
614 )));
615 }
616 }
617
618 *overloaded_methods = overloaded_methods.copy_with_added_functions(
619 &super_overloaded_methods.copy_with_mapped_functions(
620 |internal_function| internal_function.
621 copy_with_super_level(internal_function.super_level().unwrap() + 1)
622 ),
623 );
624 }
625 }
626 }
627
628 if constructors.get_overloaded_function_count() == 0 {
629 return Err(DataTypeConstraintError::with_message(
630 "There must be at least one constructor",
631 ));
632 }
633
634 if constructor_visibility.len() != constructors.get_overloaded_function_count() {
635 return Err(DataTypeConstraintError::with_message(
636 "Count of constructor visibility does not match overloaded constructor count",
637 ));
638 }
639
640 let mut constructors = constructors.
641 copy_with_function_name("construct").
642 copy_with_mapped_functions(|internal_functions| internal_functions.
643 copy_with_super_level(0));
644 for (i, constructor) in constructors.functions_mut().iter_mut().
645 enumerate() {
646 *constructor = constructor.copy_with_class_member_attributes(
647 new_value.clone(),
648 constructor_visibility[i],
649 );
650 }
651
652 {
653 let function_signatures = constructors.functions().iter().
654 map(|internal_function| internal_function.function()).
655 collect::<Vec<_>>();
656
657 for func_a in function_signatures.iter() {
658 for func_b in function_signatures.iter() {
659 if ptr::eq(*func_a, *func_b) {
661 continue;
662 }
663
664 if utils::are_function_signatures_equals(func_a, func_b) {
665 return Err(DataTypeConstraintError::with_message(format!(
666 "Duplicated function signatures: \"construct{}\" and \"construct{}\"",
667 func_a.to_function_signature_string(),
668 func_b.to_function_signature_string(),
669 )));
670 }
671 }
672 }
673 }
674
675 {
678 let mut new_value_ref = new_value.borrow_mut();
679
680 new_value_ref.static_members = static_members;
681 let LangObjectData::Class(new_value_data) = &mut new_value_ref.data else {
682 panic!();
683 };
684
685 new_value_data.members = members_new;
686 new_value_ref.methods = HashMap::from_iter(methods_new.into_iter().
687 map(|(key, value)| (key, Gc::new(value))));
688 new_value_ref.constructors = Gc::new(constructors);
689 }
690
691 Ok(new_value)
692 }
693
694 pub fn new_object(
698 class_base_definition: &LangObjectRef,
699 ) -> Result<LangObjectRef, DataTypeConstraintError> {
700 if !class_base_definition.borrow().is_class() {
701 return Err(DataTypeConstraintError::with_message(
702 "Class base definition must be a class",
703 ));
704 }
705
706 let new_value = Gc::new(GcCell::new(Self {
707 class_id: class_base_definition.borrow().class_id,
708
709 class_name: class_base_definition.borrow().class_name.clone(),
710
711 static_members: class_base_definition.borrow().static_members.clone(),
713
714 methods: HashMap::new(),
715 constructors: Gc::new(FunctionPointerObject::new_dummy_definition()),
716
717 data: LangObjectData::Object(LangObjectObject::new(
718 0,
719 Vec::new(),
720 class_base_definition.clone(),
721 false,
722 )),
723 }));
724
725 let mut members = Vec::with_capacity(class_base_definition.borrow().member_definitions().unwrap().len());
726 for member in class_base_definition.borrow().member_definitions().unwrap() {
727 let mut new_member = DataObject::new();
728
729 new_member.set_member_visibility(Some(member.member_of_visibility));
730 new_member.set_member_of_class(Some(new_value.clone()));
731 new_member.set_variable_name(Some(&member.name))?;
732
733 members.push(DataObjectRef::new(new_member));
734 }
735
736 let mut methods: HashMap<Box<str>, FunctionPointerObjectRef> = HashMap::with_capacity(class_base_definition.borrow().methods.len());
737 for (method_name, method) in class_base_definition.borrow().methods.iter() {
738 methods.insert(method_name.clone(), Gc::new(FunctionPointerObject::copy_with_this_object(method, new_value.clone())?));
739 }
740
741 let constructors = FunctionPointerObject::copy_with_this_object(
742 &class_base_definition.borrow().constructors,
743 new_value.clone(),
744 )?;
745
746 {
747 let mut new_value_ref = new_value.borrow_mut();
748 let LangObjectData::Object(new_value_data) = &mut new_value_ref.data else {
749 panic!();
750 };
751
752 new_value_data.members = members;
753 new_value_ref.methods = methods;
754 new_value_ref.constructors = Gc::new(constructors);
755 }
756
757 Ok(new_value)
758 }
759
760 pub fn super_level(&self) -> Option<usize> {
761 match &self.data {
762 LangObjectData::Object(object) => Some(object.super_level),
763
764 LangObjectData::Class(..) => None,
765 }
766 }
767
768 pub fn set_super_level(&mut self, super_level: usize) -> Result<(), DataTypeConstraintError> {
769 match &mut self.data {
770 LangObjectData::Object(object) => {
771 object.super_level = super_level;
772
773 Ok(())
774 },
775
776 LangObjectData::Class(..) => Err(DataTypeConstraintError::with_message(
777 "Super level can only be modified on objects",
778 )),
779 }
780 }
781
782 pub fn post_construct(&mut self) -> Result<(), DataTypeConstraintError> {
783 let LangObjectData::Object(object) = &mut self.data else {
784 return Err(DataTypeConstraintError::with_message(
785 "Post construct must be called on an object",
786 ));
787 };
788
789 if object.initialized {
790 return Err(DataTypeConstraintError::with_message(
791 "Object is already initialized",
792 ));
793 }
794
795 for (i, member) in object.members.iter_mut().
796 enumerate() {
797 if let Some(member_definition) = object.class_base_definition.borrow().
798 member_definitions().
799 and_then(|member_definitions| member_definitions.get(i)) {
800 let mut member = member.borrow_mut();
801 if let Some(type_constraint) = &member_definition.type_constraint {
802 member.set_type_constraint(type_constraint.clone())?;
803 }
804
805 if member_definition.final_flag {
806 member.set_final_data(true);
807 }
808 };
809 }
810
811 object.initialized = true;
812
813 Ok(())
814 }
815
816 pub fn is_initialized(&self) -> Option<bool> {
817 match &self.data {
818 LangObjectData::Object(object) => Some(object.initialized),
819
820 LangObjectData::Class(..) => None,
821 }
822 }
823
824 pub fn is_class(&self) -> bool {
825 match &self.data {
826 LangObjectData::Object(..) => false,
827 LangObjectData::Class(..) => true,
828 }
829 }
830
831 pub fn class_name(&self) -> Option<&str> {
832 self.class_name.as_deref()
833 }
834
835 pub fn static_members(&self) -> &[DataObjectRef] {
836 &self.static_members
837 }
838
839 pub fn index_of_static_member(&self, member_name: &str) -> Option<usize> {
840 for (i, static_member) in self.static_members.iter().enumerate() {
841 if static_member.borrow().variable_name.as_ref().
842 is_some_and(|variable_name| **variable_name == *member_name) {
843 return Some(i);
844 }
845 }
846
847 None
848 }
849
850 pub fn static_member(&self, member_name: &str) -> Result<&DataObjectRef, DataTypeConstraintError> {
851 let index = self.index_of_static_member(member_name).
852 ok_or_else(|| DataTypeConstraintError::with_message(format!(
853 "The static member \"{member_name}\" is not part of this class or object",
854 )))?;
855
856 Ok(&self.static_members[index])
857 }
858
859 pub fn member_definitions(&self) -> Option<&[MemberDefinition]> {
860 match &self.data {
861 LangObjectData::Class(class) => Some(&class.members),
862 LangObjectData::Object(_) => None,
863 }
864 }
865
866 pub fn members(&self) -> Option<&[DataObjectRef]> {
867 match &self.data {
868 LangObjectData::Object(object) => Some(&object.members),
869 LangObjectData::Class(_) => None,
870 }
871 }
872
873 pub fn index_of_member(&self, member_name: &str) -> Result<Option<usize>, DataTypeConstraintError> {
874 let LangObjectData::Object(object) = &self.data else {
875 return Err(DataTypeConstraintError::with_message(
876 "Members can only be read in objects",
877 ));
878 };
879
880 for (i, static_member) in object.members.iter().enumerate() {
881 if static_member.borrow().variable_name.as_ref().
882 is_some_and(|variable_name| **variable_name == *member_name) {
883 return Ok(Some(i));
884 }
885 }
886
887 Ok(None)
888 }
889
890 pub fn member(&self, member_name: &str) -> Result<&DataObjectRef, DataTypeConstraintError> {
891 let index = self.index_of_member(member_name)?.
892 ok_or_else(|| DataTypeConstraintError::with_message(format!(
893 "The member \"{member_name}\" is not part of this class",
894 )))?;
895
896 let LangObjectData::Object(object) = &self.data else {
897 return Err(DataTypeConstraintError::with_message(
898 "Members can only be read in objects",
899 ));
900 };
901
902 Ok(&object.members[index])
903 }
904
905 pub fn methods(&self) -> &HashMap<Box<str>, Gc<FunctionPointerObject>> {
906 &self.methods
907 }
908
909 fn super_methods_internal(&self, super_level: usize) -> HashMap<Box<str>, FunctionPointerObjectRef> {
910 let base_class_definition = if let LangObjectData::Object(object) = &self.data {
911 Ok(object.class_base_definition.borrow())
912 }else {
913 Err(self)
914 };
915
916 let mut super_methods: HashMap<Box<str>, FunctionPointerObjectRef> = HashMap::new();
917
918 let base_class_definition_ref = base_class_definition.
919 as_deref().unwrap_or_else(|lang_object| *lang_object);
920 for parent_class in base_class_definition_ref.parent_classes().unwrap() {
921 if super_level > 0 {
922 let super_super_methods = parent_class.borrow().
923 super_methods_internal(super_level - 1);
924
925 for (method_name, method) in super_super_methods {
926 if let Some(super_method) = super_methods.get_mut(&method_name) {
927 *super_method = Gc::new(super_method.copy_with_added_functions(&method));
928 }else {
929 super_methods.insert(method_name, method.clone());
930 }
931 }
932 }else {
933 for (method_name, method) in parent_class.borrow().methods.iter() {
934 if let Some(super_method) = super_methods.get_mut(method_name) {
935 *super_method = Gc::new(super_method.copy_with_added_functions(method));
936 }else {
937 super_methods.insert(method_name.clone(), method.clone());
938 }
939 }
940 }
941 }
942
943 super_methods
944 }
945
946 pub fn super_methods(&self) -> HashMap<Box<str>, FunctionPointerObjectRef> {
947 let super_level = if let LangObjectData::Object(object) = &self.data {
948 object.super_level
949 }else {
950 0
951 };
952
953 self.super_methods_internal(super_level)
954 }
955
956 pub fn constructors(&self) -> FunctionPointerObjectRef {
957 self.constructors.clone()
958 }
959
960 pub fn constructors_for_current_super_level(&self) -> FunctionPointerObjectRef {
965 let super_level = if let LangObjectData::Object(object) = &self.data {
966 object.super_level
967 }else {
968 0
969 };
970
971 if super_level == 0 {
972 return self.constructors.clone();
973 }
974
975 self.super_constructors_internal(super_level - 1)
976 }
977
978 fn super_constructors_internal(&self, super_level: usize) -> FunctionPointerObjectRef {
979 let base_class_definition = if let LangObjectData::Object(object) = &self.data {
980 Ok(object.class_base_definition.borrow())
981 }else {
982 Err(self)
983 };
984
985 let mut super_constructors: Option<FunctionPointerObjectRef> = None;
986
987 let base_class_definition_ref = base_class_definition.
988 as_deref().unwrap_or_else(|lang_object| *lang_object);
989 for parent_class in base_class_definition_ref.parent_classes().unwrap() {
990 if super_level > 0 {
991 let super_super_constructors = parent_class.borrow().
992 super_constructors_internal(super_level - 1);
993
994 if let Some(super_constructors) = &mut super_constructors {
995 *super_constructors = Gc::new(super_constructors.copy_with_added_functions(&super_super_constructors));
996 }else {
997 super_constructors = Some(super_super_constructors);
998 }
999 }else {
1000 let parent_class = parent_class.borrow();
1001 let super_super_constructors = parent_class.constructors();
1002
1003 if let Some(super_constructors) = &mut super_constructors {
1004 *super_constructors = Gc::new(super_constructors.copy_with_added_functions(&super_super_constructors));
1005 }else {
1006 super_constructors = Some(super_super_constructors.clone());
1007 }
1008 }
1009 }
1010
1011 super_constructors.expect("Internal error: No constructor in base class found")
1012 }
1013
1014 pub fn super_constructors(&self) -> FunctionPointerObjectRef {
1015 let super_level = if let LangObjectData::Object(object) = &self.data {
1016 object.super_level
1017 }else {
1018 0
1019 };
1020
1021 self.super_constructors_internal(super_level)
1022 }
1023
1024 pub fn parent_classes(&self) -> Option<&[LangObjectRef]> {
1025 match &self.data {
1026 LangObjectData::Class(class) => Some(&class.parent_classes),
1027 LangObjectData::Object(_) => None,
1028 }
1029 }
1030
1031 pub fn base_definition(&self) -> OptionLangObjectRef {
1032 match &self.data {
1033 LangObjectData::Object(object) => Some(object.class_base_definition.clone()),
1034
1035 LangObjectData::Class(..) => None,
1036 }
1037 }
1038
1039 pub fn is_instance_of(&self, lang_object: &LangObject) -> bool {
1040 if !lang_object.is_class() {
1041 return false;
1042 }
1043
1044 if let LangObjectData::Object(object) = &self.data {
1045 return object.class_base_definition.borrow().is_instance_of(lang_object);
1046 }
1047
1048 if ptr::eq(self, lang_object) {
1049 return true;
1050 }
1051
1052 if let LangObjectData::Class(class) = &self.data {
1053 for parent_class in &class.parent_classes {
1054 if parent_class.borrow().is_instance_of(lang_object) {
1055 return true;
1056 }
1057 }
1058 }
1059
1060 false
1061 }
1062}
1063
1064impl Display for LangObject {
1065 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1066 if self.is_class() {
1067 write!(f, "<Class>")
1068 }else {
1069 write!(f, "<Object>")
1070 }
1071 }
1072}