goscript 0.1.4 → 0.2.1

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.
Files changed (295) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript-wasm/main.go +38 -6
  8. package/compiler/compile-request.go +12 -9
  9. package/compiler/compliance_test.go +0 -1
  10. package/compiler/config.go +2 -0
  11. package/compiler/diagnostic.go +104 -12
  12. package/compiler/diagnostic_test.go +106 -0
  13. package/compiler/gotest/request.go +28 -0
  14. package/compiler/gotest/runner.go +354 -44
  15. package/compiler/gotest/runner_test.go +293 -1
  16. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  17. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  18. package/compiler/index.test.ts +23 -0
  19. package/compiler/lowered-program.go +33 -24
  20. package/compiler/lowering.go +746 -194
  21. package/compiler/lowering_bench_test.go +42 -27
  22. package/compiler/lowering_internal_test.go +18 -0
  23. package/compiler/override-facts.go +15 -0
  24. package/compiler/override-parity-verifier.go +450 -0
  25. package/compiler/override-parity.go +122 -0
  26. package/compiler/override-registry_test.go +559 -0
  27. package/compiler/protobuf-ts-binding.go +567 -0
  28. package/compiler/protobuf-ts-binding_test.go +402 -0
  29. package/compiler/runtime-contract.go +4 -0
  30. package/compiler/runtime-contract_test.go +2 -0
  31. package/compiler/semantic-model-types.go +9 -4
  32. package/compiler/semantic-model.go +282 -70
  33. package/compiler/semantic-model_test.go +82 -1
  34. package/compiler/service.go +21 -1
  35. package/compiler/skeleton_test.go +118 -10
  36. package/compiler/typescript-emitter.go +128 -13
  37. package/compiler/wasm/compile_test.go +37 -4
  38. package/compiler/{wasm_api.go → wasm-api.go} +57 -7
  39. package/dist/gs/builtin/hostio.js +5 -0
  40. package/dist/gs/builtin/hostio.js.map +1 -1
  41. package/dist/gs/builtin/slice.d.ts +13 -2
  42. package/dist/gs/builtin/slice.js +187 -6
  43. package/dist/gs/builtin/slice.js.map +1 -1
  44. package/dist/gs/builtin/type.d.ts +13 -5
  45. package/dist/gs/builtin/type.js +153 -60
  46. package/dist/gs/builtin/type.js.map +1 -1
  47. package/dist/gs/builtin/varRef.d.ts +11 -0
  48. package/dist/gs/builtin/varRef.js +57 -2
  49. package/dist/gs/builtin/varRef.js.map +1 -1
  50. package/dist/gs/bytes/buffer.gs.js +1 -1
  51. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  52. package/dist/gs/bytes/reader.gs.js +1 -1
  53. package/dist/gs/bytes/reader.gs.js.map +1 -1
  54. package/dist/gs/compress/zlib/index.d.ts +10 -3
  55. package/dist/gs/compress/zlib/index.js +50 -16
  56. package/dist/gs/compress/zlib/index.js.map +1 -1
  57. package/dist/gs/encoding/json/index.d.ts +114 -0
  58. package/dist/gs/encoding/json/index.js +544 -36
  59. package/dist/gs/encoding/json/index.js.map +1 -1
  60. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
  61. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
  62. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  63. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +1 -0
  64. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
  65. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  66. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  67. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  68. package/dist/gs/go/scanner/index.d.ts +2 -0
  69. package/dist/gs/go/scanner/index.js +29 -5
  70. package/dist/gs/go/scanner/index.js.map +1 -1
  71. package/dist/gs/go/token/index.js +22 -6
  72. package/dist/gs/go/token/index.js.map +1 -1
  73. package/dist/gs/hash/index.d.ts +6 -0
  74. package/dist/gs/hash/index.js +20 -0
  75. package/dist/gs/hash/index.js.map +1 -1
  76. package/dist/gs/internal/byteorder/index.js +2 -2
  77. package/dist/gs/internal/byteorder/index.js.map +1 -1
  78. package/dist/gs/internal/goarch/index.d.ts +43 -3
  79. package/dist/gs/internal/goarch/index.js +42 -10
  80. package/dist/gs/internal/goarch/index.js.map +1 -1
  81. package/dist/gs/io/fs/fs.js +26 -14
  82. package/dist/gs/io/fs/fs.js.map +1 -1
  83. package/dist/gs/io/fs/readdir.js +4 -2
  84. package/dist/gs/io/fs/readdir.js.map +1 -1
  85. package/dist/gs/io/fs/sub.js +8 -1
  86. package/dist/gs/io/fs/sub.js.map +1 -1
  87. package/dist/gs/io/io.d.ts +2 -0
  88. package/dist/gs/io/io.js.map +1 -1
  89. package/dist/gs/math/bits/index.d.ts +5 -0
  90. package/dist/gs/math/bits/index.js +16 -4
  91. package/dist/gs/math/bits/index.js.map +1 -1
  92. package/dist/gs/mime/index.d.ts +16 -0
  93. package/dist/gs/mime/index.js +315 -6
  94. package/dist/gs/mime/index.js.map +1 -1
  95. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  96. package/dist/gs/net/http/httptest/index.js +85 -6
  97. package/dist/gs/net/http/httptest/index.js.map +1 -1
  98. package/dist/gs/net/http/index.d.ts +300 -5
  99. package/dist/gs/net/http/index.js +1598 -58
  100. package/dist/gs/net/http/index.js.map +1 -1
  101. package/dist/gs/os/dir_unix.gs.js +1 -1
  102. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  103. package/dist/gs/os/error.gs.js +1 -1
  104. package/dist/gs/os/error.gs.js.map +1 -1
  105. package/dist/gs/os/exec.gs.d.ts +1 -0
  106. package/dist/gs/os/exec.gs.js +4 -8
  107. package/dist/gs/os/exec.gs.js.map +1 -1
  108. package/dist/gs/os/exec_posix.gs.js +1 -1
  109. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  110. package/dist/gs/os/index.d.ts +1 -1
  111. package/dist/gs/os/index.js +1 -1
  112. package/dist/gs/os/index.js.map +1 -1
  113. package/dist/gs/os/proc.gs.d.ts +4 -0
  114. package/dist/gs/os/proc.gs.js +12 -6
  115. package/dist/gs/os/proc.gs.js.map +1 -1
  116. package/dist/gs/os/root_js.gs.js +1 -1
  117. package/dist/gs/os/root_js.gs.js.map +1 -1
  118. package/dist/gs/os/types.gs.js +1 -1
  119. package/dist/gs/os/types.gs.js.map +1 -1
  120. package/dist/gs/os/types_js.gs.js +1 -1
  121. package/dist/gs/os/types_js.gs.js.map +1 -1
  122. package/dist/gs/os/types_unix.gs.js +1 -1
  123. package/dist/gs/os/types_unix.gs.js.map +1 -1
  124. package/dist/gs/path/path.js +11 -7
  125. package/dist/gs/path/path.js.map +1 -1
  126. package/dist/gs/reflect/index.d.ts +5 -4
  127. package/dist/gs/reflect/index.js +4 -3
  128. package/dist/gs/reflect/index.js.map +1 -1
  129. package/dist/gs/reflect/map.js +15 -0
  130. package/dist/gs/reflect/map.js.map +1 -1
  131. package/dist/gs/reflect/type.d.ts +25 -6
  132. package/dist/gs/reflect/type.js +1475 -228
  133. package/dist/gs/reflect/type.js.map +1 -1
  134. package/dist/gs/reflect/types.d.ts +14 -6
  135. package/dist/gs/reflect/types.js +35 -1
  136. package/dist/gs/reflect/types.js.map +1 -1
  137. package/dist/gs/reflect/value.d.ts +1 -0
  138. package/dist/gs/reflect/value.js +83 -41
  139. package/dist/gs/reflect/value.js.map +1 -1
  140. package/dist/gs/reflect/visiblefields.js +4 -140
  141. package/dist/gs/reflect/visiblefields.js.map +1 -1
  142. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  143. package/dist/gs/runtime/pprof/index.js +50 -30
  144. package/dist/gs/runtime/pprof/index.js.map +1 -1
  145. package/dist/gs/runtime/runtime.js +5 -4
  146. package/dist/gs/runtime/runtime.js.map +1 -1
  147. package/dist/gs/runtime/trace/index.js +5 -19
  148. package/dist/gs/runtime/trace/index.js.map +1 -1
  149. package/dist/gs/strconv/atoi.gs.js +1 -1
  150. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  151. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  152. package/dist/gs/strconv/complex.gs.js +148 -0
  153. package/dist/gs/strconv/complex.gs.js.map +1 -0
  154. package/dist/gs/strconv/index.d.ts +1 -0
  155. package/dist/gs/strconv/index.js +1 -0
  156. package/dist/gs/strconv/index.js.map +1 -1
  157. package/dist/gs/strings/builder.js +1 -1
  158. package/dist/gs/strings/reader.js +9 -5
  159. package/dist/gs/strings/reader.js.map +1 -1
  160. package/dist/gs/strings/replace.js +15 -7
  161. package/dist/gs/strings/replace.js.map +1 -1
  162. package/dist/gs/strings/strings.d.ts +5 -0
  163. package/dist/gs/strings/strings.js +57 -5
  164. package/dist/gs/strings/strings.js.map +1 -1
  165. package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
  166. package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
  167. package/dist/gs/sync/atomic/type.gs.js +9 -9
  168. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  169. package/dist/gs/sync/atomic/value.gs.js +2 -2
  170. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  171. package/dist/gs/syscall/env.js +22 -14
  172. package/dist/gs/syscall/env.js.map +1 -1
  173. package/dist/gs/testing/testing.js +55 -13
  174. package/dist/gs/testing/testing.js.map +1 -1
  175. package/dist/gs/time/time.d.ts +24 -1
  176. package/dist/gs/time/time.js +43 -3
  177. package/dist/gs/time/time.js.map +1 -1
  178. package/dist/gs/unique/index.js +7 -1
  179. package/dist/gs/unique/index.js.map +1 -1
  180. package/go.mod +3 -3
  181. package/go.sum +16 -0
  182. package/gs/builtin/hostio.test.ts +16 -0
  183. package/gs/builtin/hostio.ts +7 -0
  184. package/gs/builtin/runtime-contract.test.ts +246 -21
  185. package/gs/builtin/slice.ts +269 -24
  186. package/gs/builtin/type.ts +226 -59
  187. package/gs/builtin/varRef.ts +85 -2
  188. package/gs/bytes/buffer.gs.ts +1 -1
  189. package/gs/bytes/reader.gs.ts +1 -1
  190. package/gs/compress/zlib/index.test.ts +62 -1
  191. package/gs/compress/zlib/index.ts +53 -16
  192. package/gs/compress/zlib/parity.json +51 -0
  193. package/gs/encoding/json/index.test.ts +360 -6
  194. package/gs/encoding/json/index.ts +679 -38
  195. package/gs/encoding/json/parity.json +81 -0
  196. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
  197. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
  198. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
  199. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
  200. package/gs/github.com/pkg/errors/errors.ts +54 -30
  201. package/gs/go/scanner/index.test.ts +39 -56
  202. package/gs/go/scanner/index.ts +33 -5
  203. package/gs/go/scanner/parity.json +27 -0
  204. package/gs/go/token/index.ts +22 -6
  205. package/gs/hash/index.test.ts +20 -33
  206. package/gs/hash/index.ts +28 -0
  207. package/gs/hash/parity.json +21 -0
  208. package/gs/internal/byteorder/index.test.ts +2 -2
  209. package/gs/internal/byteorder/index.ts +2 -2
  210. package/gs/internal/goarch/index.test.ts +32 -0
  211. package/gs/internal/goarch/index.ts +45 -13
  212. package/gs/internal/goarch/parity.json +144 -0
  213. package/gs/io/fs/fs.ts +26 -14
  214. package/gs/io/fs/readdir.ts +4 -4
  215. package/gs/io/fs/sub.ts +8 -1
  216. package/gs/io/io.ts +1 -0
  217. package/gs/io/parity.json +162 -0
  218. package/gs/math/bits/index.test.ts +14 -1
  219. package/gs/math/bits/index.ts +23 -4
  220. package/gs/math/bits/parity.json +156 -0
  221. package/gs/mime/index.test.ts +90 -0
  222. package/gs/mime/index.ts +369 -6
  223. package/gs/mime/parity.json +36 -0
  224. package/gs/net/http/httptest/index.test.ts +98 -2
  225. package/gs/net/http/httptest/index.ts +101 -6
  226. package/gs/net/http/httptest/parity.json +15 -0
  227. package/gs/net/http/index.test.ts +781 -12
  228. package/gs/net/http/index.ts +1860 -139
  229. package/gs/net/http/meta.json +16 -1
  230. package/gs/net/http/parity.json +193 -0
  231. package/gs/os/dir_unix.gs.ts +1 -1
  232. package/gs/os/error.gs.ts +1 -1
  233. package/gs/os/exec.gs.ts +4 -8
  234. package/gs/os/exec_posix.gs.ts +1 -1
  235. package/gs/os/index.test.ts +9 -0
  236. package/gs/os/index.ts +1 -0
  237. package/gs/os/parity.json +9 -0
  238. package/gs/os/proc.gs.ts +18 -5
  239. package/gs/os/proc.test.ts +26 -0
  240. package/gs/os/root_js.gs.ts +1 -1
  241. package/gs/os/types.gs.ts +1 -1
  242. package/gs/os/types_js.gs.ts +1 -1
  243. package/gs/os/types_unix.gs.ts +1 -1
  244. package/gs/path/path.ts +11 -7
  245. package/gs/reflect/field.test.ts +37 -15
  246. package/gs/reflect/function-types.test.ts +518 -22
  247. package/gs/reflect/index.ts +8 -6
  248. package/gs/reflect/map.ts +20 -0
  249. package/gs/reflect/meta.json +6 -4
  250. package/gs/reflect/parity.json +234 -0
  251. package/gs/reflect/sliceat.test.ts +156 -0
  252. package/gs/reflect/structof.test.ts +401 -0
  253. package/gs/reflect/type.ts +1961 -317
  254. package/gs/reflect/typefor.test.ts +530 -10
  255. package/gs/reflect/types.ts +43 -18
  256. package/gs/reflect/value.ts +105 -45
  257. package/gs/reflect/visiblefields.ts +5 -168
  258. package/gs/runtime/parity.json +24 -0
  259. package/gs/runtime/pprof/index.test.ts +29 -7
  260. package/gs/runtime/pprof/index.ts +56 -30
  261. package/gs/runtime/pprof/parity.json +27 -0
  262. package/gs/runtime/runtime.test.ts +3 -1
  263. package/gs/runtime/runtime.ts +4 -3
  264. package/gs/runtime/trace/index.test.ts +5 -3
  265. package/gs/runtime/trace/index.ts +8 -20
  266. package/gs/runtime/trace/parity.json +36 -0
  267. package/gs/strconv/atoi.gs.ts +1 -1
  268. package/gs/strconv/complex.gs.ts +174 -0
  269. package/gs/strconv/complex.test.ts +65 -0
  270. package/gs/strconv/index.ts +1 -0
  271. package/gs/strconv/parity.json +120 -0
  272. package/gs/strings/builder.ts +1 -1
  273. package/gs/strings/parity.json +186 -0
  274. package/gs/strings/reader.ts +9 -5
  275. package/gs/strings/replace.ts +15 -7
  276. package/gs/strings/strings.test.ts +22 -2
  277. package/gs/strings/strings.ts +64 -6
  278. package/gs/sync/atomic/doc_64.gs.ts +6 -7
  279. package/gs/sync/atomic/doc_64.test.ts +43 -0
  280. package/gs/sync/atomic/type.gs.ts +9 -9
  281. package/gs/sync/atomic/value.gs.ts +2 -2
  282. package/gs/syscall/env.ts +29 -14
  283. package/gs/testing/testing.test.ts +67 -0
  284. package/gs/testing/testing.ts +87 -19
  285. package/gs/time/parity.json +225 -0
  286. package/gs/time/time.test.ts +20 -2
  287. package/gs/time/time.ts +49 -7
  288. package/gs/unique/index.ts +7 -1
  289. package/package.json +4 -2
  290. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  291. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
  292. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  293. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
  294. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
  295. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
