lang_interpreter/interpreter/data/
object.rs

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    /**
25     * false for classes and uninitialized objects, true for objects where post construct was called
26     */
27    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    //SAFETY: There are no GC reference inside DataTypeConstraint
62    #[unsafe_ignore_trace]
63    type_constraint: Option<Box<DataTypeConstraint>>,
64
65    final_flag: bool,
66
67    //SAFETY: There are no GC reference inside Visibility
68    #[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    /**
116     * If size = 0: This is the base object<br>
117     * If size > 0: This is a normal object
118     */
119    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 is ok for now, because data objects are neither Send nor Sync
158    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    /// Returns the "<class-definition>" lang initialization class
227    pub(crate) fn dummy_class_definition_class() -> LangObjectRef {
228        Self::DUMMY_CLASS_DEFINITION_CLASS.with(Clone::clone)
229    }
230
231    /// Returns the "&Object" lang object base class
232    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        //TODO allow multi-inheritance (Check if a static member is in both super classes)
390        for parent_class in parent_classes.iter() {
391            for super_static_member in &parent_class.borrow().static_members {
392                //No copies (static members must be the same reference across all uses)
393                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        //TODO allow multi-inheritance (Check if a member is in both super classes)
437        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            //Set visibility
493            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            //Check override flag
502            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                    //Do not compare to same function signature
509                    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        //TODO allow multi-inheritance (Check if a method with the same function signature is in both super classes)
576        {
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                    //Override check
591                    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                    //Do not compare to same function signature
666                    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        //TODO allow super constructor call from constructor [Dynamically bind super constructors to this]
682
683        {
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    /**
701     * The constructor must be called separately, afterward postConstructor must be called
702     */
703    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            //No copies, because static members should be the same across all objects
718            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    /**
967     * @return Returns all constructors for the current super level without going to super
968     * [0 is current, 1 is parent, 2 is grandparent]
969     */
970    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}