goscript 0.1.4 → 0.2.0

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 (270) 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/compiler/compile-request.go +12 -9
  8. package/compiler/compliance_test.go +0 -1
  9. package/compiler/config.go +2 -0
  10. package/compiler/gotest/request.go +28 -0
  11. package/compiler/gotest/runner.go +353 -27
  12. package/compiler/gotest/runner_test.go +273 -1
  13. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  14. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  15. package/compiler/lowered-program.go +24 -17
  16. package/compiler/lowering.go +392 -127
  17. package/compiler/lowering_bench_test.go +41 -27
  18. package/compiler/override-facts.go +15 -0
  19. package/compiler/override-parity-verifier.go +450 -0
  20. package/compiler/override-parity.go +122 -0
  21. package/compiler/override-registry_test.go +559 -0
  22. package/compiler/protobuf-ts-binding.go +514 -0
  23. package/compiler/protobuf-ts-binding_test.go +172 -0
  24. package/compiler/semantic-model-types.go +9 -4
  25. package/compiler/semantic-model.go +282 -70
  26. package/compiler/semantic-model_test.go +82 -1
  27. package/compiler/service.go +20 -1
  28. package/compiler/skeleton_test.go +62 -8
  29. package/compiler/typescript-emitter.go +128 -13
  30. package/dist/gs/builtin/slice.d.ts +2 -1
  31. package/dist/gs/builtin/slice.js +29 -4
  32. package/dist/gs/builtin/slice.js.map +1 -1
  33. package/dist/gs/builtin/type.d.ts +13 -5
  34. package/dist/gs/builtin/type.js +153 -60
  35. package/dist/gs/builtin/type.js.map +1 -1
  36. package/dist/gs/builtin/varRef.d.ts +11 -0
  37. package/dist/gs/builtin/varRef.js +57 -2
  38. package/dist/gs/builtin/varRef.js.map +1 -1
  39. package/dist/gs/bytes/buffer.gs.js +1 -1
  40. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  41. package/dist/gs/bytes/reader.gs.js +1 -1
  42. package/dist/gs/bytes/reader.gs.js.map +1 -1
  43. package/dist/gs/compress/zlib/index.d.ts +10 -3
  44. package/dist/gs/compress/zlib/index.js +50 -16
  45. package/dist/gs/compress/zlib/index.js.map +1 -1
  46. package/dist/gs/encoding/json/index.d.ts +114 -0
  47. package/dist/gs/encoding/json/index.js +544 -36
  48. package/dist/gs/encoding/json/index.js.map +1 -1
  49. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  50. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  51. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  52. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  53. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  54. package/dist/gs/go/scanner/index.d.ts +2 -0
  55. package/dist/gs/go/scanner/index.js +29 -5
  56. package/dist/gs/go/scanner/index.js.map +1 -1
  57. package/dist/gs/go/token/index.js +22 -6
  58. package/dist/gs/go/token/index.js.map +1 -1
  59. package/dist/gs/hash/index.d.ts +6 -0
  60. package/dist/gs/hash/index.js +20 -0
  61. package/dist/gs/hash/index.js.map +1 -1
  62. package/dist/gs/internal/goarch/index.d.ts +43 -3
  63. package/dist/gs/internal/goarch/index.js +42 -10
  64. package/dist/gs/internal/goarch/index.js.map +1 -1
  65. package/dist/gs/io/fs/fs.js +26 -14
  66. package/dist/gs/io/fs/fs.js.map +1 -1
  67. package/dist/gs/io/fs/readdir.js +4 -2
  68. package/dist/gs/io/fs/readdir.js.map +1 -1
  69. package/dist/gs/io/fs/sub.js +8 -1
  70. package/dist/gs/io/fs/sub.js.map +1 -1
  71. package/dist/gs/io/io.d.ts +2 -0
  72. package/dist/gs/io/io.js.map +1 -1
  73. package/dist/gs/math/bits/index.d.ts +5 -0
  74. package/dist/gs/math/bits/index.js +16 -4
  75. package/dist/gs/math/bits/index.js.map +1 -1
  76. package/dist/gs/mime/index.d.ts +16 -0
  77. package/dist/gs/mime/index.js +315 -6
  78. package/dist/gs/mime/index.js.map +1 -1
  79. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  80. package/dist/gs/net/http/httptest/index.js +85 -6
  81. package/dist/gs/net/http/httptest/index.js.map +1 -1
  82. package/dist/gs/net/http/index.d.ts +300 -5
  83. package/dist/gs/net/http/index.js +1598 -58
  84. package/dist/gs/net/http/index.js.map +1 -1
  85. package/dist/gs/os/dir_unix.gs.js +1 -1
  86. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  87. package/dist/gs/os/error.gs.js +1 -1
  88. package/dist/gs/os/error.gs.js.map +1 -1
  89. package/dist/gs/os/exec.gs.d.ts +1 -0
  90. package/dist/gs/os/exec.gs.js +4 -8
  91. package/dist/gs/os/exec.gs.js.map +1 -1
  92. package/dist/gs/os/exec_posix.gs.js +1 -1
  93. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  94. package/dist/gs/os/index.d.ts +1 -1
  95. package/dist/gs/os/index.js +1 -1
  96. package/dist/gs/os/index.js.map +1 -1
  97. package/dist/gs/os/proc.gs.d.ts +4 -0
  98. package/dist/gs/os/proc.gs.js +12 -6
  99. package/dist/gs/os/proc.gs.js.map +1 -1
  100. package/dist/gs/os/root_js.gs.js +1 -1
  101. package/dist/gs/os/root_js.gs.js.map +1 -1
  102. package/dist/gs/os/types.gs.js +1 -1
  103. package/dist/gs/os/types.gs.js.map +1 -1
  104. package/dist/gs/os/types_js.gs.js +1 -1
  105. package/dist/gs/os/types_js.gs.js.map +1 -1
  106. package/dist/gs/os/types_unix.gs.js +1 -1
  107. package/dist/gs/os/types_unix.gs.js.map +1 -1
  108. package/dist/gs/path/path.js +11 -7
  109. package/dist/gs/path/path.js.map +1 -1
  110. package/dist/gs/reflect/index.d.ts +5 -4
  111. package/dist/gs/reflect/index.js +4 -3
  112. package/dist/gs/reflect/index.js.map +1 -1
  113. package/dist/gs/reflect/map.js +15 -0
  114. package/dist/gs/reflect/map.js.map +1 -1
  115. package/dist/gs/reflect/type.d.ts +25 -6
  116. package/dist/gs/reflect/type.js +1418 -228
  117. package/dist/gs/reflect/type.js.map +1 -1
  118. package/dist/gs/reflect/types.d.ts +14 -6
  119. package/dist/gs/reflect/types.js +35 -1
  120. package/dist/gs/reflect/types.js.map +1 -1
  121. package/dist/gs/reflect/value.d.ts +1 -0
  122. package/dist/gs/reflect/value.js +83 -41
  123. package/dist/gs/reflect/value.js.map +1 -1
  124. package/dist/gs/reflect/visiblefields.js +4 -140
  125. package/dist/gs/reflect/visiblefields.js.map +1 -1
  126. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  127. package/dist/gs/runtime/pprof/index.js +50 -30
  128. package/dist/gs/runtime/pprof/index.js.map +1 -1
  129. package/dist/gs/runtime/runtime.js +5 -4
  130. package/dist/gs/runtime/runtime.js.map +1 -1
  131. package/dist/gs/runtime/trace/index.js +5 -19
  132. package/dist/gs/runtime/trace/index.js.map +1 -1
  133. package/dist/gs/strconv/atoi.gs.js +1 -1
  134. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  135. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  136. package/dist/gs/strconv/complex.gs.js +148 -0
  137. package/dist/gs/strconv/complex.gs.js.map +1 -0
  138. package/dist/gs/strconv/index.d.ts +1 -0
  139. package/dist/gs/strconv/index.js +1 -0
  140. package/dist/gs/strconv/index.js.map +1 -1
  141. package/dist/gs/strings/builder.js +1 -1
  142. package/dist/gs/strings/reader.js +9 -5
  143. package/dist/gs/strings/reader.js.map +1 -1
  144. package/dist/gs/strings/replace.js +15 -7
  145. package/dist/gs/strings/replace.js.map +1 -1
  146. package/dist/gs/strings/strings.d.ts +5 -0
  147. package/dist/gs/strings/strings.js +57 -5
  148. package/dist/gs/strings/strings.js.map +1 -1
  149. package/dist/gs/sync/atomic/type.gs.js +9 -9
  150. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  151. package/dist/gs/sync/atomic/value.gs.js +2 -2
  152. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  153. package/dist/gs/syscall/env.js +22 -14
  154. package/dist/gs/syscall/env.js.map +1 -1
  155. package/dist/gs/testing/testing.js +55 -13
  156. package/dist/gs/testing/testing.js.map +1 -1
  157. package/dist/gs/time/time.d.ts +24 -1
  158. package/dist/gs/time/time.js +43 -3
  159. package/dist/gs/time/time.js.map +1 -1
  160. package/dist/gs/unique/index.js +7 -1
  161. package/dist/gs/unique/index.js.map +1 -1
  162. package/go.mod +3 -3
  163. package/go.sum +16 -0
  164. package/gs/builtin/runtime-contract.test.ts +218 -21
  165. package/gs/builtin/slice.ts +44 -4
  166. package/gs/builtin/type.ts +226 -59
  167. package/gs/builtin/varRef.ts +85 -2
  168. package/gs/bytes/buffer.gs.ts +1 -1
  169. package/gs/bytes/reader.gs.ts +1 -1
  170. package/gs/compress/zlib/index.test.ts +62 -1
  171. package/gs/compress/zlib/index.ts +53 -16
  172. package/gs/compress/zlib/parity.json +51 -0
  173. package/gs/encoding/json/index.test.ts +360 -6
  174. package/gs/encoding/json/index.ts +679 -38
  175. package/gs/encoding/json/parity.json +81 -0
  176. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  177. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  178. package/gs/github.com/pkg/errors/errors.ts +54 -30
  179. package/gs/go/scanner/index.test.ts +39 -56
  180. package/gs/go/scanner/index.ts +33 -5
  181. package/gs/go/scanner/parity.json +27 -0
  182. package/gs/go/token/index.ts +22 -6
  183. package/gs/hash/index.test.ts +20 -33
  184. package/gs/hash/index.ts +28 -0
  185. package/gs/hash/parity.json +21 -0
  186. package/gs/internal/goarch/index.test.ts +32 -0
  187. package/gs/internal/goarch/index.ts +45 -13
  188. package/gs/internal/goarch/parity.json +144 -0
  189. package/gs/io/fs/fs.ts +26 -14
  190. package/gs/io/fs/readdir.ts +4 -4
  191. package/gs/io/fs/sub.ts +8 -1
  192. package/gs/io/io.ts +1 -0
  193. package/gs/io/parity.json +162 -0
  194. package/gs/math/bits/index.test.ts +14 -1
  195. package/gs/math/bits/index.ts +23 -4
  196. package/gs/math/bits/parity.json +156 -0
  197. package/gs/mime/index.test.ts +90 -0
  198. package/gs/mime/index.ts +369 -6
  199. package/gs/mime/parity.json +36 -0
  200. package/gs/net/http/httptest/index.test.ts +98 -2
  201. package/gs/net/http/httptest/index.ts +101 -6
  202. package/gs/net/http/httptest/parity.json +15 -0
  203. package/gs/net/http/index.test.ts +781 -12
  204. package/gs/net/http/index.ts +1860 -139
  205. package/gs/net/http/meta.json +16 -1
  206. package/gs/net/http/parity.json +193 -0
  207. package/gs/os/dir_unix.gs.ts +1 -1
  208. package/gs/os/error.gs.ts +1 -1
  209. package/gs/os/exec.gs.ts +4 -8
  210. package/gs/os/exec_posix.gs.ts +1 -1
  211. package/gs/os/index.test.ts +9 -0
  212. package/gs/os/index.ts +1 -0
  213. package/gs/os/parity.json +9 -0
  214. package/gs/os/proc.gs.ts +18 -5
  215. package/gs/os/proc.test.ts +26 -0
  216. package/gs/os/root_js.gs.ts +1 -1
  217. package/gs/os/types.gs.ts +1 -1
  218. package/gs/os/types_js.gs.ts +1 -1
  219. package/gs/os/types_unix.gs.ts +1 -1
  220. package/gs/path/path.ts +11 -7
  221. package/gs/reflect/field.test.ts +37 -15
  222. package/gs/reflect/function-types.test.ts +518 -22
  223. package/gs/reflect/index.ts +8 -6
  224. package/gs/reflect/map.ts +20 -0
  225. package/gs/reflect/meta.json +6 -4
  226. package/gs/reflect/parity.json +234 -0
  227. package/gs/reflect/sliceat.test.ts +156 -0
  228. package/gs/reflect/structof.test.ts +401 -0
  229. package/gs/reflect/type.ts +1897 -317
  230. package/gs/reflect/typefor.test.ts +510 -10
  231. package/gs/reflect/types.ts +43 -18
  232. package/gs/reflect/value.ts +105 -45
  233. package/gs/reflect/visiblefields.ts +5 -168
  234. package/gs/runtime/parity.json +24 -0
  235. package/gs/runtime/pprof/index.test.ts +29 -7
  236. package/gs/runtime/pprof/index.ts +56 -30
  237. package/gs/runtime/pprof/parity.json +27 -0
  238. package/gs/runtime/runtime.test.ts +3 -1
  239. package/gs/runtime/runtime.ts +4 -3
  240. package/gs/runtime/trace/index.test.ts +5 -3
  241. package/gs/runtime/trace/index.ts +8 -20
  242. package/gs/runtime/trace/parity.json +36 -0
  243. package/gs/strconv/atoi.gs.ts +1 -1
  244. package/gs/strconv/complex.gs.ts +174 -0
  245. package/gs/strconv/complex.test.ts +65 -0
  246. package/gs/strconv/index.ts +1 -0
  247. package/gs/strconv/parity.json +120 -0
  248. package/gs/strings/builder.ts +1 -1
  249. package/gs/strings/parity.json +186 -0
  250. package/gs/strings/reader.ts +9 -5
  251. package/gs/strings/replace.ts +15 -7
  252. package/gs/strings/strings.test.ts +22 -2
  253. package/gs/strings/strings.ts +64 -6
  254. package/gs/sync/atomic/type.gs.ts +9 -9
  255. package/gs/sync/atomic/value.gs.ts +2 -2
  256. package/gs/syscall/env.ts +29 -14
  257. package/gs/testing/testing.test.ts +67 -0
  258. package/gs/testing/testing.ts +87 -19
  259. package/gs/time/parity.json +225 -0
  260. package/gs/time/time.test.ts +20 -2
  261. package/gs/time/time.ts +49 -7
  262. package/gs/unique/index.ts +7 -1
  263. package/package.json +4 -2
  264. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  265. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
  266. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  267. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
  268. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
  269. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  270. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { StructField, StructTag, ValueError, } from './types.js';