@@ -45,8 +45,14 @@ export interface MethodSignature {
45
45
  */
46
46
  export interface StructFieldInfo {
47
47
  type: TypeInfo | string // The field's type
48
- name?: string // The Go field name when it differs from the TypeScript key.
48
+ name: string // The Go field name.
49
+ key?: string // The runtime storage key on generated or dynamic values.
49
50
  tag?: string // The struct field tag (e.g., `json:"name,omitempty"`)
51
+ pkgPath?: string // Non-empty for unexported fields.
52
+ anonymous?: boolean
53
+ index?: number[]
54
+ offset?: number
55
+ exported?: boolean
50
56
  }
51
57
 
52
58
  /**
@@ -56,7 +62,7 @@ export interface StructTypeInfo extends BaseTypeInfo {
56
62
  kind: TypeKind.Struct
57
63
  methods: MethodSignature[] // Array of method signatures
58
64
  ctor?: new (...args: any[]) => any
59
- fields: Record<string, TypeInfo | string | StructFieldInfo> // Field names and types for struct fields
65
+ fields: StructFieldInfo[] // Ordered field descriptors.
60
66
  }
61
67
 
62
68
  /**
@@ -185,12 +191,13 @@ export function isChannelTypeInfo(info: TypeInfo): info is ChannelTypeInfo {
185
191
  * vs a direct TypeInfo or string
186
192
  */
187
193
  export function isStructFieldInfo(
188
- fieldValue: TypeInfo | string | StructFieldInfo,
194
+ fieldValue: unknown,
189
195
  ): fieldValue is StructFieldInfo {
190
196
  return (
191
197
  typeof fieldValue === 'object' &&
192
198
  fieldValue !== null &&
193
199
  'type' in fieldValue &&
200
+ 'name' in fieldValue &&
194
201
  !('kind' in fieldValue)
195
202
  )
196
203
  }
@@ -234,7 +241,7 @@ export const registerStructType = (
234
241
  zeroValue: any,
235
242
  methods: MethodSignature[],
236
243
  ctor: new (...args: any[]) => any,
237
- fields: Record<string, TypeInfo | string | StructFieldInfo> = {},
244
+ fields: StructFieldInfo[] = [],
238
245
  ): StructTypeInfo => {
239
246
  const typeInfo: StructTypeInfo = {
240
247
  name,
@@ -327,26 +334,62 @@ function goTypeMatchesTypeInfo(goType: string, info: TypeInfo): boolean {
327
334
  )
328
335
  }
329
336
 
337
+ interface TypeInfoComparisonState {
338
+ seenPairs: Set<string>
339
+ objectIDs: WeakMap<object, number>
340
+ nextObjectID: number
341
+ }
342
+
343
+ function newTypeInfoComparisonState(): TypeInfoComparisonState {
344
+ return {
345
+ seenPairs: new Set(),
346
+ objectIDs: new WeakMap(),
347
+ nextObjectID: 0,
348
+ }
349
+ }
350
+
351
+ function typeInfoComparisonID(
352
+ raw: string | TypeInfo,
353
+ normalized: TypeInfo,
354
+ state: TypeInfoComparisonState,
355
+ ): string {
356
+ const runtimeName = typeInfoRuntimeName(normalized)
357
+ if (runtimeName !== undefined) {
358
+ return `${normalized.kind}:${runtimeName}`
359
+ }
360
+ if (typeof raw === 'string') {
361
+ return `string:${raw}`
362
+ }
363
+ const existing = state.objectIDs.get(raw)
364
+ if (existing !== undefined) {
365
+ return `object:${existing}`
366
+ }
367
+ const id = state.nextObjectID
368
+ state.nextObjectID += 1
369
+ state.objectIDs.set(raw, id)
370
+ return `object:${id}`
371
+ }
372
+
330
373
  function compareOptionalTypeInfo(
331
- type1?: string | TypeInfo,
332
- type2?: string | TypeInfo,
374
+ type1: string | TypeInfo | undefined,
375
+ type2: string | TypeInfo | undefined,
376
+ state: TypeInfoComparisonState,
333
377
  ): boolean {
334
378
  if (type1 === undefined && type2 === undefined) return true
335
379
  if (type1 === undefined || type2 === undefined) return false
336
- // Assuming areTypeInfosIdentical will handle normalization if needed,
337
- // but type1 and type2 here are expected to be direct fields from TypeInfo objects.
338
- return areTypeInfosIdentical(type1, type2)
380
+ return areTypeInfosIdenticalWithSeen(type1, type2, state)
339
381
  }
340
382
 
341
383
  function areFuncParamOrResultArraysIdentical(
342
384
  arr1?: (string | TypeInfo)[],
343
385
  arr2?: (string | TypeInfo)[],
386
+ state = newTypeInfoComparisonState(),
344
387
  ): boolean {
345
388
  if (arr1 === undefined && arr2 === undefined) return true
346
389
  if (arr1 === undefined || arr2 === undefined) return false
347
390
  if (arr1.length !== arr2.length) return false
348
- for (let i = 0; i < arr1.length; i++) {
349
- if (!areTypeInfosIdentical(arr1[i], arr2[i])) {
391
+ for (const [index, typeInfo] of arr1.entries()) {
392
+ if (!areTypeInfosIdenticalWithSeen(typeInfo, arr2[index], state)) {
350
393
  return false
351
394
  }
352
395
  }
@@ -356,58 +399,75 @@ function areFuncParamOrResultArraysIdentical(
356
399
  function areFuncSignaturesIdentical(
357
400
  func1: FunctionTypeInfo,
358
401
  func2: FunctionTypeInfo,
402
+ state = newTypeInfoComparisonState(),
359
403
  ): boolean {
360
404
  if ((func1.isVariadic || false) !== (func2.isVariadic || false)) {
361
405
  return false
362
406
  }
363
407
  return (
364
- areFuncParamOrResultArraysIdentical(func1.params, func2.params) &&
365
- areFuncParamOrResultArraysIdentical(func1.results, func2.results)
408
+ areFuncParamOrResultArraysIdentical(func1.params, func2.params, state) &&
409
+ areFuncParamOrResultArraysIdentical(func1.results, func2.results, state)
366
410
  )
367
411
  }
368
412
 
369
413
  export function areTypeInfosIdentical(
370
414
  type1InfoOrName: string | TypeInfo,
371
415
  type2InfoOrName: string | TypeInfo,
416
+ ): boolean {
417
+ return areTypeInfosIdenticalWithSeen(
418
+ type1InfoOrName,
419
+ type2InfoOrName,
420
+ newTypeInfoComparisonState(),
421
+ )
422
+ }
423
+
424
+ function areTypeInfosIdenticalWithSeen(
425
+ type1InfoOrName: string | TypeInfo,
426
+ type2InfoOrName: string | TypeInfo,
427
+ state: TypeInfoComparisonState,
372
428
  ): boolean {
373
429
  const t1Norm = normalizeTypeInfo(type1InfoOrName)
374
430
  const t2Norm = normalizeTypeInfo(type2InfoOrName)
375
431
 
376
- if (t1Norm === t2Norm) return true // Object identity
432
+ if (t1Norm === t2Norm) return true
377
433
  if (t1Norm.kind !== t2Norm.kind) return false
378
434
 
379
- // If types have names, the names must match for identity.
380
- // If one has a name and the other doesn't, they are not identical.
435
+ if ((t1Norm.typeName ?? '') !== (t2Norm.typeName ?? '')) return false
381
436
  if (t1Norm.name !== t2Norm.name) return false
382
437
 
383
- // If both are named and names match, for Basic, Struct, Interface, this is sufficient for identity.
384
438
  if (
385
- t1Norm.name !== undefined /* && t2Norm.name is also defined and equal */
386
- ) {
387
- if (
388
- t1Norm.kind === TypeKind.Basic ||
439
+ t1Norm.name !== undefined &&
440
+ (t1Norm.kind === TypeKind.Basic ||
389
441
  t1Norm.kind === TypeKind.Struct ||
390
- t1Norm.kind === TypeKind.Interface
391
- ) {
392
- return true
393
- }
442
+ t1Norm.kind === TypeKind.Interface)
443
+ ) {
444
+ return true
445
+ }
446
+
447
+ const pairKey = `${typeInfoComparisonID(
448
+ type1InfoOrName,
449
+ t1Norm,
450
+ state,
451
+ )}|${typeInfoComparisonID(type2InfoOrName, t2Norm, state)}`
452
+ if (state.seenPairs.has(pairKey)) {
453
+ return true
394
454
  }
395
- // For other types (Pointer, Slice, etc.), or if both are anonymous (name is undefined),
396
- // structural comparison is needed.
455
+ state.seenPairs.add(pairKey)
397
456
 
398
457
  switch (t1Norm.kind) {
399
458
  case TypeKind.Basic:
400
- // Names matched if they were defined, or both undefined (which means true by t1Norm.name !== t2Norm.name being false)
401
459
  return true
402
460
  case TypeKind.Pointer:
403
461
  return compareOptionalTypeInfo(
404
462
  (t1Norm as PointerTypeInfo).elemType,
405
463
  (t2Norm as PointerTypeInfo).elemType,
464
+ state,
406
465
  )
407
466
  case TypeKind.Slice:
408
467
  return compareOptionalTypeInfo(
409
468
  (t1Norm as SliceTypeInfo).elemType,
410
469
  (t2Norm as SliceTypeInfo).elemType,
470
+ state,
411
471
  )
412
472
  case TypeKind.Array:
413
473
  return (
@@ -415,6 +475,7 @@ export function areTypeInfosIdentical(
415
475
  compareOptionalTypeInfo(
416
476
  (t1Norm as ArrayTypeInfo).elemType,
417
477
  (t2Norm as ArrayTypeInfo).elemType,
478
+ state,
418
479
  )
419
480
  )
420
481
  case TypeKind.Map:
@@ -422,39 +483,119 @@ export function areTypeInfosIdentical(
422
483
  compareOptionalTypeInfo(
423
484
  (t1Norm as MapTypeInfo).keyType,
424
485
  (t2Norm as MapTypeInfo).keyType,
486
+ state,
425
487
  ) &&
426
488
  compareOptionalTypeInfo(
427
489
  (t1Norm as MapTypeInfo).elemType,
428
490
  (t2Norm as MapTypeInfo).elemType,
491
+ state,
429
492
  )
430
493
  )
431
494
  case TypeKind.Channel:
432
495
  return (
433
- // Ensure direction property exists before comparing, or handle undefined if it can be
434
496
  ((t1Norm as ChannelTypeInfo).direction || 'both') ===
435
497
  ((t2Norm as ChannelTypeInfo).direction || 'both') &&
436
498
  compareOptionalTypeInfo(
437
499
  (t1Norm as ChannelTypeInfo).elemType,
438
500
  (t2Norm as ChannelTypeInfo).elemType,
501
+ state,
439
502
  )
440
503
  )
441
504
  case TypeKind.Function:
442
505
  return areFuncSignaturesIdentical(
443
506
  t1Norm as FunctionTypeInfo,
444
507
  t2Norm as FunctionTypeInfo,
508
+ state,
445
509
  )
446
510
  case TypeKind.Struct:
511
+ if (t2Norm.kind !== TypeKind.Struct) {
512
+ return false
513
+ }
514
+ return areStructTypeInfosIdentical(t1Norm, t2Norm, state)
447
515
  case TypeKind.Interface:
448
- // If we reach here, names were undefined (both anonymous) or names matched but was not Basic/Struct/Interface.
449
- // For anonymous Struct/Interface, strict identity means full structural comparison.
450
- // For now, we consider anonymous types not identical unless they are the same object (caught above).
451
- // If they were named and matched, 'return true' was hit earlier for these kinds.
452
- return false
516
+ if (t2Norm.kind !== TypeKind.Interface) {
517
+ return false
518
+ }
519
+ return areInterfaceTypeInfosIdentical(t1Norm, t2Norm, state)
453
520
  default:
454
521
  return false
455
522
  }
456
523
  }
457
524
 
525
+ function areStructTypeInfosIdentical(
526
+ struct1: StructTypeInfo,
527
+ struct2: StructTypeInfo,
528
+ state: TypeInfoComparisonState,
529
+ ): boolean {
530
+ if (struct1.fields.length !== struct2.fields.length) {
531
+ return false
532
+ }
533
+ for (const [index, field1] of struct1.fields.entries()) {
534
+ const field2 = struct2.fields[index]
535
+ if (
536
+ field2 === undefined ||
537
+ field1.name !== field2.name ||
538
+ (field1.pkgPath ?? '') !== (field2.pkgPath ?? '') ||
539
+ (field1.tag ?? '') !== (field2.tag ?? '') ||
540
+ (field1.anonymous ?? false) !== (field2.anonymous ?? false) ||
541
+ !areTypeInfosIdenticalWithSeen(field1.type, field2.type, state)
542
+ ) {
543
+ return false
544
+ }
545
+ }
546
+ return true
547
+ }
548
+
549
+ function areInterfaceTypeInfosIdentical(
550
+ interface1: InterfaceTypeInfo,
551
+ interface2: InterfaceTypeInfo,
552
+ state: TypeInfoComparisonState,
553
+ ): boolean {
554
+ const methods1 = sortedMethodSignatures(interface1.methods)
555
+ const methods2 = sortedMethodSignatures(interface2.methods)
556
+ if (methods1.length !== methods2.length) {
557
+ return false
558
+ }
559
+ for (const [index, method1] of methods1.entries()) {
560
+ const method2 = methods2[index]
561
+ if (
562
+ method2 === undefined ||
563
+ method1.name !== method2.name ||
564
+ !areMethodArgArraysIdentical(method1.args, method2.args, state) ||
565
+ !areMethodArgArraysIdentical(method1.returns, method2.returns, state)
566
+ ) {
567
+ return false
568
+ }
569
+ }
570
+ return true
571
+ }
572
+
573
+ function sortedMethodSignatures(
574
+ methods: MethodSignature[] = [],
575
+ ): MethodSignature[] {
576
+ return [...methods].sort((left, right) => left.name.localeCompare(right.name))
577
+ }
578
+
579
+ function areMethodArgArraysIdentical(
580
+ args1: MethodArg[],
581
+ args2: MethodArg[],
582
+ state: TypeInfoComparisonState,
583
+ ): boolean {
584
+ if (args1.length !== args2.length) {
585
+ return false
586
+ }
587
+ for (const [index, arg1] of args1.entries()) {
588
+ const arg2 = args2[index]
589
+ if (
590
+ arg2 === undefined ||
591
+ !areTypeInfosIdenticalWithSeen(arg1.type, arg2.type, state)
592
+ ) {
593
+ return false
594
+ }
595
+ }
596
+ return true
597
+ }
598
+
458
599
  /**
459
600
  * Validates that a map key matches the expected type info.
460
601
  *
@@ -539,7 +680,8 @@ function matchesStructType(value: any, info: TypeInfo): boolean {
539
680
 
540
681
  // For anonymous struct types (no constructor), use structural matching
541
682
  if (typeof value === 'object' && value !== null && info.fields) {
542
- const fieldNames = Object.keys(info.fields || {})
683
+ const fields = info.fields || []
684
+ const fieldNames = fields.map((field) => structFieldRuntimeKey(field))
543
685
  const valueFields = Object.keys(value)
544
686
 
545
687
  const fieldsExist = fieldNames.every((field) => field in value)
@@ -549,10 +691,9 @@ function matchesStructType(value: any, info: TypeInfo): boolean {
549
691
  )
550
692
 
551
693
  if (fieldsExist && sameFieldCount && allFieldsInStruct) {
552
- return Object.entries(info.fields).every(([fieldName, fieldType]) => {
553
- const fieldTypeInfo =
554
- isStructFieldInfo(fieldType) ? fieldType.type : fieldType
555
- return matchesType(value[fieldName], normalizeTypeInfo(fieldTypeInfo))
694
+ return fields.every((field) => {
695
+ const key = structFieldRuntimeKey(field)
696
+ return matchesType(value[key], normalizeTypeInfo(field.type))
556
697
  })
557
698
  }
558
699
 
@@ -562,6 +703,10 @@ function matchesStructType(value: any, info: TypeInfo): boolean {
562
703
  return false
563
704
  }
564
705
 
706
+ export function structFieldRuntimeKey(field: StructFieldInfo): string {
707
+ return field.key || field.name
708
+ }
709
+
565
710
  /**
566
711
  * Checks if a value matches an interface type info by verifying it implements
567
712
  * all required methods with compatible signatures.
@@ -879,17 +1024,30 @@ function matchesPointerType(value: any, info: TypeInfo): boolean {
879
1024
  * @returns True if the value matches the function type, false otherwise.
880
1025
  */
881
1026
  function matchesFunctionType(value: any, info: FunctionTypeInfo): boolean {
882
- // First check if the value is a function
883
1027
  if (typeof value !== 'function') {
884
1028
  return false
885
1029
  }
886
-
887
- // This is important for named function types
888
- if (info.name && value.__goTypeName) {
889
- return info.name === value.__goTypeName
1030
+ const valueInfo = functionValueTypeInfo(value)
1031
+ if (!valueInfo) {
1032
+ return false
890
1033
  }
1034
+ return areTypeInfosIdentical(valueInfo, info)
1035
+ }
891
1036
 
892
- return true
1037
+ function functionValueTypeInfo(value: any): FunctionTypeInfo | null {
1038
+ const typeInfo = value.__typeInfo
1039
+ if (!typeInfo || typeInfo.kind !== TypeKind.Function) {
1040
+ return null
1041
+ }
1042
+ const goTypeName =
1043
+ typeof value.__goTypeName === 'string' ? value.__goTypeName : undefined
1044
+ if (goTypeName && typeInfo.name && goTypeName !== typeInfo.name) {
1045
+ return null
1046
+ }
1047
+ if (goTypeName && !typeInfo.name) {
1048
+ return { ...typeInfo, name: goTypeName }
1049
+ }
1050
+ return typeInfo
893
1051
  }
894
1052
 
895
1053
  /**
@@ -1062,8 +1220,8 @@ function compareTypeStringWithTypeInfo(
1062
1220
  }
1063
1221
 
1064
1222
  // Compare fields
1065
- const typeInfoFields = elemTypeInfo.fields || {}
1066
- const typeInfoFieldNames = Object.keys(typeInfoFields)
1223
+ const typeInfoFields = elemTypeInfo.fields || []
1224
+ const typeInfoFieldNames = typeInfoFields.map((field) => field.name)
1067
1225
  const parsedFieldNames = Object.keys(parsedFields)
1068
1226
 
1069
1227
  if (typeInfoFieldNames.length !== parsedFieldNames.length) {
@@ -1071,16 +1229,13 @@ function compareTypeStringWithTypeInfo(
1071
1229
  }
1072
1230
 
1073
1231
  // Check if all field names match and types are compatible
1074
- for (const fieldName of typeInfoFieldNames) {
1232
+ for (const field of typeInfoFields) {
1233
+ const fieldName = field.name
1075
1234
  if (!(fieldName in parsedFields)) {
1076
1235
  return false
1077
1236
  }
1078
1237
 
1079
- const fieldValue = typeInfoFields[fieldName]
1080
- // Handle StructFieldInfo (which has 'type' and optional 'tag' properties)
1081
- const fieldTypeInfo: TypeInfo | string =
1082
- isStructFieldInfo(fieldValue) ? fieldValue.type : fieldValue
1083
- const typeInfoFieldType = normalizeTypeInfo(fieldTypeInfo)
1238
+ const typeInfoFieldType = normalizeTypeInfo(field.type)
1084
1239
  const parsedFieldType = parsedFields[fieldName]
1085
1240
 
1086
1241
  // Compare basic types
@@ -1107,9 +1262,6 @@ function compareTypeStringWithTypeInfo(
1107
1262
  if (typeof elemType === 'string') {
1108
1263
  return elemStr === elemType
1109
1264
  }
1110
- if (elemType.name) {
1111
- return elemStr === elemType.name
1112
- }
1113
1265
  return compareTypeStringWithTypeInfo(elemStr, elemType)
1114
1266
  }
1115
1267
 
@@ -1463,24 +1615,39 @@ export function namedValueInterfaceValue<T>(
1463
1615
  return boxed as T
1464
1616
  }
1465
1617
 
1466
- export function namedFunction<T>(fn: T, typeName: string): T {
1618
+ export function namedFunction<T>(
1619
+ fn: T,
1620
+ typeName: string,
1621
+ typeInfo?: FunctionTypeInfo,
1622
+ ): T {
1467
1623
  if (typeof fn !== 'function') {
1468
1624
  return fn
1469
1625
  }
1470
- return Object.assign(fn, { __goTypeName: typeName })
1626
+ return Object.assign(
1627
+ fn,
1628
+ typeInfo ?
1629
+ { __goTypeName: typeName, __typeInfo: typeInfo }
1630
+ : { __goTypeName: typeName },
1631
+ )
1471
1632
  }
1472
1633
 
1473
1634
  export function functionValue<T extends (...args: any[]) => any>(
1474
1635
  fn: T,
1475
1636
  typeInfo: FunctionTypeInfo,
1476
1637
  ): T {
1477
- return Object.assign(fn, { __typeInfo: typeInfo })
1638
+ return Object.assign(
1639
+ fn,
1640
+ typeInfo.name ?
1641
+ { __typeInfo: typeInfo, __goTypeName: typeInfo.name }
1642
+ : { __typeInfo: typeInfo },
1643
+ )
1478
1644
  }
1479
1645
 
1480
1646
  export interface GenericTypeDescriptor<T = any> {
1481
1647
  type?: TypeInfo | string
1482
1648
  zero?: () => T
1483
1649
  methods?: Record<string, (receiver: T, ...args: any[]) => any>
1650
+ methodSignatures?: MethodSignature[]
1484
1651
  }
1485
1652
 
1486
1653
  export type GenericTypeArgs = Record<string, GenericTypeDescriptor>
@@ -1,3 +1,10 @@
1
+ export interface OwnedPointerHandle<T = unknown> {
2
+ readonly __goOwnedPointer: true
3
+ __goAddress: () => number
4
+ __goRef: () => VarRef<T>
5
+ __goSlice?: (length: number) => unknown
6
+ }
7
+
1
8
  /**
2
9
  * VarRef represents a Go variable which can be referred to by other variables.
3
10
  *
@@ -12,6 +19,51 @@ export type VarRef<T> = {
12
19
  __goAddress?: () => number
13
20
  __goCollection?: unknown
14
21
  __goIndex?: number
22
+ __goPointer?: OwnedPointerHandle<T>
23
+ }
24
+
25
+ const pointerAddressStride = 0x100000000
26
+ const pointerAddresses = new WeakMap<object, number>()
27
+ const fieldPointerAddresses = new WeakMap<
28
+ object,
29
+ globalThis.Map<PropertyKey, number>
30
+ >()
31
+ let nextPointerAddress = 1
32
+
33
+ function pointerAddress(value: object): number {
34
+ let address = pointerAddresses.get(value)
35
+ if (address === undefined) {
36
+ address = nextPointerAddress * pointerAddressStride
37
+ nextPointerAddress++
38
+ pointerAddresses.set(value, address)
39
+ }
40
+ return address
41
+ }
42
+
43
+ function fieldPointerAddress(target: object, key: PropertyKey): number {
44
+ let addresses = fieldPointerAddresses.get(target)
45
+ if (addresses === undefined) {
46
+ addresses = new globalThis.Map<PropertyKey, number>()
47
+ fieldPointerAddresses.set(target, addresses)
48
+ }
49
+ let address = addresses.get(key)
50
+ if (address === undefined) {
51
+ address = nextPointerAddress * pointerAddressStride
52
+ nextPointerAddress++
53
+ addresses.set(key, address)
54
+ }
55
+ return address
56
+ }
57
+
58
+ function refPointer<T>(
59
+ ref: VarRef<T>,
60
+ address: () => number,
61
+ ): OwnedPointerHandle<T> {
62
+ return {
63
+ __goOwnedPointer: true,
64
+ __goAddress: address,
65
+ __goRef: () => ref,
66
+ }
15
67
  }
16
68
 
17
69
  /** Wrap a non-null T in a variable reference. */
@@ -19,7 +71,10 @@ export function varRef<T>(v: T): VarRef<T> {
19
71
  // We create a new object wrapper for every varRef call to ensure
20
72
  // distinct pointer identity, crucial for pointer comparisons (p1 == p2).
21
73
  // The __isVarRef marker allows the reflect system to identify this as a pointer type.
22
- return { value: v, __isVarRef: true }
74
+ const ref: VarRef<T> = { value: v, __isVarRef: true }
75
+ ref.__goAddress = () => pointerAddress(ref)
76
+ ref.__goPointer = refPointer(ref, ref.__goAddress)
77
+ return ref
23
78
  }
24
79
 
25
80
  /** Create a variable reference to an object field. */
@@ -27,7 +82,8 @@ export function fieldRef<T extends object, K extends keyof T>(
27
82
  target: T,
28
83
  key: K,
29
84
  ): VarRef<T[K]> {
30
- return {
85
+ const address = () => fieldPointerAddress(target, key)
86
+ const ref: VarRef<T[K]> = {
31
87
  get value(): T[K] {
32
88
  return target[key]
33
89
  },
@@ -35,7 +91,10 @@ export function fieldRef<T extends object, K extends keyof T>(
35
91
  target[key] = value
36
92
  },
37
93
  __isVarRef: true,
94
+ __goAddress: address,
38
95
  }
96
+ ref.__goPointer = refPointer(ref, address)
97
+ return ref
39
98
  }
40
99
 
41
100
  /** Check if a value is a VarRef (pointer) */
@@ -43,6 +102,30 @@ export function isVarRef(v: unknown): v is VarRef<unknown> {
43
102
  return v !== null && typeof v === 'object' && (v as any).__isVarRef === true
44
103
  }
45
104
 
105
+ export function isOwnedPointerHandle(
106
+ value: unknown,
107
+ ): value is OwnedPointerHandle {
108
+ return (
109
+ value !== null &&
110
+ typeof value === 'object' &&
111
+ (value as { __goOwnedPointer?: unknown }).__goOwnedPointer === true
112
+ )
113
+ }
114
+
115
+ export function ownedPointerFromRef<T>(
116
+ ref: VarRef<T>,
117
+ ): OwnedPointerHandle<T> | undefined {
118
+ return ref.__goPointer
119
+ }
120
+
121
+ export function ownedPointerAddress(pointer: OwnedPointerHandle): number {
122
+ return pointer.__goAddress()
123
+ }
124
+
125
+ export function ownedPointerRef<T>(pointer: OwnedPointerHandle<T>): VarRef<T> {
126
+ return pointer.__goRef()
127
+ }
128
+
46
129
  /** Dereference a variable reference, throws on null → simulates Go panic. */
47
130
  export function unref<T>(b: VarRef<T>): T {
48
131
  if (b === null) {
@@ -549,7 +549,7 @@ export class Buffer {
549
549
  new Buffer(),
550
550
  [{ name: "Bytes", args: [], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "AvailableBuffer", args: [], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "String", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }] }, { name: "empty", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Len", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Cap", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Available", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Truncate", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Reset", args: [], returns: [] }, { name: "tryGrowByReslice", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "grow", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Grow", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Write", args: [{ name: "p", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteString", args: [{ name: "s", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadFrom", args: [{ name: "r", type: "Reader" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteTo", args: [{ name: "w", type: "Writer" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteByte", args: [{ name: "c", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteRune", args: [{ name: "r", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Read", args: [{ name: "p", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Next", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "ReadByte", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadRune", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadRune", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadByte", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadBytes", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "readSlice", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadString", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }],
551
551
  Buffer,
552
- {"buf": { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } }, "off": { kind: $.TypeKind.Basic, name: "number" }, "lastRead": "readOp"}
552
+ [{ name: "buf", key: "buf", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "off", key: "off", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "lastRead", key: "lastRead", type: "readOp" }]
553
553
  );
554
554
  }
555
555
 
@@ -221,7 +221,7 @@ export class Reader {
221
221
  new Reader(),
222
222
  [{ name: "Len", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Size", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Read", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadAt", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "off", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadByte", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadByte", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadRune", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadRune", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Seek", args: [{ name: "offset", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "whence", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteTo", args: [{ name: "w", type: "Writer" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Reset", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [] }],
223
223
  Reader,
224
- {"s": { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } }, "i": { kind: $.TypeKind.Basic, name: "number" }, "prevRune": { kind: $.TypeKind.Basic, name: "number" }}
224
+ [{ name: "s", key: "s", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "i", key: "i", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "prevRune", key: "prevRune", type: { kind: $.TypeKind.Basic, name: "number" } }]
225
225
  );
226
226
  }
227
227