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