goscript 0.0.61 → 0.0.63

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.
Files changed (92) hide show
  1. package/README.md +62 -46
  2. package/compiler/analysis.go +621 -19
  3. package/compiler/analysis_test.go +3 -3
  4. package/compiler/assignment.go +100 -0
  5. package/compiler/builtin_test.go +1 -1
  6. package/compiler/compiler.go +76 -16
  7. package/compiler/compiler_test.go +9 -9
  8. package/compiler/composite-lit.go +29 -8
  9. package/compiler/decl.go +20 -11
  10. package/compiler/expr-call-async.go +26 -1
  11. package/compiler/expr-call-builtins.go +60 -4
  12. package/compiler/expr-call-type-conversion.go +37 -5
  13. package/compiler/expr-call.go +26 -6
  14. package/compiler/expr-selector.go +35 -2
  15. package/compiler/expr-type.go +12 -2
  16. package/compiler/expr.go +61 -0
  17. package/compiler/index.test.ts +3 -1
  18. package/compiler/lit.go +13 -4
  19. package/compiler/spec-struct.go +30 -8
  20. package/compiler/spec-value.go +2 -2
  21. package/compiler/spec.go +23 -4
  22. package/compiler/stmt-assign.go +124 -0
  23. package/compiler/stmt-range.go +2 -2
  24. package/compiler/stmt.go +160 -14
  25. package/compiler/type-info.go +3 -5
  26. package/compiler/type-utils.go +40 -1
  27. package/compiler/type.go +52 -14
  28. package/dist/gs/builtin/builtin.d.ts +8 -1
  29. package/dist/gs/builtin/builtin.js +26 -1
  30. package/dist/gs/builtin/builtin.js.map +1 -1
  31. package/dist/gs/builtin/errors.d.ts +1 -0
  32. package/dist/gs/builtin/errors.js +8 -0
  33. package/dist/gs/builtin/errors.js.map +1 -1
  34. package/dist/gs/builtin/slice.d.ts +5 -4
  35. package/dist/gs/builtin/slice.js +88 -51
  36. package/dist/gs/builtin/slice.js.map +1 -1
  37. package/dist/gs/builtin/type.d.ts +23 -2
  38. package/dist/gs/builtin/type.js +125 -0
  39. package/dist/gs/builtin/type.js.map +1 -1
  40. package/dist/gs/builtin/varRef.d.ts +3 -0
  41. package/dist/gs/builtin/varRef.js +6 -1
  42. package/dist/gs/builtin/varRef.js.map +1 -1
  43. package/dist/gs/bytes/reader.gs.d.ts +1 -1
  44. package/dist/gs/bytes/reader.gs.js +1 -1
  45. package/dist/gs/bytes/reader.gs.js.map +1 -1
  46. package/dist/gs/reflect/index.d.ts +2 -2
  47. package/dist/gs/reflect/index.js +1 -1
  48. package/dist/gs/reflect/index.js.map +1 -1
  49. package/dist/gs/reflect/map.d.ts +3 -2
  50. package/dist/gs/reflect/map.js +37 -3
  51. package/dist/gs/reflect/map.js.map +1 -1
  52. package/dist/gs/reflect/type.d.ts +53 -12
  53. package/dist/gs/reflect/type.js +906 -31
  54. package/dist/gs/reflect/type.js.map +1 -1
  55. package/dist/gs/reflect/types.d.ts +11 -12
  56. package/dist/gs/reflect/types.js +26 -15
  57. package/dist/gs/reflect/types.js.map +1 -1
  58. package/dist/gs/reflect/value.d.ts +4 -4
  59. package/dist/gs/reflect/value.js +8 -2
  60. package/dist/gs/reflect/value.js.map +1 -1
  61. package/dist/gs/slices/slices.d.ts +21 -0
  62. package/dist/gs/slices/slices.js +48 -0
  63. package/dist/gs/slices/slices.js.map +1 -1
  64. package/dist/gs/strconv/atoi.gs.js +20 -2
  65. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  66. package/dist/gs/sync/atomic/type.gs.d.ts +3 -3
  67. package/dist/gs/sync/atomic/type.gs.js +13 -7
  68. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  69. package/dist/gs/unicode/utf8/utf8.d.ts +2 -2
  70. package/dist/gs/unicode/utf8/utf8.js +10 -6
  71. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  72. package/go.mod +6 -6
  73. package/go.sum +12 -8
  74. package/gs/builtin/builtin.ts +27 -2
  75. package/gs/builtin/errors.ts +12 -0
  76. package/gs/builtin/slice.ts +126 -55
  77. package/gs/builtin/type.ts +159 -2
  78. package/gs/builtin/varRef.ts +8 -2
  79. package/gs/bytes/reader.gs.ts +2 -2
  80. package/gs/math/hypot.gs.test.ts +3 -1
  81. package/gs/math/pow10.gs.test.ts +5 -4
  82. package/gs/reflect/index.ts +3 -2
  83. package/gs/reflect/map.test.ts +7 -6
  84. package/gs/reflect/map.ts +49 -7
  85. package/gs/reflect/type.ts +1150 -57
  86. package/gs/reflect/types.ts +34 -21
  87. package/gs/reflect/value.ts +12 -6
  88. package/gs/slices/slices.ts +55 -0
  89. package/gs/strconv/atoi.gs.ts +18 -2
  90. package/gs/sync/atomic/type.gs.ts +15 -10
  91. package/gs/unicode/utf8/utf8.ts +12 -8
  92. package/package.json +23 -14
@@ -1,9 +1,16 @@
1
- import { ReflectValue, StructField } from './types.js'
1
+ import { ReflectValue, StructField, StructTag, ValueError } from './types.js'
2
+ export { StructField }
2
3
  import { MapIter } from './map.js'
3
4
  import {
4
5
  getTypeByName as builtinGetTypeByName,
5
6
  TypeKind,
7
+ isStructTypeInfo,
8
+ isInterfaceTypeInfo,
9
+ isStructFieldInfo,
6
10
  } from '../builtin/type.js'
11
+ import { Zero } from './value.js'
12
+ import { DeepEqual } from './deepequal.js'
13
+ import * as $ from '../builtin/index.js'
7
14
 
8
15
  // rtype is the common implementation of most values
