t-ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRuby
4
+ # Custom exceptions for type alias errors
5
+ class DuplicateTypeAliasError < StandardError; end
6
+ class CircularTypeAliasError < StandardError; end
7
+ class UndefinedTypeError < StandardError; end
8
+
9
+ class TypeAliasRegistry
10
+ BUILT_IN_TYPES = %w[String Integer Boolean Array Hash Symbol void nil].freeze
11
+
12
+ def initialize
13
+ @aliases = {}
14
+ end
15
+
16
+ def register(name, definition)
17
+ if @aliases.key?(name)
18
+ raise DuplicateTypeAliasError, "Type alias '#{name}' is already defined"
19
+ end
20
+
21
+ # Check for self-reference
22
+ if name == definition
23
+ raise CircularTypeAliasError, "Type alias '#{name}' cannot reference itself"
24
+ end
25
+
26
+ # Check for circular references (including longer chains)
27
+ if would_create_cycle?(name, definition)
28
+ raise CircularTypeAliasError, "Circular type alias detected involving '#{name}'"
29
+ end
30
+
31
+ @aliases[name] = definition
32
+ end
33
+
34
+ def resolve(name)
35
+ @aliases[name]
36
+ end
37
+
38
+ def all
39
+ @aliases.dup
40
+ end
41
+
42
+ def clear
43
+ @aliases.clear
44
+ end
45
+
46
+ def valid_type?(name)
47
+ return true if BUILT_IN_TYPES.include?(name)
48
+ @aliases.key?(name)
49
+ end
50
+
51
+ def validate_all
52
+ @aliases.each do |name, definition|
53
+ check_circular_references(name)
54
+ check_undefined_types(definition)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def would_create_cycle?(name, definition)
61
+ # Follow the chain of definitions from 'definition' to see if it leads back to 'name'
62
+ visited = Set.new
63
+ current = definition
64
+
65
+ # Check each step in the chain
66
+ until visited.include?(current)
67
+ return true if current == name
68
+ return false unless @aliases.key?(current)
69
+
70
+ visited.add(current)
71
+ current = @aliases[current]
72
+ end
73
+
74
+ false
75
+ end
76
+
77
+ def check_circular_references(name, visited = Set.new)
78
+ return if visited.include?(name)
79
+
80
+ visited.add(name)
81
+ definition = @aliases[name]
82
+
83
+ return unless @aliases.key?(definition)
84
+
85
+ if visited.include?(definition)
86
+ raise CircularTypeAliasError, "Circular type alias detected involving '#{name}'"
87
+ end
88
+
89
+ check_circular_references(definition, visited)
90
+ end
91
+
92
+ def check_undefined_types(type_name)
93
+ return if BUILT_IN_TYPES.include?(type_name)
94
+ return if @aliases.key?(type_name)
95
+
96
+ # Ignore generic types for now (e.g., Array<String>, Result<T, E>)
97
+ return if type_name.include?("<")
98
+
99
+ raise UndefinedTypeError, "Type '#{type_name}' is not defined"
100
+ end
101
+ end
102
+ end