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/gs/reflect/type.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { ReflectValue, StructField } from './types.js'
|
|
1
|
+
import { ReflectValue, StructField, StructTag, ValueError } from './types.js'
|
|
2
|
+
export { StructField }
|
|
2
3
|
import { MapIter } from './map.js'
|
|
3
4
|
import {
|
|
4
5
|
getTypeByName as builtinGetTypeByName,
|
|
5
6
|
TypeKind,
|
|
7
|
+
isStructTypeInfo,
|
|
8
|
+
isInterfaceTypeInfo,
|
|
9
|
+
isStructFieldInfo,
|
|
6
10
|
} from '../builtin/type.js'
|
|
11
|
+
import { Zero } from './value.js'
|
|
12
|
+
import { DeepEqual } from './deepequal.js'
|
|
13
|
+
import * as $ from '../builtin/index.js'
|
|
7
14
|
|
|
8
15
|
// rtype is the common implementation of most values
|
|
9
16
|
export class rtype {
|
|
@@ -177,7 +184,8 @@ export interface Type {
|
|
|
177
184
|
Size(): number
|
|
178
185
|
|
|
179
186
|
// Elem returns a type's element type.
|
|
180
|
-
|
|
187
|
+
// Panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
|
|
188
|
+
Elem(): Type
|
|
181
189
|
|
|
182
190
|
// NumField returns a struct type's field count.
|
|
183
191
|
NumField(): number
|
|
@@ -186,27 +194,113 @@ export interface Type {
|
|
|
186
194
|
PkgPath?(): string
|
|
187
195
|
|
|
188
196
|
// Field returns a struct type's i'th field.
|
|
189
|
-
|
|
197
|
+
// Panics if the type's Kind is not Struct or i is out of range.
|
|
198
|
+
Field(i: number): StructField
|
|
190
199
|
|
|
191
|
-
// Key returns a map type's key type
|
|
192
|
-
|
|
200
|
+
// Key returns a map type's key type.
|
|
201
|
+
// Panics if the type's Kind is not Map.
|
|
202
|
+
Key(): Type
|
|
193
203
|
|
|
194
204
|
// Name returns the type's name within its package.
|
|
195
|
-
Name
|
|
205
|
+
Name(): string
|
|
196
206
|
|
|
197
207
|
// Implements reports whether the type implements the interface type u.
|
|
198
|
-
Implements
|
|
208
|
+
Implements(u: Type | null): boolean
|
|
199
209
|
|
|
200
210
|
// common returns the common type implementation.
|
|
201
211
|
common?(): rtype
|
|
212
|
+
|
|
213
|
+
// OverflowInt reports whether the int64 x cannot be represented by the type
|
|
214
|
+
// Panics if the type's Kind is not Int, Int8, Int16, Int32, or Int64.
|
|
215
|
+
OverflowInt(x: number): boolean
|
|
216
|
+
|
|
217
|
+
// OverflowUint reports whether the uint64 x cannot be represented by the type
|
|
218
|
+
// Panics if the type's Kind is not Uint, Uint8, Uint16, Uint32, Uint64, or Uintptr.
|
|
219
|
+
OverflowUint(x: number): boolean
|
|
220
|
+
|
|
221
|
+
// OverflowFloat reports whether the float64 x cannot be represented by the type
|
|
222
|
+
// Panics if the type's Kind is not Float32 or Float64.
|
|
223
|
+
OverflowFloat(x: number): boolean
|
|
224
|
+
|
|
225
|
+
// NumMethod returns the number of methods in the type's method set
|
|
226
|
+
NumMethod(): number
|
|
227
|
+
|
|
228
|
+
// Bits returns the size of the type in bits
|
|
229
|
+
// Panics if the type's Kind is not a sized type.
|
|
230
|
+
Bits(): number
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// InvalidTypeInstance is a singleton type for invalid/zero reflect.Value
|
|
234
|
+
class InvalidTypeClass implements Type {
|
|
235
|
+
Kind(): Kind {
|
|
236
|
+
return Invalid
|
|
237
|
+
}
|
|
238
|
+
String(): string {
|
|
239
|
+
return '<invalid reflect.Value>'
|
|
240
|
+
}
|
|
241
|
+
Name(): string {
|
|
242
|
+
return ''
|
|
243
|
+
}
|
|
244
|
+
Size(): number {
|
|
245
|
+
return 0
|
|
246
|
+
}
|
|
247
|
+
Elem(): Type {
|
|
248
|
+
throw new Error('reflect: Elem of invalid type')
|
|
249
|
+
}
|
|
250
|
+
Key(): Type {
|
|
251
|
+
throw new Error('reflect: Key of invalid type')
|
|
252
|
+
}
|
|
253
|
+
NumField(): number {
|
|
254
|
+
return 0
|
|
255
|
+
}
|
|
256
|
+
Field(_i: number): StructField {
|
|
257
|
+
throw new Error('reflect: Field of invalid type')
|
|
258
|
+
}
|
|
259
|
+
Implements(_u: Type | null): boolean {
|
|
260
|
+
return false
|
|
261
|
+
}
|
|
262
|
+
OverflowInt(_x: number): boolean {
|
|
263
|
+
throw new Error('reflect: OverflowInt of invalid type')
|
|
264
|
+
}
|
|
265
|
+
OverflowUint(_x: number): boolean {
|
|
266
|
+
throw new Error('reflect: OverflowUint of invalid type')
|
|
267
|
+
}
|
|
268
|
+
OverflowFloat(_x: number): boolean {
|
|
269
|
+
throw new Error('reflect: OverflowFloat of invalid type')
|
|
270
|
+
}
|
|
271
|
+
NumMethod(): number {
|
|
272
|
+
return 0
|
|
273
|
+
}
|
|
274
|
+
Bits(): number {
|
|
275
|
+
throw new Error('reflect: Bits of invalid type')
|
|
276
|
+
}
|
|
202
277
|
}
|
|
278
|
+
const invalidTypeInstance = new InvalidTypeClass()
|
|
203
279
|
|
|
204
280
|
// Value is the reflection interface to a Go value - consolidated from all implementations
|
|
205
281
|
export class Value {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
) {
|
|
282
|
+
private _value: ReflectValue
|
|
283
|
+
private _type: Type
|
|
284
|
+
|
|
285
|
+
constructor(value?: ReflectValue | Record<string, never>, type?: Type | null) {
|
|
286
|
+
// Handle zero-value initialization: new Value({}) or new Value()
|
|
287
|
+
// This corresponds to reflect.Value{} in Go which is an invalid/zero value
|
|
288
|
+
if (
|
|
289
|
+
type === undefined ||
|
|
290
|
+
type === null ||
|
|
291
|
+
(typeof value === 'object' &&
|
|
292
|
+
value !== null &&
|
|
293
|
+
Object.keys(value).length === 0 &&
|
|
294
|
+
!(value instanceof globalThis.Array) &&
|
|
295
|
+
!(value instanceof globalThis.Map))
|
|
296
|
+
) {
|
|
297
|
+
this._value = null
|
|
298
|
+
this._type = invalidTypeInstance
|
|
299
|
+
} else {
|
|
300
|
+
this._value = value as ReflectValue
|
|
301
|
+
this._type = type
|
|
302
|
+
}
|
|
303
|
+
}
|
|
210
304
|
|
|
211
305
|
public clone(): Value {
|
|
212
306
|
return new Value(this._value, this._type)
|
|
@@ -359,9 +453,21 @@ export class Value {
|
|
|
359
453
|
return this._type.NumField()
|
|
360
454
|
}
|
|
361
455
|
|
|
362
|
-
public Field(
|
|
363
|
-
|
|
364
|
-
|
|
456
|
+
public Field(i: number): Value {
|
|
457
|
+
if (this.Kind() !== Struct) {
|
|
458
|
+
throw new ValueError({ Kind: this.Kind(), Method: 'Field' })
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const field = this.Type().Field(i)
|
|
462
|
+
if (!field) {
|
|
463
|
+
throw new Error('reflect: struct field index out of range')
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
let fieldVal = (this._value as Record<string, any>)[field.Name]
|
|
467
|
+
if (fieldVal === undefined) {
|
|
468
|
+
fieldVal = null
|
|
469
|
+
}
|
|
470
|
+
return new Value(fieldVal, field.Type)
|
|
365
471
|
}
|
|
366
472
|
|
|
367
473
|
// Additional methods needed by various parts of the codebase
|
|
@@ -388,7 +494,42 @@ export class Value {
|
|
|
388
494
|
return new Value(this._value, t)
|
|
389
495
|
}
|
|
390
496
|
|
|
497
|
+
public CanAddr(): boolean {
|
|
498
|
+
return this.Kind() !== Ptr && this._value !== null // Simplified
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
public Addr(): Value {
|
|
502
|
+
if (!this.CanAddr()) {
|
|
503
|
+
throw new Error('reflect: call of reflect.Value.Addr on invalid Value')
|
|
504
|
+
}
|
|
505
|
+
const ptrType = PointerTo(this.Type())
|
|
506
|
+
return new Value(this, ptrType) // Simplified
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
public CanSet(): boolean {
|
|
510
|
+
return this.IsValid() && this.Kind() !== Ptr // Simplified
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
public Set(x: Value): void {
|
|
514
|
+
if (!this.CanSet()) {
|
|
515
|
+
throw new Error('reflect: assign to invalid value')
|
|
516
|
+
}
|
|
517
|
+
if (this.Type() !== x.Type()) {
|
|
518
|
+
throw new Error('reflect: assign to wrong type')
|
|
519
|
+
}
|
|
520
|
+
this._value = x.value
|
|
521
|
+
}
|
|
522
|
+
|
|
391
523
|
// Additional methods from deleted reflect.gs.ts
|
|
524
|
+
public Interface(): any {
|
|
525
|
+
return this._value
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
public IsZero(): boolean {
|
|
529
|
+
const zeroVal = Zero(this.Type()).value
|
|
530
|
+
return DeepEqual(this._value, zeroVal)
|
|
531
|
+
}
|
|
532
|
+
|
|
392
533
|
public typ(): rtype | null {
|
|
393
534
|
return new rtype(this._type.Kind())
|
|
394
535
|
}
|
|
@@ -439,6 +580,269 @@ export class Value {
|
|
|
439
580
|
channelObj._sendQueue.push(valueToSend)
|
|
440
581
|
}
|
|
441
582
|
}
|
|
583
|
+
|
|
584
|
+
// SetString sets v's underlying value to x
|
|
585
|
+
public SetString(x: string): void {
|
|
586
|
+
if (!this.CanSet()) {
|
|
587
|
+
throw new Error(
|
|
588
|
+
'reflect: call of reflect.Value.SetString on unaddressable value',
|
|
589
|
+
)
|
|
590
|
+
}
|
|
591
|
+
if (this.Kind() !== String) {
|
|
592
|
+
throw new Error(
|
|
593
|
+
'reflect: call of reflect.Value.SetString on ' + this.Kind() + ' Value',
|
|
594
|
+
)
|
|
595
|
+
}
|
|
596
|
+
this._value = x
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// SetInt sets v's underlying value to x
|
|
600
|
+
public SetInt(x: number): void {
|
|
601
|
+
if (!this.CanSet()) {
|
|
602
|
+
throw new Error(
|
|
603
|
+
'reflect: call of reflect.Value.SetInt on unaddressable value',
|
|
604
|
+
)
|
|
605
|
+
}
|
|
606
|
+
const k = this.Kind()
|
|
607
|
+
if (k !== Int && k !== Int8 && k !== Int16 && k !== Int32 && k !== Int64) {
|
|
608
|
+
throw new Error(
|
|
609
|
+
'reflect: call of reflect.Value.SetInt on ' + k + ' Value',
|
|
610
|
+
)
|
|
611
|
+
}
|
|
612
|
+
this._value = x
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// SetUint sets v's underlying value to x
|
|
616
|
+
public SetUint(x: number): void {
|
|
617
|
+
if (!this.CanSet()) {
|
|
618
|
+
throw new Error(
|
|
619
|
+
'reflect: call of reflect.Value.SetUint on unaddressable value',
|
|
620
|
+
)
|
|
621
|
+
}
|
|
622
|
+
const k = this.Kind()
|
|
623
|
+
if (
|
|
624
|
+
k !== Uint &&
|
|
625
|
+
k !== Uint8 &&
|
|
626
|
+
k !== Uint16 &&
|
|
627
|
+
k !== Uint32 &&
|
|
628
|
+
k !== Uint64 &&
|
|
629
|
+
k !== Uintptr
|
|
630
|
+
) {
|
|
631
|
+
throw new Error(
|
|
632
|
+
'reflect: call of reflect.Value.SetUint on ' + k + ' Value',
|
|
633
|
+
)
|
|
634
|
+
}
|
|
635
|
+
this._value = x
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// SetBool sets v's underlying value to x
|
|
639
|
+
public SetBool(x: boolean): void {
|
|
640
|
+
if (!this.CanSet()) {
|
|
641
|
+
throw new Error(
|
|
642
|
+
'reflect: call of reflect.Value.SetBool on unaddressable value',
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
if (this.Kind() !== Bool) {
|
|
646
|
+
throw new Error(
|
|
647
|
+
'reflect: call of reflect.Value.SetBool on ' + this.Kind() + ' Value',
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
this._value = x
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// SetFloat sets v's underlying value to x
|
|
654
|
+
public SetFloat(x: number): void {
|
|
655
|
+
if (!this.CanSet()) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
'reflect: call of reflect.Value.SetFloat on unaddressable value',
|
|
658
|
+
)
|
|
659
|
+
}
|
|
660
|
+
const k = this.Kind()
|
|
661
|
+
if (k !== Float32 && k !== Float64) {
|
|
662
|
+
throw new Error(
|
|
663
|
+
'reflect: call of reflect.Value.SetFloat on ' + k + ' Value',
|
|
664
|
+
)
|
|
665
|
+
}
|
|
666
|
+
this._value = x
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// SetBytes sets v's underlying value to x
|
|
670
|
+
public SetBytes(x: $.Slice<number>): void {
|
|
671
|
+
if (!this.CanSet()) {
|
|
672
|
+
throw new Error(
|
|
673
|
+
'reflect: call of reflect.Value.SetBytes on unaddressable value',
|
|
674
|
+
)
|
|
675
|
+
}
|
|
676
|
+
if (this.Kind() !== Slice) {
|
|
677
|
+
throw new Error(
|
|
678
|
+
'reflect: call of reflect.Value.SetBytes on ' + this.Kind() + ' Value',
|
|
679
|
+
)
|
|
680
|
+
}
|
|
681
|
+
// Convert Uint8Array or slice to array
|
|
682
|
+
if (x instanceof Uint8Array) {
|
|
683
|
+
this._value = globalThis.Array.from(x)
|
|
684
|
+
} else if (globalThis.Array.isArray(x)) {
|
|
685
|
+
this._value = x
|
|
686
|
+
} else {
|
|
687
|
+
this._value = x
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// SetZero sets v to be the zero value of v's type
|
|
692
|
+
public SetZero(): void {
|
|
693
|
+
if (!this.CanSet()) {
|
|
694
|
+
throw new Error(
|
|
695
|
+
'reflect: call of reflect.Value.SetZero on unaddressable value',
|
|
696
|
+
)
|
|
697
|
+
}
|
|
698
|
+
const zeroVal = Zero(this.Type())
|
|
699
|
+
this._value = (zeroVal as unknown as { value: ReflectValue }).value
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// SetLen sets v's length to n
|
|
703
|
+
public SetLen(n: number): void {
|
|
704
|
+
if (!this.CanSet()) {
|
|
705
|
+
throw new Error(
|
|
706
|
+
'reflect: call of reflect.Value.SetLen on unaddressable value',
|
|
707
|
+
)
|
|
708
|
+
}
|
|
709
|
+
if (this.Kind() !== Slice) {
|
|
710
|
+
throw new Error(
|
|
711
|
+
'reflect: call of reflect.Value.SetLen on ' + this.Kind() + ' Value',
|
|
712
|
+
)
|
|
713
|
+
}
|
|
714
|
+
if (globalThis.Array.isArray(this._value)) {
|
|
715
|
+
this._value.length = n
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// SetMapIndex sets the element associated with key in the map v to elem
|
|
720
|
+
public SetMapIndex(key: Value, elem: Value): void {
|
|
721
|
+
if (!this.CanSet()) {
|
|
722
|
+
throw new Error(
|
|
723
|
+
'reflect: call of reflect.Value.SetMapIndex on unaddressable value',
|
|
724
|
+
)
|
|
725
|
+
}
|
|
726
|
+
if (this.Kind() !== Map) {
|
|
727
|
+
throw new Error(
|
|
728
|
+
'reflect: call of reflect.Value.SetMapIndex on ' +
|
|
729
|
+
this.Kind() +
|
|
730
|
+
' Value',
|
|
731
|
+
)
|
|
732
|
+
}
|
|
733
|
+
const mapObj = this._value as globalThis.Map<unknown, unknown>
|
|
734
|
+
const keyVal = (key as unknown as { value: ReflectValue }).value
|
|
735
|
+
const elemVal = (elem as unknown as { value: ReflectValue }).value
|
|
736
|
+
mapObj.set(keyVal, elemVal)
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Grow increases the slice's capacity, if necessary
|
|
740
|
+
public Grow(n: number): void {
|
|
741
|
+
if (this.Kind() !== Slice) {
|
|
742
|
+
throw new Error(
|
|
743
|
+
'reflect: call of reflect.Value.Grow on ' + this.Kind() + ' Value',
|
|
744
|
+
)
|
|
745
|
+
}
|
|
746
|
+
if (!globalThis.Array.isArray(this._value)) {
|
|
747
|
+
return
|
|
748
|
+
}
|
|
749
|
+
// JavaScript arrays grow automatically, but we ensure capacity
|
|
750
|
+
const currentLen = this._value.length
|
|
751
|
+
const targetCap = currentLen + n
|
|
752
|
+
if (this._value.length < targetCap) {
|
|
753
|
+
this._value.length = targetCap
|
|
754
|
+
this._value.length = currentLen // Reset to original length
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Cap returns v's capacity
|
|
759
|
+
public Cap(): number {
|
|
760
|
+
const k = this.Kind()
|
|
761
|
+
if (k === Slice || k === Array) {
|
|
762
|
+
if (globalThis.Array.isArray(this._value)) {
|
|
763
|
+
return this._value.length
|
|
764
|
+
}
|
|
765
|
+
return 0
|
|
766
|
+
}
|
|
767
|
+
if (k === Chan) {
|
|
768
|
+
return 0 // Simplified
|
|
769
|
+
}
|
|
770
|
+
throw new Error('reflect: call of reflect.Value.Cap on ' + k + ' Value')
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// NumMethod returns the number of methods in the value's method set
|
|
774
|
+
public NumMethod(): number {
|
|
775
|
+
return 0 // Simplified - methods not fully implemented
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// Equal reports whether v is equal to u
|
|
779
|
+
public Equal(u: Value): boolean {
|
|
780
|
+
return DeepEqual(
|
|
781
|
+
this._value,
|
|
782
|
+
(u as unknown as { value: ReflectValue }).value,
|
|
783
|
+
)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// CanInterface reports whether Interface can be used without panicking
|
|
787
|
+
public CanInterface(): boolean {
|
|
788
|
+
return this.IsValid()
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// OverflowInt reports whether the int64 x cannot be represented by v's type
|
|
792
|
+
public OverflowInt(x: number): boolean {
|
|
793
|
+
const k = this.Kind()
|
|
794
|
+
switch (k) {
|
|
795
|
+
case Int8:
|
|
796
|
+
return x < -128 || x > 127
|
|
797
|
+
case Int16:
|
|
798
|
+
return x < -32768 || x > 32767
|
|
799
|
+
case Int32:
|
|
800
|
+
return x < -2147483648 || x > 2147483647
|
|
801
|
+
case Int:
|
|
802
|
+
case Int64:
|
|
803
|
+
return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER
|
|
804
|
+
default:
|
|
805
|
+
throw new Error(
|
|
806
|
+
'reflect: call of reflect.Value.OverflowInt on ' + k + ' Value',
|
|
807
|
+
)
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// OverflowUint reports whether the uint64 x cannot be represented by v's type
|
|
812
|
+
public OverflowUint(x: number): boolean {
|
|
813
|
+
const k = this.Kind()
|
|
814
|
+
switch (k) {
|
|
815
|
+
case Uint8:
|
|
816
|
+
return x < 0 || x > 255
|
|
817
|
+
case Uint16:
|
|
818
|
+
return x < 0 || x > 65535
|
|
819
|
+
case Uint32:
|
|
820
|
+
return x < 0 || x > 4294967295
|
|
821
|
+
case Uint:
|
|
822
|
+
case Uint64:
|
|
823
|
+
case Uintptr:
|
|
824
|
+
return x < 0 || x > Number.MAX_SAFE_INTEGER
|
|
825
|
+
default:
|
|
826
|
+
throw new Error(
|
|
827
|
+
'reflect: call of reflect.Value.OverflowUint on ' + k + ' Value',
|
|
828
|
+
)
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// OverflowFloat reports whether the float64 x cannot be represented by v's type
|
|
833
|
+
public OverflowFloat(x: number): boolean {
|
|
834
|
+
const k = this.Kind()
|
|
835
|
+
if (k === Float32) {
|
|
836
|
+
const f32max = 3.4028234663852886e38
|
|
837
|
+
return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x)
|
|
838
|
+
}
|
|
839
|
+
if (k === Float64) {
|
|
840
|
+
return false // float64 can represent any JavaScript number
|
|
841
|
+
}
|
|
842
|
+
throw new Error(
|
|
843
|
+
'reflect: call of reflect.Value.OverflowFloat on ' + k + ' Value',
|
|
844
|
+
)
|
|
845
|
+
}
|
|
442
846
|
}
|
|
443
847
|
|
|
444
848
|
// Basic type implementation - exported for compatibility
|
|
@@ -461,8 +865,8 @@ export class BasicType implements Type {
|
|
|
461
865
|
return this._size
|
|
462
866
|
}
|
|
463
867
|
|
|
464
|
-
public Elem(): Type
|
|
465
|
-
|
|
868
|
+
public Elem(): Type {
|
|
869
|
+
throw new Error(`reflect: Elem of invalid type ${this._name}`)
|
|
466
870
|
}
|
|
467
871
|
|
|
468
872
|
public NumField(): number {
|
|
@@ -473,13 +877,125 @@ export class BasicType implements Type {
|
|
|
473
877
|
return ''
|
|
474
878
|
}
|
|
475
879
|
|
|
476
|
-
public
|
|
477
|
-
|
|
880
|
+
public Name(): string {
|
|
881
|
+
// Basic types have names like 'int', 'string', etc.
|
|
882
|
+
return this._name
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
public Field(_i: number): StructField {
|
|
886
|
+
throw new Error(`reflect: Field of non-struct type ${this._name}`)
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
public Key(): Type {
|
|
890
|
+
throw new Error(`reflect: Key of non-map type ${this._name}`)
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
public Implements(u: Type | null): boolean {
|
|
894
|
+
if (!u) {
|
|
895
|
+
return false
|
|
896
|
+
}
|
|
897
|
+
if (u.Kind() !== Interface) {
|
|
898
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
899
|
+
}
|
|
900
|
+
return false
|
|
478
901
|
}
|
|
479
902
|
|
|
480
903
|
public common?(): rtype {
|
|
481
904
|
return new rtype(this._kind)
|
|
482
905
|
}
|
|
906
|
+
|
|
907
|
+
public OverflowInt(x: number): boolean {
|
|
908
|
+
const k = this._kind
|
|
909
|
+
switch (k) {
|
|
910
|
+
case Int8:
|
|
911
|
+
return x < -128 || x > 127
|
|
912
|
+
case Int16:
|
|
913
|
+
return x < -32768 || x > 32767
|
|
914
|
+
case Int32:
|
|
915
|
+
return x < -2147483648 || x > 2147483647
|
|
916
|
+
case Int:
|
|
917
|
+
case Int64:
|
|
918
|
+
return x < Number.MIN_SAFE_INTEGER || x > Number.MAX_SAFE_INTEGER
|
|
919
|
+
default:
|
|
920
|
+
throw new Error(
|
|
921
|
+
'reflect: call of reflect.Type.OverflowInt on ' +
|
|
922
|
+
Kind_String(k) +
|
|
923
|
+
' Type',
|
|
924
|
+
)
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
public OverflowUint(x: number): boolean {
|
|
929
|
+
const k = this._kind
|
|
930
|
+
switch (k) {
|
|
931
|
+
case Uint8:
|
|
932
|
+
return x < 0 || x > 255
|
|
933
|
+
case Uint16:
|
|
934
|
+
return x < 0 || x > 65535
|
|
935
|
+
case Uint32:
|
|
936
|
+
return x < 0 || x > 4294967295
|
|
937
|
+
case Uint:
|
|
938
|
+
case Uint64:
|
|
939
|
+
case Uintptr:
|
|
940
|
+
return x < 0 || x > Number.MAX_SAFE_INTEGER
|
|
941
|
+
default:
|
|
942
|
+
throw new Error(
|
|
943
|
+
'reflect: call of reflect.Type.OverflowUint on ' +
|
|
944
|
+
Kind_String(k) +
|
|
945
|
+
' Type',
|
|
946
|
+
)
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
public OverflowFloat(x: number): boolean {
|
|
951
|
+
const k = this._kind
|
|
952
|
+
if (k === Float32) {
|
|
953
|
+
const f32max = 3.4028234663852886e38
|
|
954
|
+
return Math.abs(x) > f32max && !isNaN(x) && !!isFinite(x)
|
|
955
|
+
}
|
|
956
|
+
if (k === Float64) {
|
|
957
|
+
return false
|
|
958
|
+
}
|
|
959
|
+
throw new Error(
|
|
960
|
+
'reflect: call of reflect.Type.OverflowFloat on ' +
|
|
961
|
+
Kind_String(k) +
|
|
962
|
+
' Type',
|
|
963
|
+
)
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
public NumMethod(): number {
|
|
967
|
+
return 0
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
public Bits(): number {
|
|
971
|
+
const k = this._kind
|
|
972
|
+
switch (k) {
|
|
973
|
+
case Bool:
|
|
974
|
+
return 1
|
|
975
|
+
case Int8:
|
|
976
|
+
case Uint8:
|
|
977
|
+
return 8
|
|
978
|
+
case Int16:
|
|
979
|
+
case Uint16:
|
|
980
|
+
return 16
|
|
981
|
+
case Int32:
|
|
982
|
+
case Uint32:
|
|
983
|
+
case Float32:
|
|
984
|
+
return 32
|
|
985
|
+
case Int64:
|
|
986
|
+
case Uint64:
|
|
987
|
+
case Float64:
|
|
988
|
+
return 64
|
|
989
|
+
case Int:
|
|
990
|
+
case Uint:
|
|
991
|
+
case Uintptr:
|
|
992
|
+
return 64 // Assuming 64-bit architecture
|
|
993
|
+
default:
|
|
994
|
+
throw new Error(
|
|
995
|
+
'reflect: call of reflect.Type.Bits on ' + Kind_String(k) + ' Type',
|
|
996
|
+
)
|
|
997
|
+
}
|
|
998
|
+
}
|
|
483
999
|
}
|
|
484
1000
|
|
|
485
1001
|
// Slice type implementation
|
|
@@ -498,7 +1014,7 @@ class SliceType implements Type {
|
|
|
498
1014
|
return 24 // slice header size
|
|
499
1015
|
}
|
|
500
1016
|
|
|
501
|
-
public Elem(): Type
|
|
1017
|
+
public Elem(): Type {
|
|
502
1018
|
return this._elemType
|
|
503
1019
|
}
|
|
504
1020
|
|
|
@@ -509,6 +1025,49 @@ class SliceType implements Type {
|
|
|
509
1025
|
public PkgPath?(): string {
|
|
510
1026
|
return ''
|
|
511
1027
|
}
|
|
1028
|
+
|
|
1029
|
+
public Name(): string {
|
|
1030
|
+
// Slice types are unnamed composite types
|
|
1031
|
+
return ''
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
public Field(_i: number): StructField {
|
|
1035
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
public Key(): Type {
|
|
1039
|
+
throw new Error('reflect: Key of non-map type')
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
public Implements(u: Type | null): boolean {
|
|
1043
|
+
if (!u) {
|
|
1044
|
+
return false
|
|
1045
|
+
}
|
|
1046
|
+
if (u.Kind() !== Interface) {
|
|
1047
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1048
|
+
}
|
|
1049
|
+
return false
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
public OverflowInt(_x: number): boolean {
|
|
1053
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on slice Type')
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
public OverflowUint(_x: number): boolean {
|
|
1057
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on slice Type')
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
public OverflowFloat(_x: number): boolean {
|
|
1061
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on slice Type')
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
public NumMethod(): number {
|
|
1065
|
+
return 0
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
public Bits(): number {
|
|
1069
|
+
throw new Error('reflect: call of reflect.Type.Bits on slice Type')
|
|
1070
|
+
}
|
|
512
1071
|
}
|
|
513
1072
|
|
|
514
1073
|
// Array type implementation
|
|
@@ -530,7 +1089,7 @@ class ArrayType implements Type {
|
|
|
530
1089
|
return this._elemType.Size() * this._len
|
|
531
1090
|
}
|
|
532
1091
|
|
|
533
|
-
public Elem(): Type
|
|
1092
|
+
public Elem(): Type {
|
|
534
1093
|
return this._elemType
|
|
535
1094
|
}
|
|
536
1095
|
|
|
@@ -546,13 +1105,52 @@ class ArrayType implements Type {
|
|
|
546
1105
|
return ''
|
|
547
1106
|
}
|
|
548
1107
|
|
|
549
|
-
public
|
|
550
|
-
|
|
1108
|
+
public Name(): string {
|
|
1109
|
+
// Array types are unnamed composite types
|
|
1110
|
+
return ''
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
public Field(_i: number): StructField {
|
|
1114
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
public Key(): Type {
|
|
1118
|
+
throw new Error('reflect: Key of non-map type')
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
public Implements(u: Type | null): boolean {
|
|
1122
|
+
if (!u) {
|
|
1123
|
+
return false
|
|
1124
|
+
}
|
|
1125
|
+
if (u.Kind() !== Interface) {
|
|
1126
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1127
|
+
}
|
|
1128
|
+
return false
|
|
551
1129
|
}
|
|
552
1130
|
|
|
553
1131
|
public common?(): rtype {
|
|
554
1132
|
return new rtype(this.Kind())
|
|
555
1133
|
}
|
|
1134
|
+
|
|
1135
|
+
public OverflowInt(_x: number): boolean {
|
|
1136
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on array Type')
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
public OverflowUint(_x: number): boolean {
|
|
1140
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on array Type')
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
public OverflowFloat(_x: number): boolean {
|
|
1144
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on array Type')
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
public NumMethod(): number {
|
|
1148
|
+
return 0
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
public Bits(): number {
|
|
1152
|
+
throw new Error('reflect: call of reflect.Type.Bits on array Type')
|
|
1153
|
+
}
|
|
556
1154
|
}
|
|
557
1155
|
|
|
558
1156
|
// Pointer type implementation
|
|
@@ -571,7 +1169,7 @@ class PointerType implements Type {
|
|
|
571
1169
|
return 8 // pointer size
|
|
572
1170
|
}
|
|
573
1171
|
|
|
574
|
-
public Elem(): Type
|
|
1172
|
+
public Elem(): Type {
|
|
575
1173
|
return this._elemType
|
|
576
1174
|
}
|
|
577
1175
|
|
|
@@ -583,13 +1181,58 @@ class PointerType implements Type {
|
|
|
583
1181
|
return ''
|
|
584
1182
|
}
|
|
585
1183
|
|
|
586
|
-
public
|
|
587
|
-
|
|
1184
|
+
public Name(): string {
|
|
1185
|
+
// Pointer types are unnamed composite types
|
|
1186
|
+
return ''
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
public Field(_i: number): StructField {
|
|
1190
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
public Key(): Type {
|
|
1194
|
+
throw new Error('reflect: Key of non-map type')
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
public Implements(u: Type | null): boolean {
|
|
1198
|
+
if (!u) {
|
|
1199
|
+
return false
|
|
1200
|
+
}
|
|
1201
|
+
if (u.Kind() !== Interface) {
|
|
1202
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1203
|
+
}
|
|
1204
|
+
// For pointer types, check if the element type implements the interface
|
|
1205
|
+
const elemTypeName = this._elemType.String()
|
|
1206
|
+
return typeImplementsInterface(elemTypeName, u)
|
|
588
1207
|
}
|
|
589
1208
|
|
|
590
1209
|
public common?(): rtype {
|
|
591
1210
|
return new rtype(this.Kind())
|
|
592
1211
|
}
|
|
1212
|
+
|
|
1213
|
+
public OverflowInt(_x: number): boolean {
|
|
1214
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on pointer Type')
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
public OverflowUint(_x: number): boolean {
|
|
1218
|
+
throw new Error(
|
|
1219
|
+
'reflect: call of reflect.Type.OverflowUint on pointer Type',
|
|
1220
|
+
)
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
public OverflowFloat(_x: number): boolean {
|
|
1224
|
+
throw new Error(
|
|
1225
|
+
'reflect: call of reflect.Type.OverflowFloat on pointer Type',
|
|
1226
|
+
)
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
public NumMethod(): number {
|
|
1230
|
+
return 0
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
public Bits(): number {
|
|
1234
|
+
throw new Error('reflect: call of reflect.Type.Bits on pointer Type')
|
|
1235
|
+
}
|
|
593
1236
|
}
|
|
594
1237
|
|
|
595
1238
|
// Function type implementation
|
|
@@ -608,8 +1251,8 @@ class FunctionType implements Type {
|
|
|
608
1251
|
return 8 // function pointer size
|
|
609
1252
|
}
|
|
610
1253
|
|
|
611
|
-
public Elem(): Type
|
|
612
|
-
|
|
1254
|
+
public Elem(): Type {
|
|
1255
|
+
throw new Error('reflect: Elem of invalid type')
|
|
613
1256
|
}
|
|
614
1257
|
|
|
615
1258
|
public NumField(): number {
|
|
@@ -620,13 +1263,52 @@ class FunctionType implements Type {
|
|
|
620
1263
|
return ''
|
|
621
1264
|
}
|
|
622
1265
|
|
|
623
|
-
public
|
|
624
|
-
|
|
1266
|
+
public Name(): string {
|
|
1267
|
+
// Function types are unnamed composite types
|
|
1268
|
+
return ''
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
public Field(_i: number): StructField {
|
|
1272
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
public Key(): Type {
|
|
1276
|
+
throw new Error('reflect: Key of non-map type')
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
public Implements(u: Type | null): boolean {
|
|
1280
|
+
if (!u) {
|
|
1281
|
+
return false
|
|
1282
|
+
}
|
|
1283
|
+
if (u.Kind() !== Interface) {
|
|
1284
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1285
|
+
}
|
|
1286
|
+
return false
|
|
625
1287
|
}
|
|
626
1288
|
|
|
627
1289
|
public common?(): rtype {
|
|
628
1290
|
return new rtype(this.Kind())
|
|
629
1291
|
}
|
|
1292
|
+
|
|
1293
|
+
public OverflowInt(_x: number): boolean {
|
|
1294
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on func Type')
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
public OverflowUint(_x: number): boolean {
|
|
1298
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on func Type')
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
public OverflowFloat(_x: number): boolean {
|
|
1302
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type')
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
public NumMethod(): number {
|
|
1306
|
+
return 0
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
public Bits(): number {
|
|
1310
|
+
throw new Error('reflect: call of reflect.Type.Bits on func Type')
|
|
1311
|
+
}
|
|
630
1312
|
}
|
|
631
1313
|
|
|
632
1314
|
// Map type implementation
|
|
@@ -648,7 +1330,7 @@ class MapType implements Type {
|
|
|
648
1330
|
return 8 // map header size
|
|
649
1331
|
}
|
|
650
1332
|
|
|
651
|
-
public Elem(): Type
|
|
1333
|
+
public Elem(): Type {
|
|
652
1334
|
return this._elemType
|
|
653
1335
|
}
|
|
654
1336
|
|
|
@@ -664,20 +1346,109 @@ class MapType implements Type {
|
|
|
664
1346
|
return ''
|
|
665
1347
|
}
|
|
666
1348
|
|
|
667
|
-
public
|
|
668
|
-
|
|
1349
|
+
public Name(): string {
|
|
1350
|
+
// Map types are unnamed composite types
|
|
1351
|
+
return ''
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
public Field(_i: number): StructField {
|
|
1355
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
public Implements(u: Type | null): boolean {
|
|
1359
|
+
if (!u) {
|
|
1360
|
+
return false
|
|
1361
|
+
}
|
|
1362
|
+
if (u.Kind() !== Interface) {
|
|
1363
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1364
|
+
}
|
|
1365
|
+
return false
|
|
669
1366
|
}
|
|
670
1367
|
|
|
671
1368
|
public common?(): rtype {
|
|
672
1369
|
return new rtype(this.Kind())
|
|
673
1370
|
}
|
|
1371
|
+
|
|
1372
|
+
public OverflowInt(_x: number): boolean {
|
|
1373
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on map Type')
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
public OverflowUint(_x: number): boolean {
|
|
1377
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on map Type')
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
public OverflowFloat(_x: number): boolean {
|
|
1381
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on map Type')
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
public NumMethod(): number {
|
|
1385
|
+
return 0
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
public Bits(): number {
|
|
1389
|
+
throw new Error('reflect: call of reflect.Type.Bits on map Type')
|
|
1390
|
+
}
|
|
674
1391
|
}
|
|
675
1392
|
|
|
676
1393
|
// Struct type implementation
|
|
1394
|
+
/**
|
|
1395
|
+
* Helper function to check if a type's method set contains all methods
|
|
1396
|
+
* required by an interface.
|
|
1397
|
+
*
|
|
1398
|
+
* @param typeName The name of the type to check (e.g., "main.MyType")
|
|
1399
|
+
* @param interfaceType The interface type that must be implemented
|
|
1400
|
+
* @returns True if the type implements the interface, false otherwise
|
|
1401
|
+
*/
|
|
1402
|
+
function typeImplementsInterface(
|
|
1403
|
+
typeName: string,
|
|
1404
|
+
interfaceType: Type,
|
|
1405
|
+
): boolean {
|
|
1406
|
+
// Get the interface name and look it up in the type registry
|
|
1407
|
+
const interfaceName = interfaceType.String()
|
|
1408
|
+
const interfaceTypeInfo = builtinGetTypeByName(interfaceName)
|
|
1409
|
+
|
|
1410
|
+
if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
|
|
1411
|
+
return false
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
// Get the type info for the struct/type
|
|
1415
|
+
const typeInfo = builtinGetTypeByName(typeName)
|
|
1416
|
+
|
|
1417
|
+
if (!typeInfo || !isStructTypeInfo(typeInfo)) {
|
|
1418
|
+
return false
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// Check if the type has all required methods
|
|
1422
|
+
const requiredMethods = interfaceTypeInfo.methods || []
|
|
1423
|
+
const typeMethods = typeInfo.methods || []
|
|
1424
|
+
|
|
1425
|
+
// For each required method, check if the type has a matching method
|
|
1426
|
+
for (const requiredMethod of requiredMethods) {
|
|
1427
|
+
const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name)
|
|
1428
|
+
|
|
1429
|
+
if (!typeMethod) {
|
|
1430
|
+
return false
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
// Check if method signatures match (simplified - just check counts)
|
|
1434
|
+
if (typeMethod.args.length !== requiredMethod.args.length) {
|
|
1435
|
+
return false
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
if (typeMethod.returns.length !== requiredMethod.returns.length) {
|
|
1439
|
+
return false
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
// Could add deeper type checking here, but for now this is sufficient
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
return true
|
|
1446
|
+
}
|
|
1447
|
+
|
|
677
1448
|
class StructType implements Type {
|
|
678
1449
|
constructor(
|
|
679
1450
|
private _name: string,
|
|
680
|
-
private _fields: Array<{ name: string; type: Type }> = [],
|
|
1451
|
+
private _fields: Array<{ name: string; type: Type; tag?: string }> = [],
|
|
681
1452
|
) {}
|
|
682
1453
|
|
|
683
1454
|
public String(): string {
|
|
@@ -693,8 +1464,8 @@ class StructType implements Type {
|
|
|
693
1464
|
return this._fields.reduce((sum, field) => sum + field.type.Size(), 0)
|
|
694
1465
|
}
|
|
695
1466
|
|
|
696
|
-
public Elem(): Type
|
|
697
|
-
|
|
1467
|
+
public Elem(): Type {
|
|
1468
|
+
throw new Error('reflect: Elem of invalid type')
|
|
698
1469
|
}
|
|
699
1470
|
|
|
700
1471
|
public NumField(): number {
|
|
@@ -702,17 +1473,139 @@ class StructType implements Type {
|
|
|
702
1473
|
}
|
|
703
1474
|
|
|
704
1475
|
public PkgPath?(): string {
|
|
1476
|
+
// Extract package path from full type name (e.g., "main.Person" -> "main")
|
|
1477
|
+
const dotIndex = this._name.lastIndexOf('.')
|
|
1478
|
+
if (dotIndex > 0) {
|
|
1479
|
+
return this._name.substring(0, dotIndex)
|
|
1480
|
+
}
|
|
705
1481
|
return ''
|
|
706
1482
|
}
|
|
707
1483
|
|
|
708
|
-
public
|
|
709
|
-
//
|
|
710
|
-
|
|
1484
|
+
public Name(): string {
|
|
1485
|
+
// Extract type name from full type name (e.g., "main.Person" -> "Person")
|
|
1486
|
+
const dotIndex = this._name.lastIndexOf('.')
|
|
1487
|
+
if (dotIndex >= 0) {
|
|
1488
|
+
return this._name.substring(dotIndex + 1)
|
|
1489
|
+
}
|
|
1490
|
+
return this._name
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
public Field(i: number): StructField {
|
|
1494
|
+
if (i < 0 || i >= this.NumField()) {
|
|
1495
|
+
throw new Error(`reflect: Field index out of range [${i}] with length ${this.NumField()}`)
|
|
1496
|
+
}
|
|
1497
|
+
const f = this._fields[i]
|
|
1498
|
+
return new StructField({
|
|
1499
|
+
Name: f.name,
|
|
1500
|
+
Type: f.type,
|
|
1501
|
+
Tag: f.tag ? new StructTag(f.tag) : undefined,
|
|
1502
|
+
})
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
public Key(): Type {
|
|
1506
|
+
throw new Error('reflect: Key of non-map type')
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
public Implements(u: Type | null): boolean {
|
|
1510
|
+
if (!u) {
|
|
1511
|
+
return false
|
|
1512
|
+
}
|
|
1513
|
+
if (u.Kind() !== Interface) {
|
|
1514
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1515
|
+
}
|
|
1516
|
+
return typeImplementsInterface(this._name, u)
|
|
711
1517
|
}
|
|
712
1518
|
|
|
713
1519
|
public common?(): rtype {
|
|
714
1520
|
return new rtype(this.Kind())
|
|
715
1521
|
}
|
|
1522
|
+
|
|
1523
|
+
public OverflowInt(_x: number): boolean {
|
|
1524
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on struct Type')
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
public OverflowUint(_x: number): boolean {
|
|
1528
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on struct Type')
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
public OverflowFloat(_x: number): boolean {
|
|
1532
|
+
throw new Error(
|
|
1533
|
+
'reflect: call of reflect.Type.OverflowFloat on struct Type',
|
|
1534
|
+
)
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
public NumMethod(): number {
|
|
1538
|
+
return 0
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
public Bits(): number {
|
|
1542
|
+
throw new Error('reflect: call of reflect.Type.Bits on struct Type')
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
static createTypeFromFieldInfo(ti: any): Type {
|
|
1546
|
+
if (typeof ti === 'string') {
|
|
1547
|
+
switch (ti) {
|
|
1548
|
+
case 'string':
|
|
1549
|
+
return new BasicType(String, ti, 16)
|
|
1550
|
+
case 'int':
|
|
1551
|
+
case 'int32':
|
|
1552
|
+
case 'int64':
|
|
1553
|
+
case 'number':
|
|
1554
|
+
return new BasicType(Int, ti === 'number' ? 'int' : ti, 8)
|
|
1555
|
+
case 'bool':
|
|
1556
|
+
case 'boolean':
|
|
1557
|
+
return new BasicType(Bool, 'bool', 1)
|
|
1558
|
+
case 'float64':
|
|
1559
|
+
return new BasicType(Float64, ti, 8)
|
|
1560
|
+
case 'uint':
|
|
1561
|
+
case 'uint32':
|
|
1562
|
+
case 'uint64':
|
|
1563
|
+
return new BasicType(Uint, ti, 8)
|
|
1564
|
+
default:
|
|
1565
|
+
return new BasicType(Invalid, ti, 8)
|
|
1566
|
+
}
|
|
1567
|
+
} else if (ti && ti.kind) {
|
|
1568
|
+
// Handle TypeInfo objects from the builtin type system
|
|
1569
|
+
const name = ti.name || 'unknown'
|
|
1570
|
+
switch (ti.kind) {
|
|
1571
|
+
case 'basic':
|
|
1572
|
+
// Map TypeScript type names to Go type names
|
|
1573
|
+
switch (name) {
|
|
1574
|
+
case 'string':
|
|
1575
|
+
return new BasicType(String, 'string', 16)
|
|
1576
|
+
case 'number':
|
|
1577
|
+
case 'int':
|
|
1578
|
+
case 'int32':
|
|
1579
|
+
case 'int64':
|
|
1580
|
+
return new BasicType(Int, name === 'number' ? 'int' : name, 8)
|
|
1581
|
+
case 'boolean':
|
|
1582
|
+
case 'bool':
|
|
1583
|
+
return new BasicType(Bool, 'bool', 1)
|
|
1584
|
+
case 'float64':
|
|
1585
|
+
return new BasicType(Float64, 'float64', 8)
|
|
1586
|
+
default:
|
|
1587
|
+
return new BasicType(Invalid, name, 8)
|
|
1588
|
+
}
|
|
1589
|
+
case 'slice':
|
|
1590
|
+
if (ti.elemType) {
|
|
1591
|
+
return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType))
|
|
1592
|
+
}
|
|
1593
|
+
return new SliceType(new BasicType(Invalid, 'unknown', 8))
|
|
1594
|
+
case 'pointer':
|
|
1595
|
+
if (ti.elemType) {
|
|
1596
|
+
return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType))
|
|
1597
|
+
}
|
|
1598
|
+
return new PointerType(new BasicType(Invalid, 'unknown', 8))
|
|
1599
|
+
case 'interface':
|
|
1600
|
+
return new InterfaceType(name)
|
|
1601
|
+
case 'struct':
|
|
1602
|
+
return new StructType(name, [])
|
|
1603
|
+
default:
|
|
1604
|
+
return new BasicType(Invalid, name, 8)
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
return new BasicType(Invalid, 'unknown', 8)
|
|
1608
|
+
}
|
|
716
1609
|
}
|
|
717
1610
|
|
|
718
1611
|
class ChannelType implements Type {
|
|
@@ -744,7 +1637,7 @@ class ChannelType implements Type {
|
|
|
744
1637
|
return 8
|
|
745
1638
|
}
|
|
746
1639
|
|
|
747
|
-
public Elem(): Type
|
|
1640
|
+
public Elem(): Type {
|
|
748
1641
|
return this._elemType
|
|
749
1642
|
}
|
|
750
1643
|
|
|
@@ -756,8 +1649,27 @@ class ChannelType implements Type {
|
|
|
756
1649
|
return ''
|
|
757
1650
|
}
|
|
758
1651
|
|
|
759
|
-
public
|
|
760
|
-
|
|
1652
|
+
public Name(): string {
|
|
1653
|
+
// Channel types are unnamed composite types
|
|
1654
|
+
return ''
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
public Field(_i: number): StructField {
|
|
1658
|
+
throw new Error('reflect: Field of non-struct type')
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
public Key(): Type {
|
|
1662
|
+
throw new Error('reflect: Key of non-map type')
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
public Implements(u: Type | null): boolean {
|
|
1666
|
+
if (!u) {
|
|
1667
|
+
return false
|
|
1668
|
+
}
|
|
1669
|
+
if (u.Kind() !== Interface) {
|
|
1670
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
1671
|
+
}
|
|
1672
|
+
return false
|
|
761
1673
|
}
|
|
762
1674
|
|
|
763
1675
|
public common?(): rtype {
|
|
@@ -767,6 +1679,26 @@ class ChannelType implements Type {
|
|
|
767
1679
|
public ChanDir(): ChanDir {
|
|
768
1680
|
return this._dir
|
|
769
1681
|
}
|
|
1682
|
+
|
|
1683
|
+
public OverflowInt(_x: number): boolean {
|
|
1684
|
+
throw new Error('reflect: call of reflect.Type.OverflowInt on chan Type')
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
public OverflowUint(_x: number): boolean {
|
|
1688
|
+
throw new Error('reflect: call of reflect.Type.OverflowUint on chan Type')
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
public OverflowFloat(_x: number): boolean {
|
|
1692
|
+
throw new Error('reflect: call of reflect.Type.OverflowFloat on chan Type')
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
public NumMethod(): number {
|
|
1696
|
+
return 0
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
public Bits(): number {
|
|
1700
|
+
throw new Error('reflect: call of reflect.Type.Bits on chan Type')
|
|
1701
|
+
}
|
|
770
1702
|
}
|
|
771
1703
|
|
|
772
1704
|
// Interface type implementation
|
|
@@ -785,8 +1717,8 @@ class InterfaceType implements Type {
|
|
|
785
1717
|
return 16
|
|
786
1718
|
}
|
|
787
1719
|
|
|
788
|
-
public Elem(): Type
|
|
789
|
-
|
|
1720
|
+
public Elem(): Type {
|
|
1721
|
+
throw new Error('reflect: Elem of invalid type')
|
|
790
1722
|
}
|
|
791
1723
|
|
|
792
1724
|
public NumField(): number {
|
|
@@ -797,24 +1729,70 @@ class InterfaceType implements Type {
|
|
|
797
1729
|
return ''
|
|
798
1730
|
}
|
|
799
1731
|
|
|
800
|
-
public Name
|
|
1732
|
+
public Name(): string {
|
|
801
1733
|
return this._name
|
|
802
1734
|
}
|
|
803
1735
|
|
|
804
|
-
public Field
|
|
805
|
-
|
|
1736
|
+
public Field(_i: number): StructField {
|
|
1737
|
+
throw new Error('reflect: Field of non-struct type')
|
|
806
1738
|
}
|
|
807
1739
|
|
|
808
|
-
public
|
|
1740
|
+
public Key(): Type {
|
|
1741
|
+
throw new Error('reflect: Key of non-map type')
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
public Implements(_u: Type | null): boolean {
|
|
809
1745
|
return false
|
|
810
1746
|
}
|
|
811
1747
|
|
|
812
1748
|
public common?(): rtype {
|
|
813
1749
|
return new rtype(this.Kind())
|
|
814
1750
|
}
|
|
1751
|
+
|
|
1752
|
+
public OverflowInt(_x: number): boolean {
|
|
1753
|
+
throw new Error(
|
|
1754
|
+
'reflect: call of reflect.Type.OverflowInt on interface Type',
|
|
1755
|
+
)
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
public OverflowUint(_x: number): boolean {
|
|
1759
|
+
throw new Error(
|
|
1760
|
+
'reflect: call of reflect.Type.OverflowUint on interface Type',
|
|
1761
|
+
)
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
public OverflowFloat(_x: number): boolean {
|
|
1765
|
+
throw new Error(
|
|
1766
|
+
'reflect: call of reflect.Type.OverflowFloat on interface Type',
|
|
1767
|
+
)
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
public NumMethod(): number {
|
|
1771
|
+
return 0
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
public Bits(): number {
|
|
1775
|
+
throw new Error('reflect: call of reflect.Type.Bits on interface Type')
|
|
1776
|
+
}
|
|
815
1777
|
}
|
|
816
1778
|
|
|
817
1779
|
function getTypeOf(value: ReflectValue): Type {
|
|
1780
|
+
// Check for typed nil before checking for plain null
|
|
1781
|
+
// Typed nils are created by $.typedNil() and have __goType and __isTypedNil properties
|
|
1782
|
+
if (value && typeof value === 'object' && (value as any).__isTypedNil) {
|
|
1783
|
+
const typeName = (value as any).__goType
|
|
1784
|
+
if (typeName && typeof typeName === 'string') {
|
|
1785
|
+
// Parse the type name to construct the appropriate Type
|
|
1786
|
+
// For pointer types like "*main.Stringer", extract the element type
|
|
1787
|
+
if (typeName.startsWith('*')) {
|
|
1788
|
+
const elemTypeName = typeName.slice(1) // Remove the '*' prefix
|
|
1789
|
+
// Create an InterfaceType for the element (works for interfaces and other types)
|
|
1790
|
+
const elemType = new InterfaceType(elemTypeName)
|
|
1791
|
+
return new PointerType(elemType)
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
818
1796
|
if (value === null || value === undefined) {
|
|
819
1797
|
return new BasicType(Interface, 'interface{}', 16)
|
|
820
1798
|
}
|
|
@@ -995,23 +1973,43 @@ function getTypeOf(value: ReflectValue): Type {
|
|
|
995
1973
|
value.constructor as { __typeInfo?: { name?: string } }
|
|
996
1974
|
).__typeInfo
|
|
997
1975
|
if (typeInfo && typeInfo.name) {
|
|
998
|
-
// Add package prefix for struct types if not already present
|
|
999
1976
|
const typeName =
|
|
1000
1977
|
typeInfo.name.includes('.') ?
|
|
1001
1978
|
typeInfo.name
|
|
1002
1979
|
: `main.${typeInfo.name}`
|
|
1003
|
-
|
|
1980
|
+
const regTypeInfo = builtinGetTypeByName(typeName)
|
|
1981
|
+
let fields: Array<{ name: string; type: Type; tag?: string }> = []
|
|
1982
|
+
if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
|
|
1983
|
+
fields = Object.entries(regTypeInfo.fields || {}).map(
|
|
1984
|
+
([name, fieldInfo]) => {
|
|
1985
|
+
// Check if fieldInfo is a StructFieldInfo with type and tag
|
|
1986
|
+
if (isStructFieldInfo(fieldInfo)) {
|
|
1987
|
+
return {
|
|
1988
|
+
name,
|
|
1989
|
+
type: StructType.createTypeFromFieldInfo(fieldInfo.type),
|
|
1990
|
+
tag: fieldInfo.tag,
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
// Otherwise it's just the type info directly (backwards compatible)
|
|
1994
|
+
return {
|
|
1995
|
+
name,
|
|
1996
|
+
type: StructType.createTypeFromFieldInfo(fieldInfo),
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
)
|
|
2000
|
+
}
|
|
2001
|
+
return new StructType(typeName, fields)
|
|
1004
2002
|
}
|
|
1005
2003
|
}
|
|
1006
2004
|
|
|
1007
2005
|
// Check if it has a constructor name we can use (fallback)
|
|
1008
2006
|
const constructorName = (value as object).constructor?.name
|
|
1009
2007
|
if (constructorName && constructorName !== 'Object') {
|
|
1010
|
-
return new StructType(constructorName)
|
|
2008
|
+
return new StructType(constructorName, [])
|
|
1011
2009
|
}
|
|
1012
2010
|
|
|
1013
2011
|
// Default to struct type for plain objects
|
|
1014
|
-
return new StructType('struct')
|
|
2012
|
+
return new StructType('struct', [])
|
|
1015
2013
|
}
|
|
1016
2014
|
default:
|
|
1017
2015
|
return new BasicType(Interface, 'interface{}', 16)
|
|
@@ -1035,11 +2033,12 @@ export function SliceOf(t: Type): Type {
|
|
|
1035
2033
|
return new SliceType(t)
|
|
1036
2034
|
}
|
|
1037
2035
|
|
|
1038
|
-
export function PointerTo(t: Type): Type {
|
|
2036
|
+
export function PointerTo(t: Type | null): Type | null {
|
|
2037
|
+
if (t === null) return null
|
|
1039
2038
|
return new PointerType(t)
|
|
1040
2039
|
}
|
|
1041
2040
|
|
|
1042
|
-
export function PtrTo(t: Type): Type {
|
|
2041
|
+
export function PtrTo(t: Type | null): Type | null {
|
|
1043
2042
|
return PointerTo(t) // PtrTo is an alias for PointerTo
|
|
1044
2043
|
}
|
|
1045
2044
|
|
|
@@ -1051,7 +2050,7 @@ export function ChanOf(dir: ChanDir, t: Type): Type {
|
|
|
1051
2050
|
return new ChannelType(t, dir)
|
|
1052
2051
|
}
|
|
1053
2052
|
|
|
1054
|
-
export function TypeFor
|
|
2053
|
+
export function TypeFor(): Type {
|
|
1055
2054
|
return new InterfaceType('interface{}')
|
|
1056
2055
|
}
|
|
1057
2056
|
|