goscript 0.0.60 → 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 +974 -369
- package/compiler/assignment.go +72 -0
- package/compiler/compiler.go +74 -15
- package/compiler/composite-lit.go +29 -8
- package/compiler/decl.go +67 -98
- package/compiler/expr-call-async.go +26 -1
- package/compiler/expr-call-builtins.go +60 -4
- package/compiler/expr-call-helpers.go +182 -0
- package/compiler/expr-call-type-conversion.go +37 -5
- package/compiler/expr-call.go +25 -33
- package/compiler/expr-selector.go +71 -1
- package/compiler/expr-type.go +49 -3
- package/compiler/expr.go +37 -28
- package/compiler/index.test.ts +3 -1
- package/compiler/lit.go +13 -4
- package/compiler/spec-struct.go +42 -9
- package/compiler/spec-value.go +2 -2
- package/compiler/spec.go +42 -5
- package/compiler/stmt-assign.go +71 -0
- package/compiler/stmt-range.go +2 -2
- package/compiler/stmt.go +130 -10
- package/compiler/type-utils.go +40 -16
- 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 +51 -21
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +28 -2
- package/dist/gs/builtin/type.js +132 -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/internal/byteorder/index.d.ts +6 -0
- package/dist/gs/internal/byteorder/index.js +34 -0
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +3 -3
- package/dist/gs/reflect/index.js +2 -2
- 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 +55 -8
- package/dist/gs/reflect/type.js +889 -23
- 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 +32 -0
- package/dist/gs/slices/slices.js +81 -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 -16
- package/gs/builtin/builtin.ts +27 -2
- package/gs/builtin/errors.ts +12 -0
- package/gs/builtin/slice.ts +77 -14
- package/gs/builtin/type.ts +167 -2
- package/gs/bytes/reader.gs.ts +2 -2
- package/gs/internal/byteorder/index.ts +40 -0
- package/gs/math/hypot.gs.test.ts +3 -1
- package/gs/math/pow10.gs.test.ts +5 -4
- package/gs/reflect/index.ts +6 -3
- package/gs/reflect/map.test.ts +7 -6
- package/gs/reflect/map.ts +49 -7
- package/gs/reflect/type.ts +1139 -43
- package/gs/reflect/types.ts +34 -21
- package/gs/reflect/value.ts +12 -6
- package/gs/slices/slices.ts +92 -0
- package/gs/sync/atomic/type.gs.ts +14 -5
- package/gs/sync/meta.json +1 -1
- package/gs/unicode/utf8/utf8.ts +12 -8
- package/package.json +13 -13
package/dist/gs/reflect/type.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
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';
|
|
1
6
|
// rtype is the common implementation of most values
|
|
2
7
|
export class rtype {
|
|
3
8
|
kind;
|
|
@@ -143,13 +148,73 @@ export const Slice = 23;
|
|
|
143
148
|
export const String = 24;
|
|
144
149
|
export const Struct = 25;
|
|
145
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();
|
|
146
197
|
// Value is the reflection interface to a Go value - consolidated from all implementations
|
|
147
198
|
export class Value {
|
|
148
199
|
_value;
|
|
149
200
|
_type;
|
|
150
|
-
constructor(
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
}
|
|
153
218
|
}
|
|
154
219
|
clone() {
|
|
155
220
|
return new Value(this._value, this._type);
|
|
@@ -265,9 +330,19 @@ export class Value {
|
|
|
265
330
|
NumField() {
|
|
266
331
|
return this._type.NumField();
|
|
267
332
|
}
|
|
268
|
-
Field(
|
|
269
|
-
|
|
270
|
-
|
|
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);
|
|
271
346
|
}
|
|
272
347
|
// Additional methods needed by various parts of the codebase
|
|
273
348
|
UnsafePointer() {
|
|
@@ -288,7 +363,36 @@ export class Value {
|
|
|
288
363
|
// Simple conversion - in a real implementation this would do type conversion
|
|
289
364
|
return new Value(this._value, t);
|
|
290
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
|
+
}
|
|
291
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
|
+
}
|
|
292
396
|
typ() {
|
|
293
397
|
return new rtype(this._type.Kind());
|
|
294
398
|
}
|
|
@@ -331,6 +435,207 @@ export class Value {
|
|
|
331
435
|
channelObj._sendQueue.push(valueToSend);
|
|
332
436
|
}
|
|
333
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
|
+
}
|
|
334
639
|
}
|
|
335
640
|
// Basic type implementation - exported for compatibility
|
|
336
641
|
export class BasicType {
|
|
@@ -352,7 +657,7 @@ export class BasicType {
|
|
|
352
657
|
return this._size;
|
|
353
658
|
}
|
|
354
659
|
Elem() {
|
|
355
|
-
|
|
660
|
+
throw new Error(`reflect: Elem of invalid type ${this._name}`);
|
|
356
661
|
}
|
|
357
662
|
NumField() {
|
|
358
663
|
return 0;
|
|
@@ -360,12 +665,108 @@ export class BasicType {
|
|
|
360
665
|
PkgPath() {
|
|
361
666
|
return '';
|
|
362
667
|
}
|
|
668
|
+
Name() {
|
|
669
|
+
// Basic types have names like 'int', 'string', etc.
|
|
670
|
+
return this._name;
|
|
671
|
+
}
|
|
363
672
|
Field(_i) {
|
|
364
|
-
|
|
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;
|
|
365
686
|
}
|
|
366
687
|
common() {
|
|
367
688
|
return new rtype(this._kind);
|
|
368
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
|
+
}
|
|
369
770
|
}
|
|
370
771
|
// Slice type implementation
|
|
371
772
|
class SliceType {
|
|
@@ -391,6 +792,40 @@ class SliceType {
|
|
|
391
792
|
PkgPath() {
|
|
392
793
|
return '';
|
|
393
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
|
+
}
|
|
394
829
|
}
|
|
395
830
|
// Array type implementation
|
|
396
831
|
class ArrayType {
|
|
@@ -421,12 +856,43 @@ class ArrayType {
|
|
|
421
856
|
PkgPath() {
|
|
422
857
|
return '';
|
|
423
858
|
}
|
|
859
|
+
Name() {
|
|
860
|
+
// Array types are unnamed composite types
|
|
861
|
+
return '';
|
|
862
|
+
}
|
|
424
863
|
Field(_i) {
|
|
425
|
-
|
|
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;
|
|
426
877
|
}
|
|
427
878
|
common() {
|
|
428
879
|
return new rtype(this.Kind());
|
|
429
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
|
+
}
|
|
430
896
|
}
|
|
431
897
|
// Pointer type implementation
|
|
432
898
|
class PointerType {
|
|
@@ -452,12 +918,45 @@ class PointerType {
|
|
|
452
918
|
PkgPath() {
|
|
453
919
|
return '';
|
|
454
920
|
}
|
|
921
|
+
Name() {
|
|
922
|
+
// Pointer types are unnamed composite types
|
|
923
|
+
return '';
|
|
924
|
+
}
|
|
455
925
|
Field(_i) {
|
|
456
|
-
|
|
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);
|
|
457
941
|
}
|
|
458
942
|
common() {
|
|
459
943
|
return new rtype(this.Kind());
|
|
460
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
|
+
}
|
|
461
960
|
}
|
|
462
961
|
// Function type implementation
|
|
463
962
|
class FunctionType {
|
|
@@ -475,7 +974,7 @@ class FunctionType {
|
|
|
475
974
|
return 8; // function pointer size
|
|
476
975
|
}
|
|
477
976
|
Elem() {
|
|
478
|
-
|
|
977
|
+
throw new Error('reflect: Elem of invalid type');
|
|
479
978
|
}
|
|
480
979
|
NumField() {
|
|
481
980
|
return 0;
|
|
@@ -483,12 +982,43 @@ class FunctionType {
|
|
|
483
982
|
PkgPath() {
|
|
484
983
|
return '';
|
|
485
984
|
}
|
|
985
|
+
Name() {
|
|
986
|
+
// Function types are unnamed composite types
|
|
987
|
+
return '';
|
|
988
|
+
}
|
|
486
989
|
Field(_i) {
|
|
487
|
-
|
|
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;
|
|
488
1003
|
}
|
|
489
1004
|
common() {
|
|
490
1005
|
return new rtype(this.Kind());
|
|
491
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
|
+
}
|
|
492
1022
|
}
|
|
493
1023
|
// Map type implementation
|
|
494
1024
|
class MapType {
|
|
@@ -519,14 +1049,82 @@ class MapType {
|
|
|
519
1049
|
PkgPath() {
|
|
520
1050
|
return '';
|
|
521
1051
|
}
|
|
1052
|
+
Name() {
|
|
1053
|
+
// Map types are unnamed composite types
|
|
1054
|
+
return '';
|
|
1055
|
+
}
|
|
522
1056
|
Field(_i) {
|
|
523
|
-
|
|
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;
|
|
524
1067
|
}
|
|
525
1068
|
common() {
|
|
526
1069
|
return new rtype(this.Kind());
|
|
527
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
|
+
}
|
|
528
1086
|
}
|
|
529
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
|
+
}
|
|
530
1128
|
class StructType {
|
|
531
1129
|
_name;
|
|
532
1130
|
_fields;
|
|
@@ -545,21 +1143,133 @@ class StructType {
|
|
|
545
1143
|
return this._fields.reduce((sum, field) => sum + field.type.Size(), 0);
|
|
546
1144
|
}
|
|
547
1145
|
Elem() {
|
|
548
|
-
|
|
1146
|
+
throw new Error('reflect: Elem of invalid type');
|
|
549
1147
|
}
|
|
550
1148
|
NumField() {
|
|
551
1149
|
return this._fields.length;
|
|
552
1150
|
}
|
|
553
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
|
+
}
|
|
554
1157
|
return '';
|
|
555
1158
|
}
|
|
556
|
-
|
|
557
|
-
//
|
|
558
|
-
|
|
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);
|
|
559
1189
|
}
|
|
560
1190
|
common() {
|
|
561
1191
|
return new rtype(this.Kind());
|
|
562
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
|
+
}
|
|
563
1273
|
}
|
|
564
1274
|
class ChannelType {
|
|
565
1275
|
_elemType;
|
|
@@ -597,8 +1307,24 @@ class ChannelType {
|
|
|
597
1307
|
PkgPath() {
|
|
598
1308
|
return '';
|
|
599
1309
|
}
|
|
600
|
-
|
|
601
|
-
|
|
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;
|
|
602
1328
|
}
|
|
603
1329
|
common() {
|
|
604
1330
|
return new rtype(this.Kind());
|
|
@@ -606,8 +1332,93 @@ class ChannelType {
|
|
|
606
1332
|
ChanDir() {
|
|
607
1333
|
return this._dir;
|
|
608
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
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
// Interface type implementation
|
|
1352
|
+
class InterfaceType {
|
|
1353
|
+
_name;
|
|
1354
|
+
constructor(_name = 'interface{}') {
|
|
1355
|
+
this._name = _name;
|
|
1356
|
+
}
|
|
1357
|
+
String() {
|
|
1358
|
+
return this._name;
|
|
1359
|
+
}
|
|
1360
|
+
Kind() {
|
|
1361
|
+
return Interface;
|
|
1362
|
+
}
|
|
1363
|
+
Size() {
|
|
1364
|
+
return 16;
|
|
1365
|
+
}
|
|
1366
|
+
Elem() {
|
|
1367
|
+
throw new Error('reflect: Elem of invalid type');
|
|
1368
|
+
}
|
|
1369
|
+
NumField() {
|
|
1370
|
+
return 0;
|
|
1371
|
+
}
|
|
1372
|
+
PkgPath() {
|
|
1373
|
+
return '';
|
|
1374
|
+
}
|
|
1375
|
+
Name() {
|
|
1376
|
+
return this._name;
|
|
1377
|
+
}
|
|
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');
|
|
1383
|
+
}
|
|
1384
|
+
Implements(_u) {
|
|
1385
|
+
return false;
|
|
1386
|
+
}
|
|
1387
|
+
common() {
|
|
1388
|
+
return new rtype(this.Kind());
|
|
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
|
+
}
|
|
609
1405
|
}
|
|
610
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
|
+
}
|
|
611
1422
|
if (value === null || value === undefined) {
|
|
612
1423
|
return new BasicType(Interface, 'interface{}', 16);
|
|
613
1424
|
}
|
|
@@ -757,20 +1568,38 @@ function getTypeOf(value) {
|
|
|
757
1568
|
'__typeInfo' in value.constructor) {
|
|
758
1569
|
const typeInfo = value.constructor.__typeInfo;
|
|
759
1570
|
if (typeInfo && typeInfo.name) {
|
|
760
|
-
// Add package prefix for struct types if not already present
|
|
761
1571
|
const typeName = typeInfo.name.includes('.') ?
|
|
762
1572
|
typeInfo.name
|
|
763
1573
|
: `main.${typeInfo.name}`;
|
|
764
|
-
|
|
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);
|
|
765
1594
|
}
|
|
766
1595
|
}
|
|
767
1596
|
// Check if it has a constructor name we can use (fallback)
|
|
768
1597
|
const constructorName = value.constructor?.name;
|
|
769
1598
|
if (constructorName && constructorName !== 'Object') {
|
|
770
|
-
return new StructType(constructorName);
|
|
1599
|
+
return new StructType(constructorName, []);
|
|
771
1600
|
}
|
|
772
1601
|
// Default to struct type for plain objects
|
|
773
|
-
return new StructType('struct');
|
|
1602
|
+
return new StructType('struct', []);
|
|
774
1603
|
}
|
|
775
1604
|
default:
|
|
776
1605
|
return new BasicType(Interface, 'interface{}', 16);
|
|
@@ -790,6 +1619,8 @@ export function SliceOf(t) {
|
|
|
790
1619
|
return new SliceType(t);
|
|
791
1620
|
}
|
|
792
1621
|
export function PointerTo(t) {
|
|
1622
|
+
if (t === null)
|
|
1623
|
+
return null;
|
|
793
1624
|
return new PointerType(t);
|
|
794
1625
|
}
|
|
795
1626
|
export function PtrTo(t) {
|
|
@@ -801,6 +1632,41 @@ export function MapOf(key, elem) {
|
|
|
801
1632
|
export function ChanOf(dir, t) {
|
|
802
1633
|
return new ChannelType(t, dir);
|
|
803
1634
|
}
|
|
1635
|
+
export function TypeFor() {
|
|
1636
|
+
return new InterfaceType('interface{}');
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* getInterfaceTypeByName looks up a registered interface type by name
|
|
1640
|
+
* and returns a Type for it. Returns an interface{} type if not found.
|
|
1641
|
+
*/
|
|
1642
|
+
export function getInterfaceTypeByName(name) {
|
|
1643
|
+
const typeInfo = builtinGetTypeByName(name);
|
|
1644
|
+
if (typeInfo && typeInfo.kind === TypeKind.Interface) {
|
|
1645
|
+
// InterfaceTypeInfo
|
|
1646
|
+
const methods = typeInfo.methods || [];
|
|
1647
|
+
if (methods.length > 0) {
|
|
1648
|
+
// Build interface signature with methods
|
|
1649
|
+
const methodSigs = methods
|
|
1650
|
+
.map((m) => {
|
|
1651
|
+
const args = m.args
|
|
1652
|
+
?.map((a) => (typeof a === 'string' ? a : 'any'))
|
|
1653
|
+
.join(', ') || '';
|
|
1654
|
+
const returns = m.returns?.map((r) => typeof r === 'string' ? r : 'any');
|
|
1655
|
+
let returnSig = '';
|
|
1656
|
+
if (returns && returns.length === 1) {
|
|
1657
|
+
returnSig = ` ${returns[0]}`;
|
|
1658
|
+
}
|
|
1659
|
+
else if (returns && returns.length > 1) {
|
|
1660
|
+
returnSig = ` (${returns.join(', ')})`;
|
|
1661
|
+
}
|
|
1662
|
+
return `${m.name}(${args})${returnSig}`;
|
|
1663
|
+
})
|
|
1664
|
+
.join('; ');
|
|
1665
|
+
return new InterfaceType(`interface { ${methodSigs} }`);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
return new InterfaceType('interface{}');
|
|
1669
|
+
}
|
|
804
1670
|
// Additional functions from merged files
|
|
805
1671
|
export function canRangeFunc(t) {
|
|
806
1672
|
const kind = t.Kind();
|