2
2
  export { StructField };
3
3
  import { MapIter } from './map.js';
4
- import { getTypeByName as builtinGetTypeByName, TypeKind, isStructTypeInfo, isInterfaceTypeInfo, isStructFieldInfo, } from '../builtin/type.js';
4
+ import { getTypeByName as builtinGetTypeByName, isStructTypeInfo, isInterfaceTypeInfo, structFieldRuntimeKey, } from '../builtin/type.js';
5
5
  import { Zero } from './value.js';
6
6
  import { DeepEqual } from './deepequal.js';
7
7
  import * as $ from '../builtin/index.js';
@@ -153,8 +153,10 @@ export const Struct = 25;
153
153
  export const UnsafePointer = 26;
154
154
  const pointerAddressStride = 0x100000000;
155
155
  const pointerAddresses = new WeakMap();
156
+ const fieldPointerAddresses = new WeakMap();
156
157
  let nextPointerAddress = 1;
157
158
  const canonicalTypes = new globalThis.Map();
159
+ const constructingRegisteredTypes = new globalThis.Map();
158
160
  function pointerAddress(value) {
159
161
  let address = pointerAddresses.get(value);
160
162
  if (address === undefined) {
@@ -164,15 +166,121 @@ function pointerAddress(value) {
164
166
  }
165
167
  return address;
166
168
  }
169
+ function fieldPointerAddress(target, key) {
170
+ let addresses = fieldPointerAddresses.get(target);
171
+ if (addresses === undefined) {
172
+ addresses = new globalThis.Map();
173
+ fieldPointerAddresses.set(target, addresses);
174
+ }
175
+ let address = addresses.get(key);
176
+ if (address === undefined) {
177
+ address = nextPointerAddress * pointerAddressStride;
178
+ nextPointerAddress++;
179
+ addresses.set(key, address);
180
+ }
181
+ return address;
182
+ }
167
183
  function internType(t) {
168
- const key = `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}`;
184
+ const key = typeIdentityKey(t);
169
185
  const existing = canonicalTypes.get(key);
170
186
  if (existing) {
187
+ mergeTypeMetadata(existing, t);
171
188
  return existing;
172
189
  }
173
190
  canonicalTypes.set(key, t);
174
191
  return t;
175
192
  }
193
+ function mergeTypeMetadata(target, source) {
194
+ if (target instanceof BasicType && source instanceof BasicType) {
195
+ target.mergeMethodSignatures(source.methodSignatures());
196
+ return;
197
+ }
198
+ if (target instanceof PointerType && source instanceof PointerType) {
199
+ target.mergeMethodSignatures(source.methodSignatures());
200
+ return;
201
+ }
202
+ if (target instanceof FunctionType && source instanceof FunctionType) {
203
+ target.mergeSignature(source);
204
+ target.mergeMethodSignatures(source.methodSignatures());
205
+ }
206
+ }
207
+ function typeIdentityKey(t, seen = new Set()) {
208
+ if (seen.has(t)) {
209
+ return `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}`;
210
+ }
211
+ seen.add(t);
212
+ if (t instanceof StructType) {
213
+ return t.identityKey(seen);
214
+ }
215
+ switch (t.Kind()) {
216
+ case Array:
217
+ return `${t.Kind()}:${t.Len()}:${typeIdentityKey(t.Elem(), seen)}`;
218
+ case Chan:
219
+ case Ptr:
220
+ case Slice:
221
+ return `${t.Kind()}:${t.String()}:${typeIdentityKey(t.Elem(), seen)}`;
222
+ case Map:
223
+ return `${t.Kind()}:${typeIdentityKey(t.Key(), seen)}:${typeIdentityKey(t.Elem(), seen)}`;
224
+ case Func: {
225
+ if (t.Name() !== '') {
226
+ return `${t.Kind()}:named:${t.PkgPath()}:${t.Name()}`;
227
+ }
228
+ const params = globalThis.Array.from({ length: t.NumIn() }, (_unused, idx) => typeIdentityKey(t.In(idx), seen));
229
+ const results = globalThis.Array.from({ length: t.NumOut() }, (_unused, idx) => typeIdentityKey(t.Out(idx), seen));
230
+ return `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}:${t.IsVariadic()}:${params.join(',')}:${results.join(',')}`;
231
+ }
232
+ default:
233
+ return `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}`;
234
+ }
235
+ }
236
+ function typeUnderlyingIdentityKey(t, seen = new Set()) {
237
+ if (seen.has(t)) {
238
+ return `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}`;
239
+ }
240
+ seen.add(t);
241
+ if (t instanceof BasicType) {
242
+ return `basic:${t.underlyingName()}`;
243
+ }
244
+ if (t instanceof StructType) {
245
+ return t.underlyingIdentityKey(seen);
246
+ }
247
+ switch (t.Kind()) {
248
+ case Array:
249
+ return `array:${t.Len()}:${typeIdentityKey(t.Elem(), seen)}`;
250
+ case Chan:
251
+ return `chan:${t.String()}:${typeIdentityKey(t.Elem(), seen)}`;
252
+ case Ptr:
253
+ return `ptr:${typeIdentityKey(t.Elem(), seen)}`;
254
+ case Slice:
255
+ return `slice:${typeIdentityKey(t.Elem(), seen)}`;
256
+ case Map:
257
+ return `map:${typeIdentityKey(t.Key(), seen)}:${typeIdentityKey(t.Elem(), seen)}`;
258
+ case Func: {
259
+ const params = globalThis.Array.from({ length: t.NumIn() }, (_unused, idx) => typeIdentityKey(t.In(idx), seen));
260
+ const results = globalThis.Array.from({ length: t.NumOut() }, (_unused, idx) => typeIdentityKey(t.Out(idx), seen));
261
+ return `func:${t.IsVariadic()}:${params.join(',')}:${results.join(',')}`;
262
+ }
263
+ case Interface:
264
+ return `interface:${typeMethods(t).map(methodSignatureIdentityKey).join('|')}`;
265
+ default:
266
+ return `${t.Kind()}:${t.PkgPath()}:${t.Name()}:${t.String()}`;
267
+ }
268
+ }
269
+ function typeIsNamed(t) {
270
+ if (t.Kind() === Interface) {
271
+ return t.String() !== 'interface{}' && !t.String().startsWith('interface {');
272
+ }
273
+ if (t.Kind() === Struct || t.Kind() === Func) {
274
+ return t.Name() !== '';
275
+ }
276
+ if (t instanceof BasicType) {
277
+ return t.Kind() !== Invalid && t.Name() !== '';
278
+ }
279
+ return t.Name() !== '';
280
+ }
281
+ function nonFunctionTypePanic(method, t) {
282
+ throw new Error(`reflect: ${method} of non-func type ${t.String()}`);
283
+ }
176
284
  // InvalidTypeInstance is a singleton type for invalid/zero reflect.Value
177
285
  class InvalidTypeClass {
178
286
  Kind() {
@@ -202,6 +310,21 @@ class InvalidTypeClass {
202
310
  NumField() {
203
311
  return 0;
204
312
  }
313
+ NumIn() {
314
+ return nonFunctionTypePanic('NumIn', this);
315
+ }
316
+ In(_i) {
317
+ return nonFunctionTypePanic('In', this);
318
+ }
319
+ NumOut() {
320
+ return nonFunctionTypePanic('NumOut', this);
321
+ }
322
+ Out(_i) {
323
+ return nonFunctionTypePanic('Out', this);
324
+ }
325
+ IsVariadic() {
326
+ return nonFunctionTypePanic('IsVariadic', this);
327
+ }
205
328
  Field(_i) {
206
329
  throw new Error('reflect: Field of invalid type');
207
330
  }
@@ -335,6 +458,9 @@ export class Value {
335
458
  return this._type.String();
336
459
  }
337
460
  Len() {
461
+ if (this.Kind() === Slice || this.Kind() === Array) {
462
+ return $.len(this._value);
463
+ }
338
464
  // Check for slice objects created by $.arrayToSlice
339
465
  if (this._value &&
340
466
  typeof this._value === 'object' &&
@@ -383,8 +509,9 @@ export class Value {
383
509
  return this._value === null || this._value === undefined;
384
510
  }
385
511
  Index(i) {
386
- if (globalThis.Array.isArray(this._value)) {
387
- return new Value(this._value[i], getTypeOf(this._value[i]));
512
+ if (this.Kind() === Slice || this.Kind() === Array) {
513
+ const ref = $.indexRef(this._value, i);
514
+ return new Value(ref.value, this._type.Elem(), ref);
388
515
  }
389
516
  throw new Error('reflect: call of reflect.Value.Index on ' +
390
517
  Kind_String(this._type.Kind()) +
@@ -446,16 +573,17 @@ export class Value {
446
573
  throw new ValueError({ Kind: this.Kind(), Method: 'Field' });
447
574
  }
448
575
  const field = this.Type().Field(i);
576
+ const fieldKey = structFieldStorageKey(this.Type(), i);
449
577
  if (!field) {
450
578
  throw new Error('reflect: struct field index out of range');
451
579
  }
452
580
  const parentObj = this._value;
453
- let fieldVal = parentObj[field.Name];
581
+ let fieldVal = parentObj[fieldKey];
454
582
  if (fieldVal === undefined) {
455
583
  fieldVal = null;
456
584
  }
457
585
  // Pass parent struct and field name so Set() can update the struct
458
- return new Value(fieldVal, field.Type, undefined, parentObj, field.Name);
586
+ return new Value(fieldVal, field.Type, undefined, parentObj, fieldKey);
459
587
  }
460
588
  FieldByIndex(index) {
461
589
  let current = this;
@@ -488,6 +616,9 @@ export class Value {
488
616
  if (this._value === null || this._value === undefined) {
489
617
  return 0;
490
618
  }
619
+ if ($.isOwnedPointerHandle(this._value)) {
620
+ return $.ownedPointerAddress(this._value);
621
+ }
491
622
  if ($.isVarRef(this._value)) {
492
623
  const address = this._value.__goAddress?.();
493
624
  if (address !== undefined) {
@@ -517,7 +648,18 @@ export class Value {
517
648
  throw new ValueError({ Kind: this.Kind(), Method: 'UnsafeAddr' });
518
649
  }
519
650
  if (this._parentStruct && this._fieldName) {
520
- return { value: this };
651
+ const target = this._parentStruct;
652
+ const key = this._fieldName;
653
+ const ref = $.fieldRef(target, key);
654
+ return {
655
+ __goOwnedPointer: true,
656
+ __goAddress: () => fieldPointerAddress(target, key),
657
+ __goRef: () => ref,
658
+ };
659
+ }
660
+ if (this._parentVarRef?.__goPointer) {
661
+ return this._parentVarRef
662
+ .__goPointer;
521
663
  }
522
664
  return this.Pointer();
523
665
  }
@@ -547,6 +689,9 @@ export class Value {
547
689
  if (this._parentStruct && this._fieldName) {
548
690
  return new Value($.fieldRef(this._parentStruct, this._fieldName), ptrType);
549
691
  }
692
+ if (this._parentVarRef) {
693
+ return new Value(this._parentVarRef, ptrType);
694
+ }
550
695
  return new Value($.varRef(this._value), ptrType);
551
696
  }
552
697
  CanSet() {
@@ -558,23 +703,9 @@ export class Value {
558
703
  if (!this.CanSet()) {
559
704
  throw new Error('reflect: assign to invalid value');
560
705
  }
561
- // Interface types can accept any value
562
- if (this.Kind() === Interface) {
563
- this._value = x.value;
564
- // Also update the parent VarRef if we were dereferenced from one
565
- if (this._parentVarRef) {
566
- this._parentVarRef.value = x.value;
567
- }
568
- // Also update the parent struct field if this is a struct field
569
- if (this._parentStruct && this._fieldName) {
570
- this._parentStruct[this._fieldName] = x.value;
571
- }
572
- return;
573
- }
574
- // For other types, check if types are compatible (simplified check)
575
706
  const thisType = this.Type();
576
707
  const xType = x.Type();
577
- if (thisType.Kind() !== xType.Kind()) {
708
+ if (!xType.AssignableTo(thisType)) {
578
709
  throw new Error('reflect: assign to wrong type');
579
710
  }
580
711
  this._value = x.value;
@@ -605,21 +736,23 @@ export class Value {
605
736
  if (typeof method !== 'function') {
606
737
  return new Value();
607
738
  }
608
- return new Value(method.bind(receiver), new FunctionType('func'));
739
+ const [signature] = methodSignatureByName(this.Type(), name);
740
+ const methodType = signature ?
741
+ methodTypeFromSignature(signature, this.Type(), false)
742
+ : new FunctionType('func');
743
+ return new Value(method.bind(receiver), methodType);
609
744
  }
610
- Call(inArgs) {
745
+ async Call(inArgs) {
611
746
  if (this.Kind() !== Func || typeof this._value !== 'function') {
612
747
  throw new ValueError({ Kind: this.Kind(), Method: 'Call' });
613
748
  }
614
- const args = $.asArray(inArgs).map((arg) => arg.Interface());
615
- const result = this._value(...args);
616
- if (globalThis.Array.isArray(result)) {
617
- return $.arrayToSlice(result.map((value) => ValueOf(value)));
618
- }
619
- if (result === undefined) {
620
- return $.makeSlice(0);
749
+ return await callReflectFunction(this._value, this._type, inArgs, 'Call');
750
+ }
751
+ async CallSlice(inArgs) {
752
+ if (this.Kind() !== Func || typeof this._value !== 'function') {
753
+ throw new ValueError({ Kind: this.Kind(), Method: 'CallSlice' });
621
754
  }
622
- return $.arrayToSlice([ValueOf(result)]);
755
+ return await callReflectFunction(this._value, this._type, inArgs, 'CallSlice');
623
756
  }
624
757
  IsZero() {
625
758
  const zeroVal = Zero(this.Type()).value;
@@ -886,10 +1019,7 @@ export class Value {
886
1019
  Cap() {
887
1020
  const k = this.Kind();
888
1021
  if (k === Slice || k === Array) {
889
- if (globalThis.Array.isArray(this._value)) {
890
- return this._value.length;
891
- }
892
- return 0;
1022
+ return $.cap(this._value);
893
1023
  }
894
1024
  if (k === Chan) {
895
1025
  return 0; // Simplified
@@ -962,11 +1092,13 @@ export class BasicType {
962
1092
  _name;
963
1093
  _size;
964
1094
  _typeName;
965
- constructor(_kind, _name, _size = 8, _typeName = '') {
1095
+ _methods;
1096
+ constructor(_kind, _name, _size = 8, _typeName = '', _methods = []) {
966
1097
  this._kind = _kind;
967
1098
  this._name = _name;
968
1099
  this._size = _size;
969
1100
  this._typeName = _typeName;
1101
+ this._methods = _methods;
970
1102
  }
971
1103
  String() {
972
1104
  return this._typeName || this._name;
@@ -974,6 +1106,9 @@ export class BasicType {
974
1106
  Kind() {
975
1107
  return this._kind;
976
1108
  }
1109
+ underlyingName() {
1110
+ return Kind_String(this._kind);
1111
+ }
977
1112
  Comparable() {
978
1113
  return this._kind !== Func && this._kind !== Map && this._kind !== Slice;
979
1114
  }
@@ -986,6 +1121,21 @@ export class BasicType {
986
1121
  NumField() {
987
1122
  return 0;
988
1123
  }
1124
+ NumIn() {
1125
+ return nonFunctionTypePanic('NumIn', this);
1126
+ }
1127
+ In(_i) {
1128
+ return nonFunctionTypePanic('In', this);
1129
+ }
1130
+ NumOut() {
1131
+ return nonFunctionTypePanic('NumOut', this);
1132
+ }
1133
+ Out(_i) {
1134
+ return nonFunctionTypePanic('Out', this);
1135
+ }
1136
+ IsVariadic() {
1137
+ return nonFunctionTypePanic('IsVariadic', this);
1138
+ }
989
1139
  PkgPath() {
990
1140
  if (this._typeName) {
991
1141
  const dotIndex = this._typeName.lastIndexOf('.');
@@ -1025,7 +1175,7 @@ export class BasicType {
1025
1175
  if (u.Kind() !== Interface) {
1026
1176
  throw new Error('reflect: non-interface type passed to Type.Implements');
1027
1177
  }
1028
- return false;
1178
+ return typeImplementsInterface(this, u);
1029
1179
  }
1030
1180
  AssignableTo(u) {
1031
1181
  return typeAssignableTo(this, u);
@@ -1084,10 +1234,16 @@ export class BasicType {
1084
1234
  ' Type');
1085
1235
  }
1086
1236
  NumMethod() {
1087
- return 0;
1237
+ return typeMethods(this).length;
1088
1238
  }
1089
- MethodByName(_name) {
1090
- return [zeroMethod(), false];
1239
+ MethodByName(name) {
1240
+ return typeMethodByName(this, name);
1241
+ }
1242
+ methodSignatures() {
1243
+ return this._methods;
1244
+ }
1245
+ mergeMethodSignatures(methods) {
1246
+ this._methods = mergeMethodSignatureList(this._methods, methods);
1091
1247
  }
1092
1248
  Len() {
1093
1249
  throw new Error('reflect: call of reflect.Type.Len on ' +
@@ -1150,6 +1306,21 @@ class SliceType {
1150
1306
  NumField() {
1151
1307
  return 0;
1152
1308
  }
1309
+ NumIn() {
1310
+ return nonFunctionTypePanic('NumIn', this);
1311
+ }
1312
+ In(_i) {
1313
+ return nonFunctionTypePanic('In', this);
1314
+ }
1315
+ NumOut() {
1316
+ return nonFunctionTypePanic('NumOut', this);
1317
+ }
1318
+ Out(_i) {
1319
+ return nonFunctionTypePanic('Out', this);
1320
+ }
1321
+ IsVariadic() {
1322
+ return nonFunctionTypePanic('IsVariadic', this);
1323
+ }
1153
1324
  PkgPath() {
1154
1325
  return '';
1155
1326
  }
@@ -1176,7 +1347,7 @@ class SliceType {
1176
1347
  if (u.Kind() !== Interface) {
1177
1348
  throw new Error('reflect: non-interface type passed to Type.Implements');
1178
1349
  }
1179
- return false;
1350
+ return typeImplementsInterface(this, u);
1180
1351
  }
1181
1352
  AssignableTo(u) {
1182
1353
  return typeAssignableTo(this, u);
@@ -1229,6 +1400,21 @@ class ArrayType {
1229
1400
  NumField() {
1230
1401
  return 0;
1231
1402
  }
1403
+ NumIn() {
1404
+ return nonFunctionTypePanic('NumIn', this);
1405
+ }
1406
+ In(_i) {
1407
+ return nonFunctionTypePanic('In', this);
1408
+ }
1409
+ NumOut() {
1410
+ return nonFunctionTypePanic('NumOut', this);
1411
+ }
1412
+ Out(_i) {
1413
+ return nonFunctionTypePanic('Out', this);
1414
+ }
1415
+ IsVariadic() {
1416
+ return nonFunctionTypePanic('IsVariadic', this);
1417
+ }
1232
1418
  Len() {
1233
1419
  return this._len;
1234
1420
  }
@@ -1258,7 +1444,7 @@ class ArrayType {
1258
1444
  if (u.Kind() !== Interface) {
1259
1445
  throw new Error('reflect: non-interface type passed to Type.Implements');
1260
1446
  }
1261
- return false;
1447
+ return typeImplementsInterface(this, u);
1262
1448
  }
1263
1449
  AssignableTo(u) {
1264
1450
  return typeAssignableTo(this, u);
@@ -1288,8 +1474,10 @@ class ArrayType {
1288
1474
  // Pointer type implementation
1289
1475
  class PointerType {
1290
1476
  _elemType;
1291
- constructor(_elemType) {
1477
+ _methods;
1478
+ constructor(_elemType, _methods = []) {
1292
1479
  this._elemType = _elemType;
1480
+ this._methods = _methods;
1293
1481
  }
1294
1482
  String() {
1295
1483
  return '*' + this._elemType.String();
@@ -1309,6 +1497,21 @@ class PointerType {
1309
1497
  NumField() {
1310
1498
  return 0;
1311
1499
  }
1500
+ NumIn() {
1501
+ return nonFunctionTypePanic('NumIn', this);
1502
+ }
1503
+ In(_i) {
1504
+ return nonFunctionTypePanic('In', this);
1505
+ }
1506
+ NumOut() {
1507
+ return nonFunctionTypePanic('NumOut', this);
1508
+ }
1509
+ Out(_i) {
1510
+ return nonFunctionTypePanic('Out', this);
1511
+ }
1512
+ IsVariadic() {
1513
+ return nonFunctionTypePanic('IsVariadic', this);
1514
+ }
1312
1515
  PkgPath() {
1313
1516
  return '';
1314
1517
  }
@@ -1335,9 +1538,7 @@ class PointerType {
1335
1538
  if (u.Kind() !== Interface) {
1336
1539
  throw new Error('reflect: non-interface type passed to Type.Implements');
1337
1540
  }
1338
- // For pointer types, check if the element type implements the interface
1339
- const elemTypeName = this._elemType.String();
1340
- return typeImplementsInterface(elemTypeName, u);
1541
+ return typeImplementsInterface(this, u);
1341
1542
  }
1342
1543
  AssignableTo(u) {
1343
1544
  return typeAssignableTo(this, u);
@@ -1355,10 +1556,16 @@ class PointerType {
1355
1556
  throw new Error('reflect: call of reflect.Type.OverflowFloat on pointer Type');
1356
1557
  }
1357
1558
  NumMethod() {
1358
- return 0;
1559
+ return typeMethods(this).length;
1359
1560
  }
1360
1561
  MethodByName(name) {
1361
- return typeMethodByName(this._elemType, name);
1562
+ return typeMethodByName(this, name);
1563
+ }
1564
+ methodSignatures() {
1565
+ return this._methods;
1566
+ }
1567
+ mergeMethodSignatures(methods) {
1568
+ this._methods = mergeMethodSignatureList(this._methods, methods);
1362
1569
  }
1363
1570
  Len() {
1364
1571
  throw new Error('reflect: call of reflect.Type.Len on pointer Type');
@@ -1367,13 +1574,42 @@ class PointerType {
1367
1574
  throw new Error('reflect: call of reflect.Type.Bits on pointer Type');
1368
1575
  }
1369
1576
  }
1370
- // Function type implementation
1371
1577
  class FunctionType {
1578
+ _name;
1372
1579
  _signature;
1373
- constructor(_signature) {
1374
- this._signature = _signature;
1580
+ _params;
1581
+ _results;
1582
+ _variadic;
1583
+ _hasSignature;
1584
+ _methods;
1585
+ constructor(signatureOrDescriptor) {
1586
+ if (typeof signatureOrDescriptor === 'string') {
1587
+ this._name = '';
1588
+ this._signature = signatureOrDescriptor;
1589
+ this._params = [];
1590
+ this._results = [];
1591
+ this._variadic = false;
1592
+ this._hasSignature = false;
1593
+ this._methods = [];
1594
+ return;
1595
+ }
1596
+ this._name = signatureOrDescriptor.name ?? '';
1597
+ this._params = signatureOrDescriptor.params ?? [];
1598
+ this._results = signatureOrDescriptor.results ?? [];
1599
+ this._variadic = signatureOrDescriptor.variadic ?? false;
1600
+ this._hasSignature =
1601
+ signatureOrDescriptor.signature !== undefined ||
1602
+ signatureOrDescriptor.params !== undefined ||
1603
+ signatureOrDescriptor.results !== undefined;
1604
+ this._methods = signatureOrDescriptor.methods ?? [];
1605
+ this._signature =
1606
+ signatureOrDescriptor.signature ??
1607
+ formatFunctionSignature(this._params, this._results, this._variadic);
1375
1608
  }
1376
1609
  String() {
1610
+ if (this._name !== '') {
1611
+ return this._name;
1612
+ }
1377
1613
  return this._signature;
1378
1614
  }
1379
1615
  Kind() {
@@ -1391,11 +1627,44 @@ class FunctionType {
1391
1627
  NumField() {
1392
1628
  return 0;
1393
1629
  }
1630
+ NumIn() {
1631
+ return this._params.length;
1632
+ }
1633
+ In(i) {
1634
+ if (i < 0 || i >= this._params.length) {
1635
+ throw new Error(`reflect: In index out of range [${i}] with length ${this._params.length}`);
1636
+ }
1637
+ return this._params[i];
1638
+ }
1639
+ NumOut() {
1640
+ return this._results.length;
1641
+ }
1642
+ Out(i) {
1643
+ if (i < 0 || i >= this._results.length) {
1644
+ throw new Error(`reflect: Out index out of range [${i}] with length ${this._results.length}`);
1645
+ }
1646
+ return this._results[i];
1647
+ }
1648
+ IsVariadic() {
1649
+ return this._variadic;
1650
+ }
1394
1651
  PkgPath() {
1652
+ if (this._name !== '') {
1653
+ const dotIndex = this._name.lastIndexOf('.');
1654
+ if (dotIndex > 0) {
1655
+ return this._name.substring(0, dotIndex);
1656
+ }
1657
+ }
1395
1658
  return '';
1396
1659
  }
1397
1660
  Name() {
1398
- // Function types are unnamed composite types
1661
+ if (this._name !== '') {
1662
+ const dotIndex = this._name.lastIndexOf('.');
1663
+ if (dotIndex >= 0) {
1664
+ return this._name.substring(dotIndex + 1);
1665
+ }
1666
+ return this._name;
1667
+ }
1399
1668
  return '';
1400
1669
  }
1401
1670
  Field(_i) {
@@ -1417,7 +1686,7 @@ class FunctionType {
1417
1686
  if (u.Kind() !== Interface) {
1418
1687
  throw new Error('reflect: non-interface type passed to Type.Implements');
1419
1688
  }
1420
- return false;
1689
+ return typeImplementsInterface(this, u);
1421
1690
  }
1422
1691
  AssignableTo(u) {
1423
1692
  return typeAssignableTo(this, u);
@@ -1435,10 +1704,26 @@ class FunctionType {
1435
1704
  throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type');
1436
1705
  }
1437
1706
  NumMethod() {
1438
- return 0;
1707
+ return typeMethods(this).length;
1439
1708
  }
1440
- MethodByName(_name) {
1441
- return [zeroMethod(), false];
1709
+ MethodByName(name) {
1710
+ return typeMethodByName(this, name);
1711
+ }
1712
+ methodSignatures() {
1713
+ return this._methods;
1714
+ }
1715
+ mergeMethodSignatures(methods) {
1716
+ this._methods = mergeMethodSignatureList(this._methods, methods);
1717
+ }
1718
+ mergeSignature(source) {
1719
+ if (!source._hasSignature || this._hasSignature) {
1720
+ return;
1721
+ }
1722
+ this._params = source._params;
1723
+ this._results = source._results;
1724
+ this._variadic = source._variadic;
1725
+ this._signature = source._signature;
1726
+ this._hasSignature = true;
1442
1727
  }
1443
1728
  Len() {
1444
1729
  throw new Error('reflect: call of reflect.Type.Len on func Type');
@@ -1447,6 +1732,174 @@ class FunctionType {
1447
1732
  throw new Error('reflect: call of reflect.Type.Bits on func Type');
1448
1733
  }
1449
1734
  }
1735
+ function formatFunctionSignature(params, results, variadic) {
1736
+ const paramStrings = params.map((param, index) => {
1737
+ const typeName = param.String();
1738
+ if (!variadic || index !== params.length - 1) {
1739
+ return typeName;
1740
+ }
1741
+ if (typeName.startsWith('[]')) {
1742
+ return '...' + typeName.slice(2);
1743
+ }
1744
+ return '...' + typeName;
1745
+ });
1746
+ let signature = `func(${paramStrings.join(', ')})`;
1747
+ if (results.length === 1) {
1748
+ signature += ` ${results[0].String()}`;
1749
+ }
1750
+ else if (results.length > 1) {
1751
+ signature += ` (${results.map((result) => result.String()).join(', ')})`;
1752
+ }
1753
+ return signature;
1754
+ }
1755
+ async function callReflectFunction(fn, fnType, inArgs, op) {
1756
+ const args = $.asArray(inArgs);
1757
+ const rawArgs = reflectCallRawArgs(fnType, args, op);
1758
+ const result = await fn(...rawArgs);
1759
+ return normalizeReflectCallResults(fnType, result);
1760
+ }
1761
+ function reflectCallRawArgs(fnType, args, op) {
1762
+ if (op === 'CallSlice') {
1763
+ return reflectCallSliceRawArgs(fnType, args);
1764
+ }
1765
+ if (!fnType.IsVariadic()) {
1766
+ validateReflectCallInputCount(fnType, args.length);
1767
+ return args.map((arg, index) => reflectCallValueInterface(op, arg, fnType.In(index), index));
1768
+ }
1769
+ const fixedCount = fnType.NumIn() - 1;
1770
+ if (args.length < fixedCount) {
1771
+ throw new Error('reflect: Call with too few input arguments');
1772
+ }
1773
+ const rawArgs = [];
1774
+ for (let i = 0; i < fixedCount; i++) {
1775
+ rawArgs.push(reflectCallValueInterface(op, args[i], fnType.In(i), i));
1776
+ }
1777
+ const variadicElemType = fnType.In(fixedCount).Elem();
1778
+ const variadicValues = args.slice(fixedCount);
1779
+ for (let i = 0; i < variadicValues.length; i++) {
1780
+ const value = variadicValues[i];
1781
+ if (!value.IsValid()) {
1782
+ throw new Error(`reflect: ${op} using zero Value argument`);
1783
+ }
1784
+ if (!value.Type().AssignableTo(variadicElemType)) {
1785
+ throw new Error(`reflect: cannot use ${value.Type().String()} as type ${variadicElemType.String()} in ${op}`);
1786
+ }
1787
+ }
1788
+ rawArgs.push($.arrayToSlice(variadicValues.map((value) => value.Interface())));
1789
+ return rawArgs;
1790
+ }
1791
+ function reflectCallSliceRawArgs(fnType, args) {
1792
+ if (!fnType.IsVariadic()) {
1793
+ throw new Error('reflect: CallSlice of non-variadic function');
1794
+ }
1795
+ const expected = fnType.NumIn();
1796
+ if (args.length < expected) {
1797
+ throw new Error('reflect: CallSlice with too few input arguments');
1798
+ }
1799
+ if (args.length > expected) {
1800
+ throw new Error('reflect: CallSlice with too many input arguments');
1801
+ }
1802
+ return args.map((arg, index) => reflectCallValueInterface('CallSlice', arg, fnType.In(index), index));
1803
+ }
1804
+ function reflectCallValueInterface(op, value, target, _index) {
1805
+ if (!value.IsValid()) {
1806
+ throw new Error(`reflect: ${op} using zero Value argument`);
1807
+ }
1808
+ if (!value.Type().AssignableTo(target)) {
1809
+ throw new Error(`reflect: ${op} using ${value.Type().String()} as type ${target.String()}`);
1810
+ }
1811
+ return value.Interface();
1812
+ }
1813
+ function validateReflectCallInputCount(fnType, actual) {
1814
+ const expected = fnType.NumIn();
1815
+ if (actual !== expected) {
1816
+ throw new Error(`reflect: Call with ${actual} input arguments for function with ${expected} inputs`);
1817
+ }
1818
+ }
1819
+ function normalizeReflectCallResults(fnType, result) {
1820
+ const expected = fnType.NumOut();
1821
+ if (expected === 0) {
1822
+ if (result !== undefined) {
1823
+ throw new Error('reflect: Call returned 1 results for function with 0 outputs');
1824
+ }
1825
+ return $.makeSlice(0);
1826
+ }
1827
+ if (expected === 1) {
1828
+ return $.arrayToSlice([new Value(result, fnType.Out(0))]);
1829
+ }
1830
+ if (!globalThis.Array.isArray(result)) {
1831
+ throw new Error(`reflect: Call returned 1 results for function with ${expected} outputs`);
1832
+ }
1833
+ if (result.length !== expected) {
1834
+ throw new Error(`reflect: Call returned ${result.length} results for function with ${expected} outputs`);
1835
+ }
1836
+ return $.arrayToSlice(result.map((value, index) => new Value(value, fnType.Out(index))));
1837
+ }
1838
+ export function MakeFunc(typ, fn) {
1839
+ if (!typ || typ.Kind() !== Func) {
1840
+ throw new Error('reflect: call of MakeFunc with non-Func type');
1841
+ }
1842
+ if (typeof fn !== 'function') {
1843
+ throw new Error('reflect.MakeFunc: nil implementation');
1844
+ }
1845
+ const typeInfo = functionTypeInfoFromType(typ);
1846
+ const wrapper = $.functionValue(async (...rawArgs) => {
1847
+ const args = makeFuncArgs(typ, rawArgs);
1848
+ const resultValues = $.asArray(await fn($.arrayToSlice(args)));
1849
+ validateMakeFuncResults(typ, resultValues);
1850
+ if (typ.NumOut() === 0) {
1851
+ return undefined;
1852
+ }
1853
+ if (typ.NumOut() === 1) {
1854
+ return makeFuncReturnInterface(resultValues[0], typ.Out(0));
1855
+ }
1856
+ return resultValues.map((value, index) => makeFuncReturnInterface(value, typ.Out(index)));
1857
+ }, typeInfo);
1858
+ return new Value(wrapper, typ);
1859
+ }
1860
+ function makeFuncArgs(typ, rawArgs) {
1861
+ validateReflectCallInputCount(typ, rawArgs.length);
1862
+ return rawArgs.map((arg, index) => {
1863
+ const value = ValueOf(arg);
1864
+ const target = typ.In(index);
1865
+ if (!value.Type().AssignableTo(target)) {
1866
+ throw new Error(`reflect.MakeFunc: cannot use ${value.Type().String()} as type ${target.String()} in argument ${index}`);
1867
+ }
1868
+ return value;
1869
+ });
1870
+ }
1871
+ function validateMakeFuncResults(typ, resultValues) {
1872
+ const expected = typ.NumOut();
1873
+ if (resultValues.length !== expected) {
1874
+ throw new Error(`reflect.MakeFunc: returned ${resultValues.length} results for function with ${expected} outputs`);
1875
+ }
1876
+ for (let i = 0; i < resultValues.length; i++) {
1877
+ const result = resultValues[i];
1878
+ if (!result.IsValid()) {
1879
+ throw new Error(`reflect.MakeFunc: returned zero Value for result ${i}`);
1880
+ }
1881
+ const target = typ.Out(i);
1882
+ if (!result.Type().AssignableTo(target)) {
1883
+ throw new Error(`reflect.MakeFunc: cannot use ${result.Type().String()} as type ${target.String()} in result ${i}`);
1884
+ }
1885
+ }
1886
+ }
1887
+ function makeFuncReturnInterface(value, target) {
1888
+ const raw = value.Interface();
1889
+ if (target.Kind() === Interface) {
1890
+ return raw;
1891
+ }
1892
+ return unwrapGoInterfaceBox(raw);
1893
+ }
1894
+ function unwrapGoInterfaceBox(value) {
1895
+ if (value !== null &&
1896
+ value !== undefined &&
1897
+ typeof value === 'object' &&
1898
+ '__goValue' in value) {
1899
+ return value.__goValue;
1900
+ }
1901
+ return value;
1902
+ }
1450
1903
  // Map type implementation
1451
1904
  class MapType {
1452
1905
  _keyType;
@@ -1473,6 +1926,21 @@ class MapType {
1473
1926
  NumField() {
1474
1927
  return 0;
1475
1928
  }
1929
+ NumIn() {
1930
+ return nonFunctionTypePanic('NumIn', this);
1931
+ }
1932
+ In(_i) {
1933
+ return nonFunctionTypePanic('In', this);
1934
+ }
1935
+ NumOut() {
1936
+ return nonFunctionTypePanic('NumOut', this);
1937
+ }
1938
+ Out(_i) {
1939
+ return nonFunctionTypePanic('Out', this);
1940
+ }
1941
+ IsVariadic() {
1942
+ return nonFunctionTypePanic('IsVariadic', this);
1943
+ }
1476
1944
  Key() {
1477
1945
  return this._keyType;
1478
1946
  }
@@ -1499,7 +1967,7 @@ class MapType {
1499
1967
  if (u.Kind() !== Interface) {
1500
1968
  throw new Error('reflect: non-interface type passed to Type.Implements');
1501
1969
  }
1502
- return false;
1970
+ return typeImplementsInterface(this, u);
1503
1971
  }
1504
1972
  AssignableTo(u) {
1505
1973
  return typeAssignableTo(this, u);
@@ -1530,47 +1998,122 @@ class MapType {
1530
1998
  }
1531
1999
  }
1532
2000
  // Struct type implementation
1533
- /**
1534
- * Helper function to check if a type's method set contains all methods
1535
- * required by an interface.
1536
- *
1537
- * @param typeName The name of the type to check (e.g., "main.MyType")
1538
- * @param interfaceType The interface type that must be implemented
1539
- * @returns True if the type implements the interface, false otherwise
1540
- */
1541
- function typeImplementsInterface(typeName, interfaceType) {
1542
- // Get the interface name and look it up in the type registry
1543
- const interfaceName = interfaceType instanceof InterfaceType ?
1544
- interfaceType.registeredName() || interfaceType.String()
1545
- : interfaceType.String();
1546
- const interfaceTypeInfo = builtinGetTypeByName(interfaceName);
1547
- if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
1548
- return false;
2001
+ function typeImplementsInterface(t, interfaceType) {
2002
+ if (interfaceType.Kind() !== Interface) {
2003
+ throw new Error('reflect: non-interface type passed to Type.Implements');
2004
+ }
2005
+ const requiredMethods = typeMethods(interfaceType);
2006
+ if (requiredMethods.length === 0) {
2007
+ return true;
1549
2008
  }
1550
- // Get the type info for the struct/type
1551
- const typeInfo = builtinGetTypeByName(typeName);
1552
- if (!typeInfo || !isStructTypeInfo(typeInfo)) {
2009
+ const methods = typeMethods(t);
2010
+ return requiredMethods.every((requiredMethod) => {
2011
+ const method = methods.find((candidate) => candidate.name === requiredMethod.name);
2012
+ return (method !== undefined && methodSignatureIdentical(method, requiredMethod));
2013
+ });
2014
+ }
2015
+ function methodSignatureIdentical(actual, required) {
2016
+ return (methodArgListIdentical(actual.args, required.args) &&
2017
+ methodArgListIdentical(actual.returns, required.returns));
2018
+ }
2019
+ function methodArgListIdentical(actual, required) {
2020
+ if (actual.length !== required.length) {
1553
2021
  return false;
1554
2022
  }
1555
- // Check if the type has all required methods
1556
- const requiredMethods = interfaceTypeInfo.methods || [];
1557
- const typeMethods = typeInfo.methods || [];
1558
- // For each required method, check if the type has a matching method
1559
- for (const requiredMethod of requiredMethods) {
1560
- const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name);
1561
- if (!typeMethod) {
1562
- return false;
2023
+ return actual.every((arg, index) => methodArgIdentityKey(arg) === methodArgIdentityKey(required[index]));
2024
+ }
2025
+ function methodArgIdentityKey(arg) {
2026
+ return typeInfoIdentityKey(arg.type, new Set());
2027
+ }
2028
+ function methodSignatureIdentityKey(method) {
2029
+ const args = method.args.map(methodArgIdentityKey).join(',');
2030
+ const returns = method.returns.map(methodArgIdentityKey).join(',');
2031
+ return `${method.name}(${args})(${returns})`;
2032
+ }
2033
+ function mergeMethodSignatureList(existing, incoming) {
2034
+ if (incoming.length === 0) {
2035
+ return existing;
2036
+ }
2037
+ const merged = [...existing];
2038
+ for (const method of incoming) {
2039
+ const existingIndex = merged.findIndex((candidate) => candidate.name === method.name);
2040
+ if (existingIndex === -1) {
2041
+ merged.push(method);
2042
+ continue;
1563
2043
  }
1564
- // Check if method signatures match (simplified - just check counts)
1565
- if (typeMethod.args.length !== requiredMethod.args.length) {
1566
- return false;
2044
+ if (methodSignatureIdentityKey(merged[existingIndex]) !==
2045
+ methodSignatureIdentityKey(method)) {
2046
+ merged[existingIndex] = method;
1567
2047
  }
1568
- if (typeMethod.returns.length !== requiredMethod.returns.length) {
1569
- return false;
2048
+ }
2049
+ return merged.sort((left, right) => left.name.localeCompare(right.name));
2050
+ }
2051
+ function typeInfoIdentityKey(info, seen) {
2052
+ if (typeof info === 'string') {
2053
+ const registered = builtinGetTypeByName(info);
2054
+ if (!registered) {
2055
+ return `named:${info}`;
2056
+ }
2057
+ const registeredName = registered.name ?? info;
2058
+ if (registeredName !== '') {
2059
+ return `named:${registeredName}`;
1570
2060
  }
1571
- // Could add deeper type checking here, but for now this is sufficient
2061
+ if (seen.has(info)) {
2062
+ return `named:${info}`;
2063
+ }
2064
+ seen.add(info);
2065
+ const key = typeInfoIdentityKey(registered, seen);
2066
+ seen.delete(info);
2067
+ return key;
2068
+ }
2069
+ switch (info.kind) {
2070
+ case $.TypeKind.Basic:
2071
+ if (info.typeName) {
2072
+ return `named:${info.typeName}`;
2073
+ }
2074
+ return `basic:${info.name ?? 'unknown'}`;
2075
+ case $.TypeKind.Interface:
2076
+ if (info.name) {
2077
+ return `named:${info.name}`;
2078
+ }
2079
+ return `interface:${(info.methods ?? [])
2080
+ .map(methodSignatureIdentityKey)
2081
+ .join('|')}`;
2082
+ case $.TypeKind.Struct:
2083
+ if (info.name) {
2084
+ return `named:${info.name}`;
2085
+ }
2086
+ return `struct:${(info.fields ?? [])
2087
+ .map((field) => [
2088
+ field.name,
2089
+ field.pkgPath ?? '',
2090
+ field.tag ?? '',
2091
+ field.anonymous === true ? 'anonymous' : 'named',
2092
+ typeInfoIdentityKey(field.type, seen),
2093
+ ].join('\u0000'))
2094
+ .join('\u0001')}`;
2095
+ case $.TypeKind.Pointer:
2096
+ return `ptr:${typeInfoIdentityKey(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
2097
+ case $.TypeKind.Slice:
2098
+ return `slice:${typeInfoIdentityKey(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
2099
+ case $.TypeKind.Array:
2100
+ return `array:${info.length}:${typeInfoIdentityKey(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
2101
+ case $.TypeKind.Map:
2102
+ return `map:${typeInfoIdentityKey(info.keyType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}:${typeInfoIdentityKey(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
2103
+ case $.TypeKind.Function:
2104
+ if (info.name) {
2105
+ return `named:${info.name}`;
2106
+ }
2107
+ return `func:${info.isVariadic === true}:${(info.params ?? [])
2108
+ .map((param) => typeInfoIdentityKey(param, seen))
2109
+ .join(',')}:${(info.results ?? [])
2110
+ .map((result) => typeInfoIdentityKey(result, seen))
2111
+ .join(',')}`;
2112
+ case $.TypeKind.Channel:
2113
+ return `chan:${info.direction ?? 'both'}:${typeInfoIdentityKey(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
2114
+ default:
2115
+ return 'unknown';
1572
2116
  }
1573
- return true;
1574
2117
  }
1575
2118
  function typeFieldByName(t, name) {
1576
2119
  return typeFieldByNameFunc(t, (fieldName) => fieldName === name);
@@ -1579,14 +2122,62 @@ function typeFieldByNameFunc(t, match) {
1579
2122
  if (t.Kind() !== Struct) {
1580
2123
  throw new Error('reflect: FieldByName of non-struct type');
1581
2124
  }
1582
- for (let i = 0; i < t.NumField(); i++) {
1583
- const field = t.Field(i);
2125
+ for (const field of visibleStructFields(t)) {
1584
2126
  if (match(field.Name)) {
1585
2127
  return [field, true];
1586
2128
  }
1587
2129
  }
1588
2130
  return [new StructField(), false];
1589
2131
  }
2132
+ export function visibleStructFields(t) {
2133
+ const fields = [];
2134
+ const byName = new globalThis.Map();
2135
+ const visiting = new Set();
2136
+ const index = [];
2137
+ const walk = (typ) => {
2138
+ if (visiting.has(typ)) {
2139
+ return;
2140
+ }
2141
+ visiting.add(typ);
2142
+ for (let i = 0; i < typ.NumField(); i++) {
2143
+ const field = typ.Field(i).clone();
2144
+ index.push(i);
2145
+ let add = true;
2146
+ const oldIndex = byName.get(field.Name);
2147
+ if (oldIndex !== undefined) {
2148
+ const old = fields[oldIndex];
2149
+ if (index.length === old.Index.length) {
2150
+ old.Name = '';
2151
+ add = false;
2152
+ }
2153
+ else if (index.length < old.Index.length) {
2154
+ old.Name = '';
2155
+ }
2156
+ else {
2157
+ add = false;
2158
+ }
2159
+ }
2160
+ if (add) {
2161
+ field.Index = [...index];
2162
+ byName.set(field.Name, fields.length);
2163
+ fields.push(field);
2164
+ }
2165
+ if (field.Anonymous) {
2166
+ let fieldType = field.Type;
2167
+ if (fieldType.Kind() === Ptr) {
2168
+ fieldType = fieldType.Elem();
2169
+ }
2170
+ if (fieldType.Kind() === Struct) {
2171
+ walk(fieldType);
2172
+ }
2173
+ }
2174
+ index.pop();
2175
+ }
2176
+ visiting.delete(typ);
2177
+ };
2178
+ walk(t);
2179
+ return fields.filter((field) => field.Name !== '');
2180
+ }
1590
2181
  function zeroMethod() {
1591
2182
  return {
1592
2183
  Name: '',
@@ -1595,16 +2186,50 @@ function zeroMethod() {
1595
2186
  Index: 0,
1596
2187
  };
1597
2188
  }
1598
- function methodFromSignature(signature, index) {
2189
+ function methodFromSignature(signature, index, receiver) {
1599
2190
  return {
1600
2191
  Name: signature.name,
1601
- Type: new FunctionType('func'),
2192
+ Type: methodTypeFromSignature(signature, receiver, receiver.Kind() !== Interface),
1602
2193
  Func: () => undefined,
1603
2194
  Index: index,
1604
2195
  };
1605
2196
  }
2197
+ function methodTypeFromSignature(signature, receiver, includeReceiver) {
2198
+ const params = signature.args.map(methodArgType);
2199
+ if (includeReceiver) {
2200
+ params.unshift(receiver);
2201
+ }
2202
+ return new FunctionType({
2203
+ params,
2204
+ results: signature.returns.map(methodArgType),
2205
+ });
2206
+ }
2207
+ function methodArgType(arg) {
2208
+ return typeFromTypeInfoWithSeen(arg.type, new Set());
2209
+ }
1606
2210
  function typeMethods(t) {
1607
- const typeInfo = builtinGetTypeByName(t.String());
2211
+ let typeInfo = builtinGetTypeByName(t.String());
2212
+ if (!typeInfo && t.Kind() === Ptr) {
2213
+ typeInfo = builtinGetTypeByName(t.Elem().String());
2214
+ }
2215
+ if (!typeInfo && t instanceof InterfaceType) {
2216
+ const registeredName = t.registeredName();
2217
+ if (registeredName) {
2218
+ typeInfo = builtinGetTypeByName(registeredName);
2219
+ }
2220
+ }
2221
+ if (!typeInfo && t instanceof InterfaceType) {
2222
+ return t.methodSignatures();
2223
+ }
2224
+ if (!typeInfo && t instanceof PointerType) {
2225
+ return mergeMethodSignatureList(typeMethods(t.Elem()), t.methodSignatures());
2226
+ }
2227
+ if (!typeInfo && t instanceof BasicType) {
2228
+ return t.methodSignatures();
2229
+ }
2230
+ if (!typeInfo && t instanceof FunctionType) {
2231
+ return t.methodSignatures();
2232
+ }
1608
2233
  if (!typeInfo) {
1609
2234
  return [];
1610
2235
  }
@@ -1613,29 +2238,98 @@ function typeMethods(t) {
1613
2238
  }
1614
2239
  return [];
1615
2240
  }
1616
- function typeMethodByName(t, name) {
2241
+ function methodSignatureByName(t, name) {
1617
2242
  const methods = typeMethods(t);
1618
2243
  const index = methods.findIndex((method) => method.name === name);
1619
2244
  if (index === -1) {
2245
+ return [undefined, -1];
2246
+ }
2247
+ return [methods[index], index];
2248
+ }
2249
+ function typeMethodByName(t, name) {
2250
+ const [signature, index] = methodSignatureByName(t, name);
2251
+ if (!signature) {
1620
2252
  return [zeroMethod(), false];
1621
2253
  }
1622
- return [methodFromSignature(methods[index], index), true];
2254
+ return [methodFromSignature(signature, index, t), true];
1623
2255
  }
1624
2256
  function typeAssignableTo(t, u) {
1625
2257
  if (u === null) {
1626
2258
  return false;
1627
2259
  }
1628
- return t.String() === u.String() || t.Implements(u);
2260
+ if (typeIdentityKey(t) === typeIdentityKey(u)) {
2261
+ return true;
2262
+ }
2263
+ if ((!typeIsNamed(t) || !typeIsNamed(u)) &&
2264
+ typeUnderlyingIdentityKey(t) === typeUnderlyingIdentityKey(u)) {
2265
+ return true;
2266
+ }
2267
+ if (u.Kind() !== Interface) {
2268
+ return false;
2269
+ }
2270
+ return t.Implements(u);
2271
+ }
2272
+ export function structFieldStorageKey(t, i) {
2273
+ if (t instanceof StructType) {
2274
+ return t.fieldKey(i);
2275
+ }
2276
+ return t.Field(i).Name;
2277
+ }
2278
+ function typeAlignment(typ) {
2279
+ switch (typ.Kind()) {
2280
+ case Bool:
2281
+ case Int8:
2282
+ case Uint8:
2283
+ return 1;
2284
+ case Int16:
2285
+ case Uint16:
2286
+ return 2;
2287
+ case Int32:
2288
+ case Uint32:
2289
+ case Float32:
2290
+ case Complex64:
2291
+ return 4;
2292
+ case Array:
2293
+ return typeAlignment(typ.Elem());
2294
+ case Struct: {
2295
+ let align = 1;
2296
+ for (let i = 0; i < typ.NumField(); i++) {
2297
+ align = Math.max(align, typeAlignment(typ.Field(i).Type));
2298
+ }
2299
+ return align;
2300
+ }
2301
+ default:
2302
+ return 8;
2303
+ }
2304
+ }
2305
+ function alignOffset(offset, alignment) {
2306
+ if (alignment <= 1) {
2307
+ return offset;
2308
+ }
2309
+ return Math.ceil(offset / alignment) * alignment;
2310
+ }
2311
+ function structDescriptorSize(fields) {
2312
+ let size = 0;
2313
+ let alignment = 1;
2314
+ for (const field of fields) {
2315
+ alignment = Math.max(alignment, typeAlignment(field.type));
2316
+ size = Math.max(size, field.offset + field.type.Size());
2317
+ }
2318
+ return alignOffset(size, alignment);
1629
2319
  }
1630
2320
  class StructType {
1631
2321
  _name;
1632
2322
  _fields;
1633
- constructor(_name, _fields = []) {
2323
+ _pkgPath;
2324
+ _string;
2325
+ constructor(_name, _fields = [], _pkgPath = '', _string = _name) {
1634
2326
  this._name = _name;
1635
2327
  this._fields = _fields;
2328
+ this._pkgPath = _pkgPath;
2329
+ this._string = _string;
1636
2330
  }
1637
2331
  String() {
1638
- return this._name;
2332
+ return this._string;
1639
2333
  }
1640
2334
  Kind() {
1641
2335
  return Struct;
@@ -1644,8 +2338,7 @@ class StructType {
1644
2338
  return this._fields.every((field) => field.type.Comparable());
1645
2339
  }
1646
2340
  Size() {
1647
- // Struct size is implementation-defined, we'll use a reasonable default
1648
- return this._fields.reduce((sum, field) => sum + field.type.Size(), 0);
2341
+ return structDescriptorSize(this._fields);
1649
2342
  }
1650
2343
  Elem() {
1651
2344
  throw new Error('reflect: Elem of invalid type');
@@ -1653,7 +2346,28 @@ class StructType {
1653
2346
  NumField() {
1654
2347
  return this._fields.length;
1655
2348
  }
2349
+ NumIn() {
2350
+ return nonFunctionTypePanic('NumIn', this);
2351
+ }
2352
+ In(_i) {
2353
+ return nonFunctionTypePanic('In', this);
2354
+ }
2355
+ NumOut() {
2356
+ return nonFunctionTypePanic('NumOut', this);
2357
+ }
2358
+ Out(_i) {
2359
+ return nonFunctionTypePanic('Out', this);
2360
+ }
2361
+ IsVariadic() {
2362
+ return nonFunctionTypePanic('IsVariadic', this);
2363
+ }
1656
2364
  PkgPath() {
2365
+ if (this._pkgPath !== '') {
2366
+ return this._pkgPath;
2367
+ }
2368
+ if (this._name === '') {
2369
+ return '';
2370
+ }
1657
2371
  // Extract package path from full type name (e.g., "main.Person" -> "main")
1658
2372
  const dotIndex = this._name.lastIndexOf('.');
1659
2373
  if (dotIndex > 0) {
@@ -1662,6 +2376,9 @@ class StructType {
1662
2376
  return '';
1663
2377
  }
1664
2378
  Name() {
2379
+ if (this._name === '') {
2380
+ return '';
2381
+ }
1665
2382
  // Extract type name from full type name (e.g., "main.Person" -> "Person")
1666
2383
  const dotIndex = this._name.lastIndexOf('.');
1667
2384
  if (dotIndex >= 0) {
@@ -1676,12 +2393,56 @@ class StructType {
1676
2393
  const f = this._fields[i];
1677
2394
  return new StructField({
1678
2395
  Name: f.name,
1679
- PkgPath: '',
2396
+ PkgPath: f.pkgPath,
1680
2397
  Type: f.type,
1681
2398
  Tag: f.tag ? new StructTag(f.tag) : undefined,
1682
- Index: [i],
2399
+ Offset: f.offset,
2400
+ Index: [...f.index],
2401
+ Anonymous: f.anonymous,
1683
2402
  });
1684
2403
  }
2404
+ fieldKey(i) {
2405
+ if (i < 0 || i >= this.NumField()) {
2406
+ throw new Error(`reflect: Field index out of range [${i}] with length ${this.NumField()}`);
2407
+ }
2408
+ return this._fields[i].key;
2409
+ }
2410
+ descriptors() {
2411
+ return this._fields.map((field) => ({
2412
+ ...field,
2413
+ index: [...field.index],
2414
+ }));
2415
+ }
2416
+ replaceDescriptors(fields) {
2417
+ this._fields = fields;
2418
+ }
2419
+ identityKey(seen) {
2420
+ if (this._name !== '') {
2421
+ return `struct:${this._name}`;
2422
+ }
2423
+ const fields = this._fields
2424
+ .map((field) => [
2425
+ field.name,
2426
+ field.pkgPath,
2427
+ field.tag ?? '',
2428
+ field.anonymous ? 'anonymous' : 'named',
2429
+ typeIdentityKey(field.type, seen),
2430
+ ].join('\u0000'))
2431
+ .join('\u0001');
2432
+ return `struct:${this._pkgPath}:${this._name}:${fields}`;
2433
+ }
2434
+ underlyingIdentityKey(seen) {
2435
+ const fields = this._fields
2436
+ .map((field) => [
2437
+ field.name,
2438
+ field.pkgPath,
2439
+ field.tag ?? '',
2440
+ field.anonymous ? 'anonymous' : 'named',
2441
+ typeIdentityKey(field.type, seen),
2442
+ ].join('\u0000'))
2443
+ .join('\u0001');
2444
+ return `struct:${fields}`;
2445
+ }
1685
2446
  FieldByName(name) {
1686
2447
  return typeFieldByName(this, name);
1687
2448
  }
@@ -1698,7 +2459,7 @@ class StructType {
1698
2459
  if (u.Kind() !== Interface) {
1699
2460
  throw new Error('reflect: non-interface type passed to Type.Implements');
1700
2461
  }
1701
- return typeImplementsInterface(this._name, u);
2462
+ return typeImplementsInterface(this, u);
1702
2463
  }
1703
2464
  AssignableTo(u) {
1704
2465
  return typeAssignableTo(this, u);
@@ -1727,7 +2488,7 @@ class StructType {
1727
2488
  Bits() {
1728
2489
  throw new Error('reflect: call of reflect.Type.Bits on struct Type');
1729
2490
  }
1730
- static createTypeFromFieldInfo(ti) {
2491
+ static createTypeFromFieldInfo(ti, seen = new Set()) {
1731
2492
  if (typeof ti === 'string') {
1732
2493
  return basicTypeFromName(ti === 'number' ? 'int' : ti);
1733
2494
  }
@@ -1740,18 +2501,21 @@ class StructType {
1740
2501
  return basicTypeFromName(name === 'number' ? 'int' : name, typeName);
1741
2502
  case 'slice':
1742
2503
  if (ti.elemType) {
1743
- return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType));
2504
+ return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType, seen));
1744
2505
  }
1745
2506
  return new SliceType(new BasicType(Invalid, 'unknown', 8));
1746
2507
  case 'pointer':
1747
2508
  if (ti.elemType) {
1748
- return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType));
2509
+ return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType, seen));
1749
2510
  }
1750
2511
  return new PointerType(new BasicType(Invalid, 'unknown', 8));
1751
2512
  case 'interface':
1752
- return new InterfaceType(name);
1753
- case 'struct':
1754
- return new StructType(name, structFieldsFromTypeInfo(ti));
2513
+ return interfaceTypeFromInfo(ti, seen);
2514
+ case 'struct': {
2515
+ const structName = ti.name ?? '';
2516
+ const fields = structFieldsFromTypeInfo(ti, seen);
2517
+ return new StructType(structName, fields, '', structName === '' ? structTypeString(fields) : structName);
2518
+ }
1755
2519
  default:
1756
2520
  return new BasicType(Invalid, name, 8);
1757
2521
  }
@@ -1801,18 +2565,18 @@ function basicTypeFromName(name, typeName = '') {
1801
2565
  return new BasicType(Invalid, name, 8, typeName);
1802
2566
  }
1803
2567
  }
1804
- function structFieldsFromTypeInfo(ti) {
1805
- return Object.entries(ti.fields || {}).map(([name, fieldInfo]) => {
1806
- if (isStructFieldInfo(fieldInfo)) {
1807
- return {
1808
- name: fieldInfo.name ?? name,
1809
- type: typeFromTypeInfo(fieldInfo.type),
1810
- tag: fieldInfo.tag,
1811
- };
1812
- }
2568
+ function structFieldsFromTypeInfo(ti, seen = new Set()) {
2569
+ return (ti.fields || []).map((fieldInfo, index) => {
1813
2570
  return {
1814
- name,
1815
- type: typeFromTypeInfo(fieldInfo),
2571
+ name: fieldInfo.name,
2572
+ key: structFieldRuntimeKey(fieldInfo),
2573
+ type: typeFromTypeInfoWithSeen(fieldInfo.type, seen),
2574
+ tag: fieldInfo.tag,
2575
+ pkgPath: fieldInfo.pkgPath ?? '',
2576
+ anonymous: fieldInfo.anonymous ?? false,
2577
+ index: fieldInfo.index ? [...fieldInfo.index] : [index],
2578
+ offset: fieldInfo.offset ?? index * 8,
2579
+ exported: fieldInfo.exported ?? (fieldInfo.pkgPath ?? '') === '',
1816
2580
  };
1817
2581
  });
1818
2582
  }
@@ -1852,6 +2616,21 @@ class ChannelType {
1852
2616
  NumField() {
1853
2617
  return 0;
1854
2618
  }
2619
+ NumIn() {
2620
+ return nonFunctionTypePanic('NumIn', this);
2621
+ }
2622
+ In(_i) {
2623
+ return nonFunctionTypePanic('In', this);
2624
+ }
2625
+ NumOut() {
2626
+ return nonFunctionTypePanic('NumOut', this);
2627
+ }
2628
+ Out(_i) {
2629
+ return nonFunctionTypePanic('Out', this);
2630
+ }
2631
+ IsVariadic() {
2632
+ return nonFunctionTypePanic('IsVariadic', this);
2633
+ }
1855
2634
  PkgPath() {
1856
2635
  return '';
1857
2636
  }
@@ -1878,7 +2657,7 @@ class ChannelType {
1878
2657
  if (u.Kind() !== Interface) {
1879
2658
  throw new Error('reflect: non-interface type passed to Type.Implements');
1880
2659
  }
1881
- return false;
2660
+ return typeImplementsInterface(this, u);
1882
2661
  }
1883
2662
  AssignableTo(u) {
1884
2663
  return typeAssignableTo(this, u);
@@ -1915,9 +2694,11 @@ class ChannelType {
1915
2694
  class InterfaceType {
1916
2695
  _name;
1917
2696
  _registeredName;
1918
- constructor(_name = 'interface{}', _registeredName) {
2697
+ _methods;
2698
+ constructor(_name = 'interface{}', _registeredName, _methods = []) {
1919
2699
  this._name = _name;
1920
2700
  this._registeredName = _registeredName;
2701
+ this._methods = _methods;
1921
2702
  }
1922
2703
  String() {
1923
2704
  return this._name;
@@ -1937,6 +2718,21 @@ class InterfaceType {
1937
2718
  NumField() {
1938
2719
  return 0;
1939
2720
  }
2721
+ NumIn() {
2722
+ return nonFunctionTypePanic('NumIn', this);
2723
+ }
2724
+ In(_i) {
2725
+ return nonFunctionTypePanic('In', this);
2726
+ }
2727
+ NumOut() {
2728
+ return nonFunctionTypePanic('NumOut', this);
2729
+ }
2730
+ Out(_i) {
2731
+ return nonFunctionTypePanic('Out', this);
2732
+ }
2733
+ IsVariadic() {
2734
+ return nonFunctionTypePanic('IsVariadic', this);
2735
+ }
1940
2736
  PkgPath() {
1941
2737
  if (this._name === 'interface{}' || this._name.startsWith('interface {')) {
1942
2738
  return '';
@@ -1969,8 +2765,14 @@ class InterfaceType {
1969
2765
  Key() {
1970
2766
  throw new Error('reflect: Key of non-map type');
1971
2767
  }
1972
- Implements(_u) {
1973
- return false;
2768
+ Implements(u) {
2769
+ if (!u) {
2770
+ return false;
2771
+ }
2772
+ if (u.Kind() !== Interface) {
2773
+ throw new Error('reflect: non-interface type passed to Type.Implements');
2774
+ }
2775
+ return typeImplementsInterface(this, u);
1974
2776
  }
1975
2777
  AssignableTo(u) {
1976
2778
  return typeAssignableTo(this, u);
@@ -2002,6 +2804,9 @@ class InterfaceType {
2002
2804
  registeredName() {
2003
2805
  return this._registeredName;
2004
2806
  }
2807
+ methodSignatures() {
2808
+ return this._methods;
2809
+ }
2005
2810
  }
2006
2811
  function getTypeOf(value) {
2007
2812
  // Check for typed nil before checking for plain null
@@ -2043,22 +2848,19 @@ function getTypeOf(value) {
2043
2848
  if ((typeInfo.kind === 'function' || typeInfo.kind === 'Function') &&
2044
2849
  typeInfo.params &&
2045
2850
  typeInfo.results) {
2851
+ if (funcWithMeta.__goTypeName && !typeInfo.name) {
2852
+ return functionTypeFromInfo({
2853
+ ...typeInfo,
2854
+ name: funcWithMeta.__goTypeName,
2855
+ });
2856
+ }
2046
2857
  return functionTypeFromInfo(typeInfo);
2047
2858
  }
2048
2859
  }
2049
2860
  // Then check for __goTypeName which indicates a typed function
2050
2861
  if (funcWithMeta.__goTypeName) {
2051
- // This is a typed Go function - try to reconstruct the signature
2052
2862
  const typeName = funcWithMeta.__goTypeName;
2053
- // For known Go function types, construct proper signatures
2054
- if (typeName === 'Greeter') {
2055
- return new FunctionType('func(string) string');
2056
- }
2057
- else if (typeName === 'Adder') {
2058
- return new FunctionType('func(int, int) int');
2059
- }
2060
- // Generic fallback for typed functions
2061
- return new FunctionType(`func`); // Could be enhanced with parameter parsing
2863
+ return new FunctionType({ name: typeName });
2062
2864
  }
2063
2865
  // For untyped functions, try to parse the signature
2064
2866
  const funcStr = value.toString();
@@ -2165,34 +2967,31 @@ function getTypeOf(value) {
2165
2967
  }
2166
2968
  }
2167
2969
  // Check if it has a constructor with __typeInfo for proper struct names
2970
+ if (value &&
2971
+ typeof value === 'object' &&
2972
+ value.constructor &&
2973
+ '__reflectType' in value.constructor) {
2974
+ const reflectType = value.constructor
2975
+ .__reflectType;
2976
+ if (reflectType) {
2977
+ return reflectType;
2978
+ }
2979
+ }
2168
2980
  if (value &&
2169
2981
  typeof value === 'object' &&
2170
2982
  value.constructor &&
2171
2983
  '__typeInfo' in value.constructor) {
2172
2984
  const typeInfo = value.constructor.__typeInfo;
2173
- if (typeInfo && typeInfo.name) {
2174
- const typeName = typeInfo.name.includes('.') ?
2175
- typeInfo.name
2176
- : `main.${typeInfo.name}`;
2177
- const regTypeInfo = builtinGetTypeByName(typeName);
2178
- let fields = [];
2179
- if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
2180
- fields = Object.entries(regTypeInfo.fields || {}).map(([name, fieldInfo]) => {
2181
- // Check if fieldInfo is a StructFieldInfo with type and tag
2182
- if (isStructFieldInfo(fieldInfo)) {
2183
- return {
2184
- name: fieldInfo.name ?? name,
2185
- type: StructType.createTypeFromFieldInfo(fieldInfo.type),
2186
- tag: fieldInfo.tag,
2187
- };
2188
- }
2189
- // Otherwise it's just the type info directly (backwards compatible)
2190
- return {
2191
- name,
2192
- type: StructType.createTypeFromFieldInfo(fieldInfo),
2193
- };
2194
- });
2985
+ if (typeInfo && isStructTypeInfo(typeInfo)) {
2986
+ const name = typeInfo.name ?? '';
2987
+ if (name === '') {
2988
+ return new StructType('', structFieldsFromTypeInfo(typeInfo));
2195
2989
  }
2990
+ const typeName = name.includes('.') ? name : `main.${name}`;
2991
+ const regTypeInfo = builtinGetTypeByName(typeName);
2992
+ const fields = regTypeInfo && isStructTypeInfo(regTypeInfo) ?
2993
+ structFieldsFromTypeInfo(regTypeInfo)
2994
+ : structFieldsFromTypeInfo(typeInfo);
2196
2995
  return new StructType(typeName, fields);
2197
2996
  }
2198
2997
  }
@@ -2242,86 +3041,497 @@ export function MapOf(key, elem) {
2242
3041
  export function ChanOf(dir, t) {
2243
3042
  return internType(new ChannelType(t, dir));
2244
3043
  }
3044
+ export function StructOf(fields) {
3045
+ const inputFields = $.asArray(fields);
3046
+ const descriptors = [];
3047
+ const names = new Set();
3048
+ let pkgPath = '';
3049
+ let offset = 0;
3050
+ for (const [idx, field] of inputFields.entries()) {
3051
+ validateStructOfField(field, idx);
3052
+ if (field.PkgPath !== '') {
3053
+ if (pkgPath === '') {
3054
+ pkgPath = field.PkgPath;
3055
+ }
3056
+ else if (pkgPath !== field.PkgPath) {
3057
+ throw new Error(`reflect.Struct: fields with different PkgPath ${pkgPath} and ${field.PkgPath}`);
3058
+ }
3059
+ }
3060
+ if (names.has(field.Name) && field.Name !== '_') {
3061
+ throw new Error(`reflect.StructOf: duplicate field ${field.Name}`);
3062
+ }
3063
+ names.add(field.Name);
3064
+ const fieldOffset = alignOffset(offset, typeAlignment(field.Type));
3065
+ const tag = field.Tag?.toString();
3066
+ const descriptor = {
3067
+ name: field.Name,
3068
+ key: field.Name === '_' ? `_${idx}` : field.Name,
3069
+ type: field.Type,
3070
+ ...(tag ? { tag } : {}),
3071
+ pkgPath: field.PkgPath,
3072
+ anonymous: field.Anonymous,
3073
+ index: [idx],
3074
+ offset: fieldOffset,
3075
+ exported: field.IsExported(),
3076
+ };
3077
+ descriptors.push(descriptor);
3078
+ offset = fieldOffset + field.Type.Size();
3079
+ }
3080
+ return internType(new StructType('', descriptors, '', structTypeString(descriptors)));
3081
+ }
3082
+ function validateStructOfField(field, idx) {
3083
+ if (field.Name === '') {
3084
+ throw new Error(`reflect.StructOf: field ${idx} has no name`);
3085
+ }
3086
+ if (!isValidStructFieldName(field.Name)) {
3087
+ throw new Error(`reflect.StructOf: field ${idx} has invalid name`);
3088
+ }
3089
+ if (!field.Type) {
3090
+ throw new Error(`reflect.StructOf: field ${idx} has no type`);
3091
+ }
3092
+ if (field.Anonymous && field.PkgPath !== '') {
3093
+ throw new Error(`reflect.StructOf: field "${field.Name}" is anonymous but has PkgPath set`);
3094
+ }
3095
+ if (field.IsExported() && isUnexportedStructFieldName(field.Name)) {
3096
+ throw new Error(`reflect.StructOf: field "${field.Name}" is unexported but missing PkgPath`);
3097
+ }
3098
+ validateAnonymousStructOfField(field);
3099
+ }
3100
+ function isValidStructFieldName(name) {
3101
+ return /^[\p{L}_][\p{L}\p{N}_]*$/u.test(name);
3102
+ }
3103
+ function isUnexportedStructFieldName(name) {
3104
+ const first = name.charCodeAt(0);
3105
+ return name[0] === '_' || (first >= 97 && first <= 122);
3106
+ }
3107
+ function validateAnonymousStructOfField(field) {
3108
+ if (!field.Anonymous) {
3109
+ return;
3110
+ }
3111
+ const typ = field.Type;
3112
+ if (typ.Kind() === Ptr) {
3113
+ const elem = typ.Elem();
3114
+ if (elem.Kind() === Ptr || elem.Kind() === Interface) {
3115
+ throw new Error(`reflect.StructOf: illegal embedded field type ${typ.String()}`);
3116
+ }
3117
+ if (embeddedMethodCount(typ) > 0) {
3118
+ throw new Error('reflect: embedded type with methods not implemented');
3119
+ }
3120
+ return;
3121
+ }
3122
+ if (embeddedMethodCount(typ) > 0) {
3123
+ throw new Error('reflect: embedded type with methods not implemented');
3124
+ }
3125
+ }
3126
+ function embeddedMethodCount(typ) {
3127
+ if (typ.Kind() === Ptr) {
3128
+ return Math.max(typ.NumMethod(), typ.Elem().NumMethod());
3129
+ }
3130
+ return typ.NumMethod();
3131
+ }
3132
+ function structTypeString(fields) {
3133
+ if (fields.length === 0) {
3134
+ return 'struct {}';
3135
+ }
3136
+ return `struct { ${fields.map(structFieldString).join('; ')} }`;
3137
+ }
3138
+ function structFieldString(field) {
3139
+ const tag = field.tag ? ` ${JSON.stringify(field.tag)}` : '';
3140
+ const prefix = field.anonymous ? '' : `${field.name} `;
3141
+ return `${prefix}${field.type.String()}${tag}`;
3142
+ }
3143
+ export function FuncOf(inTypes, outTypes, variadic) {
3144
+ const params = $.asArray(inTypes).map(funcOfType);
3145
+ const results = $.asArray(outTypes).map(funcOfType);
3146
+ if (variadic &&
3147
+ (params.length === 0 || params[params.length - 1].Kind() !== Slice)) {
3148
+ throw new Error('reflect.FuncOf: last arg of variadic func must be slice');
3149
+ }
3150
+ if (params.length + results.length > 128) {
3151
+ throw new Error('reflect.FuncOf: too many arguments');
3152
+ }
3153
+ return internType(new FunctionType({ params, results, variadic }));
3154
+ }
3155
+ function funcOfType(typ) {
3156
+ if (!typ) {
3157
+ throw new Error('reflect.FuncOf: nil Type');
3158
+ }
3159
+ return typ;
3160
+ }
2245
3161
  export function TypeFor(typeArgs) {
2246
3162
  const descriptor = typeArgs?.T;
3163
+ const methodSignatures = genericMethodSignatures(descriptor);
2247
3164
  if (descriptor?.type) {
2248
- return internType(typeFromTypeInfo(descriptor.type));
3165
+ return internType(typeWithMethodSignatures(typeFromTypeInfo(descriptor.type), methodSignatures));
2249
3166
  }
2250
- if (descriptor?.methods) {
2251
- const methods = Object.keys(descriptor.methods);
2252
- if (methods.length !== 0) {
2253
- return internType(new InterfaceType(`interface { ${methods.map((method) => method + '()').join('; ')} }`));
2254
- }
3167
+ if (methodSignatures.length !== 0) {
3168
+ return internType(new InterfaceType(interfaceTypeString(methodSignatures), undefined, methodSignatures));
2255
3169
  }
2256
3170
  if (descriptor?.zero) {
2257
3171
  return internType(getTypeOf(descriptor.zero()));
2258
3172
  }
2259
3173
  return internType(new InterfaceType('interface{}'));
2260
3174
  }
3175
+ function genericMethodSignatures(descriptor) {
3176
+ if (!descriptor) {
3177
+ return [];
3178
+ }
3179
+ if (descriptor.methodSignatures && descriptor.methodSignatures.length !== 0) {
3180
+ return descriptor.methodSignatures;
3181
+ }
3182
+ if (!descriptor.methods) {
3183
+ return [];
3184
+ }
3185
+ return Object.keys(descriptor.methods).map((method) => ({
3186
+ name: method,
3187
+ args: [],
3188
+ returns: [],
3189
+ }));
3190
+ }
3191
+ function typeWithMethodSignatures(typ, methods) {
3192
+ if (methods.length === 0) {
3193
+ return typ;
3194
+ }
3195
+ if (typ instanceof BasicType) {
3196
+ typ.mergeMethodSignatures(methods);
3197
+ return typ;
3198
+ }
3199
+ if (typ instanceof PointerType) {
3200
+ typ.mergeMethodSignatures(methods);
3201
+ return typ;
3202
+ }
3203
+ if (typ instanceof FunctionType) {
3204
+ typ.mergeMethodSignatures(methods);
3205
+ return typ;
3206
+ }
3207
+ return typ;
3208
+ }
2261
3209
  function typeFromTypeInfo(info) {
3210
+ return typeFromTypeInfoWithSeen(info, new Set());
3211
+ }
3212
+ function typeFromTypeInfoWithSeen(info, seen) {
2262
3213
  if (typeof info === 'string') {
2263
3214
  const registered = builtinGetTypeByName(info);
2264
3215
  if (registered) {
2265
- return internType(typeFromTypeInfo(registered));
3216
+ const typ = typeFromTypeInfoWithSeen(registered, seen);
3217
+ return internType(typ);
2266
3218
  }
2267
- return internType(StructType.createTypeFromFieldInfo(info));
3219
+ return internType(StructType.createTypeFromFieldInfo(info, seen));
2268
3220
  }
3221
+ const recursiveName = recursiveTypeInfoName(info);
3222
+ if (recursiveName !== '') {
3223
+ const constructing = constructingRegisteredTypes.get(recursiveName);
3224
+ if (constructing) {
3225
+ return constructing;
3226
+ }
3227
+ if (seen.has(recursiveName)) {
3228
+ return internType(shallowTypeFromRegisteredInfo(recursiveName, info));
3229
+ }
3230
+ if (info.kind === $.TypeKind.Struct) {
3231
+ const typ = new StructType(recursiveName, []);
3232
+ constructingRegisteredTypes.set(recursiveName, typ);
3233
+ seen.add(recursiveName);
3234
+ try {
3235
+ typ.replaceDescriptors(structFieldsFromTypeInfo(info, seen));
3236
+ return internType(typ);
3237
+ }
3238
+ finally {
3239
+ seen.delete(recursiveName);
3240
+ constructingRegisteredTypes.delete(recursiveName);
3241
+ }
3242
+ }
3243
+ seen.add(recursiveName);
3244
+ const typ = typeFromStructuredTypeInfoWithSeen(info, seen);
3245
+ seen.delete(recursiveName);
3246
+ return internType(typ);
3247
+ }
3248
+ return internType(typeFromStructuredTypeInfoWithSeen(info, seen));
3249
+ }
3250
+ function recursiveTypeInfoName(info) {
3251
+ if (info.kind === $.TypeKind.Basic) {
3252
+ return info.typeName ?? '';
3253
+ }
3254
+ return info.name ?? '';
3255
+ }
3256
+ function typeFromStructuredTypeInfoWithSeen(info, seen) {
2269
3257
  switch (info.kind) {
2270
3258
  case $.TypeKind.Array:
2271
- return internType(new ArrayType(typeFromTypeInfo(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }), info.length));
3259
+ return new ArrayType(typeFromTypeInfoWithSeen(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen), info.length);
2272
3260
  case $.TypeKind.Basic:
2273
- return internType(StructType.createTypeFromFieldInfo(info));
3261
+ return StructType.createTypeFromFieldInfo(info, seen);
2274
3262
  case $.TypeKind.Channel:
2275
- return internType(new ChannelType(typeFromTypeInfo(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }), chanDirFromTypeInfo(info.direction)));
3263
+ return new ChannelType(typeFromTypeInfoWithSeen(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen), chanDirFromTypeInfo(info.direction));
2276
3264
  case $.TypeKind.Function:
2277
- return internType(functionTypeFromInfo(info));
3265
+ return functionTypeFromInfo(info, seen);
2278
3266
  case $.TypeKind.Interface:
2279
- return internType(interfaceTypeFromInfo(info));
3267
+ return interfaceTypeFromInfo(info, seen);
2280
3268
  case $.TypeKind.Map:
2281
- return internType(new MapType(typeFromTypeInfo(info.keyType ?? { kind: $.TypeKind.Basic, name: 'unknown' }), typeFromTypeInfo(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' })));
3269
+ return new MapType(typeFromTypeInfoWithSeen(info.keyType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen), typeFromTypeInfoWithSeen(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen));
2282
3270
  case $.TypeKind.Slice:
2283
- return internType(new SliceType(typeFromTypeInfo(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' })));
3271
+ return new SliceType(typeFromTypeInfoWithSeen(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen));
2284
3272
  case $.TypeKind.Struct:
2285
- return internType(StructType.createTypeFromFieldInfo(info));
3273
+ return StructType.createTypeFromFieldInfo(info, seen);
2286
3274
  case $.TypeKind.Pointer:
2287
- return internType(new PointerType(typeFromTypeInfo(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' })));
3275
+ return new PointerType(typeFromTypeInfoWithSeen(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen));
2288
3276
  default:
2289
- return internType(StructType.createTypeFromFieldInfo(info));
3277
+ return StructType.createTypeFromFieldInfo(info, seen);
2290
3278
  }
2291
3279
  }
2292
- function functionTypeFromInfo(info) {
2293
- if (info.name) {
2294
- return new FunctionType(info.name);
3280
+ function shallowTypeFromRegisteredInfo(name, info) {
3281
+ switch (info.kind) {
3282
+ case $.TypeKind.Interface:
3283
+ return new InterfaceType(name, name, info.methods ?? []);
3284
+ case $.TypeKind.Struct:
3285
+ return new StructType(name, []);
3286
+ case $.TypeKind.Function:
3287
+ return new FunctionType({ name });
3288
+ case $.TypeKind.Basic:
3289
+ return StructType.createTypeFromFieldInfo({
3290
+ kind: $.TypeKind.Basic,
3291
+ name: info.name ?? 'unknown',
3292
+ typeName: info.typeName ?? name,
3293
+ });
3294
+ default:
3295
+ return StructType.createTypeFromFieldInfo(name);
2295
3296
  }
2296
- const params = info.params ?? [];
2297
- const paramTypes = params.map((param, index) => {
2298
- const typeName = functionSignatureTypeName(param);
2299
- if (!info.isVariadic || index !== params.length - 1) {
2300
- return typeName;
2301
- }
2302
- if (typeName.startsWith('[]')) {
2303
- return '...' + typeName.slice(2);
2304
- }
2305
- return '...' + typeName;
3297
+ }
3298
+ function functionTypeFromInfo(info, seen = new Set()) {
3299
+ const params = (info.params ?? []).map((param) => typeFromTypeInfoWithSeen(param, seen));
3300
+ const results = (info.results ?? []).map((result) => typeFromTypeInfoWithSeen(result, seen));
3301
+ return new FunctionType({
3302
+ name: info.name,
3303
+ params,
3304
+ results,
3305
+ variadic: info.isVariadic ?? false,
2306
3306
  });
2307
- const resultTypes = (info.results ?? []).map(functionSignatureTypeName);
2308
- let signature = `func(${paramTypes.join(', ')})`;
2309
- if (resultTypes.length === 1) {
2310
- signature += ` ${resultTypes[0]}`;
3307
+ }
3308
+ function functionTypeInfoFromType(typ) {
3309
+ const params = [];
3310
+ for (let i = 0; i < typ.NumIn(); i++) {
3311
+ params.push(typeInfoFromReflectType(typ.In(i)));
3312
+ }
3313
+ const results = [];
3314
+ for (let i = 0; i < typ.NumOut(); i++) {
3315
+ results.push(typeInfoFromReflectType(typ.Out(i)));
3316
+ }
3317
+ const info = {
3318
+ kind: $.TypeKind.Function,
3319
+ params,
3320
+ results,
3321
+ };
3322
+ if (typ.Name() !== '') {
3323
+ info.name = typ.String();
2311
3324
  }
2312
- if (resultTypes.length > 1) {
2313
- signature += ` (${resultTypes.join(', ')})`;
3325
+ if (typ.IsVariadic()) {
3326
+ info.isVariadic = true;
2314
3327
  }
2315
- return new FunctionType(signature);
3328
+ return info;
2316
3329
  }
2317
- function functionSignatureTypeName(info) {
2318
- return typeFromTypeInfo(info).String();
3330
+ export function typeInfoFromReflectType(typ) {
3331
+ if (typ.PkgPath() !== '' && typ.Name() !== '') {
3332
+ return typ.String();
3333
+ }
3334
+ switch (typ.Kind()) {
3335
+ case Bool:
3336
+ case Int:
3337
+ case Int8:
3338
+ case Int16:
3339
+ case Int32:
3340
+ case Int64:
3341
+ case Uint:
3342
+ case Uint8:
3343
+ case Uint16:
3344
+ case Uint32:
3345
+ case Uint64:
3346
+ case Uintptr:
3347
+ case Float32:
3348
+ case Float64:
3349
+ case Complex64:
3350
+ case Complex128:
3351
+ case String:
3352
+ case UnsafePointer:
3353
+ return { kind: $.TypeKind.Basic, name: typ.String() };
3354
+ case Interface:
3355
+ return {
3356
+ kind: $.TypeKind.Interface,
3357
+ methods: typeMethods(typ).map((method) => ({
3358
+ name: method.name,
3359
+ args: method.args,
3360
+ returns: method.returns,
3361
+ })),
3362
+ };
3363
+ case Slice:
3364
+ return {
3365
+ kind: $.TypeKind.Slice,
3366
+ elemType: typeInfoFromReflectType(typ.Elem()),
3367
+ };
3368
+ case Array:
3369
+ return {
3370
+ kind: $.TypeKind.Array,
3371
+ elemType: typeInfoFromReflectType(typ.Elem()),
3372
+ length: typ.Len(),
3373
+ };
3374
+ case Ptr:
3375
+ return {
3376
+ kind: $.TypeKind.Pointer,
3377
+ elemType: typeInfoFromReflectType(typ.Elem()),
3378
+ };
3379
+ case Map:
3380
+ return {
3381
+ kind: $.TypeKind.Map,
3382
+ keyType: typeInfoFromReflectType(typ.Key()),
3383
+ elemType: typeInfoFromReflectType(typ.Elem()),
3384
+ };
3385
+ case Chan:
3386
+ return {
3387
+ kind: $.TypeKind.Channel,
3388
+ elemType: typeInfoFromReflectType(typ.Elem()),
3389
+ direction: channelDirectionFromString(typ.String()),
3390
+ };
3391
+ case Func:
3392
+ return functionTypeInfoFromType(typ);
3393
+ case Struct: {
3394
+ const fields = typ instanceof StructType ?
3395
+ typ.descriptors()
3396
+ : globalThis.Array.from({ length: typ.NumField() }, (_unused, idx) => {
3397
+ const field = typ.Field(idx);
3398
+ return {
3399
+ name: field.Name,
3400
+ key: structFieldStorageKey(typ, idx),
3401
+ type: field.Type,
3402
+ tag: field.Tag?.toString(),
3403
+ pkgPath: field.PkgPath,
3404
+ anonymous: field.Anonymous,
3405
+ index: [...field.Index],
3406
+ offset: field.Offset,
3407
+ exported: field.IsExported(),
3408
+ };
3409
+ });
3410
+ return {
3411
+ kind: $.TypeKind.Struct,
3412
+ name: typ.Name() === '' ? '' : typ.String(),
3413
+ methods: [],
3414
+ fields: fields.map((field) => ({
3415
+ name: field.name,
3416
+ key: field.key,
3417
+ type: typeInfoFromReflectType(field.type),
3418
+ ...(field.tag ? { tag: field.tag } : {}),
3419
+ ...(field.pkgPath ? { pkgPath: field.pkgPath } : {}),
3420
+ ...(field.anonymous ? { anonymous: true } : {}),
3421
+ index: [...field.index],
3422
+ offset: field.offset,
3423
+ exported: field.exported,
3424
+ })),
3425
+ };
3426
+ }
3427
+ default:
3428
+ return typ.String();
3429
+ }
2319
3430
  }
2320
- function interfaceTypeFromInfo(info) {
2321
- if (info.methods.length === 0) {
2322
- return new InterfaceType('interface{}', info.name);
3431
+ function channelDirectionFromString(typeName) {
3432
+ if (typeName.startsWith('<-chan ')) {
3433
+ return 'receive';
3434
+ }
3435
+ if (typeName.startsWith('chan<- ')) {
3436
+ return 'send';
3437
+ }
3438
+ return 'both';
3439
+ }
3440
+ function interfaceTypeFromInfo(info, seen = new Set()) {
3441
+ const methods = info.methods ?? [];
3442
+ if (methods.length === 0) {
3443
+ return new InterfaceType('interface{}', info.name, methods);
3444
+ }
3445
+ return new InterfaceType(interfaceTypeString(methods, seen), info.name, methods);
3446
+ }
3447
+ function interfaceTypeString(methods, seen = new Set()) {
3448
+ return `interface { ${methods
3449
+ .map((method) => interfaceMethodString(method, seen))
3450
+ .join('; ')} }`;
3451
+ }
3452
+ function interfaceMethodString(method, seen) {
3453
+ const args = method.args.map((arg) => methodArgString(arg, seen)).join(', ');
3454
+ const returns = method.returns.map((arg) => methodArgString(arg, seen));
3455
+ if (returns.length === 0) {
3456
+ return `${method.name}(${args})`;
3457
+ }
3458
+ if (returns.length === 1) {
3459
+ return `${method.name}(${args}) ${returns[0]}`;
3460
+ }
3461
+ return `${method.name}(${args}) (${returns.join(', ')})`;
3462
+ }
3463
+ function structTypeInfoString(info, seen) {
3464
+ if (info.name) {
3465
+ return info.name;
3466
+ }
3467
+ const fields = info.fields ?? [];
3468
+ if (fields.length === 0) {
3469
+ return 'struct {}';
3470
+ }
3471
+ return `struct { ${fields
3472
+ .map((field) => structFieldInfoString(field, seen))
3473
+ .join('; ')} }`;
3474
+ }
3475
+ function structFieldInfoString(field, seen) {
3476
+ const tag = field.tag ? ` ${JSON.stringify(field.tag)}` : '';
3477
+ const prefix = field.anonymous ? '' : `${field.name} `;
3478
+ return `${prefix}${typeInfoString(field.type, seen)}${tag}`;
3479
+ }
3480
+ function methodArgString(arg, seen) {
3481
+ return typeInfoString(arg.type, seen);
3482
+ }
3483
+ function typeInfoString(info, seen) {
3484
+ if (typeof info === 'string') {
3485
+ return info;
3486
+ }
3487
+ switch (info.kind) {
3488
+ case $.TypeKind.Basic:
3489
+ return info.typeName ?? info.name ?? 'unknown';
3490
+ case $.TypeKind.Interface: {
3491
+ const name = info.name ?? '';
3492
+ if (name !== '' && seen.has(name)) {
3493
+ return name;
3494
+ }
3495
+ if (info.methods.length === 0) {
3496
+ return 'interface{}';
3497
+ }
3498
+ if (name !== '') {
3499
+ seen.add(name);
3500
+ }
3501
+ const text = interfaceTypeString(info.methods, seen);
3502
+ if (name !== '') {
3503
+ seen.delete(name);
3504
+ }
3505
+ return text;
3506
+ }
3507
+ case $.TypeKind.Struct:
3508
+ return structTypeInfoString(info, seen);
3509
+ case $.TypeKind.Pointer:
3510
+ return `*${typeInfoString(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
3511
+ case $.TypeKind.Slice:
3512
+ return `[]${typeInfoString(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
3513
+ case $.TypeKind.Array:
3514
+ return `[${info.length}]${typeInfoString(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
3515
+ case $.TypeKind.Map:
3516
+ return `map[${typeInfoString(info.keyType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}]${typeInfoString(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
3517
+ case $.TypeKind.Function: {
3518
+ const params = (info.params ?? [])
3519
+ .map((param) => typeInfoString(param, seen))
3520
+ .join(', ');
3521
+ const results = (info.results ?? []).map((result) => typeInfoString(result, seen));
3522
+ if (results.length === 0) {
3523
+ return `func(${params})`;
3524
+ }
3525
+ if (results.length === 1) {
3526
+ return `func(${params}) ${results[0]}`;
3527
+ }
3528
+ return `func(${params}) (${results.join(', ')})`;
3529
+ }
3530
+ case $.TypeKind.Channel:
3531
+ return `chan ${typeInfoString(info.elemType ?? { kind: $.TypeKind.Basic, name: 'unknown' }, seen)}`;
3532
+ default:
3533
+ return 'unknown';
2323
3534
  }
2324
- return new InterfaceType(`interface { ${info.methods.map((method) => method.name + '()').join('; ')} }`, info.name);
2325
3535
  }
2326
3536
  function chanDirFromTypeInfo(direction) {
2327
3537
  switch (direction) {
@@ -2339,35 +3549,15 @@ function chanDirFromTypeInfo(direction) {
2339
3549
  */
2340
3550
  export function getInterfaceTypeByName(name) {
2341
3551
  const typeInfo = builtinGetTypeByName(name);
2342
- if (typeInfo && typeInfo.kind === TypeKind.Interface) {
2343
- return new InterfaceType(name, name);
3552
+ if (typeInfo && isInterfaceTypeInfo(typeInfo)) {
3553
+ return new InterfaceType(name, name, typeInfo.methods ?? []);
2344
3554
  }
2345
3555
  return new InterfaceType('interface{}');
2346
3556
  }
2347
3557
  export function getInterfaceLiteralTypeByName(name) {
2348
3558
  const typeInfo = builtinGetTypeByName(name);
2349
- if (typeInfo && typeInfo.kind === TypeKind.Interface) {
2350
- const methods = typeInfo.methods || [];
2351
- if (methods.length === 0) {
2352
- return new InterfaceType('interface{}', name);
2353
- }
2354
- const methodSigs = methods
2355
- .map((m) => {
2356
- const args = m.args
2357
- ?.map((a) => (typeof a === 'string' ? a : 'any'))
2358
- .join(', ') || '';
2359
- const returns = m.returns?.map((r) => typeof r === 'string' ? r : 'any');
2360
- let returnSig = '';
2361
- if (returns && returns.length === 1) {
2362
- returnSig = ` ${returns[0]}`;
2363
- }
2364
- else if (returns && returns.length > 1) {
2365
- returnSig = ` (${returns.join(', ')})`;
2366
- }
2367
- return `${m.name}(${args})${returnSig}`;
2368
- })
2369
- .join('; ');
2370
- return new InterfaceType(`interface { ${methodSigs} }`, name);
3559
+ if (typeInfo && isInterfaceTypeInfo(typeInfo)) {
3560
+ return interfaceTypeFromInfo(typeInfo);
2371
3561
  }
2372
3562
  return new InterfaceType('interface{}');
2373
3563
  }