goscript 0.1.3 → 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 (330) 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} +35 -8
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript/cmd_compile_test.go +105 -6
  8. package/compiler/build-flags.go +9 -10
  9. package/compiler/compile-request.go +12 -9
  10. package/compiler/compliance_test.go +0 -1
  11. package/compiler/config.go +2 -0
  12. package/compiler/gotest/request.go +28 -0
  13. package/compiler/gotest/runner.go +353 -27
  14. package/compiler/gotest/runner_test.go +400 -1
  15. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  16. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  17. package/compiler/lowered-program.go +24 -17
  18. package/compiler/lowering.go +988 -263
  19. package/compiler/lowering_bench_test.go +364 -0
  20. package/compiler/override-facts.go +15 -0
  21. package/compiler/override-parity-verifier.go +450 -0
  22. package/compiler/override-parity.go +122 -0
  23. package/compiler/override-registry_test.go +559 -0
  24. package/compiler/package-graph.go +61 -4
  25. package/compiler/package-graph_test.go +30 -0
  26. package/compiler/protobuf-ts-binding.go +514 -0
  27. package/compiler/protobuf-ts-binding_test.go +172 -0
  28. package/compiler/semantic-model-types.go +17 -4
  29. package/compiler/semantic-model.go +709 -72
  30. package/compiler/semantic-model_test.go +219 -0
  31. package/compiler/service.go +20 -1
  32. package/compiler/skeleton_test.go +1008 -20
  33. package/compiler/typescript-emitter.go +147 -15
  34. package/dist/gs/builtin/builtin.d.ts +2 -2
  35. package/dist/gs/builtin/builtin.js +20 -0
  36. package/dist/gs/builtin/builtin.js.map +1 -1
  37. package/dist/gs/builtin/slice.d.ts +2 -1
  38. package/dist/gs/builtin/slice.js +34 -4
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.d.ts +14 -6
  41. package/dist/gs/builtin/type.js +224 -64
  42. package/dist/gs/builtin/type.js.map +1 -1
  43. package/dist/gs/builtin/varRef.d.ts +11 -0
  44. package/dist/gs/builtin/varRef.js +57 -2
  45. package/dist/gs/builtin/varRef.js.map +1 -1
  46. package/dist/gs/bytes/buffer.gs.js +1 -1
  47. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  48. package/dist/gs/bytes/reader.gs.js +1 -1
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/compress/zlib/index.d.ts +13 -6
  51. package/dist/gs/compress/zlib/index.js +131 -35
  52. package/dist/gs/compress/zlib/index.js.map +1 -1
  53. package/dist/gs/crypto/sha1/index.js +2 -5
  54. package/dist/gs/crypto/sha1/index.js.map +1 -1
  55. package/dist/gs/crypto/sha256/index.js +2 -5
  56. package/dist/gs/crypto/sha256/index.js.map +1 -1
  57. package/dist/gs/crypto/sha512/index.js +2 -5
  58. package/dist/gs/crypto/sha512/index.js.map +1 -1
  59. package/dist/gs/embed/index.d.ts +6 -0
  60. package/dist/gs/embed/index.js +210 -5
  61. package/dist/gs/embed/index.js.map +1 -1
  62. package/dist/gs/encoding/json/index.d.ts +114 -0
  63. package/dist/gs/encoding/json/index.js +544 -36
  64. package/dist/gs/encoding/json/index.js.map +1 -1
  65. package/dist/gs/fmt/fmt.d.ts +3 -3
  66. package/dist/gs/fmt/fmt.js +29 -16
  67. package/dist/gs/fmt/fmt.js.map +1 -1
  68. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  69. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  70. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  71. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  72. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  73. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  74. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  75. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  76. package/dist/gs/go/scanner/index.d.ts +2 -0
  77. package/dist/gs/go/scanner/index.js +29 -5
  78. package/dist/gs/go/scanner/index.js.map +1 -1
  79. package/dist/gs/go/token/index.js +22 -6
  80. package/dist/gs/go/token/index.js.map +1 -1
  81. package/dist/gs/hash/index.d.ts +6 -0
  82. package/dist/gs/hash/index.js +20 -0
  83. package/dist/gs/hash/index.js.map +1 -1
  84. package/dist/gs/internal/goarch/index.d.ts +43 -3
  85. package/dist/gs/internal/goarch/index.js +42 -10
  86. package/dist/gs/internal/goarch/index.js.map +1 -1
  87. package/dist/gs/io/fs/fs.js +26 -14
  88. package/dist/gs/io/fs/fs.js.map +1 -1
  89. package/dist/gs/io/fs/readdir.js +8 -4
  90. package/dist/gs/io/fs/readdir.js.map +1 -1
  91. package/dist/gs/io/fs/sub.js +8 -1
  92. package/dist/gs/io/fs/sub.js.map +1 -1
  93. package/dist/gs/io/io.d.ts +12 -6
  94. package/dist/gs/io/io.js +87 -42
  95. package/dist/gs/io/io.js.map +1 -1
  96. package/dist/gs/math/bits/index.d.ts +31 -5
  97. package/dist/gs/math/bits/index.js +29 -28
  98. package/dist/gs/math/bits/index.js.map +1 -1
  99. package/dist/gs/mime/index.d.ts +16 -0
  100. package/dist/gs/mime/index.js +315 -6
  101. package/dist/gs/mime/index.js.map +1 -1
  102. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  103. package/dist/gs/net/http/httptest/index.js +85 -6
  104. package/dist/gs/net/http/httptest/index.js.map +1 -1
  105. package/dist/gs/net/http/index.d.ts +303 -6
  106. package/dist/gs/net/http/index.js +1615 -58
  107. package/dist/gs/net/http/index.js.map +1 -1
  108. package/dist/gs/os/dir_unix.gs.js +1 -1
  109. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  110. package/dist/gs/os/error.gs.js +1 -1
  111. package/dist/gs/os/error.gs.js.map +1 -1
  112. package/dist/gs/os/exec.gs.d.ts +1 -0
  113. package/dist/gs/os/exec.gs.js +4 -8
  114. package/dist/gs/os/exec.gs.js.map +1 -1
  115. package/dist/gs/os/exec_posix.gs.js +1 -1
  116. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  117. package/dist/gs/os/index.d.ts +1 -1
  118. package/dist/gs/os/index.js +1 -1
  119. package/dist/gs/os/index.js.map +1 -1
  120. package/dist/gs/os/proc.gs.d.ts +4 -0
  121. package/dist/gs/os/proc.gs.js +12 -6
  122. package/dist/gs/os/proc.gs.js.map +1 -1
  123. package/dist/gs/os/root_js.gs.js +1 -1
  124. package/dist/gs/os/root_js.gs.js.map +1 -1
  125. package/dist/gs/os/types.gs.js +1 -1
  126. package/dist/gs/os/types.gs.js.map +1 -1
  127. package/dist/gs/os/types_js.gs.d.ts +6 -2
  128. package/dist/gs/os/types_js.gs.js +170 -9
  129. package/dist/gs/os/types_js.gs.js.map +1 -1
  130. package/dist/gs/os/types_unix.gs.js +1 -1
  131. package/dist/gs/os/types_unix.gs.js.map +1 -1
  132. package/dist/gs/path/path.js +11 -7
  133. package/dist/gs/path/path.js.map +1 -1
  134. package/dist/gs/reflect/index.d.ts +5 -4
  135. package/dist/gs/reflect/index.js +4 -3
  136. package/dist/gs/reflect/index.js.map +1 -1
  137. package/dist/gs/reflect/map.js +15 -0
  138. package/dist/gs/reflect/map.js.map +1 -1
  139. package/dist/gs/reflect/type.d.ts +26 -6
  140. package/dist/gs/reflect/type.js +1498 -279
  141. package/dist/gs/reflect/type.js.map +1 -1
  142. package/dist/gs/reflect/types.d.ts +14 -6
  143. package/dist/gs/reflect/types.js +35 -1
  144. package/dist/gs/reflect/types.js.map +1 -1
  145. package/dist/gs/reflect/value.d.ts +1 -0
  146. package/dist/gs/reflect/value.js +83 -41
  147. package/dist/gs/reflect/value.js.map +1 -1
  148. package/dist/gs/reflect/visiblefields.js +4 -140
  149. package/dist/gs/reflect/visiblefields.js.map +1 -1
  150. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  151. package/dist/gs/runtime/pprof/index.js +50 -30
  152. package/dist/gs/runtime/pprof/index.js.map +1 -1
  153. package/dist/gs/runtime/runtime.js +5 -4
  154. package/dist/gs/runtime/runtime.js.map +1 -1
  155. package/dist/gs/runtime/trace/index.js +5 -19
  156. package/dist/gs/runtime/trace/index.js.map +1 -1
  157. package/dist/gs/strconv/atoi.gs.js +1 -1
  158. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  159. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  160. package/dist/gs/strconv/complex.gs.js +148 -0
  161. package/dist/gs/strconv/complex.gs.js.map +1 -0
  162. package/dist/gs/strconv/index.d.ts +1 -0
  163. package/dist/gs/strconv/index.js +1 -0
  164. package/dist/gs/strconv/index.js.map +1 -1
  165. package/dist/gs/strings/builder.js +1 -1
  166. package/dist/gs/strings/reader.d.ts +1 -1
  167. package/dist/gs/strings/reader.js +11 -7
  168. package/dist/gs/strings/reader.js.map +1 -1
  169. package/dist/gs/strings/replace.js +15 -7
  170. package/dist/gs/strings/replace.js.map +1 -1
  171. package/dist/gs/strings/strings.d.ts +5 -0
  172. package/dist/gs/strings/strings.js +57 -5
  173. package/dist/gs/strings/strings.js.map +1 -1
  174. package/dist/gs/sync/atomic/type.gs.js +9 -9
  175. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  176. package/dist/gs/sync/atomic/value.gs.js +2 -2
  177. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  178. package/dist/gs/sync/sync.d.ts +2 -1
  179. package/dist/gs/sync/sync.js +37 -16
  180. package/dist/gs/sync/sync.js.map +1 -1
  181. package/dist/gs/syscall/env.js +22 -14
  182. package/dist/gs/syscall/env.js.map +1 -1
  183. package/dist/gs/syscall/js/index.js +9 -0
  184. package/dist/gs/syscall/js/index.js.map +1 -1
  185. package/dist/gs/testing/testing.js +59 -15
  186. package/dist/gs/testing/testing.js.map +1 -1
  187. package/dist/gs/time/time.d.ts +24 -1
  188. package/dist/gs/time/time.js +43 -3
  189. package/dist/gs/time/time.js.map +1 -1
  190. package/dist/gs/unique/index.js +7 -1
  191. package/dist/gs/unique/index.js.map +1 -1
  192. package/go.mod +3 -3
  193. package/go.sum +16 -0
  194. package/gs/builtin/builtin.ts +25 -2
  195. package/gs/builtin/runtime-contract.test.ts +260 -18
  196. package/gs/builtin/slice.ts +51 -4
  197. package/gs/builtin/type.ts +310 -63
  198. package/gs/builtin/varRef.ts +85 -2
  199. package/gs/bytes/buffer.gs.ts +1 -1
  200. package/gs/bytes/reader.gs.ts +1 -1
  201. package/gs/compress/zlib/index.test.ts +159 -1
  202. package/gs/compress/zlib/index.ts +164 -37
  203. package/gs/compress/zlib/meta.json +4 -1
  204. package/gs/compress/zlib/parity.json +51 -0
  205. package/gs/crypto/sha1/index.test.ts +19 -2
  206. package/gs/crypto/sha1/index.ts +3 -6
  207. package/gs/crypto/sha256/index.test.ts +14 -2
  208. package/gs/crypto/sha256/index.ts +3 -6
  209. package/gs/crypto/sha512/index.test.ts +17 -2
  210. package/gs/crypto/sha512/index.ts +3 -6
  211. package/gs/embed/index.test.ts +87 -0
  212. package/gs/embed/index.ts +229 -5
  213. package/gs/encoding/json/index.test.ts +360 -6
  214. package/gs/encoding/json/index.ts +679 -38
  215. package/gs/encoding/json/parity.json +81 -0
  216. package/gs/fmt/fmt.test.ts +41 -3
  217. package/gs/fmt/fmt.ts +40 -17
  218. package/gs/fmt/meta.json +6 -1
  219. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  220. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  221. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  222. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  223. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  224. package/gs/github.com/pkg/errors/errors.ts +54 -30
  225. package/gs/go/scanner/index.test.ts +39 -56
  226. package/gs/go/scanner/index.ts +33 -5
  227. package/gs/go/scanner/parity.json +27 -0
  228. package/gs/go/token/index.ts +22 -6
  229. package/gs/hash/index.test.ts +20 -33
  230. package/gs/hash/index.ts +28 -0
  231. package/gs/hash/parity.json +21 -0
  232. package/gs/internal/goarch/index.test.ts +32 -0
  233. package/gs/internal/goarch/index.ts +45 -13
  234. package/gs/internal/goarch/parity.json +144 -0
  235. package/gs/io/fs/fs.ts +26 -14
  236. package/gs/io/fs/readdir.test.ts +38 -0
  237. package/gs/io/fs/readdir.ts +8 -4
  238. package/gs/io/fs/sub.ts +8 -1
  239. package/gs/io/io.test.ts +77 -6
  240. package/gs/io/io.ts +115 -52
  241. package/gs/io/meta.json +7 -1
  242. package/gs/io/parity.json +162 -0
  243. package/gs/math/bits/index.test.ts +14 -1
  244. package/gs/math/bits/index.ts +75 -32
  245. package/gs/math/bits/parity.json +156 -0
  246. package/gs/mime/index.test.ts +90 -0
  247. package/gs/mime/index.ts +369 -6
  248. package/gs/mime/parity.json +36 -0
  249. package/gs/net/http/httptest/index.test.ts +98 -2
  250. package/gs/net/http/httptest/index.ts +101 -6
  251. package/gs/net/http/httptest/parity.json +15 -0
  252. package/gs/net/http/index.test.ts +797 -12
  253. package/gs/net/http/index.ts +1874 -136
  254. package/gs/net/http/meta.json +16 -1
  255. package/gs/net/http/parity.json +193 -0
  256. package/gs/os/dir_unix.gs.ts +1 -1
  257. package/gs/os/error.gs.ts +1 -1
  258. package/gs/os/exec.gs.ts +4 -8
  259. package/gs/os/exec_posix.gs.ts +1 -1
  260. package/gs/os/file_unix_js.test.ts +52 -0
  261. package/gs/os/index.test.ts +9 -0
  262. package/gs/os/index.ts +1 -0
  263. package/gs/os/meta.json +4 -0
  264. package/gs/os/parity.json +9 -0
  265. package/gs/os/proc.gs.ts +18 -5
  266. package/gs/os/proc.test.ts +26 -0
  267. package/gs/os/readdir.test.ts +56 -0
  268. package/gs/os/root_js.gs.ts +1 -1
  269. package/gs/os/types.gs.ts +1 -1
  270. package/gs/os/types_js.gs.ts +170 -9
  271. package/gs/os/types_unix.gs.ts +1 -1
  272. package/gs/path/path.ts +11 -7
  273. package/gs/reflect/deepequal.test.ts +10 -1
  274. package/gs/reflect/field.test.ts +37 -15
  275. package/gs/reflect/function-types.test.ts +518 -22
  276. package/gs/reflect/index.ts +8 -6
  277. package/gs/reflect/map.ts +20 -0
  278. package/gs/reflect/meta.json +6 -4
  279. package/gs/reflect/parity.json +234 -0
  280. package/gs/reflect/sliceat.test.ts +156 -0
  281. package/gs/reflect/structof.test.ts +401 -0
  282. package/gs/reflect/type.ts +1980 -365
  283. package/gs/reflect/typefor.test.ts +540 -10
  284. package/gs/reflect/types.ts +43 -18
  285. package/gs/reflect/value.ts +105 -45
  286. package/gs/reflect/visiblefields.ts +5 -168
  287. package/gs/runtime/parity.json +24 -0
  288. package/gs/runtime/pprof/index.test.ts +29 -7
  289. package/gs/runtime/pprof/index.ts +56 -30
  290. package/gs/runtime/pprof/parity.json +27 -0
  291. package/gs/runtime/runtime.test.ts +3 -1
  292. package/gs/runtime/runtime.ts +4 -3
  293. package/gs/runtime/trace/index.test.ts +5 -3
  294. package/gs/runtime/trace/index.ts +8 -20
  295. package/gs/runtime/trace/parity.json +36 -0
  296. package/gs/strconv/atoi.gs.ts +1 -1
  297. package/gs/strconv/complex.gs.ts +174 -0
  298. package/gs/strconv/complex.test.ts +65 -0
  299. package/gs/strconv/index.ts +1 -0
  300. package/gs/strconv/parity.json +120 -0
  301. package/gs/strings/builder.ts +1 -1
  302. package/gs/strings/meta.json +5 -2
  303. package/gs/strings/parity.json +186 -0
  304. package/gs/strings/reader.test.ts +2 -2
  305. package/gs/strings/reader.ts +11 -7
  306. package/gs/strings/replace.ts +15 -7
  307. package/gs/strings/strings.test.ts +22 -2
  308. package/gs/strings/strings.ts +64 -6
  309. package/gs/sync/atomic/type.gs.ts +9 -9
  310. package/gs/sync/atomic/value.gs.ts +2 -2
  311. package/gs/sync/meta.json +1 -0
  312. package/gs/sync/sync.test.ts +41 -1
  313. package/gs/sync/sync.ts +41 -16
  314. package/gs/syscall/env.ts +29 -14
  315. package/gs/syscall/js/index.test.ts +18 -0
  316. package/gs/syscall/js/index.ts +12 -0
  317. package/gs/testing/testing.test.ts +99 -3
  318. package/gs/testing/testing.ts +95 -24
  319. package/gs/time/parity.json +225 -0
  320. package/gs/time/time.test.ts +20 -2
  321. package/gs/time/time.ts +49 -7
  322. package/gs/unique/index.ts +7 -1
  323. package/package.json +4 -2
  324. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  325. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
  326. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  327. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
  328. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
  329. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  330. /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
  }
