shape_runtime/
type_methods.rs1use crate::type_system::annotation_to_string;
7use shape_ast::ast::{MethodDef, TypeName};
8use shape_value::KindedSlot;
9use std::collections::HashMap;
10use std::sync::{Arc, RwLock};
11
12#[derive(Debug, Clone)]
14pub struct TypeMethodRegistry {
15 methods: Arc<RwLock<HashMap<String, HashMap<String, Vec<MethodDef>>>>>,
18}
19
20impl TypeMethodRegistry {
21 pub fn new() -> Self {
23 Self {
24 methods: Arc::new(RwLock::new(HashMap::new())),
25 }
26 }
27
28 pub fn register_method(&self, type_name: &TypeName, method: MethodDef) {
30 let mut methods = self.methods.write().unwrap();
31
32 let type_str = match type_name {
34 TypeName::Simple(name) => name.to_string(),
35 TypeName::Generic { name, type_args } => {
36 if type_args.is_empty() {
39 name.to_string()
40 } else {
41 let type_arg_strs: Vec<String> =
43 type_args.iter().map(annotation_to_string).collect();
44 format!("{}<{}>", name, type_arg_strs.join(", "))
45 }
46 }
47 };
48
49 let type_methods = methods.entry(type_str.clone()).or_default();
51
52 type_methods
54 .entry(method.name.clone())
55 .or_default()
56 .push(method);
57 }
58
59 pub fn get_methods(&self, type_name: &str, method_name: &str) -> Option<Vec<MethodDef>> {
61 let methods = self.methods.read().unwrap();
62 methods
63 .get(type_name)
64 .and_then(|type_methods| type_methods.get(method_name))
65 .cloned()
66 }
67
68 pub fn get_value_type_name(value: &KindedSlot) -> String {
74 format!("{:?}", value.kind())
75 }
76
77 pub fn get_all_methods(&self, type_name: &str) -> Vec<MethodDef> {
79 let methods = self.methods.read().unwrap();
80
81 methods
82 .get(type_name)
83 .map(|type_methods| type_methods.values().flatten().cloned().collect())
84 .unwrap_or_default()
85 }
86
87 pub fn has_type(&self, type_name: &str) -> bool {
89 let methods = self.methods.read().unwrap();
90 methods.contains_key(type_name)
91 }
92
93 pub fn get_registered_types(&self) -> Vec<String> {
95 let methods = self.methods.read().unwrap();
96 methods.keys().cloned().collect()
97 }
98
99 pub fn debug_state(&self) -> String {
101 let methods = self.methods.read().unwrap();
102 let mut output = String::new();
103
104 output.push_str("TypeMethodRegistry State:\n");
105 output.push_str(&format!(" Total registered types: {}\n", methods.len()));
106
107 if methods.is_empty() {
108 output.push_str(" (No types registered)\n");
109 } else {
110 for (type_name, type_methods) in methods.iter() {
111 output.push_str(&format!(" Type: {}\n", type_name));
112 for (method_name, overloads) in type_methods.iter() {
113 output.push_str(&format!(
114 " Method: {} ({} overloads)\n",
115 method_name,
116 overloads.len()
117 ));
118 for (i, overload) in overloads.iter().enumerate() {
119 output.push_str(&format!(
120 " Overload {}: {} params",
121 i + 1,
122 overload.params.len()
123 ));
124 if overload.when_clause.is_some() {
125 output.push_str(" (with when clause)");
126 }
127 output.push('\n');
128 }
129 }
130 }
131 }
132
133 output
134 }
135}
136
137impl Default for TypeMethodRegistry {
138 fn default() -> Self {
139 Self::new()
140 }
141}