@@ -3,7 +3,6 @@ package vibes
33import (
44 "errors"
55 "fmt"
6- "reflect"
76 "sort"
87 "strings"
98)
@@ -47,177 +46,6 @@ func formatReturnTypeMismatch(fnName string, err error) string {
4746 return fmt .Sprintf ("return type check failed for %s: %s" , fnName , err .Error ())
4847}
4948
50- type typeValidationVisit struct {
51- valueKind ValueKind
52- valueID uintptr
53- ty * TypeExpr
54- }
55-
56- type typeValidationState struct {
57- active map [typeValidationVisit ]struct {}
58- }
59-
60- func valueMatchesType (val Value , ty * TypeExpr ) (bool , error ) {
61- state := typeValidationState {
62- active : make (map [typeValidationVisit ]struct {}),
63- }
64- return state .matches (val , ty )
65- }
66-
67- func (s * typeValidationState ) matches (val Value , ty * TypeExpr ) (bool , error ) {
68- if visit , ok := typeValidationVisitFor (val , ty ); ok {
69- if _ , seen := s .active [visit ]; seen {
70- // Recursive value/type pair already being validated higher in the stack.
71- return true , nil
72- }
73- s .active [visit ] = struct {}{}
74- defer delete (s .active , visit )
75- }
76-
77- if ty .Nullable && val .Kind () == KindNil {
78- return true , nil
79- }
80- switch ty .Kind {
81- case TypeAny :
82- return true , nil
83- case TypeInt :
84- return val .Kind () == KindInt , nil
85- case TypeFloat :
86- return val .Kind () == KindFloat , nil
87- case TypeNumber :
88- return val .Kind () == KindInt || val .Kind () == KindFloat , nil
89- case TypeString :
90- return val .Kind () == KindString , nil
91- case TypeBool :
92- return val .Kind () == KindBool , nil
93- case TypeNil :
94- return val .Kind () == KindNil , nil
95- case TypeDuration :
96- return val .Kind () == KindDuration , nil
97- case TypeTime :
98- return val .Kind () == KindTime , nil
99- case TypeMoney :
100- return val .Kind () == KindMoney , nil
101- case TypeArray :
102- if val .Kind () != KindArray {
103- return false , nil
104- }
105- if len (ty .TypeArgs ) == 0 {
106- return true , nil
107- }
108- if len (ty .TypeArgs ) != 1 {
109- return false , fmt .Errorf ("array type expects exactly 1 type argument" )
110- }
111- elemType := ty .TypeArgs [0 ]
112- for _ , elem := range val .Array () {
113- matches , err := s .matches (elem , elemType )
114- if err != nil {
115- return false , err
116- }
117- if ! matches {
118- return false , nil
119- }
120- }
121- return true , nil
122- case TypeHash :
123- if val .Kind () != KindHash && val .Kind () != KindObject {
124- return false , nil
125- }
126- if len (ty .TypeArgs ) == 0 {
127- return true , nil
128- }
129- if len (ty .TypeArgs ) != 2 {
130- return false , fmt .Errorf ("hash type expects exactly 2 type arguments" )
131- }
132- keyType := ty .TypeArgs [0 ]
133- valueType := ty .TypeArgs [1 ]
134- for key , value := range val .Hash () {
135- keyMatches , err := s .matches (NewString (key ), keyType )
136- if err != nil {
137- return false , err
138- }
139- if ! keyMatches {
140- return false , nil
141- }
142- valueMatches , err := s .matches (value , valueType )
143- if err != nil {
144- return false , err
145- }
146- if ! valueMatches {
147- return false , nil
148- }
149- }
150- return true , nil
151- case TypeFunction :
152- return val .Kind () == KindFunction , nil
153- case TypeShape :
154- if val .Kind () != KindHash && val .Kind () != KindObject {
155- return false , nil
156- }
157- entries := val .Hash ()
158- if len (ty .Shape ) == 0 {
159- return len (entries ) == 0 , nil
160- }
161- for field , fieldType := range ty .Shape {
162- fieldVal , ok := entries [field ]
163- if ! ok {
164- return false , nil
165- }
166- matches , err := s .matches (fieldVal , fieldType )
167- if err != nil {
168- return false , err
169- }
170- if ! matches {
171- return false , nil
172- }
173- }
174- for field := range entries {
175- if _ , ok := ty .Shape [field ]; ! ok {
176- return false , nil
177- }
178- }
179- return true , nil
180- case TypeUnion :
181- for _ , option := range ty .Union {
182- matches , err := s .matches (val , option )
183- if err != nil {
184- return false , err
185- }
186- if matches {
187- return true , nil
188- }
189- }
190- return false , nil
191- default :
192- return false , fmt .Errorf ("unknown type %s" , ty .Name )
193- }
194- }
195-
196- func typeValidationVisitFor (val Value , ty * TypeExpr ) (typeValidationVisit , bool ) {
197- if ty == nil {
198- return typeValidationVisit {}, false
199- }
200-
201- var valueID uintptr
202- switch val .Kind () {
203- case KindArray :
204- valueID = reflect .ValueOf (val .Array ()).Pointer ()
205- case KindHash , KindObject :
206- valueID = reflect .ValueOf (val .Hash ()).Pointer ()
207- default :
208- return typeValidationVisit {}, false
209- }
210- if valueID == 0 {
211- return typeValidationVisit {}, false
212- }
213-
214- return typeValidationVisit {
215- valueKind : val .Kind (),
216- valueID : valueID ,
217- ty : ty ,
218- }, true
219- }
220-
22149func formatTypeExpr (ty * TypeExpr ) string {
22250 if ty == nil {
22351 return "unknown"
0 commit comments