goscript 0.0.61 → 0.0.62
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.
- package/README.md +9 -0
- package/compiler/analysis.go +536 -15
- package/compiler/assignment.go +72 -0
- package/compiler/compiler.go +64 -11
- package/compiler/composite-lit.go +29 -8
- package/compiler/decl.go +20 -11
- package/compiler/expr-call-async.go +26 -1
- package/compiler/expr-call-builtins.go +60 -4
- package/compiler/expr-call-type-conversion.go +37 -5
- package/compiler/expr-call.go +16 -3
- package/compiler/expr-selector.go +35 -2
- package/compiler/expr-type.go +12 -2
- package/compiler/expr.go +37 -0
- package/compiler/index.test.ts +3 -1
- package/compiler/lit.go +13 -4
- package/compiler/spec-struct.go +30 -8
- package/compiler/spec-value.go +2 -2
- package/compiler/spec.go +21 -4
- package/compiler/stmt-assign.go +71 -0
- package/compiler/stmt-range.go +2 -2
- package/compiler/stmt.go +128 -0
- package/compiler/type-utils.go +40 -1
- package/compiler/type.go +50 -12
- package/dist/gs/builtin/builtin.d.ts +8 -1
- package/dist/gs/builtin/builtin.js +26 -1
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/errors.d.ts +1 -0
- package/dist/gs/builtin/errors.js +8 -0
- package/dist/gs/builtin/errors.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +5 -4
- package/dist/gs/builtin/slice.js +45 -14
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +23 -2
- package/dist/gs/builtin/type.js +125 -0
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/bytes/reader.gs.d.ts +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +2 -2
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.d.ts +3 -2
- package/dist/gs/reflect/map.js +37 -3
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +50 -12
- package/dist/gs/reflect/type.js +820 -27
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +11 -12
- package/dist/gs/reflect/types.js +26 -15
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -4
- package/dist/gs/reflect/value.js +8 -2
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +21 -0
- package/dist/gs/slices/slices.js +48 -0
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +2 -2
- package/dist/gs/sync/atomic/type.gs.js +12 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +2 -2
- package/dist/gs/unicode/utf8/utf8.js +10 -6
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/go.mod +4 -4
- package/go.sum +8 -8
- package/gs/builtin/builtin.ts +27 -2
- package/gs/builtin/errors.ts +12 -0
- package/gs/builtin/slice.ts +71 -7
- package/gs/builtin/type.ts +159 -2
- package/gs/bytes/reader.gs.ts +2 -2
- package/gs/math/hypot.gs.test.ts +3 -1
- package/gs/math/pow10.gs.test.ts +5 -4
- package/gs/reflect/index.ts +3 -2
- package/gs/reflect/map.test.ts +7 -6
- package/gs/reflect/map.ts +49 -7
- package/gs/reflect/type.ts +1053 -54
- package/gs/reflect/types.ts +34 -21
- package/gs/reflect/value.ts +12 -6
- package/gs/slices/slices.ts +55 -0
- package/gs/sync/atomic/type.gs.ts +14 -5
- package/gs/unicode/utf8/utf8.ts +12 -8
- package/package.json +13 -13
package/dist/gs/reflect/type.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
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';
|
|
2
6
|
// rtype is the common implementation of most values
|
|
3
7
|
export class rtype {
|
|
4
8
|
kind;
|
|
@@ -144,13 +148,73 @@ export const Slice = 23;
|
|
|
144
148
|
export const String = 24;
|
|
145
149
|
export const Struct = 25;
|
|
146
150
|
export const UnsafePointer = 26;
|
|
151
|
+
// InvalidTypeInstance is a singleton type for invalid/zero reflect.Value
|
|
152
|
+
class InvalidTypeClass {
|
|
153
|
+
Kind() {
|
|
154
|
+
return Invalid;
|
|
155
|
+
}
|
|
156
|
+
String() {
|
|
157
|
+
return '<invalid reflect.Value>';
|
|
158
|
+
}
|
|
159
|
+
Name() {
|
|
160
|
+
return '';
|
|
161
|
+
}
|
|
162
|
+
Size() {
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
Elem() {
|
|
166
|
+
throw new Error('reflect: Elem of invalid type');
|
|
167
|
+
}
|
|
168
|
+
Key() {
|
|
169
|
+
throw new Error('reflect: Key of invalid type');
|
|
170
|
+
}
|
|
171
|
+
NumField() {
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
Field(_i) {
|
|
175
|
+
throw new Error('reflect: Field of invalid type');
|
|
176
|
+
}
|
|
177
|
+
Implements(_u) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
OverflowInt(_x) {
|
|
181
|
+
throw new Error('reflect: OverflowInt of invalid type');
|
|
182
|
+
}
|
|
183
|
+
OverflowUint(_x) {
|
|
184
|
+
throw new Error('reflect: OverflowUint of invalid type');
|
|
185
|
+
}
|
|
186
|
+
OverflowFloat(_x) {
|
|
187
|
+
throw new Error('reflect: OverflowFloat of invalid type');
|
|
188
|
+
}
|
|
189
|
+
NumMethod() {
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
Bits() {
|
|
193
|
+
throw new Error('reflect: Bits of invalid type');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const invalidTypeInstance = new InvalidTypeClass();
|
|
147
197
|
// Value is the reflection interface to a Go value - consolidated from all implementations
|
|
148
198
|
export class Value {
|
|
149
199
|
_value;
|
|
150
200
|
_type;
|
|
151
|
-
constructor(
|
|
152
|
-
|
|
153
|
-
|
|
201
|
+
constructor(value, type) {
|
|
202
|
+
// Handle zero-value initialization: new Value({}) or new Value()
|
|
203
|
+
// This corresponds to reflect.Value{} in Go which is an invalid/zero value
|
|
204
|
+
if (type === undefined ||
|
|
205
|
+
type === null ||
|
|
206
|
+
(typeof value === 'object' &&
|
|
207
|
+
value !== null &&
|
|
208
|
+
Object.keys(value).length === 0 &&
|
|
209
|
+
!(value instanceof globalThis.Array) &&
|
|
210
|
+
!(value instanceof globalThis.Map))) {
|
|
211
|
+
this._value = null;
|
|
212
|
+
this._type = invalidTypeInstance;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this._value = value;
|
|
216
|
+
this._type = type;
|
|
217
|
+
}
|
|
154
218
|
}
|
|
155
219
|
clone() {
|
|
156
220
|
return new Value(this._value, this._type);
|
|
@@ -266,9 +330,19 @@ export class Value {
|
|
|
266
330
|
NumField() {
|
|
267
331
|
return this._type.NumField();
|
|
268
332
|
}
|
|
269
|
-
Field(
|
|
270
|
-
|
|
271
|
-
|
|
333
|
+
Field(i) {
|
|
334
|
+
if (this.Kind() !== Struct) {
|
|
335
|
+
throw new ValueError({ Kind: this.Kind(), Method: 'Field' });
|
|
336
|
+
}
|
|
337
|
+
const field = this.Type().Field(i);
|
|
338
|
+
if (!field) {
|
|
339
|
+
throw new Error('reflect: struct field index out of range');
|
|
340
|
+
}
|
|
341
|
+
let fieldVal = this._value[field.Name];
|
|
342
|
+
if (fieldVal === undefined) {
|
|
343
|
+
fieldVal = null;
|
|
344
|
+
}
|
|
345
|
+
return new Value(fieldVal, field.Type);
|
|
272
346
|
}
|
|
273
347
|
// Additional methods needed by various parts of the codebase
|
|
274
348
|
UnsafePointer() {
|
|
@@ -289,7 +363,36 @@ export class Value {
|
|
|
289
363
|
// Simple conversion - in a real implementation this would do type conversion
|
|
290
364
|
return new Value(this._value, t);
|
|
291
365
|
}
|
|
366
|
+
CanAddr() {
|
|
367
|
+
return this.Kind() !== Ptr && this._value !== null; // Simplified
|
|
368
|
+
}
|
|
369
|
+
Addr() {
|
|
370
|
+
if (!this.CanAddr()) {
|
|
371
|
+
throw new Error('reflect: call of reflect.Value.Addr on invalid Value');
|
|
372
|
+
}
|
|
373
|
+
const ptrType = PointerTo(this.Type());
|
|
374
|
+
return new Value(this, ptrType); // Simplified
|
|
375
|
+
}
|
|
376
|
+
CanSet() {
|
|
377
|
+
return this.IsValid() && this.Kind() !== Ptr; // Simplified
|
|
378
|
+
}
|
|
379
|
+
Set(x) {
|
|
380
|
+
if (!this.CanSet()) {
|
|
381
|
+
throw new Error('reflect: assign to invalid value');
|
|
382
|
+
}
|
|
383
|
+
if (this.Type() !== x.Type()) {
|
|
384
|
+
throw new Error('reflect: assign to wrong type');
|
|
385
|
+
}
|
|
386
|
+
this._value = x.value;
|
|
387
|
+
}
|
|
292
388
|
// Additional methods from deleted reflect.gs.ts
|
|
389
|
+
Interface() {
|
|
390
|
+
return this._value;
|
|
391
|
+
}
|
|
392
|
+
IsZero() {
|
|
393
|
+
const zeroVal = Zero(this.Type()).value;
|
|
394
|
+
return DeepEqual(this._value, zeroVal);
|
|
395
|
+
}
|
|
293
396
|
typ() {
|
|
294
397
|
return new rtype(this._type.Kind());
|
|
295
398
|
}
|
|
@@ -332,6 +435,207 @@ export class Value {
|
|
|
332
435
|
channelObj._sendQueue.push(valueToSend);
|
|
333
436
|
}
|
|
334
437
|
}
|
|
438
|
+
// SetString sets v's underlying value to x
|
|
439
|
+
SetString(x) {
|
|
440
|
+
if (!this.CanSet()) {
|
|
441
|
+
throw new Error('reflect: call of reflect.Value.SetString on unaddressable value');
|
|
442
|
+
}
|
|
443
|
+
if (this.Kind() !== String) {
|
|
444
|
+
throw new Error('reflect: call of reflect.Value.SetString on ' + this.Kind() + ' Value');
|
|
445
|
+
}
|
|
446
|
+
this._value = x;
|
|
447
|
+
}
|
|
448
|
+
// SetInt sets v's underlying value to x
|
|
449
|
+
SetInt(x) {
|
|
450
|
+
if (!this.CanSet()) {
|
|
451
|
+
throw new Error('reflect: call of reflect.Value.SetInt on unaddressable value');
|
|
452
|
+
}
|
|
453
|
+
const k = this.Kind();
|
|
454
|
+
if (k !== Int && k !== Int8 && k !== Int16 && k !== Int32 && k !== Int64) {
|
|
455
|
+
throw new Error('reflect: call of reflect.Value.SetInt on ' + k + ' Value');
|
|
456
|
+
}
|
|
457
|
+
this._value = x;
|
|
458
|
+
}
|
|
459
|
+
// SetUint sets v's underlying value to x
|
|
460
|
+
SetUint(x) {
|
|
461
|
+
if (!this.CanSet()) {
|
|
462
|
+
throw new Error('reflect: call of reflect.Value.SetUint on unaddressable value');
|
|
463
|
+
}
|
|
464
|
+
const k = this.Kind();
|
|
465
|
+
if (k !== Uint &&
|
|
466
|
+
k !== Uint8 &&
|
|
467
|
+
k !== Uint16 &&
|
|
468
|
+
k !== Uint32 &&
|
|
469
|
+
k !== Uint64 &&
|
|
470
|
+
k !== Uintptr) {
|
|
471
|
+
throw new Error('reflect: call of reflect.Value.SetUint on ' + k + ' Value');
|
|
472
|
+
}
|
|
473
|
+
this._value = x;
|
|
474
|
+
}
|
|
475
|
+
// SetBool sets v's underlying value to x
|
|
476
|
+
SetBool(x) {
|
|
477
|
+
if (!this.CanSet()) {
|
|
478
|
+
throw new Error('reflect: call of reflect.Value.SetBool on unaddressable value');
|
|
479
|
+
}
|
|
480
|
+
if (this.Kind() !== Bool) {
|
|
481
|
+
throw new Error('reflect: call of reflect.Value.SetBool on ' + this.Kind() + ' Value');
|
|
482
|
+
}
|
|
483
|
+
this._value = x;
|
|
484
|
+
}
|
|
485
|
+
// SetFloat sets v's underlying value to x
|
|
486
|
+
SetFloat(x) {
|
|
487
|
+
if (!this.CanSet()) {
|
|
488
|
+
throw new Error('reflect: call of reflect.Value.SetFloat on unaddressable value');
|
|
489
|
+
}
|
|
490
|
+
const k = this.Kind();
|
|
491
|
+
if (k !== Float32 && k !== Float64) {
|
|
492
|
+
throw new Error('reflect: call of reflect.Value.SetFloat on ' + k + ' Value');
|
|
493
|
+
}
|
|
494
|
+
this._value = x;
|
|
495
|
+
}
|
|
496
|
+
// SetBytes sets v's underlying value to x
|
|
497
|
+
SetBytes(x) {
|
|
498
|
+
if (!this.CanSet()) {
|
|
499
|
+
throw new Error('reflect: call of reflect.Value.SetBytes on unaddressable value');
|
|
500
|
+
}
|
|
501
|
+
if (this.Kind() !== Slice) {
|
|
502
|
+
throw new Error('reflect: call of reflect.Value.SetBytes on ' + this.Kind() + ' Value');
|
|
503
|
+
}
|
|
504
|
+
// Convert Uint8Array or slice to array
|
|
505
|
+
if (x instanceof Uint8Array) {
|
|
506
|
+
this._value = globalThis.Array.from(x);
|
|
507
|
+
}
|
|
508
|
+
else if (globalThis.Array.isArray(x)) {
|
|
509
|
+
this._value = x;
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
this._value = x;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// SetZero sets v to be the zero value of v's type
|
|
516
|
+
SetZero() {
|
|
517
|
+
if (!this.CanSet()) {
|
|
518
|
+
throw new Error('reflect: call of reflect.Value.SetZero on unaddressable value');
|
|
519
|
+
}
|
|
520
|
+
const zeroVal = Zero(this.Type());
|
|
521
|
+
this._value = zeroVal.value;
|
|
522
|
+
}
|
|
523
|
+
// SetLen sets v's length to n
|
|
524
|
+
SetLen(n) {
|
|
525
|
+
if (!this.CanSet()) {
|
|
526
|
+
throw new Error('reflect: call of reflect.Value.SetLen on unaddressable value');
|
|
527
|
+
}
|
|
528
|
+
if (this.Kind() !== Slice) {
|
|
529
|
+
throw new Error('reflect: call of reflect.Value.SetLen on ' + this.Kind() + ' Value');
|
|
530
|
+
}
|
|
531
|
+
if (globalThis.Array.isArray(this._value)) {
|
|
532
|
+
this._value.length = n;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// SetMapIndex sets the element associated with key in the map v to elem
|
|
536
|
+
SetMapIndex(key, elem) {
|
|
537
|
+
if (!this.CanSet()) {
|
|
538
|
+
throw new Error('reflect: call of reflect.Value.SetMapIndex on unaddressable value');
|
|
539
|
+
}
|
|
540
|
+
if (this.Kind() !== Map) {
|
|
541
|
+
throw new Error('reflect: call of reflect.Value.SetMapIndex on ' +
|
|
542
|
+
this.Kind() +
|
|
543
|
+
' Value');
|
|
544
|
+
}
|
|
545
|
+
const mapObj = this._value;
|
|
546
|
+
const keyVal = key.value;
|
|
547
|
+
const elemVal = elem.value;
|
|
548
|
+
mapObj.set(keyVal, elemVal);
|
|
549
|
+
}
|
|
550
|
+
// Grow increases the slice's capacity, if necessary
|
|
551
|
+
Grow(n) {
|
|
552
|
+
if (this.Kind() !== Slice) {
|
|
553
|
+
throw new Error('reflect: call of reflect.Value.Grow on ' + this.Kind() + ' Value');
|
|
554
|
+
}
|
|
555
|
+
if (!globalThis.Array.isArray(this._value)) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
// JavaScript arrays grow automatically, but we ensure capacity
|
|
559
|
+
const currentLen = this._value.length;
|
|
560
|
+
const targetCap = currentLen + n;
|
|
561
|
+
if (this._value.length < targetCap) {
|
|
562
|
+
this._value.length = targetCap;
|
|
563
|
+
this._value.length = currentLen; // Reset to original length
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
// Cap returns v's capacity
|
|
567
|
+
Cap() {
|
|
568
|
+
const k = this.Kind();
|
|
569
|
+
if (k === Slice || k === Array) {
|
|
570
|
+
if (globalThis.Array.isArray(this._value)) {
|
|
571
|
+
return this._value.length;
|
|
572
|
+
}
|
|
573
|
+
return 0;
|
|
574
|
+
}
|
|
575
|
+
if (k === Chan) {
|
|
576
|
+
return 0; // Simplified
|
|
577
|
+
}
|
|
578
|
+
throw new Error('reflect: call of reflect.Value.Cap on ' + k + ' Value');
|
|
579
|
+
}
|
|
580
|
+
// NumMethod returns the number of methods in the value's method set
|
|
581
|
+
NumMethod() {
|
|
582
|
+
return 0; // Simplified - methods not fully implemented
|
|
583
|
+
}
|
|
584
|
+
// Equal reports whether v is equal to u
|
|
585
|
+
Equal(u) {
|
|
586
|
+
return DeepEqual(this._value, u.value);
|
|
587
|
+
}
|
|
588
|
+
// CanInterface reports whether Interface can be used without panicking
|
|
589
|
+
CanInterface() {
|
|
590
|
+
return this.IsValid();
|
|
591
|
+
}
|
|
592
|
+
// OverflowInt reports whether the int64 x cannot be represented by v's type
|
|
593
|
+
OverflowInt(x) {
|
|
594
|
+
const k = this.Kind();
|
|
595
|
+
switch (k) {
|
|
596
|
+
case Int8:
|
|
597
|
+
return x < -128 || x > 127;
|
|
598
|
+
case Int16:
|
|
599
|
+
return x < -32768 || x > 32767;
|
|
600
|
+
case Int32:
|
|
601
|
+
return x < -2147483648 || x > 2147483647;
|
|
602
|
+
case Int:
|
|
603
|
+
case Int64:
|
|
604
|
+
return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER;
|
|
605
|
+
default:
|
|
606
|
+
throw new Error('reflect: call of reflect.Value.OverflowInt on ' + k + ' Value');
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
// OverflowUint reports whether the uint64 x cannot be represented by v's type
|
|
610
|
+
OverflowUint(x) {
|
|
611
|
+
const k = this.Kind();
|
|
612
|
+
switch (k) {
|
|
613
|
+
case Uint8:
|
|
614
|
+
return x < 0 || x > 255;
|
|
615
|
+
case Uint16:
|
|
616
|
+
return x < 0 || x > 65535;
|
|
617
|
+
case Uint32:
|
|
618
|
+
return x < 0 || x > 4294967295;
|
|
619
|
+
case Uint:
|
|
620
|
+
case Uint64:
|
|
621
|
+
case Uintptr:
|
|
622
|
+
return x < 0 || x > Number.MAX_SAFE_INTEGER;
|
|
623
|
+
default:
|
|
624
|
+
throw new Error('reflect: call of reflect.Value.OverflowUint on ' + k + ' Value');
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
// OverflowFloat reports whether the float64 x cannot be represented by v's type
|
|
628
|
+
OverflowFloat(x) {
|
|
629
|
+
const k = this.Kind();
|
|
630
|
+
if (k === Float32) {
|
|
631
|
+
const f32max = 3.4028234663852886e38;
|
|
632
|
+
return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x);
|
|
633
|
+
}
|
|
634
|
+
if (k === Float64) {
|
|
635
|
+
return false; // float64 can represent any JavaScript number
|
|
636
|
+
}
|
|
637
|
+
throw new Error('reflect: call of reflect.Value.OverflowFloat on ' + k + ' Value');
|
|
638
|
+
}
|
|
335
639
|
}
|
|
336
640
|
// Basic type implementation - exported for compatibility
|
|
337
641
|
export class BasicType {
|
|
@@ -353,7 +657,7 @@ export class BasicType {
|
|
|
353
657
|
return this._size;
|
|
354
658
|
}
|
|
355
659
|
Elem() {
|
|
356
|
-
|
|
660
|
+
throw new Error(`reflect: Elem of invalid type ${this._name}`);
|
|
357
661
|
}
|
|
358
662
|
NumField() {
|
|
359
663
|
return 0;
|
|
@@ -361,12 +665,108 @@ export class BasicType {
|
|
|
361
665
|
PkgPath() {
|
|
362
666
|
return '';
|
|
363
667
|
}
|
|
668
|
+
Name() {
|
|
669
|
+
// Basic types have names like 'int', 'string', etc.
|
|
670
|
+
return this._name;
|
|
671
|
+
}
|
|
364
672
|
Field(_i) {
|
|
365
|
-
|
|
673
|
+
throw new Error(`reflect: Field of non-struct type ${this._name}`);
|
|
674
|
+
}
|
|
675
|
+
Key() {
|
|
676
|
+
throw new Error(`reflect: Key of non-map type ${this._name}`);
|
|
677
|
+
}
|
|
678
|
+
Implements(u) {
|
|
679
|
+
if (!u) {
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
if (u.Kind() !== Interface) {
|
|
683
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
684
|
+
}
|
|
685
|
+
return false;
|
|
366
686
|
}
|
|
367
687
|
common() {
|
|
368
688
|
return new rtype(this._kind);
|
|
369
689
|
}
|
|
690
|
+
OverflowInt(x) {
|
|
691
|
+
const k = this._kind;
|
|
692
|
+
switch (k) {
|
|
693
|
+
case Int8:
|
|
694
|
+
return x < -128 || x > 127;
|
|
695
|
+
case Int16:
|
|
696
|
+
return x < -32768 || x > 32767;
|
|
697
|
+
case Int32:
|
|
698
|
+
return x < -2147483648 || x > 2147483647;
|
|
699
|
+
case Int:
|
|
700
|
+
case Int64:
|
|
701
|
+
return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER;
|
|
702
|
+
default:
|
|
703
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on ' +
|
|
704
|
+
Kind_String(k) +
|
|
705
|
+
' Type');
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
OverflowUint(x) {
|
|
709
|
+
const k = this._kind;
|
|
710
|
+
switch (k) {
|
|
711
|
+
case Uint8:
|
|
712
|
+
return x < 0 || x > 255;
|
|
713
|
+
case Uint16:
|
|
714
|
+
return x < 0 || x > 65535;
|
|
715
|
+
case Uint32:
|
|
716
|
+
return x < 0 || x > 4294967295;
|
|
717
|
+
case Uint:
|
|
718
|
+
case Uint64:
|
|
719
|
+
case Uintptr:
|
|
720
|
+
return x < 0 || x > Number.MAX_SAFE_INTEGER;
|
|
721
|
+
default:
|
|
722
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on ' +
|
|
723
|
+
Kind_String(k) +
|
|
724
|
+
' Type');
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
OverflowFloat(x) {
|
|
728
|
+
const k = this._kind;
|
|
729
|
+
if (k === Float32) {
|
|
730
|
+
const f32max = 3.4028234663852886e38;
|
|
731
|
+
return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x);
|
|
732
|
+
}
|
|
733
|
+
if (k === Float64) {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on ' +
|
|
737
|
+
Kind_String(k) +
|
|
738
|
+
' Type');
|
|
739
|
+
}
|
|
740
|
+
NumMethod() {
|
|
741
|
+
return 0;
|
|
742
|
+
}
|
|
743
|
+
Bits() {
|
|
744
|
+
const k = this._kind;
|
|
745
|
+
switch (k) {
|
|
746
|
+
case Bool:
|
|
747
|
+
return 1;
|
|
748
|
+
case Int8:
|
|
749
|
+
case Uint8:
|
|
750
|
+
return 8;
|
|
751
|
+
case Int16:
|
|
752
|
+
case Uint16:
|
|
753
|
+
return 16;
|
|
754
|
+
case Int32:
|
|
755
|
+
case Uint32:
|
|
756
|
+
case Float32:
|
|
757
|
+
return 32;
|
|
758
|
+
case Int64:
|
|
759
|
+
case Uint64:
|
|
760
|
+
case Float64:
|
|
761
|
+
return 64;
|
|
762
|
+
case Int:
|
|
763
|
+
case Uint:
|
|
764
|
+
case Uintptr:
|
|
765
|
+
return 64; // Assuming 64-bit architecture
|
|
766
|
+
default:
|
|
767
|
+
throw new Error('reflect: call of reflect.Type.Bits on ' + Kind_String(k) + ' Type');
|
|
768
|
+
}
|
|
769
|
+
}
|
|
370
770
|
}
|
|
371
771
|
// Slice type implementation
|
|
372
772
|
class SliceType {
|
|
@@ -392,6 +792,40 @@ class SliceType {
|
|
|
392
792
|
PkgPath() {
|
|
393
793
|
return '';
|
|
394
794
|
}
|
|
795
|
+
Name() {
|
|
796
|
+
// Slice types are unnamed composite types
|
|
797
|
+
return '';
|
|
798
|
+
}
|
|
799
|
+
Field(_i) {
|
|
800
|
+
throw new Error('reflect: Field of non-struct type');
|
|
801
|
+
}
|
|
802
|
+
Key() {
|
|
803
|
+
throw new Error('reflect: Key of non-map type');
|
|
804
|
+
}
|
|
805
|
+
Implements(u) {
|
|
806
|
+
if (!u) {
|
|
807
|
+
return false;
|
|
808
|
+
}
|
|
809
|
+
if (u.Kind() !== Interface) {
|
|
810
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
811
|
+
}
|
|
812
|
+
return false;
|
|
813
|
+
}
|
|
814
|
+
OverflowInt(_x) {
|
|
815
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on slice Type');
|
|
816
|
+
}
|
|
817
|
+
OverflowUint(_x) {
|
|
818
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on slice Type');
|
|
819
|
+
}
|
|
820
|
+
OverflowFloat(_x) {
|
|
821
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on slice Type');
|
|
822
|
+
}
|
|
823
|
+
NumMethod() {
|
|
824
|
+
return 0;
|
|
825
|
+
}
|
|
826
|
+
Bits() {
|
|
827
|
+
throw new Error('reflect: call of reflect.Type.Bits on slice Type');
|
|
828
|
+
}
|
|
395
829
|
}
|
|
396
830
|
// Array type implementation
|
|
397
831
|
class ArrayType {
|
|
@@ -422,12 +856,43 @@ class ArrayType {
|
|
|
422
856
|
PkgPath() {
|
|
423
857
|
return '';
|
|
424
858
|
}
|
|
859
|
+
Name() {
|
|
860
|
+
// Array types are unnamed composite types
|
|
861
|
+
return '';
|
|
862
|
+
}
|
|
425
863
|
Field(_i) {
|
|
426
|
-
|
|
864
|
+
throw new Error('reflect: Field of non-struct type');
|
|
865
|
+
}
|
|
866
|
+
Key() {
|
|
867
|
+
throw new Error('reflect: Key of non-map type');
|
|
868
|
+
}
|
|
869
|
+
Implements(u) {
|
|
870
|
+
if (!u) {
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
873
|
+
if (u.Kind() !== Interface) {
|
|
874
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
875
|
+
}
|
|
876
|
+
return false;
|
|
427
877
|
}
|
|
428
878
|
common() {
|
|
429
879
|
return new rtype(this.Kind());
|
|
430
880
|
}
|
|
881
|
+
OverflowInt(_x) {
|
|
882
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on array Type');
|
|
883
|
+
}
|
|
884
|
+
OverflowUint(_x) {
|
|
885
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on array Type');
|
|
886
|
+
}
|
|
887
|
+
OverflowFloat(_x) {
|
|
888
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on array Type');
|
|
889
|
+
}
|
|
890
|
+
NumMethod() {
|
|
891
|
+
return 0;
|
|
892
|
+
}
|
|
893
|
+
Bits() {
|
|
894
|
+
throw new Error('reflect: call of reflect.Type.Bits on array Type');
|
|
895
|
+
}
|
|
431
896
|
}
|
|
432
897
|
// Pointer type implementation
|
|
433
898
|
class PointerType {
|
|
@@ -453,12 +918,45 @@ class PointerType {
|
|
|
453
918
|
PkgPath() {
|
|
454
919
|
return '';
|
|
455
920
|
}
|
|
921
|
+
Name() {
|
|
922
|
+
// Pointer types are unnamed composite types
|
|
923
|
+
return '';
|
|
924
|
+
}
|
|
456
925
|
Field(_i) {
|
|
457
|
-
|
|
926
|
+
throw new Error('reflect: Field of non-struct type');
|
|
927
|
+
}
|
|
928
|
+
Key() {
|
|
929
|
+
throw new Error('reflect: Key of non-map type');
|
|
930
|
+
}
|
|
931
|
+
Implements(u) {
|
|
932
|
+
if (!u) {
|
|
933
|
+
return false;
|
|
934
|
+
}
|
|
935
|
+
if (u.Kind() !== Interface) {
|
|
936
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
937
|
+
}
|
|
938
|
+
// For pointer types, check if the element type implements the interface
|
|
939
|
+
const elemTypeName = this._elemType.String();
|
|
940
|
+
return typeImplementsInterface(elemTypeName, u);
|
|
458
941
|
}
|
|
459
942
|
common() {
|
|
460
943
|
return new rtype(this.Kind());
|
|
461
944
|
}
|
|
945
|
+
OverflowInt(_x) {
|
|
946
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on pointer Type');
|
|
947
|
+
}
|
|
948
|
+
OverflowUint(_x) {
|
|
949
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on pointer Type');
|
|
950
|
+
}
|
|
951
|
+
OverflowFloat(_x) {
|
|
952
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on pointer Type');
|
|
953
|
+
}
|
|
954
|
+
NumMethod() {
|
|
955
|
+
return 0;
|
|
956
|
+
}
|
|
957
|
+
Bits() {
|
|
958
|
+
throw new Error('reflect: call of reflect.Type.Bits on pointer Type');
|
|
959
|
+
}
|
|
462
960
|
}
|
|
463
961
|
// Function type implementation
|
|
464
962
|
class FunctionType {
|
|
@@ -476,7 +974,7 @@ class FunctionType {
|
|
|
476
974
|
return 8; // function pointer size
|
|
477
975
|
}
|
|
478
976
|
Elem() {
|
|
479
|
-
|
|
977
|
+
throw new Error('reflect: Elem of invalid type');
|
|
480
978
|
}
|
|
481
979
|
NumField() {
|
|
482
980
|
return 0;
|
|
@@ -484,12 +982,43 @@ class FunctionType {
|
|
|
484
982
|
PkgPath() {
|
|
485
983
|
return '';
|
|
486
984
|
}
|
|
985
|
+
Name() {
|
|
986
|
+
// Function types are unnamed composite types
|
|
987
|
+
return '';
|
|
988
|
+
}
|
|
487
989
|
Field(_i) {
|
|
488
|
-
|
|
990
|
+
throw new Error('reflect: Field of non-struct type');
|
|
991
|
+
}
|
|
992
|
+
Key() {
|
|
993
|
+
throw new Error('reflect: Key of non-map type');
|
|
994
|
+
}
|
|
995
|
+
Implements(u) {
|
|
996
|
+
if (!u) {
|
|
997
|
+
return false;
|
|
998
|
+
}
|
|
999
|
+
if (u.Kind() !== Interface) {
|
|
1000
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
1001
|
+
}
|
|
1002
|
+
return false;
|
|
489
1003
|
}
|
|
490
1004
|
common() {
|
|
491
1005
|
return new rtype(this.Kind());
|
|
492
1006
|
}
|
|
1007
|
+
OverflowInt(_x) {
|
|
1008
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on func Type');
|
|
1009
|
+
}
|
|
1010
|
+
OverflowUint(_x) {
|
|
1011
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on func Type');
|
|
1012
|
+
}
|
|
1013
|
+
OverflowFloat(_x) {
|
|
1014
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type');
|
|
1015
|
+
}
|
|
1016
|
+
NumMethod() {
|
|
1017
|
+
return 0;
|
|
1018
|
+
}
|
|
1019
|
+
Bits() {
|
|
1020
|
+
throw new Error('reflect: call of reflect.Type.Bits on func Type');
|
|
1021
|
+
}
|
|
493
1022
|
}
|
|
494
1023
|
// Map type implementation
|
|
495
1024
|
class MapType {
|
|
@@ -520,14 +1049,82 @@ class MapType {
|
|
|
520
1049
|
PkgPath() {
|
|
521
1050
|
return '';
|
|
522
1051
|
}
|
|
1052
|
+
Name() {
|
|
1053
|
+
// Map types are unnamed composite types
|
|
1054
|
+
return '';
|
|
1055
|
+
}
|
|
523
1056
|
Field(_i) {
|
|
524
|
-
|
|
1057
|
+
throw new Error('reflect: Field of non-struct type');
|
|
1058
|
+
}
|
|
1059
|
+
Implements(u) {
|
|
1060
|
+
if (!u) {
|
|
1061
|
+
return false;
|
|
1062
|
+
}
|
|
1063
|
+
if (u.Kind() !== Interface) {
|
|
1064
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
1065
|
+
}
|
|
1066
|
+
return false;
|
|
525
1067
|
}
|
|
526
1068
|
common() {
|
|
527
1069
|
return new rtype(this.Kind());
|
|
528
1070
|
}
|
|
1071
|
+
OverflowInt(_x) {
|
|
1072
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on map Type');
|
|
1073
|
+
}
|
|
1074
|
+
OverflowUint(_x) {
|
|
1075
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on map Type');
|
|
1076
|
+
}
|
|
1077
|
+
OverflowFloat(_x) {
|
|
1078
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on map Type');
|
|
1079
|
+
}
|
|
1080
|
+
NumMethod() {
|
|
1081
|
+
return 0;
|
|
1082
|
+
}
|
|
1083
|
+
Bits() {
|
|
1084
|
+
throw new Error('reflect: call of reflect.Type.Bits on map Type');
|
|
1085
|
+
}
|
|
529
1086
|
}
|
|
530
1087
|
// Struct type implementation
|
|
1088
|
+
/**
|
|
1089
|
+
* Helper function to check if a type's method set contains all methods
|
|
1090
|
+
* required by an interface.
|
|
1091
|
+
*
|
|
1092
|
+
* @param typeName The name of the type to check (e.g., "main.MyType")
|
|
1093
|
+
* @param interfaceType The interface type that must be implemented
|
|
1094
|
+
* @returns True if the type implements the interface, false otherwise
|
|
1095
|
+
*/
|
|
1096
|
+
function typeImplementsInterface(typeName, interfaceType) {
|
|
1097
|
+
// Get the interface name and look it up in the type registry
|
|
1098
|
+
const interfaceName = interfaceType.String();
|
|
1099
|
+
const interfaceTypeInfo = builtinGetTypeByName(interfaceName);
|
|
1100
|
+
if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
// Get the type info for the struct/type
|
|
1104
|
+
const typeInfo = builtinGetTypeByName(typeName);
|
|
1105
|
+
if (!typeInfo || !isStructTypeInfo(typeInfo)) {
|
|
1106
|
+
return false;
|
|
1107
|
+
}
|
|
1108
|
+
// Check if the type has all required methods
|
|
1109
|
+
const requiredMethods = interfaceTypeInfo.methods || [];
|
|
1110
|
+
const typeMethods = typeInfo.methods || [];
|
|
1111
|
+
// For each required method, check if the type has a matching method
|
|
1112
|
+
for (const requiredMethod of requiredMethods) {
|
|
1113
|
+
const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name);
|
|
1114
|
+
if (!typeMethod) {
|
|
1115
|
+
return false;
|
|
1116
|
+
}
|
|
1117
|
+
// Check if method signatures match (simplified - just check counts)
|
|
1118
|
+
if (typeMethod.args.length !== requiredMethod.args.length) {
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
if (typeMethod.returns.length !== requiredMethod.returns.length) {
|
|
1122
|
+
return false;
|
|
1123
|
+
}
|
|
1124
|
+
// Could add deeper type checking here, but for now this is sufficient
|
|
1125
|
+
}
|
|
1126
|
+
return true;
|
|
1127
|
+
}
|
|
531
1128
|
class StructType {
|
|
532
1129
|
_name;
|
|
533
1130
|
_fields;
|
|
@@ -546,21 +1143,133 @@ class StructType {
|
|
|
546
1143
|
return this._fields.reduce((sum, field) => sum + field.type.Size(), 0);
|
|
547
1144
|
}
|
|
548
1145
|
Elem() {
|
|
549
|
-
|
|
1146
|
+
throw new Error('reflect: Elem of invalid type');
|
|
550
1147
|
}
|
|
551
1148
|
NumField() {
|
|
552
1149
|
return this._fields.length;
|
|
553
1150
|
}
|
|
554
1151
|
PkgPath() {
|
|
1152
|
+
// Extract package path from full type name (e.g., "main.Person" -> "main")
|
|
1153
|
+
const dotIndex = this._name.lastIndexOf('.');
|
|
1154
|
+
if (dotIndex > 0) {
|
|
1155
|
+
return this._name.substring(0, dotIndex);
|
|
1156
|
+
}
|
|
555
1157
|
return '';
|
|
556
1158
|
}
|
|
557
|
-
|
|
558
|
-
//
|
|
559
|
-
|
|
1159
|
+
Name() {
|
|
1160
|
+
// Extract type name from full type name (e.g., "main.Person" -> "Person")
|
|
1161
|
+
const dotIndex = this._name.lastIndexOf('.');
|
|
1162
|
+
if (dotIndex >= 0) {
|
|
1163
|
+
return this._name.substring(dotIndex + 1);
|
|
1164
|
+
}
|
|
1165
|
+
return this._name;
|
|
1166
|
+
}
|
|
1167
|
+
Field(i) {
|
|
1168
|
+
if (i < 0 || i >= this.NumField()) {
|
|
1169
|
+
throw new Error(`reflect: Field index out of range [${i}] with length ${this.NumField()}`);
|
|
1170
|
+
}
|
|
1171
|
+
const f = this._fields[i];
|
|
1172
|
+
return new StructField({
|
|
1173
|
+
Name: f.name,
|
|
1174
|
+
Type: f.type,
|
|
1175
|
+
Tag: f.tag ? new StructTag(f.tag) : undefined,
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
Key() {
|
|
1179
|
+
throw new Error('reflect: Key of non-map type');
|
|
1180
|
+
}
|
|
1181
|
+
Implements(u) {
|
|
1182
|
+
if (!u) {
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
if (u.Kind() !== Interface) {
|
|
1186
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
1187
|
+
}
|
|
1188
|
+
return typeImplementsInterface(this._name, u);
|
|
560
1189
|
}
|
|
561
1190
|
common() {
|
|
562
1191
|
return new rtype(this.Kind());
|
|
563
1192
|
}
|
|
1193
|
+
OverflowInt(_x) {
|
|
1194
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on struct Type');
|
|
1195
|
+
}
|
|
1196
|
+
OverflowUint(_x) {
|
|
1197
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on struct Type');
|
|
1198
|
+
}
|
|
1199
|
+
OverflowFloat(_x) {
|
|
1200
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on struct Type');
|
|
1201
|
+
}
|
|
1202
|
+
NumMethod() {
|
|
1203
|
+
return 0;
|
|
1204
|
+
}
|
|
1205
|
+
Bits() {
|
|
1206
|
+
throw new Error('reflect: call of reflect.Type.Bits on struct Type');
|
|
1207
|
+
}
|
|
1208
|
+
static createTypeFromFieldInfo(ti) {
|
|
1209
|
+
if (typeof ti === 'string') {
|
|
1210
|
+
switch (ti) {
|
|
1211
|
+
case 'string':
|
|
1212
|
+
return new BasicType(String, ti, 16);
|
|
1213
|
+
case 'int':
|
|
1214
|
+
case 'int32':
|
|
1215
|
+
case 'int64':
|
|
1216
|
+
case 'number':
|
|
1217
|
+
return new BasicType(Int, ti === 'number' ? 'int' : ti, 8);
|
|
1218
|
+
case 'bool':
|
|
1219
|
+
case 'boolean':
|
|
1220
|
+
return new BasicType(Bool, 'bool', 1);
|
|
1221
|
+
case 'float64':
|
|
1222
|
+
return new BasicType(Float64, ti, 8);
|
|
1223
|
+
case 'uint':
|
|
1224
|
+
case 'uint32':
|
|
1225
|
+
case 'uint64':
|
|
1226
|
+
return new BasicType(Uint, ti, 8);
|
|
1227
|
+
default:
|
|
1228
|
+
return new BasicType(Invalid, ti, 8);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
else if (ti && ti.kind) {
|
|
1232
|
+
// Handle TypeInfo objects from the builtin type system
|
|
1233
|
+
const name = ti.name || 'unknown';
|
|
1234
|
+
switch (ti.kind) {
|
|
1235
|
+
case 'basic':
|
|
1236
|
+
// Map TypeScript type names to Go type names
|
|
1237
|
+
switch (name) {
|
|
1238
|
+
case 'string':
|
|
1239
|
+
return new BasicType(String, 'string', 16);
|
|
1240
|
+
case 'number':
|
|
1241
|
+
case 'int':
|
|
1242
|
+
case 'int32':
|
|
1243
|
+
case 'int64':
|
|
1244
|
+
return new BasicType(Int, name === 'number' ? 'int' : name, 8);
|
|
1245
|
+
case 'boolean':
|
|
1246
|
+
case 'bool':
|
|
1247
|
+
return new BasicType(Bool, 'bool', 1);
|
|
1248
|
+
case 'float64':
|
|
1249
|
+
return new BasicType(Float64, 'float64', 8);
|
|
1250
|
+
default:
|
|
1251
|
+
return new BasicType(Invalid, name, 8);
|
|
1252
|
+
}
|
|
1253
|
+
case 'slice':
|
|
1254
|
+
if (ti.elemType) {
|
|
1255
|
+
return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType));
|
|
1256
|
+
}
|
|
1257
|
+
return new SliceType(new BasicType(Invalid, 'unknown', 8));
|
|
1258
|
+
case 'pointer':
|
|
1259
|
+
if (ti.elemType) {
|
|
1260
|
+
return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType));
|
|
1261
|
+
}
|
|
1262
|
+
return new PointerType(new BasicType(Invalid, 'unknown', 8));
|
|
1263
|
+
case 'interface':
|
|
1264
|
+
return new InterfaceType(name);
|
|
1265
|
+
case 'struct':
|
|
1266
|
+
return new StructType(name, []);
|
|
1267
|
+
default:
|
|
1268
|
+
return new BasicType(Invalid, name, 8);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return new BasicType(Invalid, 'unknown', 8);
|
|
1272
|
+
}
|
|
564
1273
|
}
|
|
565
1274
|
class ChannelType {
|
|
566
1275
|
_elemType;
|
|
@@ -598,8 +1307,24 @@ class ChannelType {
|
|
|
598
1307
|
PkgPath() {
|
|
599
1308
|
return '';
|
|
600
1309
|
}
|
|
601
|
-
|
|
602
|
-
|
|
1310
|
+
Name() {
|
|
1311
|
+
// Channel types are unnamed composite types
|
|
1312
|
+
return '';
|
|
1313
|
+
}
|
|
1314
|
+
Field(_i) {
|
|
1315
|
+
throw new Error('reflect: Field of non-struct type');
|
|
1316
|
+
}
|
|
1317
|
+
Key() {
|
|
1318
|
+
throw new Error('reflect: Key of non-map type');
|
|
1319
|
+
}
|
|
1320
|
+
Implements(u) {
|
|
1321
|
+
if (!u) {
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1324
|
+
if (u.Kind() !== Interface) {
|
|
1325
|
+
throw new Error('reflect: non-interface type passed to Type.Implements');
|
|
1326
|
+
}
|
|
1327
|
+
return false;
|
|
603
1328
|
}
|
|
604
1329
|
common() {
|
|
605
1330
|
return new rtype(this.Kind());
|
|
@@ -607,6 +1332,21 @@ class ChannelType {
|
|
|
607
1332
|
ChanDir() {
|
|
608
1333
|
return this._dir;
|
|
609
1334
|
}
|
|
1335
|
+
OverflowInt(_x) {
|
|
1336
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on chan Type');
|
|
1337
|
+
}
|
|
1338
|
+
OverflowUint(_x) {
|
|
1339
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on chan Type');
|
|
1340
|
+
}
|
|
1341
|
+
OverflowFloat(_x) {
|
|
1342
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on chan Type');
|
|
1343
|
+
}
|
|
1344
|
+
NumMethod() {
|
|
1345
|
+
return 0;
|
|
1346
|
+
}
|
|
1347
|
+
Bits() {
|
|
1348
|
+
throw new Error('reflect: call of reflect.Type.Bits on chan Type');
|
|
1349
|
+
}
|
|
610
1350
|
}
|
|
611
1351
|
// Interface type implementation
|
|
612
1352
|
class InterfaceType {
|
|
@@ -624,7 +1364,7 @@ class InterfaceType {
|
|
|
624
1364
|
return 16;
|
|
625
1365
|
}
|
|
626
1366
|
Elem() {
|
|
627
|
-
|
|
1367
|
+
throw new Error('reflect: Elem of invalid type');
|
|
628
1368
|
}
|
|
629
1369
|
NumField() {
|
|
630
1370
|
return 0;
|
|
@@ -635,8 +1375,11 @@ class InterfaceType {
|
|
|
635
1375
|
Name() {
|
|
636
1376
|
return this._name;
|
|
637
1377
|
}
|
|
638
|
-
Field(
|
|
639
|
-
|
|
1378
|
+
Field(_i) {
|
|
1379
|
+
throw new Error('reflect: Field of non-struct type');
|
|
1380
|
+
}
|
|
1381
|
+
Key() {
|
|
1382
|
+
throw new Error('reflect: Key of non-map type');
|
|
640
1383
|
}
|
|
641
1384
|
Implements(_u) {
|
|
642
1385
|
return false;
|
|
@@ -644,8 +1387,38 @@ class InterfaceType {
|
|
|
644
1387
|
common() {
|
|
645
1388
|
return new rtype(this.Kind());
|
|
646
1389
|
}
|
|
1390
|
+
OverflowInt(_x) {
|
|
1391
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on interface Type');
|
|
1392
|
+
}
|
|
1393
|
+
OverflowUint(_x) {
|
|
1394
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on interface Type');
|
|
1395
|
+
}
|
|
1396
|
+
OverflowFloat(_x) {
|
|
1397
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on interface Type');
|
|
1398
|
+
}
|
|
1399
|
+
NumMethod() {
|
|
1400
|
+
return 0;
|
|
1401
|
+
}
|
|
1402
|
+
Bits() {
|
|
1403
|
+
throw new Error('reflect: call of reflect.Type.Bits on interface Type');
|
|
1404
|
+
}
|
|
647
1405
|
}
|
|
648
1406
|
function getTypeOf(value) {
|
|
1407
|
+
// Check for typed nil before checking for plain null
|
|
1408
|
+
// Typed nils are created by $.typedNil() and have __goType and __isTypedNil properties
|
|
1409
|
+
if (value && typeof value === 'object' && value.__isTypedNil) {
|
|
1410
|
+
const typeName = value.__goType;
|
|
1411
|
+
if (typeName && typeof typeName === 'string') {
|
|
1412
|
+
// Parse the type name to construct the appropriate Type
|
|
1413
|
+
// For pointer types like "*main.Stringer", extract the element type
|
|
1414
|
+
if (typeName.startsWith('*')) {
|
|
1415
|
+
const elemTypeName = typeName.slice(1); // Remove the '*' prefix
|
|
1416
|
+
// Create an InterfaceType for the element (works for interfaces and other types)
|
|
1417
|
+
const elemType = new InterfaceType(elemTypeName);
|
|
1418
|
+
return new PointerType(elemType);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
649
1422
|
if (value === null || value === undefined) {
|
|
650
1423
|
return new BasicType(Interface, 'interface{}', 16);
|
|
651
1424
|
}
|
|
@@ -795,20 +1568,38 @@ function getTypeOf(value) {
|
|
|
795
1568
|
'__typeInfo' in value.constructor) {
|
|
796
1569
|
const typeInfo = value.constructor.__typeInfo;
|
|
797
1570
|
if (typeInfo && typeInfo.name) {
|
|
798
|
-
// Add package prefix for struct types if not already present
|
|
799
1571
|
const typeName = typeInfo.name.includes('.') ?
|
|
800
1572
|
typeInfo.name
|
|
801
1573
|
: `main.${typeInfo.name}`;
|
|
802
|
-
|
|
1574
|
+
const regTypeInfo = builtinGetTypeByName(typeName);
|
|
1575
|
+
let fields = [];
|
|
1576
|
+
if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
|
|
1577
|
+
fields = Object.entries(regTypeInfo.fields || {}).map(([name, fieldInfo]) => {
|
|
1578
|
+
// Check if fieldInfo is a StructFieldInfo with type and tag
|
|
1579
|
+
if (isStructFieldInfo(fieldInfo)) {
|
|
1580
|
+
return {
|
|
1581
|
+
name,
|
|
1582
|
+
type: StructType.createTypeFromFieldInfo(fieldInfo.type),
|
|
1583
|
+
tag: fieldInfo.tag,
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
// Otherwise it's just the type info directly (backwards compatible)
|
|
1587
|
+
return {
|
|
1588
|
+
name,
|
|
1589
|
+
type: StructType.createTypeFromFieldInfo(fieldInfo),
|
|
1590
|
+
};
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
return new StructType(typeName, fields);
|
|
803
1594
|
}
|
|
804
1595
|
}
|
|
805
1596
|
// Check if it has a constructor name we can use (fallback)
|
|
806
1597
|
const constructorName = value.constructor?.name;
|
|
807
1598
|
if (constructorName && constructorName !== 'Object') {
|
|
808
|
-
return new StructType(constructorName);
|
|
1599
|
+
return new StructType(constructorName, []);
|
|
809
1600
|
}
|
|
810
1601
|
// Default to struct type for plain objects
|
|
811
|
-
return new StructType('struct');
|
|
1602
|
+
return new StructType('struct', []);
|
|
812
1603
|
}
|
|
813
1604
|
default:
|
|
814
1605
|
return new BasicType(Interface, 'interface{}', 16);
|
|
@@ -828,6 +1619,8 @@ export function SliceOf(t) {
|
|
|
828
1619
|
return new SliceType(t);
|
|
829
1620
|
}
|
|
830
1621
|
export function PointerTo(t) {
|
|
1622
|
+
if (t === null)
|
|
1623
|
+
return null;
|
|
831
1624
|
return new PointerType(t);
|
|
832
1625
|
}
|
|
833
1626
|
export function PtrTo(t) {
|