@@ -276,24 +399,27 @@ export class Value {
276
399
  }
277
400
  // Methods required by godoc.txt and used throughout the codebase
278
401
  Int() {
279
- if (typeof this._value === 'number' && Number.isInteger(this._value)) {
280
- return this._value;
402
+ const value = this.numericValue();
403
+ if (value !== null && Number.isInteger(value)) {
404
+ return value;
281
405
  }
282
406
  throw new Error('reflect: call of reflect.Value.Int on ' +
283
407
  Kind_String(this._type.Kind()) +
284
408
  ' Value');
285
409
  }
286
410
  Uint() {
287
- if (typeof this._value === 'number' && this._value >= 0) {
288
- return this._value;
411
+ const value = this.numericValue();
412
+ if (value !== null && value >= 0) {
413
+ return value;
289
414
  }
290
415
  throw new Error('reflect: call of reflect.Value.Uint on ' +
291
416
  Kind_String(this._type.Kind()) +
292
417
  ' Value');
293
418
  }
294
419
  Float() {
295
- if (typeof this._value === 'number') {
296
- return this._value;
420
+ const value = this.numericValue();
421
+ if (value !== null) {
422
+ return value;
297
423
  }
298
424
  throw new Error('reflect: call of reflect.Value.Float on ' +
299
425
  Kind_String(this._type.Kind()) +
@@ -307,6 +433,20 @@ export class Value {
307
433
  Kind_String(this._type.Kind()) +
308
434
  ' Value');
309
435
  }
436
+ numericValue() {
437
+ if (typeof this._value === 'number') {
438
+ return this._value;
439
+ }
440
+ if (this._value !== null &&
441
+ typeof this._value === 'object' &&
442
+ typeof this._value.valueOf === 'function') {
443
+ const value = this._value.valueOf();
444
+ if (typeof value === 'number') {
445
+ return value;
446
+ }
447
+ }
448
+ return null;
449
+ }
310
450
  String() {
311
451
  if (typeof this._value === 'string') {
312
452
  return this._value;
@@ -318,6 +458,9 @@ export class Value {
318
458
  return this._type.String();
319
459
  }
320
460
  Len() {
461
+ if (this.Kind() === Slice || this.Kind() === Array) {
462
+ return $.len(this._value);
463
+ }
321
464
  // Check for slice objects created by $.arrayToSlice
322
465
  if (this._value &&
323
466
  typeof this._value === 'object' &&
@@ -366,8 +509,9 @@ export class Value {
366
509
  return this._value === null || this._value === undefined;
367
510
  }
368
511
  Index(i) {
369
- if (globalThis.Array.isArray(this._value)) {
370
- 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);
371
515
  }
372
516
  throw new Error('reflect: call of reflect.Value.Index on ' +
373
517
  Kind_String(this._type.Kind()) +
@@ -409,6 +553,15 @@ export class Value {
409
553
  const elemType = this._type.Elem();
410
554
  return new Value(varRef.value, elemType, varRef);
411
555
  }
556
+ if (this._type.Kind() === Ptr &&
557
+ this._value &&
558
+ typeof this._value === 'object' &&
559
+ '__goValue' in this._value &&
560
+ $.isVarRef(this._value.__goValue)) {
561
+ const varRef = this._value
562
+ .__goValue;
563
+ return new Value(varRef.value, this._type.Elem(), varRef);
564
+ }
412
565
  // For interfaces, return the underlying value
413
566
  return new Value(this._value, this._type, this._parentVarRef);
414
567
  }
@@ -420,16 +573,17 @@ export class Value {
420
573
  throw new ValueError({ Kind: this.Kind(), Method: 'Field' });
421
574
  }
422
575
  const field = this.Type().Field(i);
576
+ const fieldKey = structFieldStorageKey(this.Type(), i);
423
577
  if (!field) {
424
578
  throw new Error('reflect: struct field index out of range');
425
579
  }
426
580
  const parentObj = this._value;
427
- let fieldVal = parentObj[field.Name];
581
+ let fieldVal = parentObj[fieldKey];
428
582
  if (fieldVal === undefined) {
429
583
  fieldVal = null;
430
584
  }
431
585
  // Pass parent struct and field name so Set() can update the struct
432
- return new Value(fieldVal, field.Type, undefined, parentObj, field.Name);
586
+ return new Value(fieldVal, field.Type, undefined, parentObj, fieldKey);
433
587
  }
434
588
  FieldByIndex(index) {
435
589
  let current = this;
@@ -462,6 +616,9 @@ export class Value {
462
616
  if (this._value === null || this._value === undefined) {
463
617
  return 0;
464
618
  }
619
+ if ($.isOwnedPointerHandle(this._value)) {
620
+ return $.ownedPointerAddress(this._value);
621
+ }
465
622
  if ($.isVarRef(this._value)) {
466
623
  const address = this._value.__goAddress?.();
467
624
  if (address !== undefined) {
@@ -491,7 +648,18 @@ export class Value {
491
648
  throw new ValueError({ Kind: this.Kind(), Method: 'UnsafeAddr' });
492
649
  }
493
650
  if (this._parentStruct && this._fieldName) {
494
- 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;
495
663
  }
496
664
  return this.Pointer();
497
665
  }
@@ -521,6 +689,9 @@ export class Value {
521
689
  if (this._parentStruct && this._fieldName) {
522
690
  return new Value($.fieldRef(this._parentStruct, this._fieldName), ptrType);
523
691
  }
692
+ if (this._parentVarRef) {
693
+ return new Value(this._parentVarRef, ptrType);
694
+ }
524
695
  return new Value($.varRef(this._value), ptrType);
525
696
  }
526
697
  CanSet() {
@@ -532,23 +703,9 @@ export class Value {
532
703
  if (!this.CanSet()) {
533
704
  throw new Error('reflect: assign to invalid value');
534
705
  }
535
- // Interface types can accept any value
536
- if (this.Kind() === Interface) {
537
- this._value = x.value;
538
- // Also update the parent VarRef if we were dereferenced from one
539
- if (this._parentVarRef) {
540
- this._parentVarRef.value = x.value;
541
- }
542
- // Also update the parent struct field if this is a struct field
543
- if (this._parentStruct && this._fieldName) {
544
- this._parentStruct[this._fieldName] = x.value;
545
- }
546
- return;
547
- }
548
- // For other types, check if types are compatible (simplified check)
549
706
  const thisType = this.Type();
550
707
  const xType = x.Type();
551
- if (thisType.Kind() !== xType.Kind()) {
708
+ if (!xType.AssignableTo(thisType)) {
552
709
  throw new Error('reflect: assign to wrong type');
553
710
  }
554
711
  this._value = x.value;
@@ -579,21 +736,23 @@ export class Value {
579
736
  if (typeof method !== 'function') {
580
737
  return new Value();
581
738
  }
582
- 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);
583
744
  }
584
- Call(inArgs) {
745
+ async Call(inArgs) {
585
746
  if (this.Kind() !== Func || typeof this._value !== 'function') {
586
747
  throw new ValueError({ Kind: this.Kind(), Method: 'Call' });
587
748
  }
588
- const args = $.asArray(inArgs).map((arg) => arg.Interface());
589
- const result = this._value(...args);
590
- if (globalThis.Array.isArray(result)) {
591
- return $.arrayToSlice(result.map((value) => ValueOf(value)));
592
- }
593
- if (result === undefined) {
594
- 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' });
595
754
  }
596
- return $.arrayToSlice([ValueOf(result)]);
755
+ return await callReflectFunction(this._value, this._type, inArgs, 'CallSlice');
597
756
  }
598
757
  IsZero() {
599
758
  const zeroVal = Zero(this.Type()).value;
@@ -860,10 +1019,7 @@ export class Value {
860
1019
  Cap() {
861
1020
  const k = this.Kind();
862
1021
  if (k === Slice || k === Array) {
863
- if (globalThis.Array.isArray(this._value)) {
864
- return this._value.length;
865
- }
866
- return 0;
1022
+ return $.cap(this._value);
867
1023
  }
868
1024
  if (k === Chan) {
869
1025
  return 0; // Simplified
@@ -936,11 +1092,13 @@ export class BasicType {
936
1092
  _name;
937
1093
  _size;
938
1094
  _typeName;
939
- constructor(_kind, _name, _size = 8, _typeName = '') {
1095
+ _methods;
1096
+ constructor(_kind, _name, _size = 8, _typeName = '', _methods = []) {
940
1097
  this._kind = _kind;
941
1098
  this._name = _name;
942
1099
  this._size = _size;
943
1100
  this._typeName = _typeName;
1101
+ this._methods = _methods;
944
1102
  }
945
1103
  String() {
946
1104
  return this._typeName || this._name;
@@ -948,6 +1106,9 @@ export class BasicType {
948
1106
  Kind() {
949
1107
  return this._kind;
950
1108
  }
1109
+ underlyingName() {
1110
+ return Kind_String(this._kind);
1111
+ }
951
1112
  Comparable() {
952
1113
  return this._kind !== Func && this._kind !== Map && this._kind !== Slice;
953
1114
  }
@@ -960,6 +1121,21 @@ export class BasicType {
960
1121
  NumField() {
961
1122
  return 0;
962
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
+ }
963
1139
  PkgPath() {
964
1140
  if (this._typeName) {
965
1141
  const dotIndex = this._typeName.lastIndexOf('.');
@@ -999,7 +1175,7 @@ export class BasicType {
999
1175
  if (u.Kind() !== Interface) {
1000
1176
  throw new Error('reflect: non-interface type passed to Type.Implements');
1001
1177
  }
1002
- return false;
1178
+ return typeImplementsInterface(this, u);
1003
1179
  }
1004
1180
  AssignableTo(u) {
1005
1181
  return typeAssignableTo(this, u);
@@ -1058,10 +1234,16 @@ export class BasicType {
1058
1234
  ' Type');
1059
1235
  }
1060
1236
  NumMethod() {
1061
- return 0;
1237
+ return typeMethods(this).length;
1062
1238
  }
1063
- MethodByName(_name) {
1064
- 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);
1065
1247
  }
1066
1248
  Len() {
1067
1249
  throw new Error('reflect: call of reflect.Type.Len on ' +
@@ -1124,6 +1306,21 @@ class SliceType {
1124
1306
  NumField() {
1125
1307
  return 0;
1126
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
+ }
1127
1324
  PkgPath() {
1128
1325
  return '';
1129
1326
  }
@@ -1150,7 +1347,7 @@ class SliceType {
1150
1347
  if (u.Kind() !== Interface) {
1151
1348
  throw new Error('reflect: non-interface type passed to Type.Implements');
1152
1349
  }
1153
- return false;
1350
+ return typeImplementsInterface(this, u);
1154
1351
  }
1155
1352
  AssignableTo(u) {
1156
1353
  return typeAssignableTo(this, u);
@@ -1203,6 +1400,21 @@ class ArrayType {
1203
1400
  NumField() {
1204
1401
  return 0;
1205
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
+ }
1206
1418
  Len() {
1207
1419
  return this._len;
1208
1420
  }
@@ -1232,7 +1444,7 @@ class ArrayType {
1232
1444
  if (u.Kind() !== Interface) {
1233
1445
  throw new Error('reflect: non-interface type passed to Type.Implements');
1234
1446
  }
1235
- return false;
1447
+ return typeImplementsInterface(this, u);
1236
1448
  }
1237
1449
  AssignableTo(u) {
1238
1450
  return typeAssignableTo(this, u);
@@ -1262,8 +1474,10 @@ class ArrayType {
1262
1474
  // Pointer type implementation
1263
1475
  class PointerType {
1264
1476
  _elemType;
1265
- constructor(_elemType) {
1477
+ _methods;
1478
+ constructor(_elemType, _methods = []) {
1266
1479
  this._elemType = _elemType;
1480
+ this._methods = _methods;
1267
1481
  }
1268
1482
  String() {
1269
1483
  return '*' + this._elemType.String();
@@ -1283,6 +1497,21 @@ class PointerType {
1283
1497
  NumField() {
1284
1498
  return 0;
1285
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
+ }
1286
1515
  PkgPath() {
1287
1516
  return '';
1288
1517
  }
@@ -1309,9 +1538,7 @@ class PointerType {
1309
1538
  if (u.Kind() !== Interface) {
1310
1539
  throw new Error('reflect: non-interface type passed to Type.Implements');
1311
1540
  }
1312
- // For pointer types, check if the element type implements the interface
1313
- const elemTypeName = this._elemType.String();
1314
- return typeImplementsInterface(elemTypeName, u);
1541
+ return typeImplementsInterface(this, u);
1315
1542
  }
1316
1543
  AssignableTo(u) {
1317
1544
  return typeAssignableTo(this, u);
@@ -1329,10 +1556,16 @@ class PointerType {
1329
1556
  throw new Error('reflect: call of reflect.Type.OverflowFloat on pointer Type');
1330
1557
  }
1331
1558
  NumMethod() {
1332
- return 0;
1559
+ return typeMethods(this).length;
1333
1560
  }
1334
1561
  MethodByName(name) {
1335
- 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);
1336
1569
  }
1337
1570
  Len() {
1338
1571
  throw new Error('reflect: call of reflect.Type.Len on pointer Type');
@@ -1341,13 +1574,42 @@ class PointerType {
1341
1574
  throw new Error('reflect: call of reflect.Type.Bits on pointer Type');
1342
1575
  }
1343
1576
  }
1344
- // Function type implementation
1345
1577
  class FunctionType {
1578
+ _name;
1346
1579
  _signature;
1347
- constructor(_signature) {
1348
- 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);
1349
1608
  }
1350
1609
  String() {
1610
+ if (this._name !== '') {
1611
+ return this._name;
1612
+ }
1351
1613
  return this._signature;
1352
1614
  }
1353
1615
  Kind() {
@@ -1365,11 +1627,44 @@ class FunctionType {
1365
1627
  NumField() {
1366
1628
  return 0;
1367
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
+ }
1368
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
+ }
1369
1658
  return '';
1370
1659
  }
1371
1660
  Name() {
1372
- // 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
+ }
1373
1668
  return '';
1374
1669
  }
1375
1670
  Field(_i) {
@@ -1391,7 +1686,7 @@ class FunctionType {
1391
1686
  if (u.Kind() !== Interface) {
1392
1687
  throw new Error('reflect: non-interface type passed to Type.Implements');
1393
1688
  }
1394
- return false;
1689
+ return typeImplementsInterface(this, u);
1395
1690
  }
1396
1691
  AssignableTo(u) {
1397
1692
  return typeAssignableTo(this, u);
@@ -1409,10 +1704,26 @@ class FunctionType {
1409
1704
  throw new Error('reflect: call of reflect.Type.OverflowFloat on func Type');
1410
1705
  }
1411
1706
  NumMethod() {
1412
- return 0;
1707
+ return typeMethods(this).length;
1413
1708
  }
1414
- MethodByName(_name) {
1415
- 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;
1416
1727
  }
1417
1728
  Len() {
1418
1729
  throw new Error('reflect: call of reflect.Type.Len on func Type');
@@ -1421,6 +1732,174 @@ class FunctionType {
1421
1732
  throw new Error('reflect: call of reflect.Type.Bits on func Type');
1422
1733
  }
1423
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
+ }
1424
1903
  // Map type implementation
1425
1904
  class MapType {
1426
1905
  _keyType;
@@ -1447,6 +1926,21 @@ class MapType {
1447
1926
  NumField() {
1448
1927
  return 0;
1449
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
+ }
1450
1944
  Key() {
1451
1945
  return this._keyType;
1452
1946
  }
@@ -1473,7 +1967,7 @@ class MapType {
1473
1967
  if (u.Kind() !== Interface) {
1474
1968
  throw new Error('reflect: non-interface type passed to Type.Implements');
1475
1969
  }
1476
- return false;
1970
+ return typeImplementsInterface(this, u);
1477
1971
  }
1478
1972
  AssignableTo(u) {
1479
1973
  return typeAssignableTo(this, u);
@@ -1504,47 +1998,122 @@ class MapType {
1504
1998
  }
1505
1999
  }
1506
2000
  // Struct type implementation
1507
- /**
1508
- * Helper function to check if a type's method set contains all methods
1509
- * required by an interface.
1510
- *
1511
- * @param typeName The name of the type to check (e.g., "main.MyType")
1512
- * @param interfaceType The interface type that must be implemented
1513
- * @returns True if the type implements the interface, false otherwise
1514
- */
1515
- function typeImplementsInterface(typeName, interfaceType) {
1516
- // Get the interface name and look it up in the type registry
1517
- const interfaceName = interfaceType instanceof InterfaceType ?
1518
- interfaceType.registeredName() || interfaceType.String()
1519
- : interfaceType.String();
1520
- const interfaceTypeInfo = builtinGetTypeByName(interfaceName);
1521
- if (!interfaceTypeInfo || !isInterfaceTypeInfo(interfaceTypeInfo)) {
1522
- return false;
2001
+ function typeImplementsInterface(t, interfaceType) {
2002
+ if (interfaceType.Kind() !== Interface) {
2003
+ throw new Error('reflect: non-interface type passed to Type.Implements');
1523
2004
  }
1524
- // Get the type info for the struct/type
1525
- const typeInfo = builtinGetTypeByName(typeName);
1526
- if (!typeInfo || !isStructTypeInfo(typeInfo)) {
2005
+ const requiredMethods = typeMethods(interfaceType);
2006
+ if (requiredMethods.length === 0) {
2007
+ return true;
2008
+ }
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) {
1527
2021
  return false;
1528
2022
  }
1529
- // Check if the type has all required methods
1530
- const requiredMethods = interfaceTypeInfo.methods || [];
1531
- const typeMethods = typeInfo.methods || [];
1532
- // For each required method, check if the type has a matching method
1533
- for (const requiredMethod of requiredMethods) {
1534
- const typeMethod = typeMethods.find((m) => m.name === requiredMethod.name);
1535
- if (!typeMethod) {
1536
- 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;
1537
2043
  }
1538
- // Check if method signatures match (simplified - just check counts)
1539
- if (typeMethod.args.length !== requiredMethod.args.length) {
1540
- return false;
2044
+ if (methodSignatureIdentityKey(merged[existingIndex]) !==
2045
+ methodSignatureIdentityKey(method)) {
2046
+ merged[existingIndex] = method;
1541
2047
  }
1542
- if (typeMethod.returns.length !== requiredMethod.returns.length) {
1543
- 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}`;
1544
2060
  }
1545
- // 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';
1546
2116
  }
1547
- return true;
1548
2117
  }
1549
2118
  function typeFieldByName(t, name) {
1550
2119
  return typeFieldByNameFunc(t, (fieldName) => fieldName === name);
@@ -1553,14 +2122,62 @@ function typeFieldByNameFunc(t, match) {
1553
2122
  if (t.Kind() !== Struct) {
1554
2123
  throw new Error('reflect: FieldByName of non-struct type');
1555
2124
  }
1556
- for (let i = 0; i < t.NumField(); i++) {
1557
- const field = t.Field(i);
2125
+ for (const field of visibleStructFields(t)) {
1558
2126
  if (match(field.Name)) {
1559
2127
  return [field, true];
1560
2128
  }
1561
2129
  }
1562
2130
  return [new StructField(), false];
1563
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
+ }
1564
2181
  function zeroMethod() {
1565
2182
  return {
1566
2183
  Name: '',
@@ -1569,16 +2186,50 @@ function zeroMethod() {
1569
2186
  Index: 0,
1570
2187
  };
1571
2188
  }
1572
- function methodFromSignature(signature, index) {
2189
+ function methodFromSignature(signature, index, receiver) {
1573
2190
  return {
1574
2191
  Name: signature.name,
1575
- Type: new FunctionType('func'),
2192
+ Type: methodTypeFromSignature(signature, receiver, receiver.Kind() !== Interface),
1576
2193
  Func: () => undefined,
1577
2194
  Index: index,
1578
2195
  };
1579
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
+ }
1580
2210
  function typeMethods(t) {
1581
- 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
+ }
1582
2233
  if (!typeInfo) {
1583
2234
  return [];
1584
2235
  }
@@ -1587,29 +2238,98 @@ function typeMethods(t) {
1587
2238
  }
1588
2239
  return [];
1589
2240
  }
1590
- function typeMethodByName(t, name) {
2241
+ function methodSignatureByName(t, name) {
1591
2242
  const methods = typeMethods(t);
1592
2243
  const index = methods.findIndex((method) => method.name === name);
1593
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) {
1594
2252
  return [zeroMethod(), false];
1595
2253
  }
1596
- return [methodFromSignature(methods[index], index), true];
2254
+ return [methodFromSignature(signature, index, t), true];
1597
2255
  }
1598
2256
  function typeAssignableTo(t, u) {
1599
2257
  if (u === null) {
1600
2258
  return false;
1601
2259
  }
1602
- 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);
1603
2319
  }
1604
2320
  class StructType {
1605
2321
  _name;
1606
2322
  _fields;
1607
- constructor(_name, _fields = []) {
2323
+ _pkgPath;
2324
+ _string;
2325
+ constructor(_name, _fields = [], _pkgPath = '', _string = _name) {
1608
2326
  this._name = _name;
1609
2327
  this._fields = _fields;
2328
+ this._pkgPath = _pkgPath;
2329
+ this._string = _string;
1610
2330
  }
1611
2331
  String() {
1612
- return this._name;
2332
+ return this._string;
1613
2333
  }
1614
2334
  Kind() {
1615
2335
  return Struct;
@@ -1618,8 +2338,7 @@ class StructType {
1618
2338
  return this._fields.every((field) => field.type.Comparable());
1619
2339
  }
1620
2340
  Size() {
1621
- // Struct size is implementation-defined, we'll use a reasonable default
1622
- return this._fields.reduce((sum, field) => sum + field.type.Size(), 0);
2341
+ return structDescriptorSize(this._fields);
1623
2342
  }
1624
2343
  Elem() {
1625
2344
  throw new Error('reflect: Elem of invalid type');
@@ -1627,7 +2346,28 @@ class StructType {
1627
2346
  NumField() {
1628
2347
  return this._fields.length;
1629
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
+ }
1630
2364
  PkgPath() {
2365
+ if (this._pkgPath !== '') {
2366
+ return this._pkgPath;
2367
+ }
2368
+ if (this._name === '') {
2369
+ return '';
2370
+ }
1631
2371
  // Extract package path from full type name (e.g., "main.Person" -> "main")
1632
2372
  const dotIndex = this._name.lastIndexOf('.');
1633
2373
  if (dotIndex > 0) {
@@ -1636,6 +2376,9 @@ class StructType {
1636
2376
  return '';
1637
2377
  }
1638
2378
  Name() {
2379
+ if (this._name === '') {
2380
+ return '';
2381
+ }
1639
2382
  // Extract type name from full type name (e.g., "main.Person" -> "Person")
1640
2383
  const dotIndex = this._name.lastIndexOf('.');
1641
2384
  if (dotIndex >= 0) {
@@ -1650,12 +2393,56 @@ class StructType {
1650
2393
  const f = this._fields[i];
1651
2394
  return new StructField({
1652
2395
  Name: f.name,
1653
- PkgPath: '',
2396
+ PkgPath: f.pkgPath,
1654
2397
  Type: f.type,
1655
2398
  Tag: f.tag ? new StructTag(f.tag) : undefined,
1656
- Index: [i],
2399
+ Offset: f.offset,
2400
+ Index: [...f.index],
2401
+ Anonymous: f.anonymous,
1657
2402
  });
1658
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
+ }
1659
2446
  FieldByName(name) {
1660
2447
  return typeFieldByName(this, name);
1661
2448
  }
@@ -1672,7 +2459,7 @@ class StructType {
1672
2459
  if (u.Kind() !== Interface) {
1673
2460
  throw new Error('reflect: non-interface type passed to Type.Implements');
1674
2461
  }
1675
- return typeImplementsInterface(this._name, u);
2462
+ return typeImplementsInterface(this, u);
1676
2463
  }
1677
2464
  AssignableTo(u) {
1678
2465
  return typeAssignableTo(this, u);
@@ -1701,32 +2488,9 @@ class StructType {
1701
2488
  Bits() {
1702
2489
  throw new Error('reflect: call of reflect.Type.Bits on struct Type');
1703
2490
  }
1704
- static createTypeFromFieldInfo(ti) {
2491
+ static createTypeFromFieldInfo(ti, seen = new Set()) {
1705
2492
  if (typeof ti === 'string') {
1706
- switch (ti) {
1707
- case 'string':
1708
- return new BasicType(String, ti, 16);
1709
- case 'int':
1710
- case 'int32':
1711
- case 'int64':
1712
- case 'number':
1713
- return new BasicType(Int, ti === 'number' ? 'int' : ti, 8);
1714
- case 'bool':
1715
- case 'boolean':
1716
- return new BasicType(Bool, 'bool', 1);
1717
- case 'float64':
1718
- return new BasicType(Float64, ti, 8);
1719
- case 'complex64':
1720
- return new BasicType(Complex64, ti, 8);
1721
- case 'complex128':
1722
- return new BasicType(Complex128, ti, 16);
1723
- case 'uint':
1724
- case 'uint32':
1725
- case 'uint64':
1726
- return new BasicType(Uint, ti, 8);
1727
- default:
1728
- return new BasicType(Invalid, ti, 8);
1729
- }
2493
+ return basicTypeFromName(ti === 'number' ? 'int' : ti);
1730
2494
  }
1731
2495
  else if (ti && ti.kind) {
1732
2496
  // Handle TypeInfo objects from the builtin type system
@@ -1734,41 +2498,24 @@ class StructType {
1734
2498
  const typeName = ti.typeName || '';
1735
2499
  switch (ti.kind) {
1736
2500
  case 'basic':
1737
- // Map TypeScript type names to Go type names
1738
- switch (name) {
1739
- case 'string':
1740
- return new BasicType(String, 'string', 16, typeName);
1741
- case 'number':
1742
- case 'int':
1743
- case 'int32':
1744
- case 'int64':
1745
- return new BasicType(Int, name === 'number' ? 'int' : name, 8, typeName);
1746
- case 'boolean':
1747
- case 'bool':
1748
- return new BasicType(Bool, 'bool', 1, typeName);
1749
- case 'float64':
1750
- return new BasicType(Float64, 'float64', 8, typeName);
1751
- case 'complex64':
1752
- return new BasicType(Complex64, 'complex64', 8, typeName);
1753
- case 'complex128':
1754
- return new BasicType(Complex128, 'complex128', 16, typeName);
1755
- default:
1756
- return new BasicType(Invalid, name, 8, typeName);
1757
- }
2501
+ return basicTypeFromName(name === 'number' ? 'int' : name, typeName);
1758
2502
  case 'slice':
1759
2503
  if (ti.elemType) {
1760
- return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType));
2504
+ return new SliceType(StructType.createTypeFromFieldInfo(ti.elemType, seen));
1761
2505
  }
1762
2506
  return new SliceType(new BasicType(Invalid, 'unknown', 8));
1763
2507
  case 'pointer':
1764
2508
  if (ti.elemType) {
1765
- return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType));
2509
+ return new PointerType(StructType.createTypeFromFieldInfo(ti.elemType, seen));
1766
2510
  }
1767
2511
  return new PointerType(new BasicType(Invalid, 'unknown', 8));
1768
2512
  case 'interface':
1769
- return new InterfaceType(name);
1770
- case 'struct':
1771
- 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
+ }
1772
2519
  default:
1773
2520
  return new BasicType(Invalid, name, 8);
1774
2521
  }
@@ -1776,18 +2523,60 @@ class StructType {
1776
2523
  return new BasicType(Invalid, 'unknown', 8);
1777
2524
  }
1778
2525
  }
1779
- function structFieldsFromTypeInfo(ti) {
1780
- return Object.entries(ti.fields || {}).map(([name, fieldInfo]) => {
1781
- if (isStructFieldInfo(fieldInfo)) {
1782
- return {
1783
- name: fieldInfo.name ?? name,
1784
- type: typeFromTypeInfo(fieldInfo.type),
1785
- tag: fieldInfo.tag,
1786
- };
1787
- }
2526
+ function basicTypeFromName(name, typeName = '') {
2527
+ switch (name) {
2528
+ case 'string':
2529
+ return new BasicType(String, 'string', 16, typeName);
2530
+ case 'bool':
2531
+ case 'boolean':
2532
+ return new BasicType(Bool, 'bool', 1, typeName);
2533
+ case 'int':
2534
+ return new BasicType(Int, 'int', 8, typeName);
2535
+ case 'int8':
2536
+ return new BasicType(Int8, 'int8', 1, typeName);
2537
+ case 'int16':
2538
+ return new BasicType(Int16, 'int16', 2, typeName);
2539
+ case 'int32':
2540
+ return new BasicType(Int32, 'int32', 4, typeName);
2541
+ case 'int64':
2542
+ return new BasicType(Int64, 'int64', 8, typeName);
2543
+ case 'uint':
2544
+ return new BasicType(Uint, 'uint', 8, typeName);
2545
+ case 'uint8':
2546
+ case 'byte':
2547
+ return new BasicType(Uint8, name, 1, typeName);
2548
+ case 'uint16':
2549
+ return new BasicType(Uint16, 'uint16', 2, typeName);
2550
+ case 'uint32':
2551
+ return new BasicType(Uint32, 'uint32', 4, typeName);
2552
+ case 'uint64':
2553
+ return new BasicType(Uint64, 'uint64', 8, typeName);
2554
+ case 'uintptr':
2555
+ return new BasicType(Uintptr, 'uintptr', 8, typeName);
2556
+ case 'float32':
2557
+ return new BasicType(Float32, 'float32', 4, typeName);
2558
+ case 'float64':
2559
+ return new BasicType(Float64, 'float64', 8, typeName);
2560
+ case 'complex64':
2561
+ return new BasicType(Complex64, 'complex64', 8, typeName);
2562
+ case 'complex128':
2563
+ return new BasicType(Complex128, 'complex128', 16, typeName);
2564
+ default:
2565
+ return new BasicType(Invalid, name, 8, typeName);
2566
+ }
2567
+ }
2568
+ function structFieldsFromTypeInfo(ti, seen = new Set()) {
2569
+ return (ti.fields || []).map((fieldInfo, index) => {
1788
2570
  return {
1789
- name,
1790
- 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 ?? '') === '',
1791
2580
  };
1792
2581
  });
1793
2582
  }
@@ -1827,6 +2616,21 @@ class ChannelType {
1827
2616
  NumField() {
1828
2617
  return 0;
1829
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
+ }
1830
2634
  PkgPath() {
1831
2635
  return '';
1832
2636
  }
@@ -1853,7 +2657,7 @@ class ChannelType {
1853
2657
  if (u.Kind() !== Interface) {
1854
2658
  throw new Error('reflect: non-interface type passed to Type.Implements');
1855
2659
  }
1856
- return false;
2660
+ return typeImplementsInterface(this, u);
1857
2661
  }
1858
2662
  AssignableTo(u) {
1859
2663
  return typeAssignableTo(this, u);
@@ -1890,9 +2694,11 @@ class ChannelType {
1890
2694
  class InterfaceType {
1891
2695
  _name;
1892
2696
  _registeredName;
1893
- constructor(_name = 'interface{}', _registeredName) {
2697
+ _methods;
2698
+ constructor(_name = 'interface{}', _registeredName, _methods = []) {
1894
2699
  this._name = _name;
1895
2700
  this._registeredName = _registeredName;
2701
+ this._methods = _methods;
1896
2702
  }
1897
2703
  String() {
1898
2704
  return this._name;
@@ -1912,6 +2718,21 @@ class InterfaceType {
1912
2718
  NumField() {
1913
2719
  return 0;
1914
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
+ }
1915
2736
  PkgPath() {
1916
2737
  if (this._name === 'interface{}' || this._name.startsWith('interface {')) {
1917
2738
  return '';
@@ -1944,8 +2765,14 @@ class InterfaceType {
1944
2765
  Key() {
1945
2766
  throw new Error('reflect: Key of non-map type');
1946
2767
  }
1947
- Implements(_u) {
1948
- 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);
1949
2776
  }
1950
2777
  AssignableTo(u) {
1951
2778
  return typeAssignableTo(this, u);
@@ -1977,6 +2804,9 @@ class InterfaceType {
1977
2804
  registeredName() {
1978
2805
  return this._registeredName;
1979
2806
  }
2807
+ methodSignatures() {
2808
+ return this._methods;
2809
+ }
1980
2810
  }
1981
2811
  function getTypeOf(value) {
1982
2812
  // Check for typed nil before checking for plain null
@@ -2018,22 +2848,19 @@ function getTypeOf(value) {
2018
2848
  if ((typeInfo.kind === 'function' || typeInfo.kind === 'Function') &&
2019
2849
  typeInfo.params &&
2020
2850
  typeInfo.results) {
2851
+ if (funcWithMeta.__goTypeName && !typeInfo.name) {
2852
+ return functionTypeFromInfo({
2853
+ ...typeInfo,
2854
+ name: funcWithMeta.__goTypeName,
2855
+ });
2856
+ }
2021
2857
  return functionTypeFromInfo(typeInfo);
2022
2858
  }
2023
2859
  }
2024
2860
  // Then check for __goTypeName which indicates a typed function
2025
2861
  if (funcWithMeta.__goTypeName) {
2026
- // This is a typed Go function - try to reconstruct the signature
2027
2862
  const typeName = funcWithMeta.__goTypeName;
2028
- // For known Go function types, construct proper signatures
2029
- if (typeName === 'Greeter') {
2030
- return new FunctionType('func(string) string');
2031
- }
2032
- else if (typeName === 'Adder') {
2033
- return new FunctionType('func(int, int) int');
2034
- }
2035
- // Generic fallback for typed functions
2036
- return new FunctionType(`func`); // Could be enhanced with parameter parsing
2863
+ return new FunctionType({ name: typeName });
2037
2864
  }
2038
2865
  // For untyped functions, try to parse the signature
2039
2866
  const funcStr = value.toString();
@@ -2069,6 +2896,10 @@ function getTypeOf(value) {
2069
2896
  const elemType = getTypeOf(value.value);
2070
2897
  return new PointerType(elemType);
2071
2898
  }
2899
+ if ('__goTypeInfo' in value &&
2900
+ value.__goTypeInfo) {
2901
+ return typeFromTypeInfo(value.__goTypeInfo);
2902
+ }
2072
2903
  if ('real' in value &&
2073
2904
  'imag' in value &&
2074
2905
  typeof value.real === 'number' &&
@@ -2136,34 +2967,31 @@ function getTypeOf(value) {
2136
2967
  }
2137
2968
  }
2138
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
+ }
2139
2980
  if (value &&
2140
2981
  typeof value === 'object' &&
2141
2982
  value.constructor &&
2142
2983
  '__typeInfo' in value.constructor) {
2143
2984
  const typeInfo = value.constructor.__typeInfo;
2144
- if (typeInfo && typeInfo.name) {
2145
- const typeName = typeInfo.name.includes('.') ?
2146
- typeInfo.name
2147
- : `main.${typeInfo.name}`;
2148
- const regTypeInfo = builtinGetTypeByName(typeName);
2149
- let fields = [];
2150
- if (regTypeInfo && isStructTypeInfo(regTypeInfo)) {
2151
- fields = Object.entries(regTypeInfo.fields || {}).map(([name, fieldInfo]) => {
2152
- // Check if fieldInfo is a StructFieldInfo with type and tag
2153
- if (isStructFieldInfo(fieldInfo)) {
2154
- return {
2155
- name: fieldInfo.name ?? name,
2156
- type: StructType.createTypeFromFieldInfo(fieldInfo.type),
2157
- tag: fieldInfo.tag,
2158
- };
2159
- }
2160
- // Otherwise it's just the type info directly (backwards compatible)
2161
- return {
2162
- name,
2163
- type: StructType.createTypeFromFieldInfo(fieldInfo),
2164
- };
2165
- });
2985
+ if (typeInfo && isStructTypeInfo(typeInfo)) {
2986
+ const name = typeInfo.name ?? '';
2987
+ if (name === '') {
2988
+ return new StructType('', structFieldsFromTypeInfo(typeInfo));
2166
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);
2167
2995
  return new StructType(typeName, fields);
2168
2996
  }
2169
2997
  }
@@ -2213,86 +3041,497 @@ export function MapOf(key, elem) {
2213
3041
  export function ChanOf(dir, t) {
2214
3042
  return internType(new ChannelType(t, dir));
2215
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
+ }
2216
3161
  export function TypeFor(typeArgs) {
2217
3162
  const descriptor = typeArgs?.T;
3163
+ const methodSignatures = genericMethodSignatures(descriptor);
2218
3164
  if (descriptor?.type) {
2219
- return internType(typeFromTypeInfo(descriptor.type));
3165
+ return internType(typeWithMethodSignatures(typeFromTypeInfo(descriptor.type), methodSignatures));
2220
3166
  }
2221
- if (descriptor?.methods) {
2222
- const methods = Object.keys(descriptor.methods);
2223
- if (methods.length !== 0) {
2224
- return internType(new InterfaceType(`interface { ${methods.map((method) => method + '()').join('; ')} }`));
2225
- }
3167
+ if (methodSignatures.length !== 0) {
3168
+ return internType(new InterfaceType(interfaceTypeString(methodSignatures), undefined, methodSignatures));
2226
3169
  }
2227
3170
  if (descriptor?.zero) {
2228
3171
  return internType(getTypeOf(descriptor.zero()));
2229
3172
  }
2230
3173
  return internType(new InterfaceType('interface{}'));
2231
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
+ }
2232
3209
  function typeFromTypeInfo(info) {
3210
+ return typeFromTypeInfoWithSeen(info, new Set());
3211
+ }
3212
+ function typeFromTypeInfoWithSeen(info, seen) {
2233
3213
  if (typeof info === 'string') {
2234
3214
  const registered = builtinGetTypeByName(info);
2235
3215
  if (registered) {
2236
- return internType(typeFromTypeInfo(registered));
3216
+ const typ = typeFromTypeInfoWithSeen(registered, seen);
3217
+ return internType(typ);
3218
+ }
3219
+ return internType(StructType.createTypeFromFieldInfo(info, seen));
3220
+ }
3221
+ const recursiveName = recursiveTypeInfoName(info);
3222
+ if (recursiveName !== '') {
3223
+ const constructing = constructingRegisteredTypes.get(recursiveName);
3224
+ if (constructing) {
3225
+ return constructing;
2237
3226
  }
2238
- return internType(StructType.createTypeFromFieldInfo(info));
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 ?? '';
2239
3253
  }
3254
+ return info.name ?? '';
3255
+ }
3256
+ function typeFromStructuredTypeInfoWithSeen(info, seen) {
2240
3257
  switch (info.kind) {
2241
3258
  case $.TypeKind.Array:
2242
- 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);
2243
3260
  case $.TypeKind.Basic:
2244
- return internType(StructType.createTypeFromFieldInfo(info));
3261
+ return StructType.createTypeFromFieldInfo(info, seen);
2245
3262
  case $.TypeKind.Channel:
2246
- 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));
2247
3264
  case $.TypeKind.Function:
2248
- return internType(functionTypeFromInfo(info));
3265
+ return functionTypeFromInfo(info, seen);
2249
3266
  case $.TypeKind.Interface:
2250
- return internType(interfaceTypeFromInfo(info));
3267
+ return interfaceTypeFromInfo(info, seen);
2251
3268
  case $.TypeKind.Map:
2252
- 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));
2253
3270
  case $.TypeKind.Slice:
2254
- 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));
2255
3272
  case $.TypeKind.Struct:
2256
- return internType(StructType.createTypeFromFieldInfo(info));
3273
+ return StructType.createTypeFromFieldInfo(info, seen);
2257
3274
  case $.TypeKind.Pointer:
2258
- 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));
2259
3276
  default:
2260
- return internType(StructType.createTypeFromFieldInfo(info));
3277
+ return StructType.createTypeFromFieldInfo(info, seen);
2261
3278
  }
2262
3279
  }
2263
- function functionTypeFromInfo(info) {
2264
- if (info.name) {
2265
- 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);
2266
3296
  }
2267
- const params = info.params ?? [];
2268
- const paramTypes = params.map((param, index) => {
2269
- const typeName = functionSignatureTypeName(param);
2270
- if (!info.isVariadic || index !== params.length - 1) {
2271
- return typeName;
2272
- }
2273
- if (typeName.startsWith('[]')) {
2274
- return '...' + typeName.slice(2);
2275
- }
2276
- 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,
2277
3306
  });
2278
- const resultTypes = (info.results ?? []).map(functionSignatureTypeName);
2279
- let signature = `func(${paramTypes.join(', ')})`;
2280
- if (resultTypes.length === 1) {
2281
- 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();
3324
+ }
3325
+ if (typ.IsVariadic()) {
3326
+ info.isVariadic = true;
3327
+ }
3328
+ return info;
3329
+ }
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
+ }
3430
+ }
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})`;
2282
3457
  }
2283
- if (resultTypes.length > 1) {
2284
- signature += ` (${resultTypes.join(', ')})`;
3458
+ if (returns.length === 1) {
3459
+ return `${method.name}(${args}) ${returns[0]}`;
2285
3460
  }
2286
- return new FunctionType(signature);
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}`;
2287
3479
  }
2288
- function functionSignatureTypeName(info) {
2289
- return typeFromTypeInfo(info).String();
3480
+ function methodArgString(arg, seen) {
3481
+ return typeInfoString(arg.type, seen);
2290
3482
  }
2291
- function interfaceTypeFromInfo(info) {
2292
- if (info.methods.length === 0) {
2293
- return new InterfaceType('interface{}', info.name);
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';
2294
3534
  }
2295
- return new InterfaceType(`interface { ${info.methods.map((method) => method.name + '()').join('; ')} }`, info.name);
2296
3535
  }
2297
3536
  function chanDirFromTypeInfo(direction) {
2298
3537
  switch (direction) {
@@ -2310,35 +3549,15 @@ function chanDirFromTypeInfo(direction) {
2310
3549
  */
2311
3550
  export function getInterfaceTypeByName(name) {
2312
3551
  const typeInfo = builtinGetTypeByName(name);
2313
- if (typeInfo && typeInfo.kind === TypeKind.Interface) {
2314
- return new InterfaceType(name, name);
3552
+ if (typeInfo && isInterfaceTypeInfo(typeInfo)) {
3553
+ return new InterfaceType(name, name, typeInfo.methods ?? []);
2315
3554
  }
2316
3555
  return new InterfaceType('interface{}');
2317
3556
  }
2318
3557
  export function getInterfaceLiteralTypeByName(name) {
2319
3558
  const typeInfo = builtinGetTypeByName(name);
2320
- if (typeInfo && typeInfo.kind === TypeKind.Interface) {
2321
- const methods = typeInfo.methods || [];
2322
- if (methods.length === 0) {
2323
- return new InterfaceType('interface{}', name);
2324
- }
2325
- const methodSigs = methods
2326
- .map((m) => {
2327
- const args = m.args
2328
- ?.map((a) => (typeof a === 'string' ? a : 'any'))
2329
- .join(', ') || '';
2330
- const returns = m.returns?.map((r) => typeof r === 'string' ? r : 'any');
2331
- let returnSig = '';
2332
- if (returns && returns.length === 1) {
2333
- returnSig = ` ${returns[0]}`;
2334
- }
2335
- else if (returns && returns.length > 1) {
2336
- returnSig = ` (${returns.join(', ')})`;
2337
- }
2338
- return `${m.name}(${args})${returnSig}`;
2339
- })
2340
- .join('; ');
2341
- return new InterfaceType(`interface { ${methodSigs} }`, name);
3559
+ if (typeInfo && isInterfaceTypeInfo(typeInfo)) {
3560
+ return interfaceTypeFromInfo(typeInfo);
2342
3561
  }
2343
3562
  return new InterfaceType('interface{}');
2344
3563
  }