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/builtin/type.ts
CHANGED
|
@@ -39,6 +39,14 @@ export interface MethodSignature {
|
|
|
39
39
|
returns: MethodArg[]
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Information about a struct field including type and optional tag
|
|
44
|
+
*/
|
|
45
|
+
export interface StructFieldInfo {
|
|
46
|
+
type: TypeInfo | string // The field's type
|
|
47
|
+
tag?: string // The struct field tag (e.g., `json:"name,omitempty"`)
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
/**
|
|
43
51
|
* Type information for struct types
|
|
44
52
|
*/
|
|
@@ -46,7 +54,7 @@ export interface StructTypeInfo extends BaseTypeInfo {
|
|
|
46
54
|
kind: TypeKind.Struct
|
|
47
55
|
methods: MethodSignature[] // Array of method signatures
|
|
48
56
|
ctor?: new (...args: any[]) => any
|
|
49
|
-
fields: Record<string, TypeInfo | string> // Field names and types for struct fields
|
|
57
|
+
fields: Record<string, TypeInfo | string | StructFieldInfo> // Field names and types for struct fields
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
/**
|
|
@@ -170,6 +178,21 @@ export function isChannelTypeInfo(info: TypeInfo): info is ChannelTypeInfo {
|
|
|
170
178
|
return info.kind === TypeKind.Channel
|
|
171
179
|
}
|
|
172
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Type guard to check if a field value is a StructFieldInfo (has 'type' property)
|
|
183
|
+
* vs a direct TypeInfo or string
|
|
184
|
+
*/
|
|
185
|
+
export function isStructFieldInfo(
|
|
186
|
+
fieldValue: TypeInfo | string | StructFieldInfo,
|
|
187
|
+
): fieldValue is StructFieldInfo {
|
|
188
|
+
return (
|
|
189
|
+
typeof fieldValue === 'object' &&
|
|
190
|
+
fieldValue !== null &&
|
|
191
|
+
'type' in fieldValue &&
|
|
192
|
+
!('kind' in fieldValue)
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
173
196
|
/**
|
|
174
197
|
* Comparable interface for Go's comparable constraint.
|
|
175
198
|
* Types that implement this can be compared with == and !=.
|
|
@@ -196,7 +219,7 @@ export const registerStructType = (
|
|
|
196
219
|
zeroValue: any,
|
|
197
220
|
methods: MethodSignature[],
|
|
198
221
|
ctor: new (...args: any[]) => any,
|
|
199
|
-
fields: Record<string, TypeInfo | string> = {},
|
|
222
|
+
fields: Record<string, TypeInfo | string | StructFieldInfo> = {},
|
|
200
223
|
): StructTypeInfo => {
|
|
201
224
|
const typeInfo: StructTypeInfo = {
|
|
202
225
|
name,
|
|
@@ -868,6 +891,110 @@ function matchesType(value: any, info: TypeInfo): boolean {
|
|
|
868
891
|
}
|
|
869
892
|
}
|
|
870
893
|
|
|
894
|
+
/**
|
|
895
|
+
* Compares a Go type string (from typedNil) with a TypeInfo object.
|
|
896
|
+
* Used to check if a typed nil pointer matches a type assertion target.
|
|
897
|
+
*
|
|
898
|
+
* @param typeStr The Go type string (e.g., "*struct{Name string}")
|
|
899
|
+
* @param typeInfo The normalized TypeInfo to compare against
|
|
900
|
+
* @returns True if the types match, false otherwise
|
|
901
|
+
*/
|
|
902
|
+
function compareTypeStringWithTypeInfo(
|
|
903
|
+
typeStr: string,
|
|
904
|
+
typeInfo: TypeInfo,
|
|
905
|
+
): boolean {
|
|
906
|
+
// For pointer types, strip the leading * and compare element types
|
|
907
|
+
if (isPointerTypeInfo(typeInfo)) {
|
|
908
|
+
if (!typeStr.startsWith('*')) {
|
|
909
|
+
return false
|
|
910
|
+
}
|
|
911
|
+
const elemStr = typeStr.slice(1)
|
|
912
|
+
const elemType = typeInfo.elemType
|
|
913
|
+
if (!elemType) {
|
|
914
|
+
return false
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
// Handle struct types
|
|
918
|
+
if (elemStr.startsWith('struct{')) {
|
|
919
|
+
const elemTypeInfo = normalizeTypeInfo(elemType)
|
|
920
|
+
if (!isStructTypeInfo(elemTypeInfo)) {
|
|
921
|
+
return false
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// For anonymous structs, compare the type string representation
|
|
925
|
+
// Extract field definitions from the string
|
|
926
|
+
const fieldsMatch = elemStr.match(/^struct{(.+)}$/)
|
|
927
|
+
if (!fieldsMatch) {
|
|
928
|
+
return false
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const fieldStr = fieldsMatch[1]
|
|
932
|
+
// Parse fields like "Name string" or "X int; Y string"
|
|
933
|
+
const fieldParts = fieldStr.split(';').map(s => s.trim())
|
|
934
|
+
const parsedFields: Record<string, string> = {}
|
|
935
|
+
|
|
936
|
+
for (const part of fieldParts) {
|
|
937
|
+
// Handle "Name string" format
|
|
938
|
+
const match = part.match(/^(\w+)\s+(.+)$/)
|
|
939
|
+
if (match) {
|
|
940
|
+
const [, fieldName, fieldType] = match
|
|
941
|
+
parsedFields[fieldName] = fieldType.trim()
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// Compare fields
|
|
946
|
+
const typeInfoFields = elemTypeInfo.fields || {}
|
|
947
|
+
const typeInfoFieldNames = Object.keys(typeInfoFields)
|
|
948
|
+
const parsedFieldNames = Object.keys(parsedFields)
|
|
949
|
+
|
|
950
|
+
if (typeInfoFieldNames.length !== parsedFieldNames.length) {
|
|
951
|
+
return false
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
// Check if all field names match and types are compatible
|
|
955
|
+
for (const fieldName of typeInfoFieldNames) {
|
|
956
|
+
if (!(fieldName in parsedFields)) {
|
|
957
|
+
return false
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
const fieldValue = typeInfoFields[fieldName]
|
|
961
|
+
// Handle StructFieldInfo (which has 'type' and optional 'tag' properties)
|
|
962
|
+
const fieldTypeInfo: TypeInfo | string = isStructFieldInfo(fieldValue)
|
|
963
|
+
? fieldValue.type
|
|
964
|
+
: fieldValue
|
|
965
|
+
const typeInfoFieldType = normalizeTypeInfo(fieldTypeInfo)
|
|
966
|
+
const parsedFieldType = parsedFields[fieldName]
|
|
967
|
+
|
|
968
|
+
// Compare basic types
|
|
969
|
+
if (isBasicTypeInfo(typeInfoFieldType)) {
|
|
970
|
+
const expectedTypeName = typeInfoFieldType.name || ''
|
|
971
|
+
// Map Go types to TypeScript/runtime types
|
|
972
|
+
if (expectedTypeName === 'string' && parsedFieldType === 'string') {
|
|
973
|
+
continue
|
|
974
|
+
}
|
|
975
|
+
if ((expectedTypeName === 'int' || expectedTypeName === 'number') &&
|
|
976
|
+
(parsedFieldType === 'int' || parsedFieldType === 'number')) {
|
|
977
|
+
continue
|
|
978
|
+
}
|
|
979
|
+
return false
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return true
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// Handle named types
|
|
987
|
+
if (typeof elemType === 'string') {
|
|
988
|
+
return elemStr === elemType
|
|
989
|
+
}
|
|
990
|
+
if (elemType.name) {
|
|
991
|
+
return elemStr === elemType.name
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
return false
|
|
996
|
+
}
|
|
997
|
+
|
|
871
998
|
/**
|
|
872
999
|
* Performs a type assertion on a value against a specified type.
|
|
873
1000
|
* Returns an object containing the value (cast to type T) and a boolean indicating success.
|
|
@@ -882,6 +1009,21 @@ export function typeAssert<T>(
|
|
|
882
1009
|
typeInfo: string | TypeInfo,
|
|
883
1010
|
): TypeAssertResult<T> {
|
|
884
1011
|
const normalizedType = normalizeTypeInfo(typeInfo)
|
|
1012
|
+
|
|
1013
|
+
// Handle typed nil pointers (created by typedNil() for conversions like (*T)(nil))
|
|
1014
|
+
if (typeof value === 'object' && value !== null && value.__isTypedNil) {
|
|
1015
|
+
// For typed nils, we need to compare the stored type with the expected type
|
|
1016
|
+
if (isPointerTypeInfo(normalizedType)) {
|
|
1017
|
+
// Parse the stored type string and compare with expected type
|
|
1018
|
+
const storedTypeStr = value.__goType as string
|
|
1019
|
+
if (compareTypeStringWithTypeInfo(storedTypeStr, normalizedType)) {
|
|
1020
|
+
return { value: null as unknown as T, ok: true }
|
|
1021
|
+
}
|
|
1022
|
+
return { value: null as unknown as T, ok: false }
|
|
1023
|
+
}
|
|
1024
|
+
return { value: null as unknown as T, ok: false }
|
|
1025
|
+
}
|
|
1026
|
+
|
|
885
1027
|
if (isPointerTypeInfo(normalizedType) && value === null) {
|
|
886
1028
|
return { value: null as unknown as T, ok: true }
|
|
887
1029
|
}
|
|
@@ -1061,3 +1203,18 @@ export function typeSwitch(
|
|
|
1061
1203
|
defaultCase()
|
|
1062
1204
|
}
|
|
1063
1205
|
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* Creates a typed nil pointer with type metadata for reflection.
|
|
1209
|
+
* This is used for type conversions like (*Interface)(nil) where we need
|
|
1210
|
+
* to preserve the pointer type information even though the value is null.
|
|
1211
|
+
*
|
|
1212
|
+
* @param typeName The full Go type name (e.g., "*main.Stringer")
|
|
1213
|
+
* @returns An object that represents a typed nil with reflection metadata
|
|
1214
|
+
*/
|
|
1215
|
+
export function typedNil(typeName: string): any {
|
|
1216
|
+
return Object.assign(Object.create(null), {
|
|
1217
|
+
__goType: typeName,
|
|
1218
|
+
__isTypedNil: true,
|
|
1219
|
+
})
|
|
1220
|
+
}
|
package/gs/builtin/varRef.ts
CHANGED
|
@@ -5,13 +5,19 @@
|
|
|
5
5
|
* var myVariable int // variable referenced
|
|
6
6
|
* myOtherVar := &myVariable
|
|
7
7
|
*/
|
|
8
|
-
export type VarRef<T> = { value: T }
|
|
8
|
+
export type VarRef<T> = { value: T; __isVarRef?: true }
|
|
9
9
|
|
|
10
10
|
/** Wrap a non-null T in a variable reference. */
|
|
11
11
|
export function varRef<T>(v: T): VarRef<T> {
|
|
12
12
|
// We create a new object wrapper for every varRef call to ensure
|
|
13
13
|
// distinct pointer identity, crucial for pointer comparisons (p1 == p2).
|
|
14
|
-
|
|
14
|
+
// The __isVarRef marker allows the reflect system to identify this as a pointer type.
|
|
15
|
+
return { value: v, __isVarRef: true }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Check if a value is a VarRef (pointer) */
|
|
19
|
+
export function isVarRef(v: unknown): v is VarRef<unknown> {
|
|
20
|
+
return v !== null && typeof v === 'object' && (v as any).__isVarRef === true
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
/** Dereference a variable reference, throws on null → simulates Go panic. */
|
package/gs/bytes/reader.gs.ts
CHANGED
|
@@ -224,7 +224,7 @@ export class Reader {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
// NewReader returns a new [Reader] reading from b.
|
|
227
|
-
export function NewReader(b: $.Bytes): Reader
|
|
228
|
-
return new Reader({})
|
|
227
|
+
export function NewReader(b: $.Bytes): Reader {
|
|
228
|
+
return new Reader({s: $.normalizeBytes(b), i: 0, prevRune: -1})
|
|
229
229
|
}
|
|
230
230
|
|
package/gs/math/hypot.gs.test.ts
CHANGED
|
@@ -43,7 +43,9 @@ describe('Hypot', () => {
|
|
|
43
43
|
it('should handle very large values without overflow', () => {
|
|
44
44
|
const large = 1e150
|
|
45
45
|
const result = Hypot(large, large)
|
|
46
|
-
|
|
46
|
+
const expected = large * Math.sqrt(2)
|
|
47
|
+
// Use relative tolerance for very large numbers
|
|
48
|
+
expect(Math.abs(result - expected) / expected).toBeLessThan(1e-10)
|
|
47
49
|
expect(IsInf(result, 0)).toBe(false)
|
|
48
50
|
})
|
|
49
51
|
|
package/gs/math/pow10.gs.test.ts
CHANGED
|
@@ -26,10 +26,11 @@ describe('Pow10', () => {
|
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
it('should handle large positive exponents', () => {
|
|
29
|
-
|
|
30
|
-
expect(Pow10(
|
|
31
|
-
expect(Pow10(
|
|
32
|
-
expect(Pow10(
|
|
29
|
+
// Use relative tolerance for very large numbers
|
|
30
|
+
expect(Math.abs(Pow10(100) - 1e100) / 1e100).toBeLessThan(1e-10)
|
|
31
|
+
expect(Math.abs(Pow10(200) - 1e200) / 1e200).toBeLessThan(1e-10)
|
|
32
|
+
expect(Math.abs(Pow10(300) - 1e300) / 1e300).toBeLessThan(1e-10)
|
|
33
|
+
expect(Math.abs(Pow10(308) - 1e308) / 1e308).toBeLessThan(1e-10)
|
|
33
34
|
expect(Pow10(309)).toBe(Number.POSITIVE_INFINITY)
|
|
34
35
|
expect(Pow10(400)).toBe(Number.POSITIVE_INFINITY)
|
|
35
36
|
})
|
package/gs/reflect/index.ts
CHANGED
|
@@ -35,19 +35,20 @@ export { Swapper } from './swapper.js'
|
|
|
35
35
|
// Export new types and constants
|
|
36
36
|
export {
|
|
37
37
|
StructTag,
|
|
38
|
+
StructTag_Get,
|
|
38
39
|
StructField,
|
|
39
40
|
ValueError,
|
|
40
|
-
SelectDir,
|
|
41
41
|
SelectSend,
|
|
42
42
|
SelectRecv,
|
|
43
43
|
SelectDefault,
|
|
44
|
+
SelectCase,
|
|
44
45
|
bitVector,
|
|
45
46
|
} from './types.js'
|
|
46
47
|
export type {
|
|
47
48
|
uintptr,
|
|
48
49
|
Pointer,
|
|
49
50
|
Method,
|
|
50
|
-
|
|
51
|
+
SelectDir,
|
|
51
52
|
SliceHeader,
|
|
52
53
|
StringHeader,
|
|
53
54
|
MapIter,
|
package/gs/reflect/map.test.ts
CHANGED
|
@@ -11,20 +11,21 @@ describe('MapIter', () => {
|
|
|
11
11
|
const iter = new MapIter<string, number>(map)
|
|
12
12
|
|
|
13
13
|
expect(iter.current?.done === false).toBe(true)
|
|
14
|
-
|
|
15
|
-
expect(iter.
|
|
14
|
+
// Key() and Value() return reflect.Value objects now
|
|
15
|
+
expect(iter.Key().Interface()).toBe('one')
|
|
16
|
+
expect(iter.Value().Interface()).toBe(1)
|
|
16
17
|
|
|
17
18
|
expect(iter.Next()).toBe(true)
|
|
18
19
|
expect(iter.current?.done === false).toBe(true)
|
|
19
|
-
expect(
|
|
20
|
-
expect(
|
|
20
|
+
expect(iter.Key().Kind()).toBe(24) // String kind
|
|
21
|
+
expect(iter.Value().Kind()).toBe(2) // Int kind
|
|
21
22
|
|
|
22
23
|
const newMap = new Map<string, number>()
|
|
23
24
|
newMap.set('reset', 100)
|
|
24
25
|
iter.Reset(newMap)
|
|
25
26
|
|
|
26
27
|
expect(iter.current?.done === false).toBe(true)
|
|
27
|
-
expect(iter.Key()).toBe('reset')
|
|
28
|
-
expect(iter.Value()).toBe(100)
|
|
28
|
+
expect(iter.Key().Interface()).toBe('reset')
|
|
29
|
+
expect(iter.Value().Interface()).toBe(100)
|
|
29
30
|
})
|
|
30
31
|
})
|
package/gs/reflect/map.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type, Kind, Value, Map as MapKind } from './type.js'
|
|
1
|
+
import { Type, Kind, Value, Map as MapKind, StructField, TypeOf } from './type.js'
|
|
2
2
|
|
|
3
3
|
// Simple MapOf implementation using JavaScript Map
|
|
4
4
|
export function MapOf(key: Type, elem: Type): Type {
|
|
@@ -20,26 +20,66 @@ class MapType implements Type {
|
|
|
20
20
|
return MapKind // Map kind
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
public Name(): string {
|
|
24
|
+
return '' // Map types are unnamed composite types
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
public Size(): number {
|
|
24
28
|
return 8 // pointer size
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
public Elem(): Type
|
|
31
|
+
public Elem(): Type {
|
|
28
32
|
return this._elemType
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
public Key(): Type
|
|
35
|
+
public Key(): Type {
|
|
32
36
|
return this._keyType
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
public NumField(): number {
|
|
36
40
|
return 0
|
|
37
41
|
}
|
|
42
|
+
|
|
43
|
+
public Field(_i: number): StructField {
|
|
44
|
+
throw new Error('reflect: Field of non-struct type map')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public Implements(u: Type | null): boolean {
|
|
48
|
+
if (!u) {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
if (u.Kind() !== 20) {
|
|
52
|
+
// Interface kind
|
|
53
|
+
throw new Error('reflect: non-interface type passed to Type.Implements')
|
|
54
|
+
}
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public OverflowInt(_x: number): boolean {
|
|
59
|
+
throw new Error('reflect: OverflowInt of non-integer type map')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public OverflowUint(_x: number): boolean {
|
|
63
|
+
throw new Error('reflect: OverflowUint of non-integer type map')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public OverflowFloat(_x: number): boolean {
|
|
67
|
+
throw new Error('reflect: OverflowFloat of non-float type map')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public NumMethod(): number {
|
|
71
|
+
return 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public Bits(): number {
|
|
75
|
+
throw new Error('reflect: Bits of non-sized type map')
|
|
76
|
+
}
|
|
38
77
|
}
|
|
39
78
|
|
|
40
79
|
/**
|
|
41
80
|
* MapIter provides an iterator interface for Go maps.
|
|
42
81
|
* It wraps a JavaScript Map iterator and provides methods to iterate over key-value pairs.
|
|
82
|
+
* Returns reflect.Value for Key() and Value() to match Go's reflect.MapIter.
|
|
43
83
|
* @template K - The type of keys in the map
|
|
44
84
|
* @template V - The type of values in the map
|
|
45
85
|
*/
|
|
@@ -57,12 +97,14 @@ export class MapIter<K = unknown, V = unknown> {
|
|
|
57
97
|
return !this.current.done
|
|
58
98
|
}
|
|
59
99
|
|
|
60
|
-
public Key():
|
|
61
|
-
|
|
100
|
+
public Key(): Value {
|
|
101
|
+
const rawKey = this.current?.value?.[0] ?? null
|
|
102
|
+
return new Value(rawKey, TypeOf(rawKey))
|
|
62
103
|
}
|
|
63
104
|
|
|
64
|
-
public Value():
|
|
65
|
-
|
|
105
|
+
public Value(): Value {
|
|
106
|
+
const rawVal = this.current?.value?.[1] ?? null
|
|
107
|
+
return new Value(rawVal, TypeOf(rawVal))
|
|
66
108
|
}
|
|
67
109
|
|
|
68
110
|
public Reset(m: Map<K, V>): void {
|