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 if **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
329 let class_id = NEXT_CLASS_ID.fetch_add(1, Ordering::Relaxed);
330 {
331 let mut class_id_to_super_class_ids = CLASS_ID_TO_SUPER_CLASS_IDS.lock().unwrap();
332
333 let mut super_class_ids = HashSet::new();
334 super_class_ids.insert(class_id);
335 for parent_class in &parent_classes {
336 let parent_class_id = parent_class.borrow().class_id;
337
338 for class_id in &class_id_to_super_class_ids[&parent_class_id] {
339 super_class_ids.insert(*class_id);
340 }
341 }
342
343 class_id_to_super_class_ids.insert(class_id, Vec::from_iter(super_class_ids));
344 }
345
346 let new_value = Gc::new(GcCell::new(Self {
347 class_id,
348
349 class_name: class_name.map(Box::from),
350
351 static_members: Vec::new(),
352
353 methods: HashMap::new(),
354 constructors: Gc::new(FunctionPointerObject::new_dummy_definition()),
355
356 data: LangObjectData::Class(LangObjectClass::new(
357 Vec::new(),
358 parent_classes.clone(),
359 )),
360 }));
361
362 let mut static_members = static_members;
363 for static_member in static_members.iter_mut() {
364 static_member.set_member_of_class(Some(new_value.clone()));
365
366 if let Some(function_pointer) = static_member.function_pointer_value() {
367 let func = function_pointer.copy_with_mapped_functions(|function| {
368 if let Some(member_of_class) = function.member_of_class() {
369 if ptr::eq(member_of_class.borrow().deref(), Self::dummy_class_definition_class().borrow().deref()) {
370 return InternalFunction::copy_with_class_member_attributes(
371 function,
372 new_value.clone(),
373 Visibility::Public,
374 );
375 }
376 }
377
378 function.clone()
379 });
380
381 static_member.set_function_pointer(Gc::new(func))?;
382 }
383 }
384
385 let mut static_members = static_members.into_iter().
386 map(DataObjectRef::new).
387 collect::<Vec<_>>();
388
389 for parent_class in parent_classes.iter() {
391 for super_static_member in &parent_class.borrow().static_members {
392 static_members.push(super_static_member.clone());
394 }
395 }
396
397 for member in members.iter() {
398 for parent_class in parent_classes.iter() {
399 let static_members = &parent_class.borrow().static_members;
400 for super_static_member in static_members {
401 if let Some(super_static_member_name) = &super_static_member.borrow().variable_name {
402 if *super_static_member_name == member.name {
403 return Err(DataTypeConstraintError::with_message(format!(
404 "Super class static member must not be shadowed (For member \"{}\")",
405 member.name,
406 )));
407 }
408 }
409 }
410
411 let parent_class = parent_class.borrow();
412 let members = parent_class.member_definitions().unwrap();
413 for super_member in members {
414 let super_member_name = &super_member.name;
415 if *super_member_name == member.name {
416 return Err(DataTypeConstraintError::with_message(format!(
417 "Super class member must not be shadowed (For member \"{}\")",
418 member.name,
419 )));
420 }
421 }
422 }
423
424 for static_member in static_members.iter() {
425 if let Some(static_member_name) = &static_member.borrow().variable_name {
426 if *static_member_name == member.name {
427 return Err(DataTypeConstraintError::with_message(format!(
428 "Static members must not be shadowed (For member \"{}\")",
429 member.name,
430 )));
431 }
432 }
433 }
434 }
435
436 let mut members_new = Vec::new();
438 for member in members.iter() {
439 members_new.push(MemberDefinition::new(
440 &member.name,
441 member.type_constraint.clone(),
442 member.final_flag,
443 member.member_of_visibility,
444 new_value.clone(),
445 ));
446 }
447
448 for parent_class in parent_classes.iter() {
449 for member in parent_class.borrow().member_definitions().unwrap() {
450 members_new.push(MemberDefinition::new(
451 &member.name,
452 member.type_constraint.clone(),
453 member.final_flag,
454 member.member_of_visibility,
455 parent_class.clone(),
456 ));
457 }
458 }
459
460 let mut methods_new = methods;
461 for (method_name, overloaded_functions) in methods_new.iter_mut() {
462 if overloaded_functions.get_overloaded_function_count() == 0 {
463 return Err(DataTypeConstraintError::with_message(format!(
464 "No method present for method (For method \"{method_name}\")",
465 )));
466 }
467
468 let Some(overloaded_method_override_flags) = method_override_flags.get(method_name) else {
469 return Err(DataTypeConstraintError::with_message(format!(
470 "Missing method override flags (For method \"{method_name}\")",
471 )));
472 };
473
474 if overloaded_method_override_flags.len() != overloaded_functions.get_overloaded_function_count() {
475 return Err(DataTypeConstraintError::with_message(format!(
476 "Count of method override flags does not match overloaded function count (For method \"{method_name}\")",
477 )));
478 }
479
480 let Some(overloaded_method_visibility) = method_visibility.get(method_name) else {
481 return Err(DataTypeConstraintError::with_message(format!(
482 "Missing method visibility (For method \"{method_name}\")",
483 )));
484 };
485
486 if overloaded_method_visibility.len() != overloaded_functions.get_overloaded_function_count() {
487 return Err(DataTypeConstraintError::with_message(format!(
488 "Count of method visibility does not match overloaded function count (For method \"{method_name}\")",
489 )));
490 }
491
492 let functions = overloaded_functions.functions_mut();
494 for (i, function) in functions.iter_mut().enumerate() {
495 *function = function.copy_with_class_member_attributes(
496 new_value.clone(),
497 overloaded_method_visibility[i],
498 ).copy_with_super_level(0);
499 }
500
501 let function_signatures = functions.iter().
503 map(|internal_function| internal_function.function()).
504 collect::<Vec<_>>();
505
506 for func_a in function_signatures.iter() {
507 for func_b in function_signatures.iter() {
508 if ptr::eq(*func_a, *func_b) {
510 continue;
511 }
512
513 if utils::are_function_signatures_equals(func_a, func_b) {
514 return Err(DataTypeConstraintError::with_message(format!(
515 "Duplicated function signatures: \"{method_name}{}\" and \"{method_name}{}\"",
516 func_a.to_function_signature_string(),
517 func_b.to_function_signature_string(),
518 )));
519 }
520 }
521 }
522 }
523
524 for method_name in methods_new.keys() {
525 let function_var_name = "fp.".to_string() + &method_name[3..];
526
527 for parent_class in parent_classes.iter() {
528 let static_members = &parent_class.borrow().static_members;
529 for super_static_member in static_members {
530 if let Some(super_static_member_name) = &super_static_member.borrow().variable_name {
531 if **super_static_member_name == *function_var_name {
532 return Err(DataTypeConstraintError::with_message(format!(
533 "\"fp.\" static members of a super class must not be shadowed by method (For method \"{}\" and member \"{}\")",
534 method_name, function_var_name,
535 )));
536 }
537 }
538 }
539
540 let parent_class = parent_class.borrow();
541 let members = parent_class.member_definitions().unwrap();
542 for super_member in members {
543 let super_member_name = &super_member.name;
544 if **super_member_name == function_var_name {
545 return Err(DataTypeConstraintError::with_message(format!(
546 "\"fp.\" members of a super class not be shadowed by method (For method \"{}\" and member \"{}\")",
547 method_name, function_var_name,
548 )));
549 }
550 }
551 }
552
553 for static_member in static_members.iter() {
554 if let Some(static_member_name) = &static_member.borrow().variable_name {
555 if **static_member_name == function_var_name {
556 return Err(DataTypeConstraintError::with_message(format!(
557 "\"fp.\" static members must not be shadowed by method (For method \"{}\" and member \"{}\")",
558 method_name, function_var_name,
559 )));
560 }
561 }
562 }
563
564 for member in members.iter() {
565 let super_static_member_name = &member.name;
566 if **super_static_member_name == function_var_name {
567 return Err(DataTypeConstraintError::with_message(format!(
568 "\"fp.\" members must not be shadowed by method (For method \"{}\" and member \"{}\")",
569 method_name, function_var_name,
570 )));
571 }
572 }
573 }
574
575 {
577 for parent_class in parent_classes.iter() {
578 for (method_name, super_overloaded_methods) in &parent_class.borrow().methods {
579 let overloaded_methods = methods_new.get_mut(method_name);
580 let Some(overloaded_methods) = overloaded_methods else {
581 methods_new.insert(
582 method_name.clone(),
583 super_overloaded_methods.copy_with_mapped_functions(|internal_function|
584 internal_function.copy_with_super_level(internal_function.super_level().unwrap() + 1)),
585 );
586
587 continue;
588 };
589
590 let override_flags = &method_override_flags[method_name];
592 let function_signatures = overloaded_methods.functions().iter().
593 map(|internal_function| internal_function.function()).
594 collect::<Vec<_>>();
595
596 let super_function_signatures = super_overloaded_methods.functions().iter().
597 map(|internal_function| internal_function.function()).
598 collect::<Vec<_>>();
599
600 for (i, func_a) in function_signatures.into_iter().enumerate() {
601 let mut is_any_equals = false;
602 for func_b in &super_function_signatures {
603 if utils::are_function_signatures_equals(func_a, func_b) {
604 is_any_equals = true;
605 break;
606 }
607 }
608
609 if override_flags[i] {
610 if !is_any_equals {
611 return Err(DataTypeConstraintError::with_message(format!(
612 "No method for override was found for function signature: \"{method_name}{}\"",
613 func_a.to_function_signature_string(),
614 )));
615 }
616 }else if is_any_equals {
617 return Err(DataTypeConstraintError::with_message(format!(
618 "Method was not declared as override for function signature: \"{method_name}{}\"",
619 func_a.to_function_signature_string(),
620 )));
621 }
622 }
623
624 *overloaded_methods = overloaded_methods.copy_with_added_functions(
625 &super_overloaded_methods.copy_with_mapped_functions(
626 |internal_function| internal_function.
627 copy_with_super_level(internal_function.super_level().unwrap() + 1)
628 ),
629 );
630 }
631 }
632 }
633
634 if constructors.get_overloaded_function_count() == 0 {
635 return Err(DataTypeConstraintError::with_message(
636 "There must be at least one constructor",
637 ));
638 }
639
640 if constructor_visibility.len() != constructors.get_overloaded_function_count() {
641 return Err(DataTypeConstraintError::with_message(
642 "Count of constructor visibility does not match overloaded constructor count",
643 ));
644 }
645
646 let mut constructors = constructors.
647 copy_with_function_name("construct").
648 copy_with_mapped_functions(|internal_functions| internal_functions.
649 copy_with_super_level(0));
650 for (i, constructor) in constructors.functions_mut().iter_mut().
651 enumerate() {
652 *constructor = constructor.copy_with_class_member_attributes(
653 new_value.clone(),
654 constructor_visibility[i],
655 );
656 }
657
658 {
659 let function_signatures = constructors.functions().iter().
660 map(|internal_function| internal_function.function()).
661 collect::<Vec<_>>();
662
663 for func_a in function_signatures.iter() {
664 for func_b in function_signatures.iter() {
665 if ptr::eq(*func_a, *func_b) {
667 continue;
668 }
669
670 if utils::are_function_signatures_equals(func_a, func_b) {
671 return Err(DataTypeConstraintError::with_message(format!(
672 "Duplicated function signatures: \"construct{}\" and \"construct{}\"",
673 func_a.to_function_signature_string(),
674 func_b.to_function_signature_string(),
675 )));
676 }
677 }
678 }
679 }
680
681 {
684 let mut new_value_ref = new_value.borrow_mut();
685
686 new_value_ref.static_members = static_members;
687 let LangObjectData::Class(new_value_data) = &mut new_value_ref.data else {
688 panic!();
689 };
690
691 new_value_data.members = members_new;
692 new_value_ref.methods = HashMap::from_iter(methods_new.into_iter().
693 map(|(key, value)| (key, Gc::new(value))));
694 new_value_ref.constructors = Gc::new(constructors);
695 }
696
697 Ok(new_value)
698 }
699
700 pub fn new_object(
704 class_base_definition: &LangObjectRef,
705 ) -> Result<LangObjectRef, DataTypeConstraintError> {
706 if !class_base_definition.borrow().is_class() {
707 return Err(DataTypeConstraintError::with_message(
708 "Class base definition must be a class",
709 ));
710 }
711
712 let new_value = Gc::new(GcCell::new(Self {
713 class_id: class_base_definition.borrow().class_id,
714
715 class_name: class_base_definition.borrow().class_name.clone(),
716
717 static_members: class_base_definition.borrow().static_members.clone(),
719
720 methods: HashMap::new(),
721 constructors: Gc::new(FunctionPointerObject::new_dummy_definition()),
722
723 data: LangObjectData::Object(LangObjectObject::new(
724 0,
725 Vec::new(),
726 class_base_definition.clone(),
727 false,
728 )),
729 }));
730
731 let mut members = Vec::with_capacity(class_base_definition.borrow().member_definitions().unwrap().len());
732 for member in class_base_definition.borrow().member_definitions().unwrap() {
733 let mut new_member = DataObject::new();
734
735 new_member.set_member_visibility(Some(member.member_of_visibility));
736 new_member.set_member_of_class(Some(new_value.clone()));
737 new_member.set_variable_name(Some(&member.name))?;
738
739 members.push(DataObjectRef::new(new_member));
740 }
741
742 let mut methods: HashMap<Box<str>, FunctionPointerObjectRef> = HashMap::with_capacity(class_base_definition.borrow().methods.len());
743 for (method_name, method) in class_base_definition.borrow().methods.iter() {
744 methods.insert(method_name.clone(), Gc::new(FunctionPointerObject::copy_with_this_object(method, new_value.clone())?));
745 }
746
747 let constructors = FunctionPointerObject::copy_with_this_object(
748 &class_base_definition.borrow().constructors,
749 new_value.clone(),
750 )?;
751
752 {
753 let mut new_value_ref = new_value.borrow_mut();
754 let LangObjectData::Object(new_value_data) = &mut new_value_ref.data else {
755 panic!();
756 };
757
758 new_value_data.members = members;
759 new_value_ref.methods = methods;
760 new_value_ref.constructors = Gc::new(constructors);
761 }
762
763 Ok(new_value)
764 }
765
766 pub fn super_level(&self) -> Option<usize> {
767 match &self.data {
768 LangObjectData::Object(object) => Some(object.super_level),
769
770 LangObjectData::Class(..) => None,
771 }
772 }
773
774 pub fn set_super_level(&mut self, super_level: usize) -> Result<(), DataTypeConstraintError> {
775 match &mut self.data {
776 LangObjectData::Object(object) => {
777 object.super_level = super_level;
778
779 Ok(())
780 },
781
782 LangObjectData::Class(..) => Err(DataTypeConstraintError::with_message(
783 "Super level can only be modified on objects",
784 )),
785 }
786 }
787
788 pub fn post_construct(&mut self) -> Result<(), DataTypeConstraintError> {
789 let LangObjectData::Object(object) = &mut self.data else {
790 return Err(DataTypeConstraintError::with_message(
791 "Post construct must be called on an object",
792 ));
793 };
794
795 if object.initialized {
796 return Err(DataTypeConstraintError::with_message(
797 "Object is already initialized",
798 ));
799 }
800
801 for (i, member) in object.members.iter_mut().
802 enumerate() {
803 if let Some(member_definition) = object.class_base_definition.borrow().
804 member_definitions().
805 and_then(|member_definitions| member_definitions.get(i)) {
806 let mut member = member.borrow_mut();
807 if let Some(type_constraint) = &member_definition.type_constraint {
808 member.set_type_constraint(type_constraint.clone())?;
809 }
810
811 if member_definition.final_flag {
812 member.set_final_data(true);
813 }
814 };
815 }
816
817 object.initialized = true;
818
819 Ok(())
820 }
821
822 pub fn is_initialized(&self) -> Option<bool> {
823 match &self.data {
824 LangObjectData::Object(object) => Some(object.initialized),
825
826 LangObjectData::Class(..) => None,
827 }
828 }
829
830 pub fn is_class(&self) -> bool {
831 match &self.data {
832 LangObjectData::Object(..) => false,
833 LangObjectData::Class(..) => true,
834 }
835 }
836
837 pub fn class_name(&self) -> Option<&str> {
838 self.class_name.as_deref()
839 }
840
841 pub fn static_members(&self) -> &[DataObjectRef] {
842 &self.static_members
843 }
844
845 pub fn index_of_static_member(&self, member_name: &str) -> Option<usize> {
846 for (i, static_member) in self.static_members.iter().enumerate() {
847 if static_member.borrow().variable_name.as_ref().
848 is_some_and(|variable_name| **variable_name == *member_name) {
849 return Some(i);
850 }
851 }
852
853 None
854 }
855
856 pub fn static_member(&self, member_name: &str) -> Result<&DataObjectRef, DataTypeConstraintError> {
857 let index = self.index_of_static_member(member_name).
858 ok_or_else(|| DataTypeConstraintError::with_message(format!(
859 "The static member \"{member_name}\" is not part of this class or object",
860 )))?;
861
862 Ok(&self.static_members[index])
863 }
864
865 pub fn member_definitions(&self) -> Option<&[MemberDefinition]> {
866 match &self.data {
867 LangObjectData::Class(class) => Some(&class.members),
868 LangObjectData::Object(_) => None,
869 }
870 }
871
872 pub fn members(&self) -> Option<&[DataObjectRef]> {
873 match &self.data {
874 LangObjectData::Object(object) => Some(&object.members),
875 LangObjectData::Class(_) => None,
876 }
877 }
878
879 pub fn index_of_member(&self, member_name: &str) -> Result<Option<usize>, DataTypeConstraintError> {
880 let LangObjectData::Object(object) = &self.data else {
881 return Err(DataTypeConstraintError::with_message(
882 "Members can only be read in objects",
883 ));
884 };
885
886 for (i, static_member) in object.members.iter().enumerate() {
887 if static_member.borrow().variable_name.as_ref().
888 is_some_and(|variable_name| **variable_name == *member_name) {
889 return Ok(Some(i));
890 }
891 }
892
893 Ok(None)
894 }
895
896 pub fn member(&self, member_name: &str) -> Result<&DataObjectRef, DataTypeConstraintError> {
897 let index = self.index_of_member(member_name)?.
898 ok_or_else(|| DataTypeConstraintError::with_message(format!(
899 "The member \"{member_name}\" is not part of this class",
900 )))?;
901
902 let LangObjectData::Object(object) = &self.data else {
903 return Err(DataTypeConstraintError::with_message(
904 "Members can only be read in objects",
905 ));
906 };
907
908 Ok(&object.members[index])
909 }
910
911 pub fn methods(&self) -> &HashMap<Box<str>, Gc<FunctionPointerObject>> {
912 &self.methods
913 }
914
915 fn super_methods_internal(&self, super_level: usize) -> HashMap<Box<str>, FunctionPointerObjectRef> {
916 let base_class_definition = if let LangObjectData::Object(object) = &self.data {
917 Ok(object.class_base_definition.borrow())
918 }else {
919 Err(self)
920 };
921
922 let mut super_methods: HashMap<Box<str>, FunctionPointerObjectRef> = HashMap::new();
923
924 let base_class_definition_ref = base_class_definition.
925 as_deref().unwrap_or_else(|lang_object| *lang_object);
926 for parent_class in base_class_definition_ref.parent_classes().unwrap() {
927 if super_level > 0 {
928 let super_super_methods = parent_class.borrow().
929 super_methods_internal(super_level - 1);
930
931 for (method_name, method) in super_super_methods {
932 if let Some(super_method) = super_methods.get_mut(&method_name) {
933 *super_method = Gc::new(super_method.copy_with_added_functions(&method));
934 }else {
935 super_methods.insert(method_name, method.clone());
936 }
937 }
938 }else {
939 for (method_name, method) in parent_class.borrow().methods.iter() {
940 if let Some(super_method) = super_methods.get_mut(method_name) {
941 *super_method = Gc::new(super_method.copy_with_added_functions(method));
942 }else {
943 super_methods.insert(method_name.clone(), method.clone());
944 }
945 }
946 }
947 }
948
949 super_methods
950 }
951
952 pub fn super_methods(&self) -> HashMap<Box<str>, FunctionPointerObjectRef> {
953 let super_level = if let LangObjectData::Object(object) = &self.data {
954 object.super_level
955 }else {
956 0
957 };
958
959 self.super_methods_internal(super_level)
960 }
961
962 pub fn constructors(&self) -> FunctionPointerObjectRef {
963 self.constructors.clone()
964 }
965
966 pub fn constructors_for_current_super_level(&self) -> FunctionPointerObjectRef {
971 let super_level = if let LangObjectData::Object(object) = &self.data {
972 object.super_level
973 }else {
974 0
975 };
976
977 if super_level == 0 {
978 return self.constructors.clone();
979 }
980
981 self.super_constructors_internal(super_level - 1)
982 }
983
984 fn super_constructors_internal(&self, super_level: usize) -> FunctionPointerObjectRef {
985 let base_class_definition = if let LangObjectData::Object(object) = &self.data {
986 Ok(object.class_base_definition.borrow())
987 }else {
988 Err(self)
989 };
990
991 let mut super_constructors: Option<FunctionPointerObjectRef> = None;
992
993 let base_class_definition_ref = base_class_definition.
994 as_deref().unwrap_or_else(|lang_object| *lang_object);
995 for parent_class in base_class_definition_ref.parent_classes().unwrap() {
996 if super_level > 0 {
997 let super_super_constructors = parent_class.borrow().
998 super_constructors_internal(super_level - 1);
999
1000 if let Some(super_constructors) = &mut super_constructors {
1001 *super_constructors = Gc::new(super_constructors.copy_with_added_functions(&super_super_constructors));
1002 }else {
1003 super_constructors = Some(super_super_constructors);
1004 }
1005 }else {
1006 let parent_class = parent_class.borrow();
1007 let super_super_constructors = parent_class.constructors();
1008
1009 if let Some(super_constructors) = &mut super_constructors {
1010 *super_constructors = Gc::new(super_constructors.copy_with_added_functions(&super_super_constructors));
1011 }else {
1012 super_constructors = Some(super_super_constructors.clone());
1013 }
1014 }
1015 }
1016
1017 super_constructors.expect("Internal error: No constructor in base class found")
1018 }
1019
1020 pub fn super_constructors(&self) -> FunctionPointerObjectRef {
1021 let super_level = if let LangObjectData::Object(object) = &self.data {
1022 object.super_level
1023 }else {
1024 0
1025 };
1026
1027 self.super_constructors_internal(super_level)
1028 }
1029
1030 pub fn parent_classes(&self) -> Option<&[LangObjectRef]> {
1031 match &self.data {
1032 LangObjectData::Class(class) => Some(&class.parent_classes),
1033 LangObjectData::Object(_) => None,
1034 }
1035 }
1036
1037 pub fn base_definition(&self) -> OptionLangObjectRef {
1038 match &self.data {
1039 LangObjectData::Object(object) => Some(object.class_base_definition.clone()),
1040
1041 LangObjectData::Class(..) => None,
1042 }
1043 }
1044
1045 pub fn is_instance_of(&self, lang_object: &LangObject) -> bool {
1046 if !lang_object.is_class() {
1047 return false;
1048 }
1049
1050 if let LangObjectData::Object(object) = &self.data {
1051 return object.class_base_definition.borrow().is_instance_of(lang_object);
1052 }
1053
1054 if ptr::eq(self, lang_object) {
1055 return true;
1056 }
1057
1058 if let LangObjectData::Class(class) = &self.data {
1059 for parent_class in &class.parent_classes {
1060 if parent_class.borrow().is_instance_of(lang_object) {
1061 return true;
1062 }
1063 }
1064 }
1065
1066 false
1067 }
1068}
1069
1070impl Display for LangObject {
1071 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1072 if self.is_class() {
1073 write!(f, "<Class>")
1074 }else {
1075 write!(f, "<Object>")
1076 }
1077 }
1078}