9
16
  export class rtype {
@@ -177,7 +184,8 @@ export interface Type {
177
184
  Size(): number
178
185
 
179
186
  // Elem returns a type's element type.
180
- Elem(): Type | null
187
+ // Panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
188
+ Elem(): Type
181
189
 
182
190
  // NumField returns a struct type's field count.
183
191
  NumField(): number
@@ -186,30 +194,137 @@ export interface Type {
186
194
  PkgPath?(): string
187
195
 
188
196
  // Field returns a struct type's i'th field.
189
- Field?(i: number): StructField | null
197
+ // Panics if the type's Kind is not Struct or i is out of range.
198
+ Field(i: number): StructField
190
199
 
191
- // Key returns a map type's key type (returns null for non-map types).
192
- Key?(): Type | null
200
+ // Key returns a map type's key type.
201
+ // Panics if the type's Kind is not Map.
202
+ Key(): Type
193
203
 
194
204
  // Name returns the type's name within its package.
195
- Name?(): string
205
+ Name(): string
196
206
 
197
207
  // Implements reports whether the type implements the interface type u.
198
- Implements?(u: Type): boolean
208
+ Implements(u: Type | null): boolean
199
209
 
200
210
  // common returns the common type implementation.
201
211
  common?(): rtype
212
+
213
+ // OverflowInt reports whether the int64 x cannot be represented by the type
214
+ // Panics if the type's Kind is not Int, Int8, Int16, Int32, or Int64.
215
+ OverflowInt(x: number): boolean
216
+
217
+ // OverflowUint reports whether the uint64 x cannot be represented by the type
218
+ // Panics if the type's Kind is not Uint, Uint8, Uint16, Uint32, Uint64, or Uintptr.
219
+ OverflowUint(x: number): boolean
220
+
221
+ // OverflowFloat reports whether the float64 x cannot be represented by the type
222
+ // Panics if the type's Kind is not Float32 or Float64.
223
+ OverflowFloat(x: number): boolean
224
+
225
+ // NumMethod returns the number of methods in the type's method set
226
+ NumMethod(): number
227
+
228
+ // Bits returns the size of the type in bits
229
+ // Panics if the type's Kind is not a sized type.
230
+ Bits(): number
231
+ }
232
+
233
+ // InvalidTypeInstance is a singleton type for invalid/zero reflect.Value
234
+ class InvalidTypeClass implements Type {
235
+ Kind(): Kind {
236
+ return Invalid
237
+ }
238
+ String(): string {
239
+ return '<invalid reflect.Value>'
240
+ }
241
+ Name(): string {
242
+ return ''
243
+ }
244
+ Size(): number {
245
+ return 0
246
+ }
247
+ Elem(): Type {
248
+ throw new Error('reflect: Elem of invalid type')
249
+ }
250
+ Key(): Type {
251
+ throw new Error('reflect: Key of invalid type')
252
+ }
253
+ NumField(): number {
254
+ return 0
255
+ }
256
+ Field(_i: number): StructField {
257
+ throw new Error('reflect: Field of invalid type')
258
+ }
259
+ Implements(_u: Type | null): boolean {
260
+ return false
261
+ }
262
+ OverflowInt(_x: number): boolean {
263
+ throw new Error('reflect: OverflowInt of invalid type')
264
+ }
265
+ OverflowUint(_x: number): boolean {
266
+ throw new Error('reflect: OverflowUint of invalid type')
267
+ }
268
+ OverflowFloat(_x: number): boolean {
269
+ throw new Error('reflect: OverflowFloat of invalid type')
270
+ }
271
+ NumMethod(): number {
272
+ return 0
273
+ }
274
+ Bits(): number {
275
+ throw new Error('reflect: Bits of invalid type')
276
+ }
202
277
  }
278
+ const invalidTypeInstance = new InvalidTypeClass()
203
279
 
204
280
  // Value is the reflection interface to a Go value - consolidated from all implementations
205
281
  export class Value {
282
+ private _value: ReflectValue
283
+ private _type: Type
284
+ // _parentVarRef tracks the VarRef this value was dereferenced from (for Set support)
285
+ private _parentVarRef?: $.VarRef<ReflectValue>
286
+ // _parentStruct and _fieldName track the parent struct and field name for struct field Set() support
287
+ private _parentStruct?: Record<string, any>
288
+ private _fieldName?: string
289
+
206
290
  constructor(
207
- private _value: ReflectValue,
208
- private _type: Type,
209
- ) {}
291
+ value?: ReflectValue | Record<string, never>,
292
+ type?: Type | null,
293
+ parentVarRef?: $.VarRef<ReflectValue>,
294
+ parentStruct?: Record<string, any>,
295
+ fieldName?: string,
296
+ ) {
297
+ // Handle zero-value initialization: new Value({}) or new Value()
298
+ // This corresponds to reflect.Value{} in Go which is an invalid/zero value
299
+ if (
300
+ type === undefined ||
301
+ type === null ||
302
+ (typeof value === 'object' &&
303
+ value !== null &&
304
+ Object.keys(value).length === 0 &&
305
+ !(value instanceof globalThis.Array) &&
306
+ !(value instanceof globalThis.Map))
307
+ ) {
308
+ this._value = null
309
+ this._type = invalidTypeInstance
310
+ } else {
311
+ this._value = value as ReflectValue
312
+ this._type = type
313
+ }
314
+ this._parentVarRef = parentVarRef
315
+ this._parentStruct = parentStruct
316
+ this._fieldName = fieldName
317
+ }
210
318
 
211
319
  public clone(): Value {
212
- return new Value(this._value, this._type)
320
+ const cloned = new Value(
321
+ this._value,
322
+ this._type,
323
+ this._parentVarRef,
324
+ this._parentStruct,
325
+ this._fieldName,
326
+ )
327
+ return cloned
213
328
  }
214
329
 
215
330
  // Methods required by godoc.txt and used throughout the codebase
@@ -321,7 +436,10 @@ export class Value {
321
436
  }
322
437
 
323
438
  public IsValid(): boolean {
324
- return this._value !== null && this._value !== undefined
439
+ // In Go, a Value is valid if it was properly constructed (not the zero Value{}).
440
+ // A valid Value can have a nil underlying value (e.g., nil map, nil pointer).
441
+ // We check if the type is valid (not the invalid type sentinel).
442
+ return this._type !== invalidTypeInstance
325
443
  }
326
444
 
327
445
  public IsNil(): boolean {
@@ -351,17 +469,37 @@ export class Value {
351
469
  }
352
470
 
353
471
  public Elem(): Value {
354
- // For pointers and interfaces, return the element
355
- return new Value(this._value, this._type)
472
+ // For pointers, unwrap the VarRef and return the element, tracking the parent
473
+ if (this._type.Kind() === Ptr && $.isVarRef(this._value)) {
474
+ const varRef = this._value as $.VarRef<ReflectValue>
475
+ const elemType = this._type.Elem()
476
+ return new Value(varRef.value, elemType, varRef)
477
+ }
478
+ // For interfaces, return the underlying value
479
+ return new Value(this._value, this._type, this._parentVarRef)
356
480
  }
357
481
 
358
482
  public NumField(): number {
359
483
  return this._type.NumField()
360
484
  }
361
485
 
362
- public Field(_i: number): Value {
363
- // Simplified implementation for struct field access
364
- return new Value(null, this._type)
486
+ public Field(i: number): Value {
487
+ if (this.Kind() !== Struct) {
488
+ throw new ValueError({ Kind: this.Kind(), Method: 'Field' })
489
+ }
490
+
491
+ const field = this.Type().Field(i)
492
+ if (!field) {
493
+ throw new Error('reflect: struct field index out of range')
494
+ }
495
+
496
+ const parentObj = this._value as Record<string, any>
497
+ let fieldVal = parentObj[field.Name]
498
+ if (fieldVal === undefined) {
499
+ fieldVal = null
500
+ }
501
+ // Pass parent struct and field name so Set() can update the struct
502
+ return new Value(fieldVal, field.Type, undefined, parentObj, field.Name)
365
503
  }
366
504
 
367
505
  // Additional methods needed by various parts of the codebase
@@ -388,7 +526,68 @@ export class Value {
388
526
  return new Value(this._value, t)
389
527
  }
390
528
 
529
+ public CanAddr(): boolean {
530
+ return this.Kind() !== Ptr && this._value !== null // Simplified
531
+ }
532
+
533
+ public Addr(): Value {
534
+ if (!this.CanAddr()) {
535
+ throw new Error('reflect: call of reflect.Value.Addr on invalid Value')
536
+ }
537
+ const ptrType = PointerTo(this.Type())
538
+ return new Value(this, ptrType) // Simplified
539
+ }
540
+
541
+ public CanSet(): boolean {
542
+ // Simplified: all valid values are settable in GoScript since we handle
543
+ // pointer semantics through VarRef. This enables JSON unmarshaling to work.
544
+ return this.IsValid()
545
+ }
546
+
547
+ public Set(x: Value): void {
548
+ if (!this.CanSet()) {
549
+ throw new Error('reflect: assign to invalid value')
550
+ }
551
+ // Interface types can accept any value
552
+ if (this.Kind() === Interface) {
553
+ this._value = x.value
554
+ // Also update the parent VarRef if we were dereferenced from one
555
+ if (this._parentVarRef) {
556
+ this._parentVarRef.value = x.value
557
+ }
558
+ // Also update the parent struct field if this is a struct field
559
+ if (this._parentStruct && this._fieldName) {
560
+ this._parentStruct[this._fieldName] = x.value
561
+ }
562
+ return
563
+ }
564
+ // For other types, check if types are compatible (simplified check)
565
+ const thisType = this.Type()
566
+ const xType = x.Type()
567
+ if (thisType.Kind() !== xType.Kind()) {
568
+ throw new Error('reflect: assign to wrong type')
569
+ }
570
+ this._value = x.value
571
+ // Also update the parent VarRef if we were dereferenced from one
572
+ if (this._parentVarRef) {
573
+ this._parentVarRef.value = x.value
574
+ }
575
+ // Also update the parent struct field if this is a struct field
576
+ if (this._parentStruct && this._fieldName) {
577
+ this._parentStruct[this._fieldName] = x.value
578
+ }
579
+ }
580
+
391
581
  // Additional methods from deleted reflect.gs.ts
582
+ public Interface(): any {
583
+ return this._value
584
+ }
585
+
586
+ public IsZero(): boolean {
587
+ const zeroVal = Zero(this.Type()).value
588
+ return DeepEqual(this._value, zeroVal)
589
+ }
590
+
392
591
  public typ(): rtype | null {
393
592
  return new rtype(this._type.Kind())
394
593
  }
@@ -439,6 +638,299 @@ export class Value {
439
638
  channelObj._sendQueue.push(valueToSend)
440
639
  }
441
640
  }
641
+
642
+ // SetString sets v's underlying value to x
643
+ public SetString(x: string): void {
644
+ if (!this.CanSet()) {
645
+ throw new Error(
646
+ 'reflect: call of reflect.Value.SetString on unaddressable value',
647
+ )
648
+ }
649
+ if (this.Kind() !== String) {
650
+ throw new Error(
651
+ 'reflect: call of reflect.Value.SetString on ' + this.Kind() + ' Value',
652
+ )
653
+ }
654
+ this._value = x
655
+ if (this._parentVarRef) {
656
+ this._parentVarRef.value = x
657
+ }
658
+ if (this._parentStruct && this._fieldName) {
659
+ this._parentStruct[this._fieldName] = x
660
+ }
661
+ }
662
+
663
+ // SetInt sets v's underlying value to x
664
+ public SetInt(x: number): void {
665
+ if (!this.CanSet()) {
666
+ throw new Error(
667
+ 'reflect: call of reflect.Value.SetInt on unaddressable value',
668
+ )
669
+ }
670
+ const k = this.Kind()
671
+ if (k !== Int && k !== Int8 && k !== Int16 && k !== Int32 && k !== Int64) {
672
+ throw new Error(
673
+ 'reflect: call of reflect.Value.SetInt on ' + k + ' Value',
674
+ )
675
+ }
676
+ this._value = x
677
+ if (this._parentVarRef) {
678
+ this._parentVarRef.value = x
679
+ }
680
+ if (this._parentStruct && this._fieldName) {
681
+ this._parentStruct[this._fieldName] = x
682
+ }
683
+ }
684
+
685
+ // SetUint sets v's underlying value to x
686
+ public SetUint(x: number): void {
687
+ if (!this.CanSet()) {
688
+ throw new Error(
689
+ 'reflect: call of reflect.Value.SetUint on unaddressable value',
690
+ )
691
+ }
692
+ const k = this.Kind()
693
+ if (
694
+ k !== Uint &&
695
+ k !== Uint8 &&
696
+ k !== Uint16 &&
697
+ k !== Uint32 &&
698
+ k !== Uint64 &&
699
+ k !== Uintptr
700
+ ) {
701
+ throw new Error(
702
+ 'reflect: call of reflect.Value.SetUint on ' + k + ' Value',
703
+ )
704
+ }
705
+ this._value = x
706
+ if (this._parentVarRef) {
707
+ this._parentVarRef.value = x
708
+ }
709
+ if (this._parentStruct && this._fieldName) {
710
+ this._parentStruct[this._fieldName] = x
711
+ }
712
+ }
713
+
714
+ // SetBool sets v's underlying value to x
715
+ public SetBool(x: boolean): void {
716
+ if (!this.CanSet()) {
717
+ throw new Error(
718
+ 'reflect: call of reflect.Value.SetBool on unaddressable value',
719
+ )
720
+ }
721
+ if (this.Kind() !== Bool) {
722
+ throw new Error(
723
+ 'reflect: call of reflect.Value.SetBool on ' + this.Kind() + ' Value',
724
+ )
725
+ }
726
+ this._value = x
727
+ if (this._parentVarRef) {
728
+ this._parentVarRef.value = x
729
+ }
730
+ if (this._parentStruct && this._fieldName) {
731
+ this._parentStruct[this._fieldName] = x
732
+ }
733
+ }
734
+
735
+ // SetFloat sets v's underlying value to x
736
+ public SetFloat(x: number): void {
737
+ if (!this.CanSet()) {
738
+ throw new Error(
739
+ 'reflect: call of reflect.Value.SetFloat on unaddressable value',
740
+ )
741
+ }
742
+ const k = this.Kind()
743
+ if (k !== Float32 && k !== Float64) {
744
+ throw new Error(
745
+ 'reflect: call of reflect.Value.SetFloat on ' + k + ' Value',
746
+ )
747
+ }
748
+ this._value = x
749
+ if (this._parentVarRef) {
750
+ this._parentVarRef.value = x
751
+ }
752
+ if (this._parentStruct && this._fieldName) {
753
+ this._parentStruct[this._fieldName] = x
754
+ }
755
+ }
756
+
757
+ // SetBytes sets v's underlying value to x
758
+ public SetBytes(x: $.Slice<number>): void {
759
+ if (!this.CanSet()) {
760
+ throw new Error(
761
+ 'reflect: call of reflect.Value.SetBytes on unaddressable value',
762
+ )
763
+ }
764
+ if (this.Kind() !== Slice) {
765
+ throw new Error(
766
+ 'reflect: call of reflect.Value.SetBytes on ' + this.Kind() + ' Value',
767
+ )
768
+ }
769
+ // Convert Uint8Array or slice to array
770
+ if (x instanceof Uint8Array) {
771
+ this._value = globalThis.Array.from(x)
772
+ } else if (globalThis.Array.isArray(x)) {
773
+ this._value = x
774
+ } else {
775
+ this._value = x
776
+ }
777
+ }
778
+
779
+ // SetZero sets v to be the zero value of v's type
780
+ public SetZero(): void {
781
+ if (!this.CanSet()) {
782
+ throw new Error(
783
+ 'reflect: call of reflect.Value.SetZero on unaddressable value',
784
+ )
785
+ }
786
+ const zeroVal = Zero(this.Type())
787
+ this._value = (zeroVal as unknown as { value: ReflectValue }).value
788
+ }
789
+
790
+ // SetLen sets v's length to n
791
+ public SetLen(n: number): void {
792
+ if (!this.CanSet()) {
793
+ throw new Error(
794
+ 'reflect: call of reflect.Value.SetLen on unaddressable value',
795
+ )
796
+ }
797
+ if (this.Kind() !== Slice) {
798
+ throw new Error(
799
+ 'reflect: call of reflect.Value.SetLen on ' + this.Kind() + ' Value',
800
+ )
801
+ }
802
+ if (globalThis.Array.isArray(this._value)) {
803
+ this._value.length = n
804
+ }
805
+ }
806
+
807
+ // SetMapIndex sets the element associated with key in the map v to elem
808
+ public SetMapIndex(key: Value, elem: Value): void {
809
+ if (!this.CanSet()) {
810
+ throw new Error(
811
+ 'reflect: call of reflect.Value.SetMapIndex on unaddressable value',
812
+ )
813
+ }
814
+ if (this.Kind() !== Map) {
815
+ throw new Error(
816
+ 'reflect: call of reflect.Value.SetMapIndex on ' +
817
+ this.Kind() +
818
+ ' Value',
819
+ )
820
+ }
821
+ const mapObj = this._value as globalThis.Map<unknown, unknown>
822
+ const keyVal = (key as unknown as { value: ReflectValue }).value
823
+ const elemVal = (elem as unknown as { value: ReflectValue }).value
824
+ mapObj.set(keyVal, elemVal)
825
+ }
826
+
827
+ // Grow increases the slice's capacity, if necessary
828
+ public Grow(n: number): void {
829
+ if (this.Kind() !== Slice) {
830
+ throw new Error(
831
+ 'reflect: call of reflect.Value.Grow on ' + this.Kind() + ' Value',
832
+ )
833
+ }
834
+ if (!globalThis.Array.isArray(this._value)) {
835
+ return
836
+ }
837
+ // JavaScript arrays grow automatically, but we ensure capacity
838
+ const currentLen = this._value.length
839
+ const targetCap = currentLen + n
840
+ if (this._value.length < targetCap) {
841
+ this._value.length = targetCap
842
+ this._value.length = currentLen // Reset to original length
843
+ }
844
+ }
845
+
846
+ // Cap returns v's capacity
847
+ public Cap(): number {
848
+ const k = this.Kind()
849
+ if (k === Slice || k === Array) {
850
+ if (globalThis.Array.isArray(this._value)) {
851
+ return this._value.length
852
+ }
853
+ return 0
854
+ }
855
+ if (k === Chan) {
856
+ return 0 // Simplified
857
+ }
858
+ throw new Error('reflect: call of reflect.Value.Cap on ' + k + ' Value')
859
+ }
860
+
861
+ // NumMethod returns the number of methods in the value's method set
862
+ public NumMethod(): number {
863
+ return 0 // Simplified - methods not fully implemented
864
+ }
865
+
866
+ // Equal reports whether v is equal to u
867
+ public Equal(u: Value): boolean {
868
+ return DeepEqual(
869
+ this._value,
870
+ (u as unknown as { value: ReflectValue }).value,
871
+ )
872
+ }
873
+
874
+ // CanInterface reports whether Interface can be used without panicking
875
+ public CanInterface(): boolean {
876
+ return this.IsValid()
877
+ }
878
+
879
+ // OverflowInt reports whether the int64 x cannot be represented by v's type
880
+ public OverflowInt(x: number): boolean {
881
+ const k = this.Kind()
882
+ switch (k) {
883
+ case Int8:
884
+ return x < -128 || x > 127
885
+ case Int16:
886
+ return x < -32768 || x > 32767
887
+ case Int32:
888
+ return x < -2147483648 || x > 2147483647
889
+ case Int:
890
+ case Int64:
891
+ return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER
892
+ default:
893
+ throw new Error(
894
+ 'reflect: call of reflect.Value.OverflowInt on ' + k + ' Value',
895
+ )
896
+ }
897
+ }
898
+
899
+ // OverflowUint reports whether the uint64 x cannot be represented by v's type
900
+ public OverflowUint(x: number): boolean {
901
+ const k = this.Kind()
902
+ switch (k) {
903
+ case Uint8:
904
+ return x < 0 || x > 255
905
+ case Uint16:
906
+ return x < 0 || x > 65535
907
+ case Uint32:
908
+ return x < 0 || x > 4294967295
909
+ case Uint:
910
+ case Uint64:
911
+ case Uintptr:
912
+ return x < 0 || x > Number.MAX_SAFE_INTEGER
913
+ default:
914
+ throw new Error(
915
+ 'reflect: call of reflect.Value.OverflowUint on ' + k + ' Value',
916
+ )
917
+ }
918
+ }
919
+
920
+ // OverflowFloat reports whether the float64 x cannot be represented by v's type
921
+ public OverflowFloat(x: number): boolean {
922
+ const k = this.Kind()
923
+ if (k === Float32) {
924
+ const f32max = 3.4028234663852886e38
925
+ return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x)
926
+ }
927
+ if (k === Float64) {
928
+ return false // float64 can represent any JavaScript number
929
+ }
930
+ throw new Error(
931
+ 'reflect: call of reflect.Value.OverflowFloat on ' + k + ' Value',
932
+ )
933
+ }
442
934
  }
443
935
 
444
936
  // Basic type implementation - exported for compatibility
@@ -461,8 +953,8 @@ export class BasicType implements Type {
461
953
  return this._size
462
954
  }
463
955
 
464
- public Elem(): Type | null {
465
- return null
956
+ public Elem(): Type {
957
+ throw new Error(`reflect: Elem of invalid type ${this._name}`)
466
958
  }
467
959
 
468
960
  public NumField(): number {
@@ -473,13 +965,125 @@ export class BasicType implements Type {
473
965
  return ''
474
966
  }
475
967
 
476
- public Field?(_i: number): StructField | null {
477
- return null
968
+ public Name(): string {
969
+ // Basic types have names like 'int', 'string', etc.
970
+ return this._name
971
+ }
972
+
973
+ public Field(_i: number): StructField {
974
+ throw new Error(`reflect: Field of non-struct type ${this._name}`)
975
+ }
976
+
977
+ public Key(): Type {
978
+ throw new Error(`reflect: Key of non-map type ${this._name}`)
979
+ }
980
+
981
+ public Implements(u: Type | null): boolean {
982
+ if (!u) {
983
+ return false
984
+ }
985
+ if (u.Kind() !== Interface) {
986
+ throw new Error('reflect: non-interface type passed to Type.Implements')
987
+ }
988
+ return false
478
989
  }
479
990
 
480
991
  public common?(): rtype {
481
992
  return new rtype(this._kind)
482
993
  }
994
+
995
+ public OverflowInt(x: number): boolean {
996
+ const k = this._kind
997
+ switch (k) {
998
+ case Int8:
999
+ return x < -128 || x > 127
1000
+ case Int16:
1001
+ return x < -32768 || x > 32767
1002
+ case Int32:
1003
+ return x < -2147483648 || x > 2147483647
1004
+ case Int:
1005
+ case Int64:
1006
+ return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER
1007
+ default:
1008
+ throw new Error(
1009
+ 'reflect: call of reflect.Type.OverflowInt on ' +
1010
+ Kind_String(k) +
1011
+ ' Type',
1012
+ )
1013
+ }
1014
+ }
1015
+
1016
+ public OverflowUint(x: number): boolean {
1017
+ const k = this._kind
1018
+ switch (k) {
1019
+ case Uint8:
1020
+ return x < 0 || x > 255
1021
+ case Uint16:
1022
+ return x < 0 || x > 65535
1023
+ case Uint32:
1024
+ return x < 0 || x > 4294967295
1025
+ case Uint:
1026
+ case Uint64:
1027
+ case Uintptr:
1028
+ return x < 0 || x > Number.MAX_SAFE_INTEGER
1029
+ default:
1030
+ throw new Error(
1031
+ 'reflect: call of reflect.Type.OverflowUint on ' +
1032
+ Kind_String(k) +
1033
+ ' Type',
1034
+ )
1035
+ }
1036
+ }
1037
+
1038
+ public OverflowFloat(x: number): boolean {
1039
+ const k = this._kind
1040
+ if (k === Float32) {
1041
+ const f32max = 3.4028234663852886e38
1042
+ return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x)
1043
+ }
1044
+ if (k === Float64) {
1045
+ return false
1046
+ }
1047
+ throw new Error(
1048
+ 'reflect: call of reflect.Type.OverflowFloat on ' +
1049
+ Kind_String(k) +
1050
+ ' Type',
1051
+ )
1052
+ }
1053
+
1054
+ public NumMethod(): number {
1055
+ return 0
1056
+ }
1057
+
1058
+ public Bits(): number {
1059
+ const k = this._kind
1060
+ switch (k) {
1061
+ case Bool:
1062
+ return 1
1063
+ case Int8:
1064
+ case Uint8:
1065
+ return 8
1066
+ case Int16:
1067
+ case Uint16:
1068
+ return 16
1069
+ case Int32:
1070
+ case Uint32:
1071
+ case Float32:
1072
+ return 32
1073
+ case Int64:
1074
+ case Uint64:
1075
+ case Float64:
1076
+ return 64
1077
+ case Int:
1078
+ case Uint:
1079
+ case Uintptr:
1080
+ return 64 // Assuming 64-bit architecture
1081
+ default:
1082
+ throw new Error(
1083
+ 'reflect: call of reflect.Type.Bits on ' + Kind_String(k) + ' Type',
1084
+ )
1085
+ }
1086
+ }
483
1087
  }
484
1088
 
485
1089
  // Slice type implementation
@@ -498,7 +1102,7 @@ class SliceType implements Type {
498
1102
  return 24 // slice header size
499
1103
  }
500
1104
 
501
- public Elem(): Type | null {
1105
+ public Elem(): Type {
502
1106
  return this._elemType
503
1107
  }
504
1108
 
@@ -509,6 +1113,49 @@ class SliceType implements Type {
509
1113
  public PkgPath?(): string {
510
1114
  return ''
511
1115
  }
1116
+
1117
+ public Name(): string {
1118
+ // Slice types are unnamed composite types
1119
+ return ''
1120
+ }
1121
+
1122
+ public Field(_i: number): StructField {
1123
+ throw new Error('reflect: Field of non-struct type')
1124
+ }
1125
+
1126
+ public Key(): Type {
1127
+ throw new Error('reflect: Key of non-map type')
1128
+ }
1129
+
1130
+ public Implements(u: Type | null): boolean {
1131
+ if (!u) {
1132
+ return false
1133
+ }
1134
+ if (u.Kind() !== Interface) {
1135
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1136
+ }
1137
+ return false
1138
+ }
1139
+
1140
+ public OverflowInt(_x: number): boolean {
1141
+ throw new Error('reflect: call of reflect.Type.OverflowInt on slice Type')
1142
+ }
1143
+
1144
+ public OverflowUint(_x: number): boolean {
1145
+ throw new Error('reflect: call of reflect.Type.OverflowUint on slice Type')
1146
+ }
1147
+
1148
+ public OverflowFloat(_x: number): boolean {
1149
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on slice Type')
1150
+ }
1151
+
1152
+ public NumMethod(): number {
1153
+ return 0
1154
+ }
1155
+
1156
+ public Bits(): number {
1157
+ throw new Error('reflect: call of reflect.Type.Bits on slice Type')
1158
+ }
512
1159
  }
513
1160
 
514
1161
  // Array type implementation
@@ -530,7 +1177,7 @@ class ArrayType implements Type {
530
1177
  return this._elemType.Size() * this._len
531
1178
  }
532
1179
 
533
- public Elem(): Type | null {
1180
+ public Elem(): Type {
534
1181
  return this._elemType
535
1182
  }
536
1183
 
@@ -546,13 +1193,52 @@ class ArrayType implements Type {
546
1193
  return ''
547
1194
  }
548
1195
 
549
- public Field?(_i: number): StructField | null {
550
- return null
1196
+ public Name(): string {
1197
+ // Array types are unnamed composite types
1198
+ return ''
1199
+ }
1200
+
1201
+ public Field(_i: number): StructField {
1202
+ throw new Error('reflect: Field of non-struct type')
1203
+ }
1204
+
1205
+ public Key(): Type {
1206
+ throw new Error('reflect: Key of non-map type')
1207
+ }
1208
+
1209
+ public Implements(u: Type | null): boolean {
1210
+ if (!u) {
1211
+ return false
1212
+ }
1213
+ if (u.Kind() !== Interface) {
1214
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1215
+ }
1216
+ return false
551
1217
  }
552
1218
 
553
1219
  public common?(): rtype {
554
1220
  return new rtype(this.Kind())
555
1221
  }
1222
+
1223
+ public OverflowInt(_x: number): boolean {
1224
+ throw new Error('reflect: call of reflect.Type.OverflowInt on array Type')
1225
+ }
1226
+
1227
+ public OverflowUint(_x: number): boolean {
1228
+ throw new Error('reflect: call of reflect.Type.OverflowUint on array Type')
1229
+ }
1230
+
1231
+ public OverflowFloat(_x: number): boolean {
1232
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on array Type')
1233
+ }
1234
+
1235
+ public NumMethod(): number {
1236
+ return 0
1237
+ }
1238
+
1239
+ public Bits(): number {
1240
+ throw new Error('reflect: call of reflect.Type.Bits on array Type')
1241
+ }
556
1242
  }
557
1243
 
558
1244
  // Pointer type implementation
@@ -571,7 +1257,7 @@ class PointerType implements Type {
571
1257
  return 8 // pointer size
572
1258
  }
573
1259
 
574
- public Elem(): Type | null {
1260
+ public Elem(): Type {
575
1261
  return this._elemType
576
1262
  }
577
1263
 
@@ -583,13 +1269,58 @@ class PointerType implements Type {
583
1269
  return ''
584
1270
  }
585
1271
 
586
- public Field?(_i: number): StructField | null {
587
- return null
1272
+ public Name(): string {
1273
+ // Pointer types are unnamed composite types
1274
+ return ''
1275
+ }
1276
+
1277
+ public Field(_i: number): StructField {
1278
+ throw new Error('reflect: Field of non-struct type')
1279
+ }
1280
+
1281
+ public Key(): Type {
1282
+ throw new Error('reflect: Key of non-map type')
1283
+ }
1284
+
1285
+ public Implements(u: Type | null): boolean {
1286
+ if (!u) {
1287
+ return false
1288
+ }
1289
+ if (u.Kind() !== Interface) {
1290
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1291
+ }
1292
+ // For pointer types, check if the element type implements the interface
1293
+ const elemTypeName = this._elemType.String()
1294
+ return typeImplementsInterface(elemTypeName, u)
588
1295
  }
589
1296
 
590
1297
  public common?(): rtype {
591
1298
  return new rtype(this.Kind())
592
1299
  }
1300
+
1301
+ public OverflowInt(_x: number): boolean {
1302
+ throw new Error('reflect: call of reflect.Type.OverflowInt on pointer Type')
1303
+ }
1304
+
1305
+ public OverflowUint(_x: number): boolean {
1306
+ throw new Error(
1307
+ 'reflect: call of reflect.Type.OverflowUint on pointer Type',
1308
+ )
1309
+ }
1310
+
1311
+ public OverflowFloat(_x: number): boolean {
1312
+ throw new Error(
1313
+ 'reflect: call of reflect.Type.OverflowFloat on pointer Type',
1314
+ )
1315
+ }
1316
+
1317
+ public NumMethod(): number {
1318
+ return 0
1319
+ }
1320
+
1321
+ public Bits(): number {
1322
+ throw new Error('reflect: call of reflect.Type.Bits on pointer Type')
1323
+ }
593
1324
  }
594
1325
 
595
1326
  // Function type implementation
@@ -608,8 +1339,8 @@ class FunctionType implements Type {
608
1339
  return 8 // function pointer size
609
1340
  }
610
1341
 
611
- public Elem(): Type | null {
612
- return null
1342
+ public Elem(): Type {
1343
+ throw new Error('reflect: Elem of invalid type')
613
1344
  }
614
1345
 
615
1346
  public NumField(): number {
@@ -620,13 +1351,52 @@ class FunctionType implements Type {
620
1351
  return ''
621
1352
  }
622
1353
 
623
- public Field?(_i: number): StructField | null {
624
- return null
1354
+ public Name(): string {
1355
+ // Function types are unnamed composite types
1356
+ return ''
1357
+ }
1358
+
1359
+ public Field(_i: number): StructField {
1360
+ throw new Error('reflect: Field of non-struct type')
1361
+ }
1362
+
1363
+ public Key(): Type {
1364
+ throw new Error('reflect: Key of non-map type')
1365
+ }
1366
+
1367
+ public Implements(u: Type | null): boolean {
1368
+ if (!u) {
1369
+ return false
1370
+ }
1371
+ if (u.Kind() !== Interface) {
1372
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1373
+ }
1374
+ return false
625
1375
  }
626
1376
 
627
1377
  public common?(): rtype {
628
1378
  return new rtype(this.Kind())
629
1379
  }
1380
+
1381
+ public OverflowInt(_x: number): boolean {
1382
+ throw new Error('reflect: call of reflect.Type.OverflowInt on func Type')
1383
+ }
1384
+
1385
+ public OverflowUint(_x: number): boolean {
1386
+ throw new Error('reflect: call of reflect.Type.OverflowUint on func Type')
1387
+ }
1388
+
1389
+ public OverflowFloat(_x: number): boolean {
1390
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type')
1391
+ }
1392
+
1393
+ public NumMethod(): number {
1394
+ return 0
1395
+ }
1396
+
1397
+ public Bits(): number {
1398
+ throw new Error('reflect: call of reflect.Type.Bits on func Type')
1399
+ }
630
1400
  }
631
1401
 
632
1402
  // Map type implementation
@@ -648,7 +1418,7 @@ class MapType implements Type {
648
1418
  return 8 // map header size
649
1419
  }
650
1420
 
651
- public Elem(): Type | null {
1421
+ public Elem(): Type {
652
1422
  return this._elemType
653
1423
  }
654
1424
 
@@ -664,20 +1434,109 @@ class MapType implements Type {
664
1434
  return ''
665
1435
  }
666
1436
 
667
- public Field?(_i: number): StructField | null {
668
- return null
1437
+ public Name(): string {
1438
+ // Map types are unnamed composite types
1439
+ return ''
1440
+ }
1441
+
1442
+ public Field(_i: number): StructField {
1443
+ throw new Error('reflect: Field of non-struct type')
1444
+ }
1445
+
1446
+ public Implements(u: Type | null): boolean {
1447
+ if (!u) {
1448
+ return false
1449
+ }
1450
+ if (u.Kind() !== Interface) {
1451
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1452
+ }
1453
+ return false
669
1454
  }
670
1455
 
671
1456
  public common?(): rtype {
672
1457
  return new rtype(this.Kind())
673
1458
  }
1459
+
1460
+ public OverflowInt(_x: number): boolean {
1461
+ throw new Error('reflect: call of reflect.Type.OverflowInt on map Type')
1462
+ }
1463
+
1464
+ public OverflowUint(_x: number): boolean {
1465
+ throw new Error('reflect: call of reflect.Type.OverflowUint on map Type')
1466
+ }
1467
+
1468
+ public OverflowFloat(_x: number): boolean {
1469
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on map Type')
1470
+ }
1471
+
1472
+ public NumMethod(): number {
1473
+ return 0
1474
+ }
1475
+
1476
+ public Bits(): number {
1477
+ throw new Error('reflect: call of reflect.Type.Bits on map Type')
1478
+ }
674
1479
  }
675
1480
 
676
1481
  // Struct type implementation
1482
+ /**
1483
+ * Helper function to check if a type's method set contains all methods
1484
+ * required by an interface.
1485
+ *
1486
+ * @param typeName The name of the type to check (e.g., "main.MyType")
1487
+ * @param interfaceType The interface type that must be implemented
1488
+ * @returns True if the type implements the interface, false otherwise
1489
+ */
1490
+ function typeImplementsInterface(
1491
+ typeName: string,
1492
+ interfaceType: Type,
1493
+ ): boolean {
1494
+ // Get the interface name and look it up in the type registry
1495
+ const interfaceName = interfaceType.String()
1496
+ const interfaceTypeInfo = builtinGetTypeByName(interfaceName)
1497
+
1498
+ if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
1499
+ return false
1500
+ }
1501
+
1502
+ // Get the type info for the struct/type
1503
+ const typeInfo = builtinGetTypeByName(typeName)
1504
+
1505
+ if (!typeInfo || !isStructTypeInfo(typeInfo)) {
1506
+ return false
1507
+ }
1508
+
1509
+ // Check if the type has all required methods
1510
+ const requiredMethods = interfaceTypeInfo.methods || []
1511
+ const typeMethods = typeInfo.methods || []
1512
+
1513
+ // For each required method, check if the type has a matching method
1514
+ for (const requiredMethod of requiredMethods) {
1515
+ const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name)
1516
+
1517
+ if (!typeMethod) {
1518
+ return false
1519
+ }
1520
+
1521
+ // Check if method signatures match (simplified - just check counts)
1522
+ if (typeMethod.args.length !== requiredMethod.args.length) {
1523
+ return false
1524
+ }
1525
+
1526
+ if (typeMethod.returns.length !== requiredMethod.returns.length) {
1527
+ return false
1528
+ }
1529
+
1530
+ // Could add deeper type checking here, but for now this is sufficient
1531
+ }
1532
+
1533
+ return true
1534
+ }
1535
+
677
1536
  class StructType implements Type {
678
1537
  constructor(
679
1538
  private _name: string,
680
- private _fields: Array<{ name: string; type: Type }> = [],
1539
+ private _fields: Array<{ name: string; type: Type; tag?: string }> = [],
681
1540
  ) {}
682
1541
 
683
1542
  public String(): string {
@@ -693,8 +1552,8 @@ class StructType implements Type {
693
1552
  return this._fields.reduce((sum, field) => sum + field.type.Size(), 0)
694
1553
  }
695
1554
 
696
- public Elem(): Type | null {
697
- return null
1555
+ public Elem(): Type {
1556
+ throw new Error('reflect: Elem of invalid type')
698
1557
  }
699
1558
 
700
1559
  public NumField(): number {
@@ -702,17 +1561,139 @@ class StructType implements Type {
702
1561
  }
703
1562
 
704
1563
  public PkgPath?(): string {
1564
+ // Extract package path from full type name (e.g., "main.Person" -> "main")
1565
+ const dotIndex = this._name.lastIndexOf('.')
1566
+ if (dotIndex > 0) {
1567
+ return this._name.substring(0, dotIndex)
1568
+ }
705
1569
  return ''
706
1570
  }
707
1571
 
708
- public Field?(_i: number): any {
709
- // Stub implementation
710
- return null
1572
+ public Name(): string {
1573
+ // Extract type name from full type name (e.g., "main.Person" -> "Person")
1574
+ const dotIndex = this._name.lastIndexOf('.')
1575
+ if (dotIndex >= 0) {
1576
+ return this._name.substring(dotIndex + 1)
1577
+ }
1578
+ return this._name
1579
+ }
1580
+
1581
+ public Field(i: number): StructField {
1582
+ if (i < 0 || i >= this.NumField()) {
1583
+ throw new Error(`reflect: Field index out of range [${i}] with length ${this.NumField()}`)
1584
+ }
1585
+ const f = this._fields[i]
1586
+ return new StructField({
1587
+ Name: f.name,
1588
+ Type: f.type,
1589
+ Tag: f.tag ? new StructTag(f.tag) : undefined,
1590
+ })
1591
+ }
1592
+
1593
+ public Key(): Type {
1594
+ throw new Error('reflect: Key of non-map type')
1595
+ }
1596
+
1597
+ public Implements(u: Type | null): boolean {
1598
+ if (!u) {
1599
+ return false
1600
+ }
1601
+ if (u.Kind() !== Interface) {
1602
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1603
+ }
1604
+ return typeImplementsInterface(this._name, u)
711
1605
  }
712
1606
 
713
1607
  public common?(): rtype {
714
1608
  return new rtype(this.Kind())
715
1609
  }
1610
+
1611
+ public OverflowInt(_x: number): boolean {
1612
+ throw new Error('reflect: call of reflect.Type.OverflowInt on struct Type')
1613
+ }
1614
+
1615
+ public OverflowUint(_x: number): boolean {
1616
+ throw new Error('reflect: call of reflect.Type.OverflowUint on struct Type')
1617
+ }
1618
+
1619
+ public OverflowFloat(_x: number): boolean {
1620
+ throw new Error(
1621
+ 'reflect: call of reflect.Type.OverflowFloat on struct Type',
1622
+ )
1623
+ }
1624
+
1625
+ public NumMethod(): number {
1626
+ return 0
1627
+ }
1628
+
1629
+ public Bits(): number {
1630
+ throw new Error('reflect: call of reflect.Type.Bits on struct Type')
1631
+ }
1632
+
1633
+ static createTypeFromFieldInfo(ti: any): Type {
1634
+ if (typeof ti === 'string') {
1635
+ switch (ti) {
1636
+ case 'string':
1637
+ return new BasicType(String, ti, 16)
1638
+ case 'int':
1639
+ case 'int32':
1640
+ case 'int64':
1641
+ case 'number':
1642
+ return new BasicType(Int, ti === 'number' ? 'int' : ti, 8)
1643
+ case 'bool':
1644
+ case 'boolean':
1645
+ return new BasicType(Bool, 'bool', 1)
1646
+ case 'float64':
1647
+ return new BasicType(Float64, ti, 8)
1648
+ case 'uint':
1649
+ case 'uint32':
1650
+ case 'uint64':
1651
+ return new BasicType(Uint, ti, 8)
1652
+ default:
1653
+ return new BasicType(Invalid, ti, 8)
1654
+ }
1655
+ } else if (ti && ti.kind) {
1656
+ // Handle TypeInfo objects from the builtin type system
1657
+ const name = ti.name || 'unknown'
1658
+ switch (ti.kind) {
1659
+ case 'basic':
1660
+ // Map TypeScript type names to Go type names
1661
+ switch (name) {
1662
+ case 'string':
1663
+ return new BasicType(String, 'string', 16)
1664
+ case 'number':
1665
+ case 'int':
1666
+ case 'int32':
1667
+ case 'int64':
1668
+ return new BasicType(Int, name === 'number' ? 'int' : name, 8)
1669
+ case 'boolean':
1670
+ case 'bool':
1671
+ return new BasicType(Bool, 'bool', 1)
1672
+ case 'float64':
1673
+ return new BasicType(Float64, 'float64', 8)
1674
+ default:
1675
+ return new BasicType(Invalid, name, 8)
1676
+ }
1677
+ case 'slice':
1678
+ if (ti.elemType) {
1679
+ return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType))
1680
+ }
1681
+ return new SliceType(new BasicType(Invalid, 'unknown', 8))
1682
+ case 'pointer':
1683
+ if (ti.elemType) {
1684
+ return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType))
1685
+ }
1686
+ return new PointerType(new BasicType(Invalid, 'unknown', 8))
1687
+ case 'interface':
1688
+ return new InterfaceType(name)
1689
+ case 'struct':
1690
+ return new StructType(name, [])
1691
+ default:
1692
+ return new BasicType(Invalid, name, 8)
1693
+ }
1694
+ }
1695
+ return new BasicType(Invalid, 'unknown', 8)
1696
+ }
716
1697
  }
717
1698
 
718
1699
  class ChannelType implements Type {
@@ -744,7 +1725,7 @@ class ChannelType implements Type {
744
1725
  return 8
745
1726
  }
746
1727
 
747
- public Elem(): Type | null {
1728
+ public Elem(): Type {
748
1729
  return this._elemType
749
1730
  }
750
1731
 
@@ -756,8 +1737,27 @@ class ChannelType implements Type {
756
1737
  return ''
757
1738
  }
758
1739
 
759
- public Field?(_: number): any {
760
- return null
1740
+ public Name(): string {
1741
+ // Channel types are unnamed composite types
1742
+ return ''
1743
+ }
1744
+
1745
+ public Field(_i: number): StructField {
1746
+ throw new Error('reflect: Field of non-struct type')
1747
+ }
1748
+
1749
+ public Key(): Type {
1750
+ throw new Error('reflect: Key of non-map type')
1751
+ }
1752
+
1753
+ public Implements(u: Type | null): boolean {
1754
+ if (!u) {
1755
+ return false
1756
+ }
1757
+ if (u.Kind() !== Interface) {
1758
+ throw new Error('reflect: non-interface type passed to Type.Implements')
1759
+ }
1760
+ return false
761
1761
  }
762
1762
 
763
1763
  public common?(): rtype {
@@ -767,6 +1767,26 @@ class ChannelType implements Type {
767
1767
  public ChanDir(): ChanDir {
768
1768
  return this._dir
769
1769
  }
1770
+
1771
+ public OverflowInt(_x: number): boolean {
1772
+ throw new Error('reflect: call of reflect.Type.OverflowInt on chan Type')
1773
+ }
1774
+
1775
+ public OverflowUint(_x: number): boolean {
1776
+ throw new Error('reflect: call of reflect.Type.OverflowUint on chan Type')
1777
+ }
1778
+
1779
+ public OverflowFloat(_x: number): boolean {
1780
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on chan Type')
1781
+ }
1782
+
1783
+ public NumMethod(): number {
1784
+ return 0
1785
+ }
1786
+
1787
+ public Bits(): number {
1788
+ throw new Error('reflect: call of reflect.Type.Bits on chan Type')
1789
+ }
770
1790
  }
771
1791
 
772
1792
  // Interface type implementation
@@ -785,8 +1805,8 @@ class InterfaceType implements Type {
785
1805
  return 16
786
1806
  }
787
1807
 
788
- public Elem(): Type | null {
789
- return null
1808
+ public Elem(): Type {
1809
+ throw new Error('reflect: Elem of invalid type')
790
1810
  }
791
1811
 
792
1812
  public NumField(): number {
@@ -797,24 +1817,70 @@ class InterfaceType implements Type {
797
1817
  return ''
798
1818
  }
799
1819
 
800
- public Name?(): string {
1820
+ public Name(): string {
801
1821
  return this._name
802
1822
  }
803
1823
 
804
- public Field?(_: number): StructField | null {
805
- return null
1824
+ public Field(_i: number): StructField {
1825
+ throw new Error('reflect: Field of non-struct type')
806
1826
  }
807
1827
 
808
- public Implements?(_u: Type): boolean {
1828
+ public Key(): Type {
1829
+ throw new Error('reflect: Key of non-map type')
1830
+ }
1831
+
1832
+ public Implements(_u: Type | null): boolean {
809
1833
  return false
810
1834
  }
811
1835
 
812
1836
  public common?(): rtype {
813
1837
  return new rtype(this.Kind())
814
1838
  }
1839
+
1840
+ public OverflowInt(_x: number): boolean {
1841
+ throw new Error(
1842
+ 'reflect: call of reflect.Type.OverflowInt on interface Type',
1843
+ )
1844
+ }
1845
+
1846
+ public OverflowUint(_x: number): boolean {
1847
+ throw new Error(
1848
+ 'reflect: call of reflect.Type.OverflowUint on interface Type',
1849
+ )
1850
+ }
1851
+
1852
+ public OverflowFloat(_x: number): boolean {
1853
+ throw new Error(
1854
+ 'reflect: call of reflect.Type.OverflowFloat on interface Type',
1855
+ )
1856
+ }
1857
+
1858
+ public NumMethod(): number {
1859
+ return 0
1860
+ }
1861
+
1862
+ public Bits(): number {
1863
+ throw new Error('reflect: call of reflect.Type.Bits on interface Type')
1864
+ }
815
1865
  }
816
1866
 
817
1867
  function getTypeOf(value: ReflectValue): Type {
1868
+ // Check for typed nil before checking for plain null
1869
+ // Typed nils are created by $.typedNil() and have __goType and __isTypedNil properties
1870
+ if (value && typeof value === 'object' && (value as any).__isTypedNil) {
1871
+ const typeName = (value as any).__goType
1872
+ if (typeName && typeof typeName === 'string') {
1873
+ // Parse the type name to construct the appropriate Type
1874
+ // For pointer types like "*main.Stringer", extract the element type
1875
+ if (typeName.startsWith('*')) {
1876
+ const elemTypeName = typeName.slice(1) // Remove the '*' prefix
1877
+ // Create an InterfaceType for the element (works for interfaces and other types)
1878
+ const elemType = new InterfaceType(elemTypeName)
1879
+ return new PointerType(elemType)
1880
+ }
1881
+ }
1882
+ }
1883
+
818
1884
  if (value === null || value === undefined) {
819
1885
  return new BasicType(Interface, 'interface{}', 16)
820
1886
  }
@@ -909,6 +1975,12 @@ function getTypeOf(value: ReflectValue): Type {
909
1975
  return new BasicType(Interface, 'interface{}', 16)
910
1976
  }
911
1977
 
1978
+ // Check for VarRef (pointer type in GoScript)
1979
+ if ($.isVarRef(value)) {
1980
+ const elemType = getTypeOf(value.value as ReflectValue)
1981
+ return new PointerType(elemType)
1982
+ }
1983
+
912
1984
  // Check for arrays
913
1985
  if (globalThis.Array.isArray(value)) {
914
1986
  if (value.length === 0) {
@@ -995,23 +2067,43 @@ function getTypeOf(value: ReflectValue): Type {
995
2067
  value.constructor as { __typeInfo?: { name?: string } }
996
2068
  ).__typeInfo
997
2069
  if (typeInfo && typeInfo.name) {
998
- // Add package prefix for struct types if not already present
999
2070
  const typeName =
1000
2071
  typeInfo.name.includes('.') ?
1001
2072
  typeInfo.name
1002
2073
  : `main.${typeInfo.name}`
1003
- return new StructType(typeName)
2074
+ const regTypeInfo = builtinGetTypeByName(typeName)
2075
+ let fields: Array<{ name: string; type: Type; tag?: string }> = []
2076
+ if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
2077
+ fields = Object.entries(regTypeInfo.fields || {}).map(
2078
+ ([name, fieldInfo]) => {
2079
+ // Check if fieldInfo is a StructFieldInfo with type and tag
2080
+ if (isStructFieldInfo(fieldInfo)) {
2081
+ return {
2082
+ name,
2083
+ type: StructType.createTypeFromFieldInfo(fieldInfo.type),
2084
+ tag: fieldInfo.tag,
2085
+ }
2086
+ }
2087
+ // Otherwise it's just the type info directly (backwards compatible)
2088
+ return {
2089
+ name,
2090
+ type: StructType.createTypeFromFieldInfo(fieldInfo),
2091
+ }
2092
+ },
2093
+ )
2094
+ }
2095
+ return new StructType(typeName, fields)
1004
2096
  }
1005
2097
  }
1006
2098
 
1007
2099
  // Check if it has a constructor name we can use (fallback)
1008
2100
  const constructorName = (value as object).constructor?.name
1009
2101
  if (constructorName && constructorName !== 'Object') {
1010
- return new StructType(constructorName)
2102
+ return new StructType(constructorName, [])
1011
2103
  }
1012
2104
 
1013
2105
  // Default to struct type for plain objects
1014
- return new StructType('struct')
2106
+ return new StructType('struct', [])
1015
2107
  }
1016
2108
  default:
1017
2109
  return new BasicType(Interface, 'interface{}', 16)
@@ -1035,11 +2127,12 @@ export function SliceOf(t: Type): Type {
1035
2127
  return new SliceType(t)
1036
2128
  }
1037
2129
 
1038
- export function PointerTo(t: Type): Type {
2130
+ export function PointerTo(t: Type | null): Type | null {
2131
+ if (t === null) return null
1039
2132
  return new PointerType(t)
1040
2133
  }
1041
2134
 
1042
- export function PtrTo(t: Type): Type {
2135
+ export function PtrTo(t: Type | null): Type | null {
1043
2136
  return PointerTo(t) // PtrTo is an alias for PointerTo
1044
2137
  }
1045
2138
 
@@ -1051,7 +2144,7 @@ export function ChanOf(dir: ChanDir, t: Type): Type {
1051
2144
  return new ChannelType(t, dir)
1052
2145
  }
1053
2146
 
1054
- export function TypeFor<T>(): Type {
2147
+ export function TypeFor(): Type {
1055
2148
  return new InterfaceType('interface{}')
1056
2149
  }
1057
2150