goscript 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/compiler/compile-request.go +12 -9
  8. package/compiler/compliance_test.go +0 -1
  9. package/compiler/config.go +2 -0
  10. package/compiler/gotest/request.go +28 -0
  11. package/compiler/gotest/runner.go +353 -27
  12. package/compiler/gotest/runner_test.go +273 -1
  13. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  14. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  15. package/compiler/lowered-program.go +24 -17
  16. package/compiler/lowering.go +392 -127
  17. package/compiler/lowering_bench_test.go +41 -27
  18. package/compiler/override-facts.go +15 -0
  19. package/compiler/override-parity-verifier.go +450 -0
  20. package/compiler/override-parity.go +122 -0
  21. package/compiler/override-registry_test.go +559 -0
  22. package/compiler/protobuf-ts-binding.go +514 -0
  23. package/compiler/protobuf-ts-binding_test.go +172 -0
  24. package/compiler/semantic-model-types.go +9 -4
  25. package/compiler/semantic-model.go +282 -70
  26. package/compiler/semantic-model_test.go +82 -1
  27. package/compiler/service.go +20 -1
  28. package/compiler/skeleton_test.go +62 -8
  29. package/compiler/typescript-emitter.go +128 -13
  30. package/dist/gs/builtin/slice.d.ts +2 -1
  31. package/dist/gs/builtin/slice.js +29 -4
  32. package/dist/gs/builtin/slice.js.map +1 -1
  33. package/dist/gs/builtin/type.d.ts +13 -5
  34. package/dist/gs/builtin/type.js +153 -60
  35. package/dist/gs/builtin/type.js.map +1 -1
  36. package/dist/gs/builtin/varRef.d.ts +11 -0
  37. package/dist/gs/builtin/varRef.js +57 -2
  38. package/dist/gs/builtin/varRef.js.map +1 -1
  39. package/dist/gs/bytes/buffer.gs.js +1 -1
  40. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  41. package/dist/gs/bytes/reader.gs.js +1 -1
  42. package/dist/gs/bytes/reader.gs.js.map +1 -1
  43. package/dist/gs/compress/zlib/index.d.ts +10 -3
  44. package/dist/gs/compress/zlib/index.js +50 -16
  45. package/dist/gs/compress/zlib/index.js.map +1 -1
  46. package/dist/gs/encoding/json/index.d.ts +114 -0
  47. package/dist/gs/encoding/json/index.js +544 -36
  48. package/dist/gs/encoding/json/index.js.map +1 -1
  49. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  50. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  51. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  52. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  53. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  54. package/dist/gs/go/scanner/index.d.ts +2 -0
  55. package/dist/gs/go/scanner/index.js +29 -5
  56. package/dist/gs/go/scanner/index.js.map +1 -1
  57. package/dist/gs/go/token/index.js +22 -6
  58. package/dist/gs/go/token/index.js.map +1 -1
  59. package/dist/gs/hash/index.d.ts +6 -0
  60. package/dist/gs/hash/index.js +20 -0
  61. package/dist/gs/hash/index.js.map +1 -1
  62. package/dist/gs/internal/goarch/index.d.ts +43 -3
  63. package/dist/gs/internal/goarch/index.js +42 -10
  64. package/dist/gs/internal/goarch/index.js.map +1 -1
  65. package/dist/gs/io/fs/fs.js +26 -14
  66. package/dist/gs/io/fs/fs.js.map +1 -1
  67. package/dist/gs/io/fs/readdir.js +4 -2
  68. package/dist/gs/io/fs/readdir.js.map +1 -1
  69. package/dist/gs/io/fs/sub.js +8 -1
  70. package/dist/gs/io/fs/sub.js.map +1 -1
  71. package/dist/gs/io/io.d.ts +2 -0
  72. package/dist/gs/io/io.js.map +1 -1
  73. package/dist/gs/math/bits/index.d.ts +5 -0
  74. package/dist/gs/math/bits/index.js +16 -4
  75. package/dist/gs/math/bits/index.js.map +1 -1
  76. package/dist/gs/mime/index.d.ts +16 -0
  77. package/dist/gs/mime/index.js +315 -6
  78. package/dist/gs/mime/index.js.map +1 -1
  79. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  80. package/dist/gs/net/http/httptest/index.js +85 -6
  81. package/dist/gs/net/http/httptest/index.js.map +1 -1
  82. package/dist/gs/net/http/index.d.ts +300 -5
  83. package/dist/gs/net/http/index.js +1598 -58
  84. package/dist/gs/net/http/index.js.map +1 -1
  85. package/dist/gs/os/dir_unix.gs.js +1 -1
  86. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  87. package/dist/gs/os/error.gs.js +1 -1
  88. package/dist/gs/os/error.gs.js.map +1 -1
  89. package/dist/gs/os/exec.gs.d.ts +1 -0
  90. package/dist/gs/os/exec.gs.js +4 -8
  91. package/dist/gs/os/exec.gs.js.map +1 -1
  92. package/dist/gs/os/exec_posix.gs.js +1 -1
  93. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  94. package/dist/gs/os/index.d.ts +1 -1
  95. package/dist/gs/os/index.js +1 -1
  96. package/dist/gs/os/index.js.map +1 -1
  97. package/dist/gs/os/proc.gs.d.ts +4 -0
  98. package/dist/gs/os/proc.gs.js +12 -6
  99. package/dist/gs/os/proc.gs.js.map +1 -1
  100. package/dist/gs/os/root_js.gs.js +1 -1
  101. package/dist/gs/os/root_js.gs.js.map +1 -1
  102. package/dist/gs/os/types.gs.js +1 -1
  103. package/dist/gs/os/types.gs.js.map +1 -1
  104. package/dist/gs/os/types_js.gs.js +1 -1
  105. package/dist/gs/os/types_js.gs.js.map +1 -1
  106. package/dist/gs/os/types_unix.gs.js +1 -1
  107. package/dist/gs/os/types_unix.gs.js.map +1 -1
  108. package/dist/gs/path/path.js +11 -7
  109. package/dist/gs/path/path.js.map +1 -1
  110. package/dist/gs/reflect/index.d.ts +5 -4
  111. package/dist/gs/reflect/index.js +4 -3
  112. package/dist/gs/reflect/index.js.map +1 -1
  113. package/dist/gs/reflect/map.js +15 -0
  114. package/dist/gs/reflect/map.js.map +1 -1
  115. package/dist/gs/reflect/type.d.ts +25 -6
  116. package/dist/gs/reflect/type.js +1418 -228
  117. package/dist/gs/reflect/type.js.map +1 -1
  118. package/dist/gs/reflect/types.d.ts +14 -6
  119. package/dist/gs/reflect/types.js +35 -1
  120. package/dist/gs/reflect/types.js.map +1 -1
  121. package/dist/gs/reflect/value.d.ts +1 -0
  122. package/dist/gs/reflect/value.js +83 -41
  123. package/dist/gs/reflect/value.js.map +1 -1
  124. package/dist/gs/reflect/visiblefields.js +4 -140
  125. package/dist/gs/reflect/visiblefields.js.map +1 -1
  126. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  127. package/dist/gs/runtime/pprof/index.js +50 -30
  128. package/dist/gs/runtime/pprof/index.js.map +1 -1
  129. package/dist/gs/runtime/runtime.js +5 -4
  130. package/dist/gs/runtime/runtime.js.map +1 -1
  131. package/dist/gs/runtime/trace/index.js +5 -19
  132. package/dist/gs/runtime/trace/index.js.map +1 -1
  133. package/dist/gs/strconv/atoi.gs.js +1 -1
  134. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  135. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  136. package/dist/gs/strconv/complex.gs.js +148 -0
  137. package/dist/gs/strconv/complex.gs.js.map +1 -0
  138. package/dist/gs/strconv/index.d.ts +1 -0
  139. package/dist/gs/strconv/index.js +1 -0
  140. package/dist/gs/strconv/index.js.map +1 -1
  141. package/dist/gs/strings/builder.js +1 -1
  142. package/dist/gs/strings/reader.js +9 -5
  143. package/dist/gs/strings/reader.js.map +1 -1
  144. package/dist/gs/strings/replace.js +15 -7
  145. package/dist/gs/strings/replace.js.map +1 -1
  146. package/dist/gs/strings/strings.d.ts +5 -0
  147. package/dist/gs/strings/strings.js +57 -5
  148. package/dist/gs/strings/strings.js.map +1 -1
  149. package/dist/gs/sync/atomic/type.gs.js +9 -9
  150. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  151. package/dist/gs/sync/atomic/value.gs.js +2 -2
  152. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  153. package/dist/gs/syscall/env.js +22 -14
  154. package/dist/gs/syscall/env.js.map +1 -1
  155. package/dist/gs/testing/testing.js +55 -13
  156. package/dist/gs/testing/testing.js.map +1 -1
  157. package/dist/gs/time/time.d.ts +24 -1
  158. package/dist/gs/time/time.js +43 -3
  159. package/dist/gs/time/time.js.map +1 -1
  160. package/dist/gs/unique/index.js +7 -1
  161. package/dist/gs/unique/index.js.map +1 -1
  162. package/go.mod +3 -3
  163. package/go.sum +16 -0
  164. package/gs/builtin/runtime-contract.test.ts +218 -21
  165. package/gs/builtin/slice.ts +44 -4
  166. package/gs/builtin/type.ts +226 -59
  167. package/gs/builtin/varRef.ts +85 -2
  168. package/gs/bytes/buffer.gs.ts +1 -1
  169. package/gs/bytes/reader.gs.ts +1 -1
  170. package/gs/compress/zlib/index.test.ts +62 -1
  171. package/gs/compress/zlib/index.ts +53 -16
  172. package/gs/compress/zlib/parity.json +51 -0
  173. package/gs/encoding/json/index.test.ts +360 -6
  174. package/gs/encoding/json/index.ts +679 -38
  175. package/gs/encoding/json/parity.json +81 -0
  176. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  177. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  178. package/gs/github.com/pkg/errors/errors.ts +54 -30
  179. package/gs/go/scanner/index.test.ts +39 -56
  180. package/gs/go/scanner/index.ts +33 -5
  181. package/gs/go/scanner/parity.json +27 -0
  182. package/gs/go/token/index.ts +22 -6
  183. package/gs/hash/index.test.ts +20 -33
  184. package/gs/hash/index.ts +28 -0
  185. package/gs/hash/parity.json +21 -0
  186. package/gs/internal/goarch/index.test.ts +32 -0
  187. package/gs/internal/goarch/index.ts +45 -13
  188. package/gs/internal/goarch/parity.json +144 -0
  189. package/gs/io/fs/fs.ts +26 -14
  190. package/gs/io/fs/readdir.ts +4 -4
  191. package/gs/io/fs/sub.ts +8 -1
  192. package/gs/io/io.ts +1 -0
  193. package/gs/io/parity.json +162 -0
  194. package/gs/math/bits/index.test.ts +14 -1
  195. package/gs/math/bits/index.ts +23 -4
  196. package/gs/math/bits/parity.json +156 -0
  197. package/gs/mime/index.test.ts +90 -0
  198. package/gs/mime/index.ts +369 -6
  199. package/gs/mime/parity.json +36 -0
  200. package/gs/net/http/httptest/index.test.ts +98 -2
  201. package/gs/net/http/httptest/index.ts +101 -6
  202. package/gs/net/http/httptest/parity.json +15 -0
  203. package/gs/net/http/index.test.ts +781 -12
  204. package/gs/net/http/index.ts +1860 -139
  205. package/gs/net/http/meta.json +16 -1
  206. package/gs/net/http/parity.json +193 -0
  207. package/gs/os/dir_unix.gs.ts +1 -1
  208. package/gs/os/error.gs.ts +1 -1
  209. package/gs/os/exec.gs.ts +4 -8
  210. package/gs/os/exec_posix.gs.ts +1 -1
  211. package/gs/os/index.test.ts +9 -0
  212. package/gs/os/index.ts +1 -0
  213. package/gs/os/parity.json +9 -0
  214. package/gs/os/proc.gs.ts +18 -5
  215. package/gs/os/proc.test.ts +26 -0
  216. package/gs/os/root_js.gs.ts +1 -1
  217. package/gs/os/types.gs.ts +1 -1
  218. package/gs/os/types_js.gs.ts +1 -1
  219. package/gs/os/types_unix.gs.ts +1 -1
  220. package/gs/path/path.ts +11 -7
  221. package/gs/reflect/field.test.ts +37 -15
  222. package/gs/reflect/function-types.test.ts +518 -22
  223. package/gs/reflect/index.ts +8 -6
  224. package/gs/reflect/map.ts +20 -0
  225. package/gs/reflect/meta.json +6 -4
  226. package/gs/reflect/parity.json +234 -0
  227. package/gs/reflect/sliceat.test.ts +156 -0
  228. package/gs/reflect/structof.test.ts +401 -0
  229. package/gs/reflect/type.ts +1897 -317
  230. package/gs/reflect/typefor.test.ts +510 -10
  231. package/gs/reflect/types.ts +43 -18
  232. package/gs/reflect/value.ts +105 -45
  233. package/gs/reflect/visiblefields.ts +5 -168
  234. package/gs/runtime/parity.json +24 -0
  235. package/gs/runtime/pprof/index.test.ts +29 -7
  236. package/gs/runtime/pprof/index.ts +56 -30
  237. package/gs/runtime/pprof/parity.json +27 -0
  238. package/gs/runtime/runtime.test.ts +3 -1
  239. package/gs/runtime/runtime.ts +4 -3
  240. package/gs/runtime/trace/index.test.ts +5 -3
  241. package/gs/runtime/trace/index.ts +8 -20
  242. package/gs/runtime/trace/parity.json +36 -0
  243. package/gs/strconv/atoi.gs.ts +1 -1
  244. package/gs/strconv/complex.gs.ts +174 -0
  245. package/gs/strconv/complex.test.ts +65 -0
  246. package/gs/strconv/index.ts +1 -0
  247. package/gs/strconv/parity.json +120 -0
  248. package/gs/strings/builder.ts +1 -1
  249. package/gs/strings/parity.json +186 -0
  250. package/gs/strings/reader.ts +9 -5
  251. package/gs/strings/replace.ts +15 -7
  252. package/gs/strings/strings.test.ts +22 -2
  253. package/gs/strings/strings.ts +64 -6
  254. package/gs/sync/atomic/type.gs.ts +9 -9
  255. package/gs/sync/atomic/value.gs.ts +2 -2
  256. package/gs/syscall/env.ts +29 -14
  257. package/gs/testing/testing.test.ts +67 -0
  258. package/gs/testing/testing.ts +87 -19
  259. package/gs/time/parity.json +225 -0
  260. package/gs/time/time.test.ts +20 -2
  261. package/gs/time/time.ts +49 -7
  262. package/gs/unique/index.ts +7 -1
  263. package/package.json +4 -2
  264. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  265. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
  266. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  267. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
  268. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
  269. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  270. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -1,5 +1,22 @@
