1use crate::core::safe_operations::SafeLock;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::sync::{Arc, Mutex, OnceLock};
12use std::time::{SystemTime, UNIX_EPOCH};
13
14static GLOBAL_GENERIC_ANALYZER: OnceLock<Arc<GenericAnalyzer>> = OnceLock::new();
16
17pub fn get_global_generic_analyzer() -> Arc<GenericAnalyzer> {
19 GLOBAL_GENERIC_ANALYZER
20 .get_or_init(|| Arc::new(GenericAnalyzer::default()))
21 .clone()
22}
23
24pub struct GenericAnalyzer {
26 generic_instances: Mutex<HashMap<String, Vec<GenericInstance>>>,
28 constraint_violations: Mutex<Vec<ConstraintViolation>>,
30 instantiation_events: Mutex<Vec<InstantiationEvent>>,
32}
33
34impl Default for GenericAnalyzer {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl GenericAnalyzer {
41 pub fn new() -> Self {
43 Self {
44 generic_instances: Mutex::new(HashMap::new()),
45 constraint_violations: Mutex::new(Vec::new()),
46 instantiation_events: Mutex::new(Vec::new()),
47 }
48 }
49
50 pub fn track_generic_instantiation(
52 &self,
53 base_type: &str,
54 type_params: Vec<String>,
55 ptr: usize,
56 ) {
57 self.track_generic_instantiation_with_name(base_type, base_type, type_params, ptr);
58 }
59
60 pub fn track_generic_instantiation_with_name(
62 &self,
63 name: &str,
64 base_type: &str,
65 type_params: Vec<String>,
66 ptr: usize,
67 ) {
68 let event = InstantiationEvent {
69 base_type: base_type.to_string(),
70 type_parameters: type_params.clone(),
71 ptr,
72 timestamp: current_timestamp(),
73 thread_id: format!("{:?}", std::thread::current().id()),
74 };
75
76 if let Ok(mut events) = self.instantiation_events.lock() {
77 events.push(event);
78 }
79
80 let instance = GenericInstance {
82 name: name.to_string(),
83 base_type: base_type.to_string(),
84 underlying_type: base_type.to_string(),
85 type_parameters: type_params,
86 ptr,
87 size: 0, constraints: extract_constraints(base_type),
89 is_type_alias: name != base_type,
90 };
91
92 if let Ok(mut instances) = self.generic_instances.lock() {
93 instances
94 .entry(name.to_string())
95 .or_default()
96 .push(instance);
97 }
98 }
99
100 pub fn track_type_alias_instantiation(
102 &self,
103 alias_name: &str,
104 underlying_type: &str,
105 type_params: Vec<String>,
106 ptr: usize,
107 ) {
108 let (base_type, resolved_params) = parse_generic_parameters(underlying_type);
110
111 let event = InstantiationEvent {
112 base_type: base_type.clone(),
113 type_parameters: if resolved_params.is_empty() {
114 type_params.clone()
115 } else {
116 resolved_params.clone()
117 },
118 ptr,
119 timestamp: current_timestamp(),
120 thread_id: format!("{:?}", std::thread::current().id()),
121 };
122
123 if let Ok(mut events) = self.instantiation_events.lock() {
124 events.push(event);
125 }
126
127 let instance = GenericInstance {
129 name: alias_name.to_string(),
130 base_type: base_type.clone(),
131 underlying_type: underlying_type.to_string(),
132 type_parameters: if resolved_params.is_empty() {
133 type_params
134 } else {
135 resolved_params
136 },
137 ptr,
138 size: 0,
139 constraints: extract_constraints(underlying_type), is_type_alias: true,
141 };
142
143 if let Ok(mut instances) = self.generic_instances.lock() {
144 instances
145 .entry(alias_name.to_string())
146 .or_default()
147 .push(instance);
148 }
149 }
150
151 pub fn analyze_constraints(&self, type_name: &str) -> Vec<GenericConstraint> {
153 extract_constraints(type_name)
154 }
155
156 pub fn check_constraint_violations(
158 &self,
159 type_name: &str,
160 actual_params: &[String],
161 ) -> Vec<ConstraintViolation> {
162 let constraints = self.analyze_constraints(type_name);
163 let mut violations = Vec::new();
164
165 for constraint in constraints {
166 if !self.validate_constraint(&constraint, actual_params) {
167 violations.push(ConstraintViolation {
168 constraint: constraint.clone(),
169 actual_type: actual_params.join(", "),
170 violation_type: ViolationType::ConstraintNotSatisfied,
171 timestamp: current_timestamp(),
172 });
173 }
174 }
175
176 violations
177 }
178
179 pub fn get_generic_statistics(&self) -> GenericStatistics {
181 let instances = self
182 .generic_instances
183 .safe_lock()
184 .expect("Failed to acquire lock on generic_instances");
185 let events = self
186 .instantiation_events
187 .safe_lock()
188 .expect("Failed to acquire lock on instantiation_events");
189 let violations = self
190 .constraint_violations
191 .safe_lock()
192 .expect("Failed to acquire lock on constraint_violations");
193
194 let total_instances: usize = instances.values().map(|v| v.len()).sum();
195 let unique_base_types = instances.len();
196 let total_instantiations = events.len();
197 let constraint_violations = violations.len();
198
199 let mut type_usage: HashMap<String, usize> = HashMap::new();
201 let mut alias_count = 0;
202
203 for (_name, instance_list) in instances.iter() {
204 for instance in instance_list {
205 if instance.is_type_alias {
206 alias_count += 1;
207 *type_usage
209 .entry(instance.underlying_type.clone())
210 .or_insert(0) += 1;
211 } else {
212 *type_usage.entry(instance.name.clone()).or_insert(0) += 1;
214 }
215 }
216 }
217
218 let most_used_types: Vec<(String, usize)> = {
219 let mut sorted: Vec<_> = type_usage.into_iter().collect();
220 sorted.sort_by(|a, b| b.1.cmp(&a.1));
221 sorted.into_iter().take(10).collect()
222 };
223
224 GenericStatistics {
225 total_instances,
226 unique_base_types,
227 total_instantiations,
228 constraint_violations,
229 most_used_types,
230 type_aliases_count: alias_count,
231 }
232 }
233
234 pub fn get_type_aliases(&self) -> Vec<TypeAliasInfo> {
236 let instances = self
237 .generic_instances
238 .safe_lock()
239 .expect("Failed to acquire lock on generic_instances");
240
241 let mut alias_map: HashMap<String, TypeAliasInfo> = HashMap::new();
242
243 for (_name, instance_list) in instances.iter() {
244 for instance in instance_list {
245 if instance.is_type_alias {
246 let alias_name = instance.name.clone();
247
248 if let Some(existing) = alias_map.get_mut(&alias_name) {
249 existing.usage_count += 1;
251 } else {
252 alias_map.insert(
254 alias_name.clone(),
255 TypeAliasInfo {
256 alias_name,
257 underlying_type: instance.underlying_type.clone(),
258 base_type: instance.base_type.clone(),
259 type_parameters: instance.type_parameters.clone(),
260 usage_count: 1,
261 },
262 );
263 }
264 }
265 }
266 }
267
268 alias_map.into_values().collect()
270 }
271
272 pub fn resolve_type_alias(&self, alias_name: &str) -> Option<String> {
274 let instances = self
275 .generic_instances
276 .safe_lock()
277 .expect("Failed to acquire lock on generic_instances");
278
279 if let Some(instance_list) = instances.get(alias_name) {
280 for instance in instance_list {
281 if instance.is_type_alias {
282 return Some(instance.underlying_type.clone());
283 }
284 }
285 }
286 None
287 }
288
289 fn validate_constraint(
291 &self,
292 constraint: &GenericConstraint,
293 actual_params: &[String],
294 ) -> bool {
295 match &constraint.constraint_type {
296 ConstraintType::Trait(trait_name) => {
297 self.type_implements_trait(actual_params, trait_name)
300 }
301 ConstraintType::Lifetime => {
302 true
304 }
305 ConstraintType::Sized => {
306 !actual_params
308 .iter()
309 .any(|t| t.contains("dyn ") || t.contains("?Sized"))
310 }
311 ConstraintType::Send => {
312 self.type_is_send(actual_params)
314 }
315 ConstraintType::Sync => {
316 self.type_is_sync(actual_params)
318 }
319 }
320 }
321
322 fn type_implements_trait(&self, types: &[String], trait_name: &str) -> bool {
324 match trait_name {
326 "Clone" => types.iter().all(|t| self.is_cloneable_type(t)),
327 "Debug" => types.iter().all(|t| self.is_debug_type(t)),
328 "Default" => types.iter().all(|t| self.is_default_type(t)),
329 "PartialEq" => types.iter().all(|t| self.is_partial_eq_type(t)),
330 _ => true, }
332 }
333
334 fn type_is_send(&self, types: &[String]) -> bool {
336 !types
337 .iter()
338 .any(|t| t.contains("Rc<") || t.contains("RefCell<"))
339 }
340
341 fn type_is_sync(&self, types: &[String]) -> bool {
343 !types
344 .iter()
345 .any(|t| t.contains("Cell<") || t.contains("RefCell<"))
346 }
347
348 fn is_cloneable_type(&self, type_name: &str) -> bool {
350 !type_name.contains("Mutex<") && !type_name.contains("File")
351 }
352
353 fn is_debug_type(&self, type_name: &str) -> bool {
354 !type_name.contains("fn(") }
356
357 fn is_default_type(&self, type_name: &str) -> bool {
358 type_name.contains("Vec<") || type_name.contains("HashMap<") || type_name.contains("String")
359 }
360
361 fn is_partial_eq_type(&self, type_name: &str) -> bool {
362 !type_name.contains("fn(") && !type_name.contains("Mutex<")
363 }
364}
365
366#[derive(Debug, Clone, Serialize, Deserialize)]
368pub struct GenericInstance {
369 pub name: String,
371 pub base_type: String,
373 pub underlying_type: String,
375 pub type_parameters: Vec<String>,
377 pub ptr: usize,
379 pub size: usize,
381 pub constraints: Vec<GenericConstraint>,
383 pub is_type_alias: bool,
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize)]
389pub struct GenericConstraint {
390 pub parameter_name: String,
392 pub constraint_type: ConstraintType,
394 pub description: String,
396}
397
398#[derive(Debug, Clone, Serialize, Deserialize)]
400pub enum ConstraintType {
401 Trait(String),
403 Lifetime,
405 Sized,
407 Send,
409 Sync,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
415pub struct InstantiationEvent {
416 pub base_type: String,
418 pub type_parameters: Vec<String>,
420 pub ptr: usize,
422 pub timestamp: u64,
424 pub thread_id: String,
426}
427
428#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct ConstraintViolation {
431 pub constraint: GenericConstraint,
433 pub actual_type: String,
435 pub violation_type: ViolationType,
437 pub timestamp: u64,
439}
440
441#[derive(Debug, Clone, Serialize, Deserialize)]
443pub enum ViolationType {
444 ConstraintNotSatisfied,
446 LifetimeMismatch,
448 MissingTraitImpl,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
454pub struct GenericStatistics {
455 pub total_instances: usize,
457 pub unique_base_types: usize,
459 pub total_instantiations: usize,
461 pub constraint_violations: usize,
463 pub most_used_types: Vec<(String, usize)>,
465 pub type_aliases_count: usize,
467}
468
469#[derive(Debug, Clone, Serialize, Deserialize)]
471pub struct TypeAliasInfo {
472 pub alias_name: String,
474 pub underlying_type: String,
476 pub base_type: String,
478 pub type_parameters: Vec<String>,
480 pub usage_count: usize,
482}
483
484fn extract_constraints(type_name: &str) -> Vec<GenericConstraint> {
486 let mut constraints = Vec::new();
487
488 if is_collection_type(type_name) {
491 constraints.push(GenericConstraint {
492 parameter_name: "T".to_string(),
493 constraint_type: ConstraintType::Sized,
494 description: "Type must be Sized for standard collections".to_string(),
495 });
496 }
497
498 if is_smart_pointer_type(type_name) {
500 constraints.push(GenericConstraint {
501 parameter_name: "T".to_string(),
502 constraint_type: ConstraintType::Sized,
503 description: "Type must be Sized for smart pointers".to_string(),
504 });
505 }
506
507 if is_thread_safe_type(type_name) {
509 constraints.push(GenericConstraint {
510 parameter_name: "T".to_string(),
511 constraint_type: ConstraintType::Send,
512 description: "Type must be Send for thread-safe containers".to_string(),
513 });
514 }
515
516 if is_sync_required_type(type_name) {
518 constraints.push(GenericConstraint {
519 parameter_name: "T".to_string(),
520 constraint_type: ConstraintType::Sync,
521 description: "Type must be Sync for shared concurrent access".to_string(),
522 });
523 }
524
525 constraints
526}
527
528fn is_collection_type(type_name: &str) -> bool {
530 let collection_patterns = [
532 r"\bVec<", r"\bVecDeque<", r"\bLinkedList<", r"\bHashMap<", r"\bBTreeMap<", r"\bHashSet<", r"\bBTreeSet<", r"\bBinaryHeap<", ];
541
542 collection_patterns.iter().any(|pattern| {
543 regex::Regex::new(pattern)
544 .map(|re| re.is_match(type_name))
545 .unwrap_or(false)
546 })
547}
548
549fn is_smart_pointer_type(type_name: &str) -> bool {
551 let smart_pointer_patterns = [
552 r"\bBox<", r"\bRc<", r"\bArc<", r"\bWeak<", ];
557
558 smart_pointer_patterns.iter().any(|pattern| {
559 regex::Regex::new(pattern)
560 .map(|re| re.is_match(type_name))
561 .unwrap_or(false)
562 })
563}
564
565fn is_thread_safe_type(type_name: &str) -> bool {
567 let thread_safe_patterns = [
568 r"\bMutex<", r"\bRwLock<", r"\bmpsc::", r"\bSender<", r"\bReceiver<", ];
574
575 thread_safe_patterns.iter().any(|pattern| {
576 regex::Regex::new(pattern)
577 .map(|re| re.is_match(type_name))
578 .unwrap_or(false)
579 })
580}
581
582fn is_sync_required_type(type_name: &str) -> bool {
584 let sync_required_patterns = [
585 r"\bArc<", r"&\s*Mutex<", r"&\s*RwLock<", ];
589
590 sync_required_patterns.iter().any(|pattern| {
591 regex::Regex::new(pattern)
592 .map(|re| re.is_match(type_name))
593 .unwrap_or(false)
594 })
595}
596
597fn current_timestamp() -> u64 {
599 SystemTime::now()
600 .duration_since(UNIX_EPOCH)
601 .unwrap_or_default()
602 .as_nanos() as u64
603}
604
605pub fn parse_generic_parameters(type_name: &str) -> (String, Vec<String>) {
607 if let Some(start) = type_name.find('<') {
608 if let Some(end) = type_name.rfind('>') {
609 let base_type = type_name[..start].to_string();
610 let params_str = &type_name[start + 1..end];
611
612 let params: Vec<String> = params_str
614 .split(',')
615 .map(|s| s.trim().to_string())
616 .filter(|s| !s.is_empty())
617 .collect();
618
619 return (base_type, params);
620 }
621 }
622
623 (type_name.to_string(), Vec::new())
624}
625
626#[cfg(test)]
627mod tests {
628 use super::*;
629
630 #[test]
631 fn test_generic_analyzer_creation() {
632 let analyzer = GenericAnalyzer::new();
633 assert!(analyzer.generic_instances.safe_lock().unwrap().is_empty());
634 assert!(analyzer
635 .constraint_violations
636 .safe_lock()
637 .unwrap()
638 .is_empty());
639 assert!(analyzer
640 .instantiation_events
641 .safe_lock()
642 .unwrap()
643 .is_empty());
644 }
645
646 #[test]
647 fn test_generic_analyzer_default() {
648 let analyzer = GenericAnalyzer::default();
649 assert!(analyzer.generic_instances.safe_lock().unwrap().is_empty());
650 assert!(analyzer
651 .constraint_violations
652 .safe_lock()
653 .unwrap()
654 .is_empty());
655 assert!(analyzer
656 .instantiation_events
657 .safe_lock()
658 .unwrap()
659 .is_empty());
660 }
661
662 #[test]
663 fn test_parse_generic_parameters() {
664 let (base, params) = parse_generic_parameters("Vec<i32>");
665 assert_eq!(base, "Vec");
666 assert_eq!(params, vec!["i32"]);
667
668 let (base, params) = parse_generic_parameters("HashMap<String, usize>");
669 assert_eq!(base, "HashMap");
670 assert_eq!(params, vec!["String", "usize"]);
671
672 let (base, params) = parse_generic_parameters("String");
673 assert_eq!(base, "String");
674 assert_eq!(params.len(), 0);
675 }
676
677 #[test]
678 fn test_constraint_extraction() {
679 let constraints = extract_constraints("Vec<T>");
680 assert!(!constraints.is_empty());
681 assert!(constraints
682 .iter()
683 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
684
685 let constraints = extract_constraints("Mutex<T>");
686 assert!(constraints
687 .iter()
688 .any(|c| matches!(c.constraint_type, ConstraintType::Send)));
689 }
690
691 #[test]
692 fn test_precise_type_matching() {
693 assert!(is_collection_type("Vec<i32>"));
695 assert!(is_collection_type("HashMap<String, i32>"));
696 assert!(is_collection_type("std::collections::HashMap<K, V>"));
697 assert!(is_collection_type("VecDeque<T>"));
698 assert!(is_collection_type("BTreeSet<String>"));
699
700 assert!(!is_collection_type("MyVec<i32>"));
702 assert!(!is_collection_type("CustomHashMap<K, V>"));
703 assert!(!is_collection_type("VectorType<T>"));
704 assert!(!is_collection_type("HashMapLike<K, V>"));
705
706 assert!(is_smart_pointer_type("Box<i32>"));
708 assert!(is_smart_pointer_type("Arc<String>"));
709 assert!(is_smart_pointer_type("Rc<RefCell<i32>>"));
710 assert!(is_smart_pointer_type("Weak<Node>"));
711
712 assert!(!is_smart_pointer_type("MyBox<i32>"));
714 assert!(!is_smart_pointer_type("ArcLike<String>"));
715 assert!(!is_smart_pointer_type("BoxedValue<T>"));
716
717 assert!(is_thread_safe_type("Mutex<i32>"));
719 assert!(is_thread_safe_type("RwLock<String>"));
720 assert!(is_thread_safe_type("Sender<Message>"));
721 assert!(is_thread_safe_type("Receiver<Data>"));
722 assert!(is_thread_safe_type("mpsc::Sender<T>"));
723
724 assert!(!is_thread_safe_type("MyMutex<i32>"));
726 assert!(!is_thread_safe_type("MutexLike<String>"));
727 assert!(!is_thread_safe_type("CustomSender<T>"));
728
729 assert!(is_sync_required_type("Arc<i32>"));
731 assert!(is_sync_required_type("&Mutex<String>"));
732 assert!(is_sync_required_type("&RwLock<Data>"));
733
734 assert!(!is_sync_required_type("Rc<i32>"));
736 assert!(!is_sync_required_type("Box<String>"));
737 assert!(!is_sync_required_type("Mutex<Data>")); }
739
740 #[test]
741 fn test_constraint_extraction_precision() {
742 let constraints = extract_constraints("Vec<i32>");
744 assert_eq!(constraints.len(), 1);
745 assert!(constraints
746 .iter()
747 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
748
749 let constraints = extract_constraints("MyVec<i32>");
751 assert!(constraints.is_empty());
752
753 let constraints = extract_constraints("Mutex<String>");
755 assert_eq!(constraints.len(), 1);
756 assert!(constraints
757 .iter()
758 .any(|c| matches!(c.constraint_type, ConstraintType::Send)));
759
760 let constraints = extract_constraints("Arc<Data>");
762 assert_eq!(constraints.len(), 2);
763 assert!(constraints
764 .iter()
765 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
766 assert!(constraints
767 .iter()
768 .any(|c| matches!(c.constraint_type, ConstraintType::Sync)));
769
770 let constraints = extract_constraints("Arc<Mutex<Vec<String>>>");
772 assert!(constraints.len() >= 2);
775 assert!(constraints
776 .iter()
777 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
778 assert!(constraints
779 .iter()
780 .any(|c| matches!(c.constraint_type, ConstraintType::Send)));
781 assert!(constraints
782 .iter()
783 .any(|c| matches!(c.constraint_type, ConstraintType::Sync)));
784 }
785
786 #[test]
787 fn test_edge_cases_and_false_positives() {
788 assert!(!is_collection_type("MyVectorClass"));
790 assert!(!is_collection_type("HashMapBuilder"));
791 assert!(!is_collection_type("VecUtils"));
792
793 assert!(is_collection_type("std::vec::Vec<T>"));
795 assert!(is_collection_type("std::collections::HashMap<K, V>"));
796 assert!(is_smart_pointer_type("std::sync::Arc<T>"));
797 assert!(is_thread_safe_type("std::sync::Mutex<T>"));
798
799 assert!(!is_collection_type(""));
801 assert!(!is_smart_pointer_type(""));
802 assert!(!is_thread_safe_type(""));
803 assert!(!is_sync_required_type(""));
804
805 assert!(!is_collection_type("Vec"));
807 assert!(!is_smart_pointer_type("Arc"));
808 assert!(!is_thread_safe_type("Mutex"));
809 }
810
811 #[test]
812 fn test_track_generic_instantiation() {
813 let analyzer = GenericAnalyzer::new();
814 analyzer.track_generic_instantiation("Vec", vec!["i32".to_string()], 0x1000);
815
816 let instances = analyzer.generic_instances.safe_lock().unwrap();
817 assert_eq!(instances.len(), 1);
818 assert!(instances.contains_key("Vec"));
819 assert_eq!(instances.get("Vec").unwrap().len(), 1);
820
821 let events = analyzer.instantiation_events.safe_lock().unwrap();
822 assert_eq!(events.len(), 1);
823 assert_eq!(events[0].base_type, "Vec");
824 assert_eq!(events[0].type_parameters, vec!["i32"]);
825 assert_eq!(events[0].ptr, 0x1000);
826 }
827
828 #[test]
829 fn test_track_multiple_generic_instantiations() {
830 let analyzer = GenericAnalyzer::new();
831
832 analyzer.track_generic_instantiation("Vec", vec!["i32".to_string()], 0x1000);
834 analyzer.track_generic_instantiation("Vec", vec!["String".to_string()], 0x2000);
835
836 analyzer.track_generic_instantiation(
838 "HashMap",
839 vec!["String".to_string(), "i32".to_string()],
840 0x3000,
841 );
842
843 let instances = analyzer.generic_instances.safe_lock().unwrap();
844 assert_eq!(instances.len(), 2); assert_eq!(instances.get("Vec").unwrap().len(), 2); assert_eq!(instances.get("HashMap").unwrap().len(), 1); let events = analyzer.instantiation_events.safe_lock().unwrap();
849 assert_eq!(events.len(), 3); assert_eq!(events[0].base_type, "Vec");
851 assert_eq!(events[1].base_type, "Vec");
852 assert_eq!(events[2].base_type, "HashMap");
853 }
854
855 #[test]
856 fn test_track_generic_instantiation_with_complex_types() {
857 let analyzer = GenericAnalyzer::new();
858
859 analyzer.track_generic_instantiation("Vec", vec!["Vec<i32>".to_string()], 0x1000);
861
862 analyzer.track_generic_instantiation(
863 "HashMap",
864 vec!["String".to_string(), "Vec<usize>".to_string()],
865 0x2000,
866 );
867
868 let instances = analyzer.generic_instances.safe_lock().unwrap();
869 assert_eq!(instances.len(), 2);
870 assert_eq!(instances.get("Vec").unwrap().len(), 1);
871 assert_eq!(instances.get("HashMap").unwrap().len(), 1);
872
873 let vec_instances = instances.get("Vec").unwrap();
874 assert_eq!(vec_instances[0].type_parameters, vec!["Vec<i32>"]);
875
876 let hashmap_instances = instances.get("HashMap").unwrap();
877 assert_eq!(
878 hashmap_instances[0].type_parameters,
879 vec!["String", "Vec<usize>"]
880 );
881 }
882
883 #[test]
884 fn test_track_generic_instantiation_instance_details() {
885 let analyzer = GenericAnalyzer::new();
886 let timestamp_before = current_timestamp();
887
888 analyzer.track_generic_instantiation("Vec<i32>", vec!["i32".to_string()], 0x1000);
890
891 let instances = analyzer.generic_instances.safe_lock().unwrap();
892 let instance = &instances.get("Vec<i32>").unwrap()[0];
893 assert_eq!(instance.name, "Vec<i32>");
894 assert_eq!(instance.base_type, "Vec<i32>");
895 assert_eq!(instance.underlying_type, "Vec<i32>");
896 assert_eq!(instance.type_parameters, vec!["i32"]);
897 assert_eq!(instance.ptr, 0x1000);
898 assert_eq!(instance.size, 0); assert!(!instance.is_type_alias);
900
901 assert!(!instance.constraints.is_empty());
904 assert!(instance
905 .constraints
906 .iter()
907 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
908
909 let events = analyzer.instantiation_events.safe_lock().unwrap();
910 let event = &events[0];
911 assert_eq!(event.base_type, "Vec<i32>");
912 assert_eq!(event.type_parameters, vec!["i32"]);
913 assert_eq!(event.ptr, 0x1000);
914 assert!(event.timestamp >= timestamp_before);
915 assert!(!event.thread_id.is_empty());
916 }
917
918 #[test]
919 fn test_analyze_constraints() {
920 let analyzer = GenericAnalyzer::new();
921
922 let constraints = analyzer.analyze_constraints("Vec<T>");
924 assert!(!constraints.is_empty());
925 assert!(constraints
926 .iter()
927 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
928
929 let constraints = analyzer.analyze_constraints("Mutex<T>");
931 assert!(!constraints.is_empty());
932 assert!(constraints
933 .iter()
934 .any(|c| matches!(c.constraint_type, ConstraintType::Send)));
935
936 let constraints = analyzer.analyze_constraints("String");
938 assert!(constraints.is_empty());
939 }
940
941 #[test]
942 fn test_analyze_constraints_detailed() {
943 let analyzer = GenericAnalyzer::new();
944
945 let constraints = analyzer.analyze_constraints("Arc<T>");
947 assert!(!constraints.is_empty());
948 assert!(constraints
949 .iter()
950 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
951
952 let constraints = analyzer.analyze_constraints("RwLock<T>");
954 assert!(!constraints.is_empty());
955 assert!(constraints
956 .iter()
957 .any(|c| matches!(c.constraint_type, ConstraintType::Send)));
958
959 let constraints = analyzer.analyze_constraints("HashMap<K, V>");
961 assert!(!constraints.is_empty());
962 assert!(constraints
963 .iter()
964 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
965 }
966
967 #[test]
968 fn test_check_constraint_violations() {
969 let analyzer = GenericAnalyzer::new();
970
971 let violations = analyzer.check_constraint_violations("Vec", &["i32".to_string()]);
973 assert!(violations.is_empty());
974
975 let violations = analyzer.check_constraint_violations("Mutex", &["Rc<i32>".to_string()]);
977 assert!(violations.is_empty() || !violations.is_empty()); }
980
981 #[test]
982 fn test_check_constraint_violations_detailed() {
983 let analyzer = GenericAnalyzer::new();
984
985 let violations =
987 analyzer.check_constraint_violations("Vec", &["i32".to_string(), "String".to_string()]);
988 assert!(violations.is_empty());
989
990 let violations =
992 analyzer.check_constraint_violations("Vec", &["dyn SomeTrait".to_string()]);
993 assert!(violations.is_empty() || !violations.is_empty()); let violations = analyzer
999 .check_constraint_violations("HashMap", &["String".to_string(), "i32".to_string()]);
1000 assert!(violations.is_empty());
1001 }
1002
1003 #[test]
1004 fn test_get_generic_statistics() {
1005 let analyzer = GenericAnalyzer::new();
1006
1007 let stats = analyzer.get_generic_statistics();
1009 assert_eq!(stats.total_instances, 0);
1010 assert_eq!(stats.unique_base_types, 0);
1011 assert_eq!(stats.total_instantiations, 0);
1012 assert_eq!(stats.constraint_violations, 0);
1013 assert_eq!(stats.type_aliases_count, 0);
1014 assert!(stats.most_used_types.is_empty());
1015
1016 analyzer.track_generic_instantiation("Vec", vec!["i32".to_string()], 0x1000);
1018 analyzer.track_generic_instantiation("Vec", vec!["String".to_string()], 0x2000);
1019 analyzer.track_generic_instantiation(
1020 "HashMap",
1021 vec!["String".to_string(), "i32".to_string()],
1022 0x3000,
1023 );
1024
1025 let stats = analyzer.get_generic_statistics();
1026 assert_eq!(stats.total_instances, 3);
1027 assert_eq!(stats.unique_base_types, 2);
1028 assert_eq!(stats.total_instantiations, 3);
1029 assert_eq!(stats.constraint_violations, 0);
1030 assert!(!stats.most_used_types.is_empty());
1031 assert_eq!(stats.most_used_types[0].0, "Vec");
1032 assert_eq!(stats.most_used_types[0].1, 2);
1033 }
1034
1035 #[test]
1036 fn test_get_generic_statistics_detailed() {
1037 let analyzer = GenericAnalyzer::new();
1038
1039 for i in 0..5 {
1041 analyzer.track_generic_instantiation("Vec", vec![format!("Type{}", i)], 0x1000 + i);
1042 }
1043
1044 for i in 0..3 {
1045 analyzer.track_generic_instantiation("HashMap", vec![format!("Type{}", i)], 0x2000 + i);
1046 }
1047
1048 analyzer.track_generic_instantiation("Box", vec!["i32".to_string()], 0x3000);
1049
1050 let stats = analyzer.get_generic_statistics();
1051 assert_eq!(stats.total_instances, 9);
1052 assert_eq!(stats.unique_base_types, 3);
1053 assert_eq!(stats.total_instantiations, 9);
1054
1055 assert_eq!(stats.most_used_types.len(), 3);
1057 assert_eq!(stats.most_used_types[0].0, "Vec");
1058 assert_eq!(stats.most_used_types[0].1, 5);
1059 assert_eq!(stats.most_used_types[1].0, "HashMap");
1060 assert_eq!(stats.most_used_types[1].1, 3);
1061 assert_eq!(stats.most_used_types[2].0, "Box");
1062 assert_eq!(stats.most_used_types[2].1, 1);
1063 }
1064
1065 #[test]
1066 fn test_constraint_validation() {
1067 let analyzer = GenericAnalyzer::new();
1068
1069 let sized_constraint = GenericConstraint {
1071 parameter_name: "T".to_string(),
1072 constraint_type: ConstraintType::Sized,
1073 description: "Type must be Sized".to_string(),
1074 };
1075 assert!(analyzer.validate_constraint(&sized_constraint, &["i32".to_string()]));
1076
1077 let send_constraint = GenericConstraint {
1079 parameter_name: "T".to_string(),
1080 constraint_type: ConstraintType::Send,
1081 description: "Type must be Send".to_string(),
1082 };
1083 assert!(analyzer.validate_constraint(&send_constraint, &["i32".to_string()]));
1084 assert!(!analyzer.validate_constraint(&send_constraint, &["Rc<i32>".to_string()]));
1086
1087 let sync_constraint = GenericConstraint {
1089 parameter_name: "T".to_string(),
1090 constraint_type: ConstraintType::Sync,
1091 description: "Type must be Sync".to_string(),
1092 };
1093 assert!(analyzer.validate_constraint(&sync_constraint, &["i32".to_string()]));
1094 assert!(!analyzer.validate_constraint(&sync_constraint, &["RefCell<i32>".to_string()]));
1096 }
1097
1098 #[test]
1099 fn test_constraint_validation_detailed() {
1100 let analyzer = GenericAnalyzer::new();
1101
1102 let lifetime_constraint = GenericConstraint {
1104 parameter_name: "T".to_string(),
1105 constraint_type: ConstraintType::Lifetime,
1106 description: "Lifetime constraint".to_string(),
1107 };
1108 assert!(analyzer.validate_constraint(&lifetime_constraint, &["i32".to_string()]));
1109
1110 let sized_constraint = GenericConstraint {
1112 parameter_name: "T".to_string(),
1113 constraint_type: ConstraintType::Sized,
1114 description: "Type must be Sized".to_string(),
1115 };
1116 assert!(analyzer.validate_constraint(&sized_constraint, &["String".to_string()]));
1117 assert!(analyzer.validate_constraint(&sized_constraint, &["Vec<i32>".to_string()]));
1118
1119 let send_constraint = GenericConstraint {
1121 parameter_name: "T".to_string(),
1122 constraint_type: ConstraintType::Send,
1123 description: "Type must be Send".to_string(),
1124 };
1125 assert!(analyzer.validate_constraint(&send_constraint, &["i32".to_string()]));
1126 assert!(analyzer.validate_constraint(&send_constraint, &["Arc<String>".to_string()]));
1127 assert!(!analyzer.validate_constraint(&send_constraint, &["Rc<i32>".to_string()]));
1128
1129 let sync_constraint = GenericConstraint {
1131 parameter_name: "T".to_string(),
1132 constraint_type: ConstraintType::Sync,
1133 description: "Type must be Sync".to_string(),
1134 };
1135 assert!(analyzer.validate_constraint(&sync_constraint, &["i32".to_string()]));
1136 assert!(analyzer.validate_constraint(&sync_constraint, &["Arc<String>".to_string()]));
1137 assert!(!analyzer.validate_constraint(&sync_constraint, &["Cell<i32>".to_string()]));
1138 }
1139
1140 #[test]
1141 fn test_trait_implementation_checks() {
1142 let analyzer = GenericAnalyzer::new();
1143
1144 assert!(analyzer.type_implements_trait(&["i32".to_string()], "Clone"));
1146 assert!(!analyzer.type_implements_trait(&["Mutex<i32>".to_string()], "Clone"));
1147
1148 assert!(analyzer.type_implements_trait(&["i32".to_string()], "Debug"));
1150 assert!(!analyzer.type_implements_trait(&["fn(i32) -> i32".to_string()], "Debug"));
1152
1153 assert!(analyzer.type_implements_trait(&["Vec<i32>".to_string()], "Default"));
1155 assert!(analyzer.type_implements_trait(&["String".to_string()], "Default"));
1156 assert!(!analyzer.type_implements_trait(&["i32".to_string()], "Default")); assert!(analyzer.type_implements_trait(&["i32".to_string()], "PartialEq"));
1160 assert!(!analyzer.type_implements_trait(&["fn(i32) -> i32".to_string()], "PartialEq"));
1162 }
1163
1164 #[test]
1165 fn test_trait_implementation_checks_detailed() {
1166 let analyzer = GenericAnalyzer::new();
1167
1168 assert!(analyzer.type_implements_trait(&["String".to_string()], "Clone"));
1170 assert!(analyzer.type_implements_trait(&["Vec<i32>".to_string()], "Clone"));
1171 assert!(!analyzer.type_implements_trait(&["Mutex<String>".to_string()], "Clone"));
1172 assert!(!analyzer.type_implements_trait(&["File".to_string()], "Clone"));
1173
1174 assert!(analyzer.type_implements_trait(&["String".to_string()], "Debug"));
1176 assert!(analyzer.type_implements_trait(&["Vec<i32>".to_string()], "Debug"));
1177 assert!(!analyzer.type_implements_trait(&["fn(i32)".to_string()], "Debug"));
1179
1180 assert!(analyzer.type_implements_trait(&["String".to_string()], "Default"));
1182 assert!(analyzer.type_implements_trait(&["Vec<i32>".to_string()], "Default"));
1183 assert!(analyzer.type_implements_trait(&["HashMap<String, i32>".to_string()], "Default"));
1184 assert!(!analyzer.type_implements_trait(&["i32".to_string()], "Default"));
1185
1186 assert!(analyzer.type_implements_trait(&["String".to_string()], "PartialEq"));
1188 assert!(analyzer.type_implements_trait(&["Vec<i32>".to_string()], "PartialEq"));
1189 assert!(!analyzer.type_implements_trait(&["fn(i32)".to_string()], "PartialEq"));
1191 assert!(!analyzer.type_implements_trait(&["Mutex<String>".to_string()], "PartialEq"));
1192 }
1193
1194 #[test]
1195 fn test_send_sync_checks() {
1196 let analyzer = GenericAnalyzer::new();
1197
1198 assert!(analyzer.type_is_send(&["i32".to_string()]));
1200 assert!(!analyzer.type_is_send(&["Rc<i32>".to_string()]));
1201 assert!(!analyzer.type_is_send(&["RefCell<i32>".to_string()]));
1202
1203 assert!(analyzer.type_is_sync(&["i32".to_string()]));
1205 assert!(analyzer.type_is_sync(&["Rc<i32>".to_string()])); assert!(!analyzer.type_is_sync(&["Cell<i32>".to_string()]));
1207 assert!(!analyzer.type_is_sync(&["RefCell<i32>".to_string()]));
1208 }
1209
1210 #[test]
1211 fn test_send_sync_checks_detailed() {
1212 let analyzer = GenericAnalyzer::new();
1213
1214 assert!(analyzer.type_is_send(&["String".to_string()]));
1216 assert!(analyzer.type_is_send(&["Vec<i32>".to_string()]));
1217 assert!(analyzer.type_is_send(&["Arc<String>".to_string()]));
1218 assert!(!analyzer.type_is_send(&["Rc<String>".to_string()]));
1219 assert!(!analyzer.type_is_send(&["RefCell<String>".to_string()]));
1220
1221 assert!(analyzer.type_is_sync(&["String".to_string()]));
1223 assert!(analyzer.type_is_sync(&["Vec<i32>".to_string()]));
1224 assert!(analyzer.type_is_sync(&["Arc<String>".to_string()]));
1225 assert!(analyzer.type_is_sync(&["Rc<String>".to_string()])); assert!(!analyzer.type_is_sync(&["Cell<i32>".to_string()]));
1227 assert!(!analyzer.type_is_sync(&["RefCell<String>".to_string()]));
1228 }
1229
1230 #[test]
1231 fn test_global_generic_analyzer() {
1232 let analyzer1 = get_global_generic_analyzer();
1233 let analyzer2 = get_global_generic_analyzer();
1234
1235 assert!(Arc::ptr_eq(&analyzer1, &analyzer2));
1237
1238 let unique_type = format!("TestVec{}", std::process::id());
1240 analyzer1.track_generic_instantiation(&unique_type, vec!["i32".to_string()], 0x1000);
1241 let stats = analyzer2.get_generic_statistics();
1242 assert!(stats.total_instances >= 1);
1244 }
1245
1246 #[test]
1247 fn test_global_generic_analyzer_isolation() {
1248 let analyzer = GenericAnalyzer::new();
1250 let initial_stats = analyzer.get_generic_statistics();
1251
1252 analyzer.track_generic_instantiation("Vec", vec!["i32".to_string()], 0x1000);
1254
1255 let stats = analyzer.get_generic_statistics();
1257 assert_eq!(stats.total_instances, initial_stats.total_instances + 1);
1258 }
1259
1260 #[test]
1261 fn test_concurrent_access() {
1262 use std::sync::Arc;
1263 use std::thread;
1264
1265 let analyzer = Arc::new(GenericAnalyzer::new());
1266 let mut handles = vec![];
1267
1268 for i in 0..5 {
1270 let analyzer_clone = analyzer.clone();
1271 let handle = thread::spawn(move || {
1272 analyzer_clone.track_generic_instantiation(
1273 &format!("Vec{i}"),
1274 vec![format!("Type{i}")],
1275 0x1000 + i,
1276 );
1277 });
1278 handles.push(handle);
1279 }
1280
1281 for handle in handles {
1283 handle.join().unwrap();
1284 }
1285
1286 let stats = analyzer.get_generic_statistics();
1288 assert_eq!(stats.total_instances, 5);
1289 assert_eq!(stats.unique_base_types, 5);
1290 }
1291
1292 #[test]
1293 fn test_concurrent_access_heavy_load() {
1294 use std::sync::Arc;
1295 use std::thread;
1296
1297 let analyzer = Arc::new(GenericAnalyzer::new());
1298 let mut handles = vec![];
1299
1300 for i in 0..4 {
1302 let analyzer_clone = analyzer.clone();
1303 let handle = thread::spawn(move || {
1304 analyzer_clone.track_generic_instantiation(
1305 "Vec",
1306 vec![format!("Type{i}")],
1307 0x1000 + i,
1308 );
1309
1310 let _stats = analyzer_clone.get_generic_statistics();
1312 });
1313 handles.push(handle);
1314 }
1315
1316 for handle in handles {
1318 handle.join().unwrap();
1319 }
1320
1321 let stats = analyzer.get_generic_statistics();
1323 assert_eq!(stats.total_instances, 4);
1324 assert_eq!(stats.unique_base_types, 1); assert_eq!(stats.total_instantiations, 4);
1326 }
1327
1328 #[test]
1329 fn test_type_alias_tracking() {
1330 let analyzer = GenericAnalyzer::new();
1331
1332 analyzer.track_type_alias_instantiation("MyA", "Vec<i32>", vec!["i32".to_string()], 0x1000);
1334
1335 let instances = analyzer.generic_instances.safe_lock().unwrap();
1336 let instance = &instances.get("MyA").unwrap()[0];
1337
1338 assert_eq!(instance.name, "MyA");
1339 assert_eq!(instance.base_type, "Vec");
1340 assert_eq!(instance.underlying_type, "Vec<i32>");
1341 assert_eq!(instance.type_parameters, vec!["i32"]);
1342 assert_eq!(instance.ptr, 0x1000);
1343 assert!(instance.is_type_alias);
1344
1345 assert!(!instance.constraints.is_empty());
1347 assert!(instance
1348 .constraints
1349 .iter()
1350 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
1351 }
1352
1353 #[test]
1354 fn test_type_alias_resolution() {
1355 let analyzer = GenericAnalyzer::new();
1356
1357 analyzer.track_type_alias_instantiation(
1359 "MyVec",
1360 "Vec<String>",
1361 vec!["String".to_string()],
1362 0x1000,
1363 );
1364 analyzer.track_type_alias_instantiation(
1365 "MyMap",
1366 "HashMap<String, i32>",
1367 vec!["String".to_string(), "i32".to_string()],
1368 0x2000,
1369 );
1370
1371 assert_eq!(
1373 analyzer.resolve_type_alias("MyVec"),
1374 Some("Vec<String>".to_string())
1375 );
1376 assert_eq!(
1377 analyzer.resolve_type_alias("MyMap"),
1378 Some("HashMap<String, i32>".to_string())
1379 );
1380 assert_eq!(analyzer.resolve_type_alias("NonExistent"), None);
1381 }
1382
1383 #[test]
1384 fn test_type_alias_statistics() {
1385 let analyzer = GenericAnalyzer::new();
1386
1387 analyzer.track_generic_instantiation("Vec<i32>", vec!["i32".to_string()], 0x1000);
1389 analyzer.track_type_alias_instantiation(
1390 "MyVec",
1391 "Vec<String>",
1392 vec!["String".to_string()],
1393 0x2000,
1394 );
1395 analyzer.track_type_alias_instantiation(
1396 "MyMap",
1397 "HashMap<String, i32>",
1398 vec!["String".to_string(), "i32".to_string()],
1399 0x3000,
1400 );
1401
1402 let stats = analyzer.get_generic_statistics();
1403 assert_eq!(stats.total_instances, 3);
1404 assert_eq!(stats.type_aliases_count, 2);
1405 assert_eq!(stats.unique_base_types, 3); let most_used = &stats.most_used_types;
1409 assert!(most_used.iter().any(|(name, _)| name.contains("Vec")));
1410 }
1411
1412 #[test]
1413 fn test_get_type_aliases() {
1414 let analyzer = GenericAnalyzer::new();
1415
1416 analyzer.track_type_alias_instantiation(
1418 "MyVec",
1419 "Vec<i32>",
1420 vec!["i32".to_string()],
1421 0x1000,
1422 );
1423 analyzer.track_type_alias_instantiation(
1424 "MyMap",
1425 "HashMap<String, usize>",
1426 vec!["String".to_string(), "usize".to_string()],
1427 0x2000,
1428 );
1429 analyzer.track_type_alias_instantiation(
1430 "MyVec",
1431 "Vec<i32>",
1432 vec!["i32".to_string()],
1433 0x3000,
1434 ); let aliases = analyzer.get_type_aliases();
1437 assert_eq!(aliases.len(), 2); let my_vec_alias = aliases.iter().find(|a| a.alias_name == "MyVec").unwrap();
1440 assert_eq!(my_vec_alias.underlying_type, "Vec<i32>");
1441 assert_eq!(my_vec_alias.base_type, "Vec");
1442 assert_eq!(my_vec_alias.usage_count, 2); let my_map_alias = aliases.iter().find(|a| a.alias_name == "MyMap").unwrap();
1445 assert_eq!(my_map_alias.underlying_type, "HashMap<String, usize>");
1446 assert_eq!(my_map_alias.base_type, "HashMap");
1447 assert_eq!(my_map_alias.usage_count, 1);
1448 }
1449
1450 #[test]
1451 fn test_track_generic_instantiation_with_name() {
1452 let analyzer = GenericAnalyzer::new();
1453
1454 analyzer.track_generic_instantiation_with_name(
1456 "my_vec",
1457 "Vec<i32>",
1458 vec!["i32".to_string()],
1459 0x1000,
1460 );
1461
1462 let instances = analyzer.generic_instances.safe_lock().unwrap();
1463 let instance = &instances.get("my_vec").unwrap()[0];
1464
1465 assert_eq!(instance.name, "my_vec");
1466 assert_eq!(instance.base_type, "Vec<i32>");
1467 assert_eq!(instance.underlying_type, "Vec<i32>");
1468 assert!(instance.is_type_alias); }
1470
1471 #[test]
1472 fn test_complex_type_alias_parsing() {
1473 let analyzer = GenericAnalyzer::new();
1474
1475 analyzer.track_type_alias_instantiation(
1477 "ComplexType",
1478 "Arc<Mutex<Vec<String>>>",
1479 vec!["String".to_string()],
1480 0x1000,
1481 );
1482
1483 let instances = analyzer.generic_instances.safe_lock().unwrap();
1484 let instance = &instances.get("ComplexType").unwrap()[0];
1485
1486 assert_eq!(instance.name, "ComplexType");
1487 assert_eq!(instance.base_type, "Arc");
1488 assert_eq!(instance.underlying_type, "Arc<Mutex<Vec<String>>>");
1489 assert!(instance.is_type_alias);
1490
1491 assert!(!instance.constraints.is_empty());
1493 assert!(instance
1495 .constraints
1496 .iter()
1497 .any(|c| matches!(c.constraint_type, ConstraintType::Sized)));
1498 assert!(instance
1499 .constraints
1500 .iter()
1501 .any(|c| matches!(c.constraint_type, ConstraintType::Sync)));
1502 }
1503
1504 #[test]
1505 fn test_type_alias_vs_regular_type() {
1506 let analyzer = GenericAnalyzer::new();
1507
1508 analyzer.track_generic_instantiation("Vec<i32>", vec!["i32".to_string()], 0x1000);
1510
1511 analyzer.track_type_alias_instantiation(
1513 "MyVec",
1514 "Vec<i32>",
1515 vec!["i32".to_string()],
1516 0x2000,
1517 );
1518
1519 let instances = analyzer.generic_instances.safe_lock().unwrap();
1520
1521 let regular_instance = &instances.get("Vec<i32>").unwrap()[0];
1523 assert!(!regular_instance.is_type_alias);
1524 assert_eq!(regular_instance.name, "Vec<i32>");
1525 assert_eq!(regular_instance.base_type, "Vec<i32>");
1526
1527 let alias_instance = &instances.get("MyVec").unwrap()[0];
1529 assert!(alias_instance.is_type_alias);
1530 assert_eq!(alias_instance.name, "MyVec");
1531 assert_eq!(alias_instance.base_type, "Vec");
1532 assert_eq!(alias_instance.underlying_type, "Vec<i32>");
1533
1534 drop(instances);
1536
1537 let stats = analyzer.get_generic_statistics();
1539 assert_eq!(stats.total_instances, 2);
1540 assert_eq!(stats.type_aliases_count, 1);
1541 }
1542}