1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Type method registry for storing user-defined methods on types
//!
//! This module provides the infrastructure for storing and retrieving
//! methods that have been added to types via the `extend` statement.
use crate::type_system::annotation_to_string;
use shape_ast::ast::{MethodDef, TypeName};
use shape_value::KindedSlot;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
/// Registry for storing type methods
#[derive(Debug, Clone)]
pub struct TypeMethodRegistry {
/// Methods stored by type name and method name
/// The Vec allows for method overloading
methods: Arc<RwLock<HashMap<String, HashMap<String, Vec<MethodDef>>>>>,
}
impl TypeMethodRegistry {
/// Create a new empty registry
pub fn new() -> Self {
Self {
methods: Arc::new(RwLock::new(HashMap::new())),
}
}
/// Register a method for a type
pub fn register_method(&self, type_name: &TypeName, method: MethodDef) {
let mut methods = self.methods.write().unwrap();
// Get the type name as a string
let type_str = match type_name {
TypeName::Simple(name) => name.to_string(),
TypeName::Generic { name, type_args } => {
// Convert generic types with their full signature
// e.g., "Table<Row>", "Vec<Number>"
if type_args.is_empty() {
name.to_string()
} else {
// Convert type arguments to strings
let type_arg_strs: Vec<String> =
type_args.iter().map(annotation_to_string).collect();
format!("{}<{}>", name, type_arg_strs.join(", "))
}
}
};
// Get or create the method map for this type
let type_methods = methods.entry(type_str.clone()).or_default();
// Add the method to the overload list
type_methods
.entry(method.name.clone())
.or_default()
.push(method);
}
/// Get all methods for a type with a given name
pub fn get_methods(&self, type_name: &str, method_name: &str) -> Option<Vec<MethodDef>> {
let methods = self.methods.read().unwrap();
methods
.get(type_name)
.and_then(|type_methods| type_methods.get(method_name))
.cloned()
}
/// Get the type name for a value.
///
/// Per ADR-006 ยง2.7.1.2 the value carrier is `KindedSlot`; the
/// type-name comes from the carried `NativeKind` rather than from
/// tag-bit dispatch on a raw `ValueWord`.
pub fn get_value_type_name(value: &KindedSlot) -> String {
format!("{:?}", value.kind())
}
/// Get all methods for a type
pub fn get_all_methods(&self, type_name: &str) -> Vec<MethodDef> {
let methods = self.methods.read().unwrap();
methods
.get(type_name)
.map(|type_methods| type_methods.values().flatten().cloned().collect())
.unwrap_or_default()
}
/// Check if a type has any methods registered
pub fn has_type(&self, type_name: &str) -> bool {
let methods = self.methods.read().unwrap();
methods.contains_key(type_name)
}
/// Get all registered type names
pub fn get_registered_types(&self) -> Vec<String> {
let methods = self.methods.read().unwrap();
methods.keys().cloned().collect()
}
/// Get a debug string representation of the registry state
pub fn debug_state(&self) -> String {
let methods = self.methods.read().unwrap();
let mut output = String::new();
output.push_str("TypeMethodRegistry State:\n");
output.push_str(&format!(" Total registered types: {}\n", methods.len()));
if methods.is_empty() {
output.push_str(" (No types registered)\n");
} else {
for (type_name, type_methods) in methods.iter() {
output.push_str(&format!(" Type: {}\n", type_name));
for (method_name, overloads) in type_methods.iter() {
output.push_str(&format!(
" Method: {} ({} overloads)\n",
method_name,
overloads.len()
));
for (i, overload) in overloads.iter().enumerate() {
output.push_str(&format!(
" Overload {}: {} params",
i + 1,
overload.params.len()
));
if overload.when_clause.is_some() {
output.push_str(" (with when clause)");
}
output.push('\n');
}
}
}
}
output
}
}
impl Default for TypeMethodRegistry {
fn default() -> Self {
Self::new()
}
}