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,4 +1,9 @@
1
- import { getTypeByName as builtinGetTypeByName, TypeKind, } from '../builtin/type.js';
1
+ import { StructField, StructTag, ValueError } from './types.js';
2
+ export { StructField };
3
+ import { getTypeByName as builtinGetTypeByName, TypeKind, isStructTypeInfo, isInterfaceTypeInfo, isStructFieldInfo, } from '../builtin/type.js';
4
+ import { Zero } from './value.js';
5
+ import { DeepEqual } from './deepequal.js';
6
+ import * as $ from '../builtin/index.js';
2
7
  // rtype is the common implementation of most values
3
8
  export class rtype {
4
9
  kind;
@@ -144,16 +149,85 @@ export const Slice = 23;
144
149
  export const String = 24;
145
150
  export const Struct = 25;
146
151
  export const UnsafePointer = 26;
152
+ // InvalidTypeInstance is a singleton type for invalid/zero reflect.Value
153
+ class InvalidTypeClass {
154
+ Kind() {
155
+ return Invalid;
156
+ }
157
+ String() {
158
+ return '<invalid reflect.Value>';
159
+ }
160
+ Name() {
161
+ return '';
162
+ }
163
+ Size() {
164
+ return 0;
165
+ }
166
+ Elem() {
167
+ throw new Error('reflect: Elem of invalid type');
168
+ }
169
+ Key() {
170
+ throw new Error('reflect: Key of invalid type');
171
+ }
172
+ NumField() {
173
+ return 0;
174
+ }
175
+ Field(_i) {
176
+ throw new Error('reflect: Field of invalid type');
177
+ }
178
+ Implements(_u) {
179
+ return false;
180
+ }
181
+ OverflowInt(_x) {
182
+ throw new Error('reflect: OverflowInt of invalid type');
183
+ }
184
+ OverflowUint(_x) {
185
+ throw new Error('reflect: OverflowUint of invalid type');
186
+ }
187
+ OverflowFloat(_x) {
188
+ throw new Error('reflect: OverflowFloat of invalid type');
189
+ }
190
+ NumMethod() {
191
+ return 0;
192
+ }
193
+ Bits() {
194
+ throw new Error('reflect: Bits of invalid type');
195
+ }
196
+ }
197
+ const invalidTypeInstance = new InvalidTypeClass();
147
198
  // Value is the reflection interface to a Go value - consolidated from all implementations
148
199
  export class Value {
149
200
  _value;
150
201
  _type;
151
- constructor(_value, _type) {
152
- this._value = _value;
153
- this._type = _type;
202
+ // _parentVarRef tracks the VarRef this value was dereferenced from (for Set support)
203
+ _parentVarRef;
204
+ // _parentStruct and _fieldName track the parent struct and field name for struct field Set() support
205
+ _parentStruct;
206
+ _fieldName;
207
+ constructor(value, type, parentVarRef, parentStruct, fieldName) {
208
+ // Handle zero-value initialization: new Value({}) or new Value()
209
+ // This corresponds to reflect.Value{} in Go which is an invalid/zero value
210
+ if (type === undefined ||
211
+ type === null ||
212
+ (typeof value === 'object' &&
213
+ value !== null &&
214
+ Object.keys(value).length === 0 &&
215
+ !(value instanceof globalThis.Array) &&
216
+ !(value instanceof globalThis.Map))) {
217
+ this._value = null;
218
+ this._type = invalidTypeInstance;
219
+ }
220
+ else {
221
+ this._value = value;
222
+ this._type = type;
223
+ }
224
+ this._parentVarRef = parentVarRef;
225
+ this._parentStruct = parentStruct;
226
+ this._fieldName = fieldName;
154
227
  }
155
228
  clone() {
156
- return new Value(this._value, this._type);
229
+ const cloned = new Value(this._value, this._type, this._parentVarRef, this._parentStruct, this._fieldName);
230
+ return cloned;
157
231
  }
158
232
  // Methods required by godoc.txt and used throughout the codebase
159
233
  Int() {
@@ -238,7 +312,10 @@ export class Value {
238
312
  return this._type;
239
313
  }
240
314
  IsValid() {
241
- return this._value !== null && this._value !== undefined;
315
+ // In Go, a Value is valid if it was properly constructed (not the zero Value{}).
316
+ // A valid Value can have a nil underlying value (e.g., nil map, nil pointer).
317
+ // We check if the type is valid (not the invalid type sentinel).
318
+ return this._type !== invalidTypeInstance;
242
319
  }
243
320
  IsNil() {
244
321
  return this._value === null || this._value === undefined;
@@ -260,15 +337,33 @@ export class Value {
260
337
  ' Value');
261
338
  }
262
339
  Elem() {
263
- // For pointers and interfaces, return the element
264
- return new Value(this._value, this._type);
340
+ // For pointers, unwrap the VarRef and return the element, tracking the parent
341
+ if (this._type.Kind() === Ptr && $.isVarRef(this._value)) {
342
+ const varRef = this._value;
343
+ const elemType = this._type.Elem();
344
+ return new Value(varRef.value, elemType, varRef);
345
+ }
346
+ // For interfaces, return the underlying value
347
+ return new Value(this._value, this._type, this._parentVarRef);
265
348
  }
266
349
  NumField() {
267
350
  return this._type.NumField();
268
351
  }
269
- Field(_i) {
270
- // Simplified implementation for struct field access
271
- return new Value(null, this._type);
352
+ Field(i) {
353
+ if (this.Kind() !== Struct) {
354
+ throw new ValueError({ Kind: this.Kind(), Method: 'Field' });
355
+ }
356
+ const field = this.Type().Field(i);
357
+ if (!field) {
358
+ throw new Error('reflect: struct field index out of range');
359
+ }
360
+ const parentObj = this._value;
361
+ let fieldVal = parentObj[field.Name];
362
+ if (fieldVal === undefined) {
363
+ fieldVal = null;
364
+ }
365
+ // Pass parent struct and field name so Set() can update the struct
366
+ return new Value(fieldVal, field.Type, undefined, parentObj, field.Name);
272
367
  }
273
368
  // Additional methods needed by various parts of the codebase
274
369
  UnsafePointer() {
@@ -289,7 +384,62 @@ export class Value {
289
384
  // Simple conversion - in a real implementation this would do type conversion
290
385
  return new Value(this._value, t);
291
386
  }
387
+ CanAddr() {
388
+ return this.Kind() !== Ptr && this._value !== null; // Simplified
389
+ }
390
+ Addr() {
391
+ if (!this.CanAddr()) {
392
+ throw new Error('reflect: call of reflect.Value.Addr on invalid Value');
393
+ }
394
+ const ptrType = PointerTo(this.Type());
395
+ return new Value(this, ptrType); // Simplified
396
+ }
397
+ CanSet() {
398
+ // Simplified: all valid values are settable in GoScript since we handle
399
+ // pointer semantics through VarRef. This enables JSON unmarshaling to work.
400
+ return this.IsValid();
401
+ }
402
+ Set(x) {
403
+ if (!this.CanSet()) {
404
+ throw new Error('reflect: assign to invalid value');
405
+ }
406
+ // Interface types can accept any value
407
+ if (this.Kind() === Interface) {
408
+ this._value = x.value;
409
+ // Also update the parent VarRef if we were dereferenced from one
410
+ if (this._parentVarRef) {
411
+ this._parentVarRef.value = x.value;
412
+ }
413
+ // Also update the parent struct field if this is a struct field
414
+ if (this._parentStruct && this._fieldName) {
415
+ this._parentStruct[this._fieldName] = x.value;
416
+ }
417
+ return;
418
+ }
419
+ // For other types, check if types are compatible (simplified check)
420
+ const thisType = this.Type();
421
+ const xType = x.Type();
422
+ if (thisType.Kind() !== xType.Kind()) {
423
+ throw new Error('reflect: assign to wrong type');
424
+ }
425
+ this._value = x.value;
426
+ // Also update the parent VarRef if we were dereferenced from one
427
+ if (this._parentVarRef) {
428
+ this._parentVarRef.value = x.value;
429
+ }
430
+ // Also update the parent struct field if this is a struct field
431
+ if (this._parentStruct && this._fieldName) {
432
+ this._parentStruct[this._fieldName] = x.value;
433
+ }
434
+ }
292
435
  // Additional methods from deleted reflect.gs.ts
436
+ Interface() {
437
+ return this._value;
438
+ }
439
+ IsZero() {
440
+ const zeroVal = Zero(this.Type()).value;
441
+ return DeepEqual(this._value, zeroVal);
442
+ }
293
443
  typ() {
294
444
  return new rtype(this._type.Kind());
295
445
  }
@@ -332,6 +482,237 @@ export class Value {
332
482
  channelObj._sendQueue.push(valueToSend);
333
483
  }
334
484
  }
485
+ // SetString sets v's underlying value to x
486
+ SetString(x) {
487
+ if (!this.CanSet()) {
488
+ throw new Error('reflect: call of reflect.Value.SetString on unaddressable value');
489
+ }
490
+ if (this.Kind() !== String) {
491
+ throw new Error('reflect: call of reflect.Value.SetString on ' + this.Kind() + ' Value');
492
+ }
493
+ this._value = x;
494
+ if (this._parentVarRef) {
495
+ this._parentVarRef.value = x;
496
+ }
497
+ if (this._parentStruct && this._fieldName) {
498
+ this._parentStruct[this._fieldName] = x;
499
+ }
500
+ }
501
+ // SetInt sets v's underlying value to x
502
+ SetInt(x) {
503
+ if (!this.CanSet()) {
504
+ throw new Error('reflect: call of reflect.Value.SetInt on unaddressable value');
505
+ }
506
+ const k = this.Kind();
507
+ if (k !== Int && k !== Int8 && k !== Int16 && k !== Int32 && k !== Int64) {
508
+ throw new Error('reflect: call of reflect.Value.SetInt on ' + k + ' Value');
509
+ }
510
+ this._value = x;
511
+ if (this._parentVarRef) {
512
+ this._parentVarRef.value = x;
513
+ }
514
+ if (this._parentStruct && this._fieldName) {
515
+ this._parentStruct[this._fieldName] = x;
516
+ }
517
+ }
518
+ // SetUint sets v's underlying value to x
519
+ SetUint(x) {
520
+ if (!this.CanSet()) {
521
+ throw new Error('reflect: call of reflect.Value.SetUint on unaddressable value');
522
+ }
523
+ const k = this.Kind();
524
+ if (k !== Uint &&
525
+ k !== Uint8 &&
526
+ k !== Uint16 &&
527
+ k !== Uint32 &&
528
+ k !== Uint64 &&
529
+ k !== Uintptr) {
530
+ throw new Error('reflect: call of reflect.Value.SetUint on ' + k + ' Value');
531
+ }
532
+ this._value = x;
533
+ if (this._parentVarRef) {
534
+ this._parentVarRef.value = x;
535
+ }
536
+ if (this._parentStruct && this._fieldName) {
537
+ this._parentStruct[this._fieldName] = x;
538
+ }
539
+ }
540
+ // SetBool sets v's underlying value to x
541
+ SetBool(x) {
542
+ if (!this.CanSet()) {
543
+ throw new Error('reflect: call of reflect.Value.SetBool on unaddressable value');
544
+ }
545
+ if (this.Kind() !== Bool) {
546
+ throw new Error('reflect: call of reflect.Value.SetBool on ' + this.Kind() + ' Value');
547
+ }
548
+ this._value = x;
549
+ if (this._parentVarRef) {
550
+ this._parentVarRef.value = x;
551
+ }
552
+ if (this._parentStruct && this._fieldName) {
553
+ this._parentStruct[this._fieldName] = x;
554
+ }
555
+ }
556
+ // SetFloat sets v's underlying value to x
557
+ SetFloat(x) {
558
+ if (!this.CanSet()) {
559
+ throw new Error('reflect: call of reflect.Value.SetFloat on unaddressable value');
560
+ }
561
+ const k = this.Kind();
562
+ if (k !== Float32 && k !== Float64) {
563
+ throw new Error('reflect: call of reflect.Value.SetFloat on ' + k + ' Value');
564
+ }
565
+ this._value = x;
566
+ if (this._parentVarRef) {
567
+ this._parentVarRef.value = x;
568
+ }
569
+ if (this._parentStruct && this._fieldName) {
570
+ this._parentStruct[this._fieldName] = x;
571
+ }
572
+ }
573
+ // SetBytes sets v's underlying value to x
574
+ SetBytes(x) {
575
+ if (!this.CanSet()) {
576
+ throw new Error('reflect: call of reflect.Value.SetBytes on unaddressable value');
577
+ }
578
+ if (this.Kind() !== Slice) {
579
+ throw new Error('reflect: call of reflect.Value.SetBytes on ' + this.Kind() + ' Value');
580
+ }
581
+ // Convert Uint8Array or slice to array
582
+ if (x instanceof Uint8Array) {
583
+ this._value = globalThis.Array.from(x);
584
+ }
585
+ else if (globalThis.Array.isArray(x)) {
586
+ this._value = x;
587
+ }
588
+ else {
589
+ this._value = x;
590
+ }
591
+ }
592
+ // SetZero sets v to be the zero value of v's type
593
+ SetZero() {
594
+ if (!this.CanSet()) {
595
+ throw new Error('reflect: call of reflect.Value.SetZero on unaddressable value');
596
+ }
597
+ const zeroVal = Zero(this.Type());
598
+ this._value = zeroVal.value;
599
+ }
600
+ // SetLen sets v's length to n
601
+ SetLen(n) {
602
+ if (!this.CanSet()) {
603
+ throw new Error('reflect: call of reflect.Value.SetLen on unaddressable value');
604
+ }
605
+ if (this.Kind() !== Slice) {
606
+ throw new Error('reflect: call of reflect.Value.SetLen on ' + this.Kind() + ' Value');
607
+ }
608
+ if (globalThis.Array.isArray(this._value)) {
609
+ this._value.length = n;
610
+ }
611
+ }
612
+ // SetMapIndex sets the element associated with key in the map v to elem
613
+ SetMapIndex(key, elem) {
614
+ if (!this.CanSet()) {
615
+ throw new Error('reflect: call of reflect.Value.SetMapIndex on unaddressable value');
616
+ }
617
+ if (this.Kind() !== Map) {
618
+ throw new Error('reflect: call of reflect.Value.SetMapIndex on ' +
619
+ this.Kind() +
620
+ ' Value');
621
+ }
622
+ const mapObj = this._value;
623
+ const keyVal = key.value;
624
+ const elemVal = elem.value;
625
+ mapObj.set(keyVal, elemVal);
626
+ }
627
+ // Grow increases the slice's capacity, if necessary
628
+ Grow(n) {
629
+ if (this.Kind() !== Slice) {
630
+ throw new Error('reflect: call of reflect.Value.Grow on ' + this.Kind() + ' Value');
631
+ }
632
+ if (!globalThis.Array.isArray(this._value)) {
633
+ return;
634
+ }
635
+ // JavaScript arrays grow automatically, but we ensure capacity
636
+ const currentLen = this._value.length;
637
+ const targetCap = currentLen + n;
638
+ if (this._value.length < targetCap) {
639
+ this._value.length = targetCap;
640
+ this._value.length = currentLen; // Reset to original length
641
+ }
642
+ }
643
+ // Cap returns v's capacity
644
+ Cap() {
645
+ const k = this.Kind();
646
+ if (k === Slice || k === Array) {
647
+ if (globalThis.Array.isArray(this._value)) {
648
+ return this._value.length;
649
+ }
650
+ return 0;
651
+ }
652
+ if (k === Chan) {
653
+ return 0; // Simplified
654
+ }
655
+ throw new Error('reflect: call of reflect.Value.Cap on ' + k + ' Value');
656
+ }
657
+ // NumMethod returns the number of methods in the value's method set
658
+ NumMethod() {
659
+ return 0; // Simplified - methods not fully implemented
660
+ }
661
+ // Equal reports whether v is equal to u
662
+ Equal(u) {
663
+ return DeepEqual(this._value, u.value);
664
+ }
665
+ // CanInterface reports whether Interface can be used without panicking
666
+ CanInterface() {
667
+ return this.IsValid();
668
+ }
669
+ // OverflowInt reports whether the int64 x cannot be represented by v's type
670
+ OverflowInt(x) {
671
+ const k = this.Kind();
672
+ switch (k) {
673
+ case Int8:
674
+ return x < -128 || x > 127;
675
+ case Int16:
676
+ return x < -32768 || x > 32767;
677
+ case Int32:
678
+ return x < -2147483648 || x > 2147483647;
679
+ case Int:
680
+ case Int64:
681
+ return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER;
682
+ default:
683
+ throw new Error('reflect: call of reflect.Value.OverflowInt on ' + k + ' Value');
684
+ }
685
+ }
686
+ // OverflowUint reports whether the uint64 x cannot be represented by v's type
687
+ OverflowUint(x) {
688
+ const k = this.Kind();
689
+ switch (k) {
690
+ case Uint8:
691
+ return x < 0 || x > 255;
692
+ case Uint16:
693
+ return x < 0 || x > 65535;
694
+ case Uint32:
695
+ return x < 0 || x > 4294967295;
696
+ case Uint:
697
+ case Uint64:
698
+ case Uintptr:
699
+ return x < 0 || x > Number.MAX_SAFE_INTEGER;
700
+ default:
701
+ throw new Error('reflect: call of reflect.Value.OverflowUint on ' + k + ' Value');
702
+ }
703
+ }
704
+ // OverflowFloat reports whether the float64 x cannot be represented by v's type
705
+ OverflowFloat(x) {
706
+ const k = this.Kind();
707
+ if (k === Float32) {
708
+ const f32max = 3.4028234663852886e38;
709
+ return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x);
710
+ }
711
+ if (k === Float64) {
712
+ return false; // float64 can represent any JavaScript number
713
+ }
714
+ throw new Error('reflect: call of reflect.Value.OverflowFloat on ' + k + ' Value');
715
+ }
335
716
  }
336
717
  // Basic type implementation - exported for compatibility
337
718
  export class BasicType {
@@ -353,7 +734,7 @@ export class BasicType {
353
734
  return this._size;
354
735
  }
355
736
  Elem() {
356
- return null;
737
+ throw new Error(`reflect: Elem of invalid type ${this._name}`);
357
738
  }
358
739
  NumField() {
359
740
  return 0;
@@ -361,12 +742,108 @@ export class BasicType {
361
742
  PkgPath() {
362
743
  return '';
363
744
  }
745
+ Name() {
746
+ // Basic types have names like 'int', 'string', etc.
747
+ return this._name;
748
+ }
364
749
  Field(_i) {
365
- return null;
750
+ throw new Error(`reflect: Field of non-struct type ${this._name}`);
751
+ }
752
+ Key() {
753
+ throw new Error(`reflect: Key of non-map type ${this._name}`);
754
+ }
755
+ Implements(u) {
756
+ if (!u) {
757
+ return false;
758
+ }
759
+ if (u.Kind() !== Interface) {
760
+ throw new Error('reflect: non-interface type passed to Type.Implements');
761
+ }
762
+ return false;
366
763
  }
367
764
  common() {
368
765
  return new rtype(this._kind);
369
766
  }
767
+ OverflowInt(x) {
768
+ const k = this._kind;
769
+ switch (k) {
770
+ case Int8:
771
+ return x < -128 || x > 127;
772
+ case Int16:
773
+ return x < -32768 || x > 32767;
774
+ case Int32:
775
+ return x < -2147483648 || x > 2147483647;
776
+ case Int:
777
+ case Int64:
778
+ return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER;
779
+ default:
780
+ throw new Error('reflect: call of reflect.Type.OverflowInt on ' +
781
+ Kind_String(k) +
782
+ ' Type');
783
+ }
784
+ }
785
+ OverflowUint(x) {
786
+ const k = this._kind;
787
+ switch (k) {
788
+ case Uint8:
789
+ return x < 0 || x > 255;
790
+ case Uint16:
791
+ return x < 0 || x > 65535;
792
+ case Uint32:
793
+ return x < 0 || x > 4294967295;
794
+ case Uint:
795
+ case Uint64:
796
+ case Uintptr:
797
+ return x < 0 || x > Number.MAX_SAFE_INTEGER;
798
+ default:
799
+ throw new Error('reflect: call of reflect.Type.OverflowUint on ' +
800
+ Kind_String(k) +
801
+ ' Type');
802
+ }
803
+ }
804
+ OverflowFloat(x) {
805
+ const k = this._kind;
806
+ if (k === Float32) {
807
+ const f32max = 3.4028234663852886e38;
808
+ return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x);
809
+ }
810
+ if (k === Float64) {
811
+ return false;
812
+ }
813
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on ' +
814
+ Kind_String(k) +
815
+ ' Type');
816
+ }
817
+ NumMethod() {
818
+ return 0;
819
+ }
820
+ Bits() {
821
+ const k = this._kind;
822
+ switch (k) {
823
+ case Bool:
824
+ return 1;
825
+ case Int8:
826
+ case Uint8:
827
+ return 8;
828
+ case Int16:
829
+ case Uint16:
830
+ return 16;
831
+ case Int32:
832
+ case Uint32:
833
+ case Float32:
834
+ return 32;
835
+ case Int64:
836
+ case Uint64:
837
+ case Float64:
838
+ return 64;
839
+ case Int:
840
+ case Uint:
841
+ case Uintptr:
842
+ return 64; // Assuming 64-bit architecture
843
+ default:
844
+ throw new Error('reflect: call of reflect.Type.Bits on ' + Kind_String(k) + ' Type');
845
+ }
846
+ }
370
847
  }
371
848
  // Slice type implementation
372
849
  class SliceType {
@@ -392,6 +869,40 @@ class SliceType {
392
869
  PkgPath() {
393
870
  return '';
394
871
  }
872
+ Name() {
873
+ // Slice types are unnamed composite types
874
+ return '';
875
+ }
876
+ Field(_i) {
877
+ throw new Error('reflect: Field of non-struct type');
878
+ }
879
+ Key() {
880
+ throw new Error('reflect: Key of non-map type');
881
+ }
882
+ Implements(u) {
883
+ if (!u) {
884
+ return false;
885
+ }
886
+ if (u.Kind() !== Interface) {
887
+ throw new Error('reflect: non-interface type passed to Type.Implements');
888
+ }
889
+ return false;
890
+ }
891
+ OverflowInt(_x) {
892
+ throw new Error('reflect: call of reflect.Type.OverflowInt on slice Type');
893
+ }
894
+ OverflowUint(_x) {
895
+ throw new Error('reflect: call of reflect.Type.OverflowUint on slice Type');
896
+ }
897
+ OverflowFloat(_x) {
898
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on slice Type');
899
+ }
900
+ NumMethod() {
901
+ return 0;
902
+ }
903
+ Bits() {
904
+ throw new Error('reflect: call of reflect.Type.Bits on slice Type');
905
+ }
395
906
  }
396
907
  // Array type implementation
397
908
  class ArrayType {
@@ -422,12 +933,43 @@ class ArrayType {
422
933
  PkgPath() {
423
934
  return '';
424
935
  }
936
+ Name() {
937
+ // Array types are unnamed composite types
938
+ return '';
939
+ }
425
940
  Field(_i) {
426
- return null;
941
+ throw new Error('reflect: Field of non-struct type');
942
+ }
943
+ Key() {
944
+ throw new Error('reflect: Key of non-map type');
945
+ }
946
+ Implements(u) {
947
+ if (!u) {
948
+ return false;
949
+ }
950
+ if (u.Kind() !== Interface) {
951
+ throw new Error('reflect: non-interface type passed to Type.Implements');
952
+ }
953
+ return false;
427
954
  }
428
955
  common() {
429
956
  return new rtype(this.Kind());
430
957
  }
958
+ OverflowInt(_x) {
959
+ throw new Error('reflect: call of reflect.Type.OverflowInt on array Type');
960
+ }
961
+ OverflowUint(_x) {
962
+ throw new Error('reflect: call of reflect.Type.OverflowUint on array Type');
963
+ }
964
+ OverflowFloat(_x) {
965
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on array Type');
966
+ }
967
+ NumMethod() {
968
+ return 0;
969
+ }
970
+ Bits() {
971
+ throw new Error('reflect: call of reflect.Type.Bits on array Type');
972
+ }
431
973
  }
432
974
  // Pointer type implementation
433
975
  class PointerType {
@@ -453,12 +995,45 @@ class PointerType {
453
995
  PkgPath() {
454
996
  return '';
455
997
  }
998
+ Name() {
999
+ // Pointer types are unnamed composite types
1000
+ return '';
1001
+ }
456
1002
  Field(_i) {
457
- return null;
1003
+ throw new Error('reflect: Field of non-struct type');
1004
+ }
1005
+ Key() {
1006
+ throw new Error('reflect: Key of non-map type');
1007
+ }
1008
+ Implements(u) {
1009
+ if (!u) {
1010
+ return false;
1011
+ }
1012
+ if (u.Kind() !== Interface) {
1013
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1014
+ }
1015
+ // For pointer types, check if the element type implements the interface
1016
+ const elemTypeName = this._elemType.String();
1017
+ return typeImplementsInterface(elemTypeName, u);
458
1018
  }
459
1019
  common() {
460
1020
  return new rtype(this.Kind());
461
1021
  }
1022
+ OverflowInt(_x) {
1023
+ throw new Error('reflect: call of reflect.Type.OverflowInt on pointer Type');
1024
+ }
1025
+ OverflowUint(_x) {
1026
+ throw new Error('reflect: call of reflect.Type.OverflowUint on pointer Type');
1027
+ }
1028
+ OverflowFloat(_x) {
1029
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on pointer Type');
1030
+ }
1031
+ NumMethod() {
1032
+ return 0;
1033
+ }
1034
+ Bits() {
1035
+ throw new Error('reflect: call of reflect.Type.Bits on pointer Type');
1036
+ }
462
1037
  }
463
1038
  // Function type implementation
464
1039
  class FunctionType {
@@ -476,7 +1051,7 @@ class FunctionType {
476
1051
  return 8; // function pointer size
477
1052
  }
478
1053
  Elem() {
479
- return null;
1054
+ throw new Error('reflect: Elem of invalid type');
480
1055
  }
481
1056
  NumField() {
482
1057
  return 0;
@@ -484,12 +1059,43 @@ class FunctionType {
484
1059
  PkgPath() {
485
1060
  return '';
486
1061
  }
1062
+ Name() {
1063
+ // Function types are unnamed composite types
1064
+ return '';
1065
+ }
487
1066
  Field(_i) {
488
- return null;
1067
+ throw new Error('reflect: Field of non-struct type');
1068
+ }
1069
+ Key() {
1070
+ throw new Error('reflect: Key of non-map type');
1071
+ }
1072
+ Implements(u) {
1073
+ if (!u) {
1074
+ return false;
1075
+ }
1076
+ if (u.Kind() !== Interface) {
1077
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1078
+ }
1079
+ return false;
489
1080
  }
490
1081
  common() {
491
1082
  return new rtype(this.Kind());
492
1083
  }
1084
+ OverflowInt(_x) {
1085
+ throw new Error('reflect: call of reflect.Type.OverflowInt on func Type');
1086
+ }
1087
+ OverflowUint(_x) {
1088
+ throw new Error('reflect: call of reflect.Type.OverflowUint on func Type');
1089
+ }
1090
+ OverflowFloat(_x) {
1091
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type');
1092
+ }
1093
+ NumMethod() {
1094
+ return 0;
1095
+ }
1096
+ Bits() {
1097
+ throw new Error('reflect: call of reflect.Type.Bits on func Type');
1098
+ }
493
1099
  }
494
1100
  // Map type implementation
495
1101
  class MapType {
@@ -520,14 +1126,82 @@ class MapType {
520
1126
  PkgPath() {
521
1127
  return '';
522
1128
  }
1129
+ Name() {
1130
+ // Map types are unnamed composite types
1131
+ return '';
1132
+ }
523
1133
  Field(_i) {
524
- return null;
1134
+ throw new Error('reflect: Field of non-struct type');
1135
+ }
1136
+ Implements(u) {
1137
+ if (!u) {
1138
+ return false;
1139
+ }
1140
+ if (u.Kind() !== Interface) {
1141
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1142
+ }
1143
+ return false;
525
1144
  }
526
1145
  common() {
527
1146
  return new rtype(this.Kind());
528
1147
  }
1148
+ OverflowInt(_x) {
1149
+ throw new Error('reflect: call of reflect.Type.OverflowInt on map Type');
1150
+ }
1151
+ OverflowUint(_x) {
1152
+ throw new Error('reflect: call of reflect.Type.OverflowUint on map Type');
1153
+ }
1154
+ OverflowFloat(_x) {
1155
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on map Type');
1156
+ }
1157
+ NumMethod() {
1158
+ return 0;
1159
+ }
1160
+ Bits() {
1161
+ throw new Error('reflect: call of reflect.Type.Bits on map Type');
1162
+ }
529
1163
  }
530
1164
  // Struct type implementation
1165
+ /**
1166
+ * Helper function to check if a type's method set contains all methods
1167
+ * required by an interface.
1168
+ *
1169
+ * @param typeName The name of the type to check (e.g., "main.MyType")
1170
+ * @param interfaceType The interface type that must be implemented
1171
+ * @returns True if the type implements the interface, false otherwise
1172
+ */
1173
+ function typeImplementsInterface(typeName, interfaceType) {
1174
+ // Get the interface name and look it up in the type registry
1175
+ const interfaceName = interfaceType.String();
1176
+ const interfaceTypeInfo = builtinGetTypeByName(interfaceName);
1177
+ if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
1178
+ return false;
1179
+ }
1180
+ // Get the type info for the struct/type
1181
+ const typeInfo = builtinGetTypeByName(typeName);
1182
+ if (!typeInfo || !isStructTypeInfo(typeInfo)) {
1183
+ return false;
1184
+ }
1185
+ // Check if the type has all required methods
1186
+ const requiredMethods = interfaceTypeInfo.methods || [];
1187
+ const typeMethods = typeInfo.methods || [];
1188
+ // For each required method, check if the type has a matching method
1189
+ for (const requiredMethod of requiredMethods) {
1190
+ const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name);
1191
+ if (!typeMethod) {
1192
+ return false;
1193
+ }
1194
+ // Check if method signatures match (simplified - just check counts)
1195
+ if (typeMethod.args.length !== requiredMethod.args.length) {
1196
+ return false;
1197
+ }
1198
+ if (typeMethod.returns.length !== requiredMethod.returns.length) {
1199
+ return false;
1200
+ }
1201
+ // Could add deeper type checking here, but for now this is sufficient
1202
+ }
1203
+ return true;
1204
+ }
531
1205
  class StructType {
532
1206
  _name;
533
1207
  _fields;
@@ -546,21 +1220,133 @@ class StructType {
546
1220
  return this._fields.reduce((sum, field) => sum + field.type.Size(), 0);
547
1221
  }
548
1222
  Elem() {
549
- return null;
1223
+ throw new Error('reflect: Elem of invalid type');
550
1224
  }
551
1225
  NumField() {
552
1226
  return this._fields.length;
553
1227
  }
554
1228
  PkgPath() {
1229
+ // Extract package path from full type name (e.g., "main.Person" -> "main")
1230
+ const dotIndex = this._name.lastIndexOf('.');
1231
+ if (dotIndex > 0) {
1232
+ return this._name.substring(0, dotIndex);
1233
+ }
555
1234
  return '';
556
1235
  }
557
- Field(_i) {
558
- // Stub implementation
559
- return null;
1236
+ Name() {
1237
+ // Extract type name from full type name (e.g., "main.Person" -> "Person")
1238
+ const dotIndex = this._name.lastIndexOf('.');
1239
+ if (dotIndex >= 0) {
1240
+ return this._name.substring(dotIndex + 1);
1241
+ }
1242
+ return this._name;
1243
+ }
1244
+ Field(i) {
1245
+ if (i < 0 || i >= this.NumField()) {
1246
+ throw new Error(`reflect: Field index out of range [${i}] with length ${this.NumField()}`);
1247
+ }
1248
+ const f = this._fields[i];
1249
+ return new StructField({
1250
+ Name: f.name,
1251
+ Type: f.type,
1252
+ Tag: f.tag ? new StructTag(f.tag) : undefined,
1253
+ });
1254
+ }
1255
+ Key() {
1256
+ throw new Error('reflect: Key of non-map type');
1257
+ }
1258
+ Implements(u) {
1259
+ if (!u) {
1260
+ return false;
1261
+ }
1262
+ if (u.Kind() !== Interface) {
1263
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1264
+ }
1265
+ return typeImplementsInterface(this._name, u);
560
1266
  }
561
1267
  common() {
562
1268
  return new rtype(this.Kind());
563
1269
  }
1270
+ OverflowInt(_x) {
1271
+ throw new Error('reflect: call of reflect.Type.OverflowInt on struct Type');
1272
+ }
1273
+ OverflowUint(_x) {
1274
+ throw new Error('reflect: call of reflect.Type.OverflowUint on struct Type');
1275
+ }
1276
+ OverflowFloat(_x) {
1277
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on struct Type');
1278
+ }
1279
+ NumMethod() {
1280
+ return 0;
1281
+ }
1282
+ Bits() {
1283
+ throw new Error('reflect: call of reflect.Type.Bits on struct Type');
1284
+ }
1285
+ static createTypeFromFieldInfo(ti) {
1286
+ if (typeof ti === 'string') {
1287
+ switch (ti) {
1288
+ case 'string':
1289
+ return new BasicType(String, ti, 16);
1290
+ case 'int':
1291
+ case 'int32':
1292
+ case 'int64':
1293
+ case 'number':
1294
+ return new BasicType(Int, ti === 'number' ? 'int' : ti, 8);
1295
+ case 'bool':
1296
+ case 'boolean':
1297
+ return new BasicType(Bool, 'bool', 1);
1298
+ case 'float64':
1299
+ return new BasicType(Float64, ti, 8);
1300
+ case 'uint':
1301
+ case 'uint32':
1302
+ case 'uint64':
1303
+ return new BasicType(Uint, ti, 8);
1304
+ default:
1305
+ return new BasicType(Invalid, ti, 8);
1306
+ }
1307
+ }
1308
+ else if (ti && ti.kind) {
1309
+ // Handle TypeInfo objects from the builtin type system
1310
+ const name = ti.name || 'unknown';
1311
+ switch (ti.kind) {
1312
+ case 'basic':
1313
+ // Map TypeScript type names to Go type names
1314
+ switch (name) {
1315
+ case 'string':
1316
+ return new BasicType(String, 'string', 16);
1317
+ case 'number':
1318
+ case 'int':
1319
+ case 'int32':
1320
+ case 'int64':
1321
+ return new BasicType(Int, name === 'number' ? 'int' : name, 8);
1322
+ case 'boolean':
1323
+ case 'bool':
1324
+ return new BasicType(Bool, 'bool', 1);
1325
+ case 'float64':
1326
+ return new BasicType(Float64, 'float64', 8);
1327
+ default:
1328
+ return new BasicType(Invalid, name, 8);
1329
+ }
1330
+ case 'slice':
1331
+ if (ti.elemType) {
1332
+ return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType));
1333
+ }
1334
+ return new SliceType(new BasicType(Invalid, 'unknown', 8));
1335
+ case 'pointer':
1336
+ if (ti.elemType) {
1337
+ return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType));
1338
+ }
1339
+ return new PointerType(new BasicType(Invalid, 'unknown', 8));
1340
+ case 'interface':
1341
+ return new InterfaceType(name);
1342
+ case 'struct':
1343
+ return new StructType(name, []);
1344
+ default:
1345
+ return new BasicType(Invalid, name, 8);
1346
+ }
1347
+ }
1348
+ return new BasicType(Invalid, 'unknown', 8);
1349
+ }
564
1350
  }
565
1351
  class ChannelType {
566
1352
  _elemType;
@@ -598,8 +1384,24 @@ class ChannelType {
598
1384
  PkgPath() {
599
1385
  return '';
600
1386
  }
601
- Field(_) {
602
- return null;
1387
+ Name() {
1388
+ // Channel types are unnamed composite types
1389
+ return '';
1390
+ }
1391
+ Field(_i) {
1392
+ throw new Error('reflect: Field of non-struct type');
1393
+ }
1394
+ Key() {
1395
+ throw new Error('reflect: Key of non-map type');
1396
+ }
1397
+ Implements(u) {
1398
+ if (!u) {
1399
+ return false;
1400
+ }
1401
+ if (u.Kind() !== Interface) {
1402
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1403
+ }
1404
+ return false;
603
1405
  }
604
1406
  common() {
605
1407
  return new rtype(this.Kind());
@@ -607,6 +1409,21 @@ class ChannelType {
607
1409
  ChanDir() {
608
1410
  return this._dir;
609
1411
  }
1412
+ OverflowInt(_x) {
1413
+ throw new Error('reflect: call of reflect.Type.OverflowInt on chan Type');
1414
+ }
1415
+ OverflowUint(_x) {
1416
+ throw new Error('reflect: call of reflect.Type.OverflowUint on chan Type');
1417
+ }
1418
+ OverflowFloat(_x) {
1419
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on chan Type');
1420
+ }
1421
+ NumMethod() {
1422
+ return 0;
1423
+ }
1424
+ Bits() {
1425
+ throw new Error('reflect: call of reflect.Type.Bits on chan Type');
1426
+ }
610
1427
  }
611
1428
  // Interface type implementation
612
1429
  class InterfaceType {
@@ -624,7 +1441,7 @@ class InterfaceType {
624
1441
  return 16;
625
1442
  }
626
1443
  Elem() {
627
- return null;
1444
+ throw new Error('reflect: Elem of invalid type');
628
1445
  }
629
1446
  NumField() {
630
1447
  return 0;
@@ -635,8 +1452,11 @@ class InterfaceType {
635
1452
  Name() {
636
1453
  return this._name;
637
1454
  }
638
- Field(_) {
639
- return null;
1455
+ Field(_i) {
1456
+ throw new Error('reflect: Field of non-struct type');
1457
+ }
1458
+ Key() {
1459
+ throw new Error('reflect: Key of non-map type');
640
1460
  }
641
1461
  Implements(_u) {
642
1462
  return false;
@@ -644,8 +1464,38 @@ class InterfaceType {
644
1464
  common() {
645
1465
  return new rtype(this.Kind());
646
1466
  }
1467
+ OverflowInt(_x) {
1468
+ throw new Error('reflect: call of reflect.Type.OverflowInt on interface Type');
1469
+ }
1470
+ OverflowUint(_x) {
1471
+ throw new Error('reflect: call of reflect.Type.OverflowUint on interface Type');
1472
+ }
1473
+ OverflowFloat(_x) {
1474
+ throw new Error('reflect: call of reflect.Type.OverflowFloat on interface Type');
1475
+ }
1476
+ NumMethod() {
1477
+ return 0;
1478
+ }
1479
+ Bits() {
1480
+ throw new Error('reflect: call of reflect.Type.Bits on interface Type');
1481
+ }
647
1482
  }
648
1483
  function getTypeOf(value) {
1484
+ // Check for typed nil before checking for plain null
1485
+ // Typed nils are created by $.typedNil() and have __goType and __isTypedNil properties
1486
+ if (value && typeof value === 'object' && value.__isTypedNil) {
1487
+ const typeName = value.__goType;
1488
+ if (typeName && typeof typeName === 'string') {
1489
+ // Parse the type name to construct the appropriate Type
1490
+ // For pointer types like "*main.Stringer", extract the element type
1491
+ if (typeName.startsWith('*')) {
1492
+ const elemTypeName = typeName.slice(1); // Remove the '*' prefix
1493
+ // Create an InterfaceType for the element (works for interfaces and other types)
1494
+ const elemType = new InterfaceType(elemTypeName);
1495
+ return new PointerType(elemType);
1496
+ }
1497
+ }
1498
+ }
649
1499
  if (value === null || value === undefined) {
650
1500
  return new BasicType(Interface, 'interface{}', 16);
651
1501
  }
@@ -728,6 +1578,11 @@ function getTypeOf(value) {
728
1578
  if (value === null) {
729
1579
  return new BasicType(Interface, 'interface{}', 16);
730
1580
  }
1581
+ // Check for VarRef (pointer type in GoScript)
1582
+ if ($.isVarRef(value)) {
1583
+ const elemType = getTypeOf(value.value);
1584
+ return new PointerType(elemType);
1585
+ }
731
1586
  // Check for arrays
732
1587
  if (globalThis.Array.isArray(value)) {
733
1588
  if (value.length === 0) {
@@ -795,20 +1650,38 @@ function getTypeOf(value) {
795
1650
  '__typeInfo' in value.constructor) {
796
1651
  const typeInfo = value.constructor.__typeInfo;
797
1652
  if (typeInfo && typeInfo.name) {
798
- // Add package prefix for struct types if not already present
799
1653
  const typeName = typeInfo.name.includes('.') ?
800
1654
  typeInfo.name
801
1655
  : `main.${typeInfo.name}`;
802
- return new StructType(typeName);
1656
+ const regTypeInfo = builtinGetTypeByName(typeName);
1657
+ let fields = [];
1658
+ if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
1659
+ fields = Object.entries(regTypeInfo.fields || {}).map(([name, fieldInfo]) => {
1660
+ // Check if fieldInfo is a StructFieldInfo with type and tag
1661
+ if (isStructFieldInfo(fieldInfo)) {
1662
+ return {
1663
+ name,
1664
+ type: StructType.createTypeFromFieldInfo(fieldInfo.type),
1665
+ tag: fieldInfo.tag,
1666
+ };
1667
+ }
1668
+ // Otherwise it's just the type info directly (backwards compatible)
1669
+ return {
1670
+ name,
1671
+ type: StructType.createTypeFromFieldInfo(fieldInfo),
1672
+ };
1673
+ });
1674
+ }
1675
+ return new StructType(typeName, fields);
803
1676
  }
804
1677
  }
805
1678
  // Check if it has a constructor name we can use (fallback)
806
1679
  const constructorName = value.constructor?.name;
807
1680
  if (constructorName && constructorName !== 'Object') {
808
- return new StructType(constructorName);
1681
+ return new StructType(constructorName, []);
809
1682
  }
810
1683
  // Default to struct type for plain objects
811
- return new StructType('struct');
1684
+ return new StructType('struct', []);
812
1685
  }
813
1686
  default:
814
1687
  return new BasicType(Interface, 'interface{}', 16);
@@ -828,6 +1701,8 @@ export function SliceOf(t) {
828
1701
  return new SliceType(t);
829
1702
  }
830
1703
  export function PointerTo(t) {
1704
+ if (t === null)
1705
+ return null;
831
1706
  return new PointerType(t);
832
1707
  }
833
1708
  export function PtrTo(t) {