1
1
  import { describe, it, expect } from 'vitest'
2
- import { TypeOf, Kind_String } from './type.js'
2
+ import {
3
+ arrayToSlice,
4
+ asArray,
5
+ functionValue,
6
+ namedFunction,
7
+ registerStructType,
8
+ typeAssertTuple,
9
+ TypeKind,
10
+ } from '../builtin/index.js'
11
+ import {
12
+ FuncOf,
13
+ Kind_String,
14
+ MakeFunc,
15
+ SliceOf,
16
+ TypeFor,
17
+ TypeOf,
18
+ ValueOf,
19
+ } from './type.js'
3
20
 
4
21
  describe('Function Type Detection', () => {
5
22
  it('should detect regular function types', () => {
@@ -12,22 +29,24 @@ describe('Function Type Detection', () => {
12
29
  })
13
30
 
14
31
  it('should detect GoScript typed functions with __goTypeName', () => {
15
- // Test Greeter function type
16
32
  const greetFunc = function (name: string) {
17
33
  return 'Hello, ' + name
18
34
  }
19
35
  Object.assign(greetFunc, { __goTypeName: 'Greeter' })
20
36
  const greetType = TypeOf(greetFunc)
21
- expect(greetType.String()).toBe('func(string) string')
37
+ expect(greetType.String()).toBe('Greeter')
38
+ expect(greetType.Name()).toBe('Greeter')
39
+ expect(greetType.NumIn()).toBe(0)
22
40
  expect(Kind_String(greetType.Kind())).toBe('func')
23
41
 
24
- // Test Adder function type
25
42
  const addFunc = function (a: number, b: number) {
26
43
  return a + b
27
44
  }
28
45
  Object.assign(addFunc, { __goTypeName: 'Adder' })
29
46
  const addType = TypeOf(addFunc)
30
- expect(addType.String()).toBe('func(int, int) int')
47
+ expect(addType.String()).toBe('Adder')
48
+ expect(addType.Name()).toBe('Adder')
49
+ expect(addType.NumIn()).toBe(0)
31
50
  expect(Kind_String(addType.Kind())).toBe('func')
32
51
  })
33
52
 
@@ -36,19 +55,27 @@ describe('Function Type Detection', () => {
36
55
  return x + y
37
56
  }
38
57
  Object.assign(complexFunc, {
39
- __goTypeName: 'MyFunc',
58
+ __goTypeName: 'example.test.MyFunc',
40
59
  __typeInfo: {
41
- kind: 'Function',
60
+ kind: TypeKind.Function,
42
61
  params: [
43
- { kind: 'Basic', name: 'int' },
44
- { kind: 'Basic', name: 'int' },
62
+ { kind: TypeKind.Basic, name: 'int' },
63
+ { kind: TypeKind.Basic, name: 'int' },
45
64
  ],
46
- results: [{ kind: 'Basic', name: 'int' }],
65
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
47
66
  },
48
67
  })
49
68
 
50
69
  const type = TypeOf(complexFunc)
51
- expect(type.String()).toBe('func(int, int) int')
70
+ expect(type.String()).toBe('example.test.MyFunc')
71
+ expect(type.PkgPath()).toBe('example.test')
72
+ expect(type.Name()).toBe('MyFunc')
73
+ expect(type.NumIn()).toBe(2)
74
+ expect(type.In(0).String()).toBe('int')
75
+ expect(type.In(1).String()).toBe('int')
76
+ expect(type.NumOut()).toBe(1)
77
+ expect(type.Out(0).String()).toBe('int')
78
+ expect(type.IsVariadic()).toBe(false)
52
79
  expect(Kind_String(type.Kind())).toBe('func')
53
80
  })
54
81
 
@@ -59,17 +86,20 @@ describe('Function Type Detection', () => {
59
86
  Object.assign(multiReturnFunc, {
60
87
  __goTypeName: 'MultiReturn',
61
88
  __typeInfo: {
62
- kind: 'Function',
89
+ kind: TypeKind.Function,
63
90
  params: [],
64
91
  results: [
65
- { kind: 'Basic', name: 'int' },
66
- { kind: 'Basic', name: 'string' },
92
+ { kind: TypeKind.Basic, name: 'int' },
93
+ { kind: TypeKind.Basic, name: 'string' },
67
94
  ],
68
95
  },
69
96
  })
70
97
 
71
98
  const type = TypeOf(multiReturnFunc)
72
- expect(type.String()).toBe('func() (int, string)')
99
+ expect(type.String()).toBe('MultiReturn')
100
+ expect(type.NumOut()).toBe(2)
101
+ expect(type.Out(0).String()).toBe('int')
102
+ expect(type.Out(1).String()).toBe('string')
73
103
  expect(Kind_String(type.Kind())).toBe('func')
74
104
  })
75
105
 
@@ -80,14 +110,17 @@ describe('Function Type Detection', () => {
80
110
  Object.assign(noParamFunc, {
81
111
  __goTypeName: 'NoParam',
82
112
  __typeInfo: {
83
- kind: 'Function',
113
+ kind: TypeKind.Function,
84
114
  params: [],
85
- results: [{ kind: 'Basic', name: 'int' }],
115
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
86
116
  },
87
117
  })
88
118
 
89
119
  const type = TypeOf(noParamFunc)
90
- expect(type.String()).toBe('func() int')
120
+ expect(type.String()).toBe('NoParam')
121
+ expect(type.NumIn()).toBe(0)
122
+ expect(type.NumOut()).toBe(1)
123
+ expect(type.Out(0).String()).toBe('int')
91
124
  expect(Kind_String(type.Kind())).toBe('func')
92
125
  })
93
126
 
@@ -98,14 +131,17 @@ describe('Function Type Detection', () => {
98
131
  Object.assign(voidFunc, {
99
132
  __goTypeName: 'VoidFunc',
100
133
  __typeInfo: {
101
- kind: 'Function',
102
- params: [{ kind: 'Basic', name: 'int' }],
134
+ kind: TypeKind.Function,
135
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
103
136
  results: [],
104
137
  },
105
138
  })
106
139
 
107
140
  const type = TypeOf(voidFunc)
108
- expect(type.String()).toBe('func(int)')
141
+ expect(type.String()).toBe('VoidFunc')
142
+ expect(type.NumIn()).toBe(1)
143
+ expect(type.In(0).String()).toBe('int')
144
+ expect(type.NumOut()).toBe(0)
109
145
  expect(Kind_String(type.Kind())).toBe('func')
110
146
  })
111
147
 
@@ -116,10 +152,470 @@ describe('Function Type Detection', () => {
116
152
  Object.assign(unknownFunc, { __goTypeName: 'UnknownType' })
117
153
 
118
154
  const type = TypeOf(unknownFunc)
119
- expect(type.String()).toBe('func')
155
+ expect(type.String()).toBe('UnknownType')
156
+ expect(type.Name()).toBe('UnknownType')
157
+ expect(type.NumIn()).toBe(0)
120
158
  expect(Kind_String(type.Kind())).toBe('func')
121
159
  })
122
160
 
161
+ it('should format unnamed function metadata and variadic parameters', () => {
162
+ const variadicFunc = function (...values: string[]) {
163
+ return values.length
164
+ }
165
+ Object.assign(variadicFunc, {
166
+ __typeInfo: {
167
+ kind: TypeKind.Function,
168
+ params: [
169
+ {
170
+ kind: TypeKind.Slice,
171
+ elemType: { kind: TypeKind.Basic, name: 'string' },
172
+ },
173
+ ],
174
+ results: [{ kind: TypeKind.Basic, name: 'int' }],
175
+ isVariadic: true,
176
+ },
177
+ })
178
+
179
+ const type = TypeOf(variadicFunc)
180
+ expect(type.String()).toBe('func(...string) int')
181
+ expect(type.NumIn()).toBe(1)
182
+ expect(type.In(0).String()).toBe('[]string')
183
+ expect(type.NumOut()).toBe(1)
184
+ expect(type.Out(0).String()).toBe('int')
185
+ expect(type.IsVariadic()).toBe(true)
186
+ })
187
+
188
+ it('should panic on function introspection for non-function types', () => {
189
+ const type = TypeOf(1)
190
+
191
+ expect(() => type.NumIn()).toThrow(/reflect: NumIn of non-func type int/)
192
+ expect(() => type.In(0)).toThrow(/reflect: In of non-func type int/)
193
+ expect(() => type.NumOut()).toThrow(/reflect: NumOut of non-func type int/)
194
+ expect(() => type.Out(0)).toThrow(/reflect: Out of non-func type int/)
195
+ expect(() => type.IsVariadic()).toThrow(
196
+ /reflect: IsVariadic of non-func type int/,
197
+ )
198
+ })
199
+
200
+ it('should construct dynamic function types with FuncOf', () => {
201
+ const intType = TypeOf(1)
202
+ const stringType = TypeOf('')
203
+
204
+ const fnType = FuncOf([intType], [stringType], false)
205
+ expect(fnType.String()).toBe('func(int) string')
206
+ expect(fnType.NumIn()).toBe(1)
207
+ expect(fnType.In(0)).toBe(intType)
208
+ expect(fnType.NumOut()).toBe(1)
209
+ expect(fnType.Out(0)).toBe(stringType)
210
+ expect(fnType.IsVariadic()).toBe(false)
211
+ expect(FuncOf([intType], [stringType], false)).toBe(fnType)
212
+
213
+ const variadicType = FuncOf([SliceOf(stringType)], [intType], true)
214
+ expect(variadicType.String()).toBe('func(...string) int')
215
+ expect(variadicType.NumIn()).toBe(1)
216
+ expect(variadicType.In(0).String()).toBe('[]string')
217
+ expect(variadicType.NumOut()).toBe(1)
218
+ expect(variadicType.Out(0)).toBe(intType)
219
+ expect(variadicType.IsVariadic()).toBe(true)
220
+
221
+ expect(() => FuncOf([stringType], [], true)).toThrow(
222
+ /reflect.FuncOf: last arg of variadic func must be slice/,
223
+ )
224
+ expect(() => FuncOf([], [], true)).toThrow(
225
+ /reflect.FuncOf: last arg of variadic func must be slice/,
226
+ )
227
+ expect(() =>
228
+ FuncOf(globalThis.Array(129).fill(intType), [], false),
229
+ ).toThrow(/reflect.FuncOf: too many arguments/)
230
+ })
231
+
232
+ it('assigns unnamed function types to named function types with matching underlying signatures', async () => {
233
+ const intType = TypeOf(0)
234
+ const unnamedFnType = FuncOf(
235
+ arrayToSlice([intType]),
236
+ arrayToSlice([]),
237
+ false,
238
+ )
239
+ const namedFnType = TypeFor({
240
+ T: {
241
+ type: {
242
+ kind: TypeKind.Function,
243
+ name: 'main.IntSink',
244
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
245
+ results: [],
246
+ },
247
+ zero: () => null,
248
+ },
249
+ })
250
+
251
+ expect(unnamedFnType.AssignableTo(namedFnType)).toBe(true)
252
+ expect(namedFnType.AssignableTo(unnamedFnType)).toBe(true)
253
+
254
+ let seen = 0
255
+ const acceptsNamed = functionValue(
256
+ (fn: (value: number) => void) => {
257
+ fn(12)
258
+ },
259
+ {
260
+ kind: TypeKind.Function,
261
+ params: [
262
+ {
263
+ kind: TypeKind.Function,
264
+ name: 'main.IntSink',
265
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
266
+ results: [],
267
+ },
268
+ ],
269
+ results: [],
270
+ },
271
+ )
272
+ const unnamedArg = functionValue(
273
+ (value: number) => {
274
+ seen = value
275
+ },
276
+ {
277
+ kind: TypeKind.Function,
278
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
279
+ results: [],
280
+ },
281
+ )
282
+
283
+ await ValueOf(acceptsNamed).Call(arrayToSlice([ValueOf(unnamedArg)]))
284
+ expect(seen).toBe(12)
285
+ })
286
+
287
+ it('merges named function signature metadata into canonical type identity', () => {
288
+ const intType = TypeOf(0)
289
+ const unnamedFnType = FuncOf(
290
+ arrayToSlice([intType]),
291
+ arrayToSlice([]),
292
+ false,
293
+ )
294
+ const nameOnlyFirst = TypeOf(
295
+ namedFunction((value: number) => String(value), 'main.NameOnlyFirst'),
296
+ )
297
+ const fullFirst = TypeFor({
298
+ T: {
299
+ type: {
300
+ kind: TypeKind.Function,
301
+ name: 'main.FullFirst',
302
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
303
+ results: [],
304
+ },
305
+ zero: () => null,
306
+ },
307
+ })
308
+
309
+ const nameOnlyFirstFull = TypeFor({
310
+ T: {
311
+ type: {
312
+ kind: TypeKind.Function,
313
+ name: 'main.NameOnlyFirst',
314
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
315
+ results: [],
316
+ },
317
+ zero: () => null,
318
+ },
319
+ })
320
+ const fullFirstNameOnly = TypeOf(
321
+ namedFunction((value: number) => String(value), 'main.FullFirst'),
322
+ )
323
+
324
+ expect(nameOnlyFirstFull).toBe(nameOnlyFirst)
325
+ expect(nameOnlyFirst.NumIn()).toBe(1)
326
+ expect(nameOnlyFirst.In(0).String()).toBe('int')
327
+ expect(nameOnlyFirst.AssignableTo(unnamedFnType)).toBe(true)
328
+ expect(unnamedFnType.AssignableTo(nameOnlyFirst)).toBe(true)
329
+
330
+ expect(fullFirstNameOnly).toBe(fullFirst)
331
+ expect(fullFirst.NumIn()).toBe(1)
332
+ expect(fullFirst.AssignableTo(unnamedFnType)).toBe(true)
333
+ expect(unnamedFnType.AssignableTo(fullFirst)).toBe(true)
334
+ })
335
+
336
+ it('should validate Value.Call counts and normalize results by descriptor', async () => {
337
+ const scalarFunc = functionValue((value: number) => String(value), {
338
+ kind: TypeKind.Function,
339
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
340
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
341
+ })
342
+ const scalarResult = asArray(
343
+ await ValueOf(scalarFunc).Call(arrayToSlice([ValueOf(7)])),
344
+ )
345
+ expect(scalarResult).toHaveLength(1)
346
+ expect(scalarResult[0].String()).toBe('7')
347
+ await expect(ValueOf(scalarFunc).Call(arrayToSlice([]))).rejects.toThrow(
348
+ /reflect: Call with 0 input arguments for function with 1 inputs/,
349
+ )
350
+
351
+ const tupleFunc = functionValue(() => [1, 'ok'], {
352
+ kind: TypeKind.Function,
353
+ params: [],
354
+ results: [
355
+ { kind: TypeKind.Basic, name: 'int' },
356
+ { kind: TypeKind.Basic, name: 'string' },
357
+ ],
358
+ })
359
+ const tupleResult = asArray(await ValueOf(tupleFunc).Call(arrayToSlice([])))
360
+ expect(tupleResult).toHaveLength(2)
361
+ expect(tupleResult[0].Int()).toBe(1)
362
+ expect(tupleResult[1].String()).toBe('ok')
363
+
364
+ const sliceFunc = functionValue(() => [1, 2], {
365
+ kind: TypeKind.Function,
366
+ params: [],
367
+ results: [
368
+ {
369
+ kind: TypeKind.Slice,
370
+ elemType: { kind: TypeKind.Basic, name: 'int' },
371
+ },
372
+ ],
373
+ })
374
+ const sliceResult = asArray(await ValueOf(sliceFunc).Call(arrayToSlice([])))
375
+ expect(sliceResult).toHaveLength(1)
376
+ expect(sliceResult[0].Len()).toBe(2)
377
+
378
+ const namedResultFunc = functionValue(() => 7, {
379
+ kind: TypeKind.Function,
380
+ params: [],
381
+ results: [{ kind: TypeKind.Basic, name: 'int', typeName: 'main.MyInt' }],
382
+ })
383
+ const namedResult = asArray(
384
+ await ValueOf(namedResultFunc).Call(arrayToSlice([])),
385
+ )
386
+ expect(namedResult[0].Type().String()).toBe('main.MyInt')
387
+ expect(namedResult[0].Int()).toBe(7)
388
+
389
+ const badTupleFunc = functionValue(() => [1], {
390
+ kind: TypeKind.Function,
391
+ params: [],
392
+ results: [
393
+ { kind: TypeKind.Basic, name: 'int' },
394
+ { kind: TypeKind.Basic, name: 'string' },
395
+ ],
396
+ })
397
+ await expect(ValueOf(badTupleFunc).Call(arrayToSlice([]))).rejects.toThrow(
398
+ /reflect: Call returned 1 results for function with 2 outputs/,
399
+ )
400
+ })
401
+
402
+ it('should construct typed functions with MakeFunc', async () => {
403
+ const intType = TypeOf(0)
404
+ const stringType = TypeOf('')
405
+ const boolType = TypeOf(false)
406
+ const unaryType = FuncOf(
407
+ arrayToSlice([intType]),
408
+ arrayToSlice([stringType]),
409
+ false,
410
+ )
411
+ const unaryValue = MakeFunc(unaryType, (args) =>
412
+ arrayToSlice([ValueOf(String(asArray(args)[0].Int()))]),
413
+ )
414
+ const [unary, ok] = typeAssertTuple<
415
+ ((value: number) => string | Promise<string>) | null
416
+ >(unaryValue.Interface(), {
417
+ kind: TypeKind.Function,
418
+ params: [{ kind: TypeKind.Basic, name: 'int' }],
419
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
420
+ })
421
+ expect(ok).toBe(true)
422
+ expect(await unary!(7)).toBe('7')
423
+ const reflectedUnary = asArray(
424
+ await unaryValue.Call(arrayToSlice([ValueOf(8)])),
425
+ )
426
+ expect(reflectedUnary).toHaveLength(1)
427
+ expect(reflectedUnary[0].String()).toBe('8')
428
+
429
+ const asyncValue = MakeFunc(unaryType, async (args) =>
430
+ arrayToSlice([ValueOf(`async-${asArray(args)[0].Int()}`)]),
431
+ )
432
+ expect(
433
+ await (asyncValue.Interface() as (value: number) => Promise<string>)(9),
434
+ ).toBe('async-9')
435
+ const reflectedAsync = asArray(
436
+ await asyncValue.Call(arrayToSlice([ValueOf(10)])),
437
+ )
438
+ expect(reflectedAsync[0].String()).toBe('async-10')
439
+
440
+ const [, wrongOk] = typeAssertTuple<
441
+ ((value: string) => string | Promise<string>) | null
442
+ >(unaryValue.Interface(), {
443
+ kind: TypeKind.Function,
444
+ params: [{ kind: TypeKind.Basic, name: 'string' }],
445
+ results: [{ kind: TypeKind.Basic, name: 'string' }],
446
+ })
447
+ expect(wrongOk).toBe(false)
448
+
449
+ const tupleType = FuncOf(
450
+ arrayToSlice([]),
451
+ arrayToSlice([intType, boolType]),
452
+ false,
453
+ )
454
+ const tupleValue = MakeFunc(tupleType, () =>
455
+ arrayToSlice([ValueOf(3), ValueOf(true)]),
456
+ )
457
+ const tuple = await (
458
+ tupleValue.Interface() as () => Promise<[number, boolean]>
459
+ )()
460
+ expect(tuple).toEqual([3, true])
461
+ const reflectedTuple = asArray(await tupleValue.Call(arrayToSlice([])))
462
+ expect(reflectedTuple[0].Int()).toBe(3)
463
+ expect(reflectedTuple[1].Bool()).toBe(true)
464
+
465
+ const zeroType = FuncOf(arrayToSlice([]), arrayToSlice([]), false)
466
+ let called = false
467
+ const zeroValue = MakeFunc(zeroType, () => {
468
+ called = true
469
+ return arrayToSlice([])
470
+ })
471
+ expect(
472
+ await (zeroValue.Interface() as () => Promise<void>)(),
473
+ ).toBeUndefined()
474
+ expect(called).toBe(true)
475
+
476
+ const variadicType = FuncOf(
477
+ arrayToSlice([intType, SliceOf(stringType)]),
478
+ arrayToSlice([intType]),
479
+ true,
480
+ )
481
+ const variadicValue = MakeFunc(variadicType, (args) => {
482
+ const values = asArray(args)
483
+ expect(values).toHaveLength(2)
484
+ return arrayToSlice([ValueOf(values[0].Int() + values[1].Len())])
485
+ })
486
+ const variadic = variadicValue.Interface() as (
487
+ prefix: number,
488
+ values: unknown,
489
+ ) => Promise<number>
490
+ expect(await variadic(1, arrayToSlice(['a', 'b']))).toBe(3)
491
+ const reflectedVariadic = asArray(
492
+ await variadicValue.Call(
493
+ arrayToSlice([ValueOf(10), ValueOf('a'), ValueOf('b')]),
494
+ ),
495
+ )
496
+ expect(reflectedVariadic[0].Int()).toBe(12)
497
+ const reflectedSliceCall = asArray(
498
+ await variadicValue.CallSlice(
499
+ arrayToSlice([ValueOf(10), ValueOf(arrayToSlice(['a', 'b', 'c']))]),
500
+ ),
501
+ )
502
+ expect(reflectedSliceCall[0].Int()).toBe(13)
503
+
504
+ const badResult = MakeFunc(unaryType, () => arrayToSlice([]))
505
+ await expect(
506
+ (badResult.Interface() as (value: number) => Promise<string>)(1),
507
+ ).rejects.toThrow(
508
+ /reflect.MakeFunc: returned 0 results for function with 1 outputs/,
509
+ )
510
+ await expect(
511
+ variadicValue.CallSlice(arrayToSlice([ValueOf(1), ValueOf('bad')])),
512
+ ).rejects.toThrow(/reflect: CallSlice using string as type \[\]string/)
513
+ })
514
+
515
+ it('should assign concrete values to interface parameters', async () => {
516
+ class CallableStringer {
517
+ public label = 'callable'
518
+
519
+ public String(): string {
520
+ return this.label
521
+ }
522
+ }
523
+
524
+ const stringResult = { kind: TypeKind.Basic, name: 'string' } as const
525
+ const stringerMethod = {
526
+ name: 'String',
527
+ args: [],
528
+ returns: [{ type: stringResult }],
529
+ }
530
+ const stringerInfo = registerStructType(
531
+ 'main.CallableStringer',
532
+ new CallableStringer(),
533
+ [stringerMethod],
534
+ CallableStringer,
535
+ [],
536
+ )
537
+ ;(CallableStringer as any).__typeInfo = stringerInfo
538
+
539
+ const anyType = TypeFor({
540
+ T: {
541
+ type: { kind: TypeKind.Interface, methods: [] },
542
+ zero: () => null,
543
+ },
544
+ })
545
+ const stringerType = TypeFor({
546
+ T: {
547
+ type: {
548
+ kind: TypeKind.Interface,
549
+ methods: [stringerMethod],
550
+ },
551
+ zero: () => null,
552
+ },
553
+ })
554
+ const stringType = TypeOf('')
555
+
556
+ const acceptsAny = functionValue((value: unknown) => String(value), {
557
+ kind: TypeKind.Function,
558
+ params: [{ kind: TypeKind.Interface, methods: [] }],
559
+ results: [stringResult],
560
+ })
561
+ const anyCallResult = asArray(
562
+ await ValueOf(acceptsAny).Call(arrayToSlice([ValueOf(7)])),
563
+ )
564
+ expect(anyCallResult[0].String()).toBe('7')
565
+
566
+ const anyMakeValue = MakeFunc(
567
+ FuncOf(arrayToSlice([anyType]), arrayToSlice([stringType]), false),
568
+ (args) => arrayToSlice([ValueOf(String(asArray(args)[0].Interface()))]),
569
+ )
570
+ expect(
571
+ await (anyMakeValue.Interface() as (value: unknown) => Promise<string>)(
572
+ 8,
573
+ ),
574
+ ).toBe('8')
575
+ const reflectedAnyMake = asArray(
576
+ await anyMakeValue.Call(arrayToSlice([ValueOf('ok')])),
577
+ )
578
+ expect(reflectedAnyMake[0].String()).toBe('ok')
579
+
580
+ const acceptsStringer = functionValue(
581
+ (value: CallableStringer) => value.String(),
582
+ {
583
+ kind: TypeKind.Function,
584
+ params: [{ kind: TypeKind.Interface, methods: [stringerMethod] }],
585
+ results: [stringResult],
586
+ },
587
+ )
588
+ const stringerCallResult = asArray(
589
+ await ValueOf(acceptsStringer).Call(
590
+ arrayToSlice([ValueOf(new CallableStringer())]),
591
+ ),
592
+ )
593
+ expect(stringerCallResult[0].String()).toBe('callable')
594
+ await expect(
595
+ ValueOf(acceptsStringer).Call(arrayToSlice([ValueOf(7)])),
596
+ ).rejects.toThrow(/reflect: Call using int as type interface/)
597
+
598
+ const stringerMakeValue = MakeFunc(
599
+ FuncOf(arrayToSlice([stringerType]), arrayToSlice([stringType]), false),
600
+ (args) =>
601
+ arrayToSlice([
602
+ ValueOf((asArray(args)[0].Interface() as CallableStringer).String()),
603
+ ]),
604
+ )
605
+ expect(
606
+ await (
607
+ stringerMakeValue.Interface() as (
608
+ value: CallableStringer,
609
+ ) => Promise<string>
610
+ )(new CallableStringer()),
611
+ ).toBe('callable')
612
+ await expect(
613
+ (stringerMakeValue.Interface() as (value: unknown) => Promise<string>)(7),
614
+ ).rejects.toThrow(
615
+ /reflect.MakeFunc: cannot use int as type interface .* in argument 0/,
616
+ )
617
+ })
618
+
123
619
  it('should handle arrow functions', () => {
124
620
  const arrowFunc = (x: number) => x * 2
125
621
  const type = TypeOf(arrowFunc)
@@ -12,6 +12,9 @@ export {
12
12
  PtrTo,
13
13
  MapOf,
14
14
  ChanOf,
15
+ FuncOf,
16
+ MakeFunc,
17
+ StructOf,
15
18
  ChanDir_String,
16
19
  RecvDir,
17
20
  SendDir,
@@ -27,6 +30,7 @@ export {
27
30
  Indirect,
28
31
  New,
29
32
  NewAt,
33
+ SliceAt,
30
34
  MakeSlice,
31
35
  MakeMap,
32
36
  MakeMapWithSize,
@@ -37,6 +41,7 @@ export {
37
41
  } from './value.js'
38
42
  export { Swapper } from './swapper.js'
39
43
  export { MapIter } from './map.js'
44
+ export { VisibleFields } from './visiblefields.js'
40
45
 
41
46
  // Export new types and constants
42
47
  export {
@@ -44,19 +49,16 @@ export {
44
49
  StructTag_Get,
45
50
  StructField,
46
51
  ValueError,
52
+ Method,
47
53
  SelectSend,
48
54
  SelectRecv,
49
55
  SelectDefault,
50
56
  SelectCase,
51
- bitVector,
52
- } from './types.js'
53
- export type {
54
- uintptr,
55
- Method,
56
- SelectDir,
57
57
  SliceHeader,
58
58
  StringHeader,
59
+ bitVector,
59
60
  } from './types.js'
61
+ export type { uintptr, SelectDir } from './types.js'
60
62
 
61
63
  // Export kind constants
62
64
  export {
package/gs/reflect/map.ts CHANGED
@@ -56,6 +56,26 @@ class MapType implements Type {
56
56
  return 0
57
57
  }
58
58
 
59
+ public NumIn(): number {
60
+ throw new Error(`reflect: NumIn of non-func type ${this.String()}`)
61
+ }
62
+
63
+ public In(_i: number): Type {
64
+ throw new Error(`reflect: In of non-func type ${this.String()}`)
65
+ }
66
+
67
+ public NumOut(): number {
68
+ throw new Error(`reflect: NumOut of non-func type ${this.String()}`)
69
+ }
70
+
71
+ public Out(_i: number): Type {
72
+ throw new Error(`reflect: Out of non-func type ${this.String()}`)
73
+ }
74
+
75
+ public IsVariadic(): boolean {
76
+ throw new Error(`reflect: IsVariadic of non-func type ${this.String()}`)
77
+ }
78
+
59
79
  public Field(_i: number): StructField {
60
80
  throw new Error('reflect: Field of non-struct type map')
61
81
  }
@@ -1,5 +1,7 @@
1
1
  {
2
- "dependencies": [
3
- "iter"
4
- ]
5
- }
2
+ "dependencies": ["iter"],
3
+ "asyncMethods": {
4
+ "Value.Call": true,
5
+ "Value.CallSlice": true
6
+ }
7
+ }