1use crate::{
7 callable::Callable,
8 env::Cx,
9 error::Result,
10 id::{ClassId, Symbol},
11 object::{ClassRef, ReadConstructorRef, ShapeRef, TableRef},
12};
13
14pub trait Class: Callable {
19 fn id(&self) -> ClassId;
21 fn symbol(&self) -> Symbol;
23 fn parents(&self, _cx: &mut Cx) -> Result<Vec<ClassRef>> {
25 Ok(Vec::new())
26 }
27 fn is_subclass_of(&self, cx: &mut Cx, expected: ClassRef) -> Result<bool>
29 where
30 Self: Sized,
31 {
32 class_is_subclass_of(cx, self, expected)
33 }
34 fn constructor_shape(&self, cx: &mut Cx) -> Result<ShapeRef>;
36 fn instance_shape(&self, cx: &mut Cx) -> Result<ShapeRef>;
38 fn read_constructor(&self, cx: &mut Cx) -> Result<Option<ReadConstructorRef>>;
40 fn members(&self, cx: &mut Cx) -> Result<TableRef>;
42}
43
44pub fn class_is_subclass_of(cx: &mut Cx, child: &dyn Class, expected: ClassRef) -> Result<bool> {
47 let Some(expected_class) = expected.object().as_class() else {
48 return Ok(false);
49 };
50 if child.id() == expected_class.id() {
51 return Ok(true);
52 }
53 for parent in child.parents(cx)? {
54 let Some(parent) = parent.object().as_class() else {
55 continue;
56 };
57 if parent.id() == expected_class.id() || class_is_subclass_of(cx, parent, expected.clone())?
58 {
59 return Ok(true);
60 }
61 }
62 Ok(false)
63}