Skip to main content

rajac_types/
class_type.rs

1use crate::{FieldId, MethodId, TypeId};
2use rajac_base::shared_string::SharedString;
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct ClassType {
7    /// Simple class name (without package).
8    pub name: SharedString,
9    /// Package name or `None` for the default package.
10    pub package: Option<SharedString>,
11    /// Type arguments applied to this class type.
12    pub type_args: Vec<TypeId>,
13    /// Superclass type id, if any.
14    pub superclass: Option<TypeId>,
15    /// Implemented interface type ids.
16    pub interfaces: Vec<TypeId>,
17    /// Method ids grouped by name for overload resolution.
18    pub methods: HashMap<SharedString, Vec<MethodId>>,
19    /// Field ids grouped by name.
20    pub fields: HashMap<SharedString, Vec<FieldId>>,
21}
22
23impl ClassType {
24    pub fn new(name: SharedString) -> Self {
25        Self {
26            name,
27            package: None,
28            type_args: Vec::new(),
29            superclass: None,
30            interfaces: Vec::new(),
31            methods: HashMap::new(),
32            fields: HashMap::new(),
33        }
34    }
35
36    pub fn with_package(mut self, package_: SharedString) -> Self {
37        self.package = Some(package_);
38        self
39    }
40
41    pub fn with_type_args(mut self, type_args: Vec<TypeId>) -> Self {
42        self.type_args = type_args;
43        self
44    }
45
46    pub fn with_superclass(mut self, superclass: TypeId) -> Self {
47        self.superclass = Some(superclass);
48        self
49    }
50
51    pub fn with_interfaces(mut self, interfaces: Vec<TypeId>) -> Self {
52        self.interfaces = interfaces;
53        self
54    }
55
56    pub fn with_methods(mut self, methods: HashMap<SharedString, Vec<MethodId>>) -> Self {
57        self.methods = methods;
58        self
59    }
60
61    pub fn with_fields(mut self, fields: HashMap<SharedString, Vec<FieldId>>) -> Self {
62        self.fields = fields;
63        self
64    }
65
66    pub fn add_method(&mut self, name: SharedString, method_id: MethodId) {
67        self.methods.entry(name).or_default().push(method_id);
68    }
69
70    pub fn add_field(&mut self, name: SharedString, field_id: FieldId) {
71        self.fields.entry(name).or_default().push(field_id);
72    }
73
74    pub fn internal_name(&self) -> String {
75        match &self.package {
76            Some(pkg) => format!("{}/{}", pkg.as_str().replace('.', "/"), self.name.as_str()),
77            None => self.name.as_str().replace('.', "/"),
78        }
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use crate::{FieldId, MethodId};
86
87    #[test]
88    fn add_method_groups_by_name() {
89        let mut class_type = ClassType::new(SharedString::new("Widget"));
90        class_type.add_method(SharedString::new("size"), MethodId(0));
91        class_type.add_method(SharedString::new("size"), MethodId(1));
92
93        let methods = class_type.methods.get("size").expect("methods");
94        assert_eq!(methods, &[MethodId(0), MethodId(1)]);
95    }
96
97    #[test]
98    fn add_field_groups_by_name() {
99        let mut class_type = ClassType::new(SharedString::new("Widget"));
100        class_type.add_field(SharedString::new("name"), FieldId(0));
101        class_type.add_field(SharedString::new("name"), FieldId(1));
102
103        let fields = class_type.fields.get("name").expect("fields");
104        assert_eq!(fields, &[FieldId(0), FieldId(1)]);
105    }
106}