goscript 0.0.84 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/README.md +267 -243
  2. package/cmd/goscript/cmd-test.go +193 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/cmd_compile.go +70 -69
  5. package/cmd/goscript/cmd_compile_test.go +79 -0
  6. package/cmd/goscript/main.go +11 -5
  7. package/compiler/build-flags.go +38 -0
  8. package/compiler/compile-request.go +220 -0
  9. package/compiler/compiler.go +16 -1336
  10. package/compiler/compliance_test.go +188 -0
  11. package/compiler/config.go +6 -13
  12. package/compiler/diagnostic.go +70 -0
  13. package/compiler/gotest/owner.go +24 -0
  14. package/compiler/gotest/package-result.go +67 -0
  15. package/compiler/gotest/request.go +145 -0
  16. package/compiler/gotest/result.go +28 -0
  17. package/compiler/gotest/runner.go +588 -0
  18. package/compiler/gotest/runner_test.go +627 -0
  19. package/compiler/gotest/test.go +9 -0
  20. package/compiler/index.test.ts +28 -28
  21. package/compiler/index.ts +40 -72
  22. package/compiler/lowered-program.go +184 -0
  23. package/compiler/lowering.go +8072 -0
  24. package/compiler/override-facts.go +307 -0
  25. package/compiler/override-registry.go +283 -0
  26. package/compiler/override-registry_test.go +254 -0
  27. package/compiler/package-graph.go +254 -0
  28. package/compiler/package-graph_test.go +316 -0
  29. package/compiler/package-test-function.go +9 -0
  30. package/compiler/package-test-graph-package.go +40 -0
  31. package/compiler/package-test-graph-variant.go +105 -0
  32. package/compiler/package-test-graph.go +117 -0
  33. package/compiler/package-test-graph_test.go +144 -0
  34. package/compiler/result.go +13 -0
  35. package/compiler/runtime-contract.go +439 -0
  36. package/compiler/runtime-contract_test.go +104 -0
  37. package/compiler/semantic-model-types.go +113 -0
  38. package/compiler/semantic-model.go +1422 -0
  39. package/compiler/semantic-model_test.go +471 -0
  40. package/compiler/service.go +133 -0
  41. package/compiler/skeleton_test.go +1775 -0
  42. package/compiler/tsworkspace/owner.go +334 -0
  43. package/compiler/tsworkspace/owner_test.go +93 -0
  44. package/compiler/tsworkspace/result.go +17 -0
  45. package/compiler/typescript-emitter.go +1040 -0
  46. package/compiler/wasm/compile.go +2 -3
  47. package/compiler/wasm/compile_test.go +79 -0
  48. package/compiler/wasm_api.go +140 -124
  49. package/dist/compiler/index.d.ts +1 -3
  50. package/dist/compiler/index.js +31 -55
  51. package/dist/compiler/index.js.map +1 -1
  52. package/dist/gs/builtin/builtin.d.ts +33 -2
  53. package/dist/gs/builtin/builtin.js +217 -6
  54. package/dist/gs/builtin/builtin.js.map +1 -1
  55. package/dist/gs/builtin/channel.d.ts +11 -3
  56. package/dist/gs/builtin/channel.js +12 -0
  57. package/dist/gs/builtin/channel.js.map +1 -1
  58. package/dist/gs/builtin/hostio.d.ts +15 -1
  59. package/dist/gs/builtin/hostio.js +134 -49
  60. package/dist/gs/builtin/hostio.js.map +1 -1
  61. package/dist/gs/builtin/index.d.ts +1 -0
  62. package/dist/gs/builtin/index.js +1 -0
  63. package/dist/gs/builtin/index.js.map +1 -1
  64. package/dist/gs/builtin/slice.d.ts +23 -3
  65. package/dist/gs/builtin/slice.js +216 -44
  66. package/dist/gs/builtin/slice.js.map +1 -1
  67. package/dist/gs/builtin/type.d.ts +16 -2
  68. package/dist/gs/builtin/type.js +134 -21
  69. package/dist/gs/builtin/type.js.map +1 -1
  70. package/dist/gs/builtin/varRef.d.ts +5 -0
  71. package/dist/gs/builtin/varRef.js +23 -0
  72. package/dist/gs/builtin/varRef.js.map +1 -1
  73. package/dist/gs/bytes/buffer.gs.js +48 -44
  74. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  75. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  76. package/dist/gs/bytes/reader.gs.js +20 -18
  77. package/dist/gs/bytes/reader.gs.js.map +1 -1
  78. package/dist/gs/context/context.d.ts +5 -4
  79. package/dist/gs/context/context.js +10 -10
  80. package/dist/gs/context/context.js.map +1 -1
  81. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  82. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  83. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  84. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  85. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  86. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  87. package/dist/gs/crypto/rand/index.d.ts +5 -0
  88. package/dist/gs/crypto/rand/index.js +77 -0
  89. package/dist/gs/crypto/rand/index.js.map +1 -0
  90. package/dist/gs/embed/index.d.ts +7 -0
  91. package/dist/gs/embed/index.js +16 -0
  92. package/dist/gs/embed/index.js.map +1 -0
  93. package/dist/gs/encoding/json/index.d.ts +4 -0
  94. package/dist/gs/encoding/json/index.js +178 -0
  95. package/dist/gs/encoding/json/index.js.map +1 -0
  96. package/dist/gs/errors/errors.d.ts +4 -0
  97. package/dist/gs/errors/errors.js +81 -0
  98. package/dist/gs/errors/errors.js.map +1 -1
  99. package/dist/gs/fmt/fmt.d.ts +4 -4
  100. package/dist/gs/fmt/fmt.js +42 -11
  101. package/dist/gs/fmt/fmt.js.map +1 -1
  102. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +36 -1
  103. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +212 -2
  104. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  105. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  106. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
  107. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  108. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
  109. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
  110. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  111. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  112. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  113. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
  114. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  115. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  116. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  117. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  118. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  119. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  120. package/dist/gs/go/scanner/index.d.ts +42 -0
  121. package/dist/gs/go/scanner/index.js +155 -0
  122. package/dist/gs/go/scanner/index.js.map +1 -0
  123. package/dist/gs/go/token/index.d.ts +187 -0
  124. package/dist/gs/go/token/index.js +578 -0
  125. package/dist/gs/go/token/index.js.map +1 -0
  126. package/dist/gs/internal/abi/index.d.ts +4 -0
  127. package/dist/gs/internal/abi/index.js +10 -0
  128. package/dist/gs/internal/abi/index.js.map +1 -1
  129. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  130. package/dist/gs/internal/bytealg/index.js +14 -0
  131. package/dist/gs/internal/bytealg/index.js.map +1 -1
  132. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  133. package/dist/gs/internal/byteorder/index.js +56 -25
  134. package/dist/gs/internal/byteorder/index.js.map +1 -1
  135. package/dist/gs/internal/godebug/index.d.ts +12 -0
  136. package/dist/gs/internal/godebug/index.js +30 -0
  137. package/dist/gs/internal/godebug/index.js.map +1 -0
  138. package/dist/gs/io/fs/fs.js.map +1 -1
  139. package/dist/gs/io/fs/index.d.ts +1 -0
  140. package/dist/gs/io/fs/index.js +1 -0
  141. package/dist/gs/io/fs/index.js.map +1 -1
  142. package/dist/gs/io/fs/readdir.js.map +1 -1
  143. package/dist/gs/io/fs/readfile.js.map +1 -1
  144. package/dist/gs/io/fs/readlink.d.ts +8 -0
  145. package/dist/gs/io/fs/readlink.js +64 -0
  146. package/dist/gs/io/fs/readlink.js.map +1 -0
  147. package/dist/gs/io/fs/stat.js.map +1 -1
  148. package/dist/gs/io/fs/sub.js.map +1 -1
  149. package/dist/gs/io/fs/walk.d.ts +3 -3
  150. package/dist/gs/io/fs/walk.js +7 -7
  151. package/dist/gs/io/fs/walk.js.map +1 -1
  152. package/dist/gs/io/io.d.ts +40 -6
  153. package/dist/gs/io/io.js +151 -26
  154. package/dist/gs/io/io.js.map +1 -1
  155. package/dist/gs/maps/iter.d.ts +3 -3
  156. package/dist/gs/maps/iter.js +3 -3
  157. package/dist/gs/maps/iter.js.map +1 -1
  158. package/dist/gs/maps/maps.d.ts +2 -2
  159. package/dist/gs/maps/maps.js +1 -1
  160. package/dist/gs/maps/maps.js.map +1 -1
  161. package/dist/gs/math/bits/index.d.ts +13 -4
  162. package/dist/gs/math/bits/index.js +66 -34
  163. package/dist/gs/math/bits/index.js.map +1 -1
  164. package/dist/gs/math/const.gs.d.ts +5 -5
  165. package/dist/gs/math/const.gs.js +4 -4
  166. package/dist/gs/math/const.gs.js.map +1 -1
  167. package/dist/gs/mime/index.d.ts +1 -0
  168. package/dist/gs/mime/index.js +50 -0
  169. package/dist/gs/mime/index.js.map +1 -0
  170. package/dist/gs/net/http/httptest/index.d.ts +11 -0
  171. package/dist/gs/net/http/httptest/index.js +21 -0
  172. package/dist/gs/net/http/httptest/index.js.map +1 -0
  173. package/dist/gs/net/http/index.d.ts +27 -0
  174. package/dist/gs/net/http/index.js +61 -0
  175. package/dist/gs/net/http/index.js.map +1 -0
  176. package/dist/gs/os/dir_unix.gs.js +2 -2
  177. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  178. package/dist/gs/os/error.gs.js +2 -4
  179. package/dist/gs/os/error.gs.js.map +1 -1
  180. package/dist/gs/os/exec.gs.js.map +1 -1
  181. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  182. package/dist/gs/os/rawconn_js.gs.js.map +1 -1
  183. package/dist/gs/os/root_js.gs.js.map +1 -1
  184. package/dist/gs/os/tempfile.gs.js +66 -9
  185. package/dist/gs/os/tempfile.gs.js.map +1 -1
  186. package/dist/gs/os/types.gs.js.map +1 -1
  187. package/dist/gs/os/types_js.gs.js +9 -9
  188. package/dist/gs/os/types_js.gs.js.map +1 -1
  189. package/dist/gs/os/types_unix.gs.js.map +1 -1
  190. package/dist/gs/path/filepath/match.js +165 -3
  191. package/dist/gs/path/filepath/match.js.map +1 -1
  192. package/dist/gs/path/filepath/path.d.ts +3 -1
  193. package/dist/gs/path/filepath/path.js +133 -4
  194. package/dist/gs/path/filepath/path.js.map +1 -1
  195. package/dist/gs/path/match.js.map +1 -1
  196. package/dist/gs/path/path.d.ts +4 -1
  197. package/dist/gs/path/path.js +16 -4
  198. package/dist/gs/path/path.js.map +1 -1
  199. package/dist/gs/reflect/index.d.ts +3 -3
  200. package/dist/gs/reflect/index.js +2 -2
  201. package/dist/gs/reflect/index.js.map +1 -1
  202. package/dist/gs/reflect/map.js +3 -0
  203. package/dist/gs/reflect/map.js.map +1 -1
  204. package/dist/gs/reflect/type.d.ts +9 -5
  205. package/dist/gs/reflect/type.js +233 -21
  206. package/dist/gs/reflect/type.js.map +1 -1
  207. package/dist/gs/reflect/types.js.map +1 -1
  208. package/dist/gs/reflect/visiblefields.js.map +1 -1
  209. package/dist/gs/runtime/debug/index.d.ts +2 -0
  210. package/dist/gs/runtime/debug/index.js +8 -0
  211. package/dist/gs/runtime/debug/index.js.map +1 -0
  212. package/dist/gs/runtime/runtime.d.ts +35 -3
  213. package/dist/gs/runtime/runtime.js +72 -0
  214. package/dist/gs/runtime/runtime.js.map +1 -1
  215. package/dist/gs/slices/slices.d.ts +24 -5
  216. package/dist/gs/slices/slices.js +214 -5
  217. package/dist/gs/slices/slices.js.map +1 -1
  218. package/dist/gs/sort/slice.gs.d.ts +3 -3
  219. package/dist/gs/sort/slice.gs.js +6 -6
  220. package/dist/gs/sort/slice.gs.js.map +1 -1
  221. package/dist/gs/sort/sort.gs.d.ts +4 -4
  222. package/dist/gs/sort/sort.gs.js +11 -8
  223. package/dist/gs/sort/sort.gs.js.map +1 -1
  224. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  225. package/dist/gs/strconv/quote.gs.js.map +1 -1
  226. package/dist/gs/strings/builder.d.ts +1 -1
  227. package/dist/gs/strings/builder.js +3 -2
  228. package/dist/gs/strings/builder.js.map +1 -1
  229. package/dist/gs/strings/reader.js.map +1 -1
  230. package/dist/gs/strings/replace.js.map +1 -1
  231. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  232. package/dist/gs/sync/atomic/type.gs.js +0 -2
  233. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  234. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  235. package/dist/gs/sync/sync.d.ts +3 -0
  236. package/dist/gs/sync/sync.js +39 -0
  237. package/dist/gs/sync/sync.js.map +1 -1
  238. package/dist/gs/syscall/constants.d.ts +36 -24
  239. package/dist/gs/syscall/constants.js +12 -0
  240. package/dist/gs/syscall/constants.js.map +1 -1
  241. package/dist/gs/syscall/errors.d.ts +2 -0
  242. package/dist/gs/syscall/errors.js +8 -0
  243. package/dist/gs/syscall/errors.js.map +1 -1
  244. package/dist/gs/syscall/fs.d.ts +43 -0
  245. package/dist/gs/syscall/fs.js +102 -0
  246. package/dist/gs/syscall/fs.js.map +1 -1
  247. package/dist/gs/syscall/js/index.d.ts +90 -0
  248. package/dist/gs/syscall/js/index.js +375 -0
  249. package/dist/gs/syscall/js/index.js.map +1 -0
  250. package/dist/gs/syscall/types.d.ts +22 -0
  251. package/dist/gs/syscall/types.js +45 -1
  252. package/dist/gs/syscall/types.js.map +1 -1
  253. package/dist/gs/testing/index.d.ts +1 -0
  254. package/dist/gs/testing/index.js +2 -0
  255. package/dist/gs/testing/index.js.map +1 -0
  256. package/dist/gs/testing/testing.d.ts +77 -0
  257. package/dist/gs/testing/testing.js +301 -0
  258. package/dist/gs/testing/testing.js.map +1 -0
  259. package/dist/gs/time/time.d.ts +41 -4
  260. package/dist/gs/time/time.js +205 -36
  261. package/dist/gs/time/time.js.map +1 -1
  262. package/dist/gs/unicode/unicode.d.ts +23 -1
  263. package/dist/gs/unicode/unicode.js +79 -10
  264. package/dist/gs/unicode/unicode.js.map +1 -1
  265. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  266. package/dist/gs/unicode/utf8/utf8.js +24 -11
  267. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  268. package/dist/gs/unique/index.d.ts +11 -0
  269. package/dist/gs/unique/index.js +71 -0
  270. package/dist/gs/unique/index.js.map +1 -0
  271. package/go.mod +2 -2
  272. package/go.sum +9 -0
  273. package/gs/builtin/builtin.ts +266 -8
  274. package/gs/builtin/channel.ts +22 -0
  275. package/gs/builtin/hostio.test.ts +177 -0
  276. package/gs/builtin/hostio.ts +171 -56
  277. package/gs/builtin/index.ts +1 -0
  278. package/gs/builtin/runtime-contract.test.ts +356 -0
  279. package/gs/builtin/slice.ts +259 -50
  280. package/gs/builtin/type.ts +188 -30
  281. package/gs/builtin/varRef.ts +38 -1
  282. package/gs/bytes/buffer.gs.ts +48 -44
  283. package/gs/bytes/meta.json +8 -3
  284. package/gs/bytes/reader.gs.ts +20 -19
  285. package/gs/context/context.test.ts +41 -0
  286. package/gs/context/context.ts +22 -26
  287. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  288. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  289. package/gs/crypto/rand/index.test.ts +32 -0
  290. package/gs/crypto/rand/index.ts +90 -0
  291. package/gs/crypto/rand/meta.json +5 -0
  292. package/gs/embed/index.ts +20 -0
  293. package/gs/embed/meta.json +5 -0
  294. package/gs/encoding/json/index.test.ts +79 -0
  295. package/gs/encoding/json/index.ts +210 -0
  296. package/gs/errors/errors.test.ts +82 -0
  297. package/gs/errors/errors.ts +104 -0
  298. package/gs/fmt/fmt.ts +56 -16
  299. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +95 -0
  300. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +300 -2
  301. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
  302. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
  303. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
  304. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
  305. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/meta.json +3 -1
  306. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
  307. package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
  308. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  309. package/gs/go/internal/scannerhooks/index.ts +9 -0
  310. package/gs/go/scanner/index.test.ts +72 -0
  311. package/gs/go/scanner/index.ts +204 -0
  312. package/gs/go/token/index.test.ts +67 -0
  313. package/gs/go/token/index.ts +686 -0
  314. package/gs/internal/abi/index.test.ts +18 -0
  315. package/gs/internal/abi/index.ts +14 -0
  316. package/gs/internal/bytealg/index.test.ts +18 -0
  317. package/gs/internal/bytealg/index.ts +16 -0
  318. package/gs/internal/byteorder/index.test.ts +39 -0
  319. package/gs/internal/byteorder/index.ts +100 -27
  320. package/gs/internal/godebug/index.test.ts +16 -0
  321. package/gs/internal/godebug/index.ts +35 -0
  322. package/gs/io/fs/index.ts +1 -0
  323. package/gs/io/fs/meta.json +5 -0
  324. package/gs/io/fs/readlink.test.ts +43 -0
  325. package/gs/io/fs/readlink.ts +77 -0
  326. package/gs/io/fs/walk.test.ts +61 -0
  327. package/gs/io/fs/walk.ts +9 -9
  328. package/gs/io/io.ts +174 -31
  329. package/gs/io/meta.json +10 -2
  330. package/gs/maps/iter.ts +12 -6
  331. package/gs/maps/maps.ts +8 -6
  332. package/gs/math/bits/index.ts +103 -47
  333. package/gs/math/const.gs.test.ts +11 -5
  334. package/gs/math/const.gs.ts +5 -6
  335. package/gs/mime/index.ts +54 -0
  336. package/gs/net/http/httptest/index.ts +25 -0
  337. package/gs/net/http/index.test.ts +20 -0
  338. package/gs/net/http/index.ts +81 -0
  339. package/gs/os/dir_unix.gs.ts +2 -3
  340. package/gs/os/file_unix_js.test.ts +50 -0
  341. package/gs/os/meta.json +1 -2
  342. package/gs/os/tempfile.gs.test.ts +85 -0
  343. package/gs/os/tempfile.gs.ts +71 -11
  344. package/gs/os/types_js.gs.ts +11 -11
  345. package/gs/path/filepath/match.test.ts +31 -12
  346. package/gs/path/filepath/match.ts +178 -3
  347. package/gs/path/filepath/path.test.ts +25 -0
  348. package/gs/path/filepath/path.ts +159 -5
  349. package/gs/path/path.ts +20 -5
  350. package/gs/reflect/index.ts +2 -1
  351. package/gs/reflect/map.test.ts +19 -0
  352. package/gs/reflect/map.ts +4 -0
  353. package/gs/reflect/type.ts +298 -29
  354. package/gs/reflect/typefor.test.ts +75 -0
  355. package/gs/runtime/debug/index.test.ts +24 -0
  356. package/gs/runtime/debug/index.ts +8 -0
  357. package/gs/runtime/runtime.test.ts +19 -0
  358. package/gs/runtime/runtime.ts +98 -3
  359. package/gs/slices/slices.test.ts +94 -0
  360. package/gs/slices/slices.ts +245 -5
  361. package/gs/sort/meta.json +7 -0
  362. package/gs/sort/slice.gs.ts +16 -7
  363. package/gs/sort/sort.gs.ts +16 -13
  364. package/gs/strings/builder.ts +4 -3
  365. package/gs/sync/atomic/type.gs.ts +13 -14
  366. package/gs/sync/meta.json +3 -1
  367. package/gs/sync/sync.test.ts +36 -0
  368. package/gs/sync/sync.ts +39 -0
  369. package/gs/syscall/constants.ts +39 -24
  370. package/gs/syscall/errors.ts +10 -0
  371. package/gs/syscall/fs.ts +195 -0
  372. package/gs/syscall/js/index.ts +458 -0
  373. package/gs/syscall/js/meta.json +4 -0
  374. package/gs/syscall/net.test.ts +85 -0
  375. package/gs/syscall/types.ts +56 -0
  376. package/gs/testing/index.ts +1 -0
  377. package/gs/testing/meta.json +5 -0
  378. package/gs/testing/testing.test.ts +90 -0
  379. package/gs/testing/testing.ts +382 -0
  380. package/gs/time/time.test.ts +106 -0
  381. package/gs/time/time.ts +278 -57
  382. package/gs/unicode/unicode.test.ts +25 -0
  383. package/gs/unicode/unicode.ts +119 -9
  384. package/gs/unicode/utf8/utf8.test.ts +13 -0
  385. package/gs/unicode/utf8/utf8.ts +28 -16
  386. package/gs/unique/index.ts +91 -0
  387. package/package.json +14 -13
  388. package/compiler/analysis.go +0 -3475
  389. package/compiler/analysis_test.go +0 -338
  390. package/compiler/assignment.go +0 -580
  391. package/compiler/builtin_test.go +0 -92
  392. package/compiler/code-writer.go +0 -115
  393. package/compiler/compiler_test.go +0 -149
  394. package/compiler/composite-lit.go +0 -779
  395. package/compiler/config_test.go +0 -62
  396. package/compiler/constraint.go +0 -86
  397. package/compiler/decl.go +0 -801
  398. package/compiler/expr-call-async.go +0 -188
  399. package/compiler/expr-call-builtins.go +0 -208
  400. package/compiler/expr-call-helpers.go +0 -382
  401. package/compiler/expr-call-make.go +0 -318
  402. package/compiler/expr-call-type-conversion.go +0 -520
  403. package/compiler/expr-call.go +0 -413
  404. package/compiler/expr-selector.go +0 -343
  405. package/compiler/expr-star.go +0 -82
  406. package/compiler/expr-type.go +0 -442
  407. package/compiler/expr-value.go +0 -89
  408. package/compiler/expr.go +0 -773
  409. package/compiler/field.go +0 -183
  410. package/compiler/gs_dependencies_test.go +0 -298
  411. package/compiler/lit.go +0 -322
  412. package/compiler/output.go +0 -72
  413. package/compiler/primitive.go +0 -149
  414. package/compiler/protobuf.go +0 -697
  415. package/compiler/sanitize.go +0 -100
  416. package/compiler/spec-struct.go +0 -995
  417. package/compiler/spec-value.go +0 -540
  418. package/compiler/spec.go +0 -725
  419. package/compiler/stmt-assign.go +0 -664
  420. package/compiler/stmt-for.go +0 -266
  421. package/compiler/stmt-range.go +0 -475
  422. package/compiler/stmt-select.go +0 -262
  423. package/compiler/stmt-type-switch.go +0 -147
  424. package/compiler/stmt.go +0 -1308
  425. package/compiler/type-assert.go +0 -386
  426. package/compiler/type-info.go +0 -156
  427. package/compiler/type-utils.go +0 -207
  428. package/compiler/type.go +0 -892
@@ -1,995 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/types"
7
- "maps"
8
- "slices"
9
- "strings"
10
- )
11
-
12
- // WriteStructTypeSpec generates the TypeScript class definition for a Go struct type.
13
- // It handles the generation of:
14
- // - The class declaration.
15
- // - Getters and setters for all fields (both direct and embedded).
16
- // - The internal `_fields` property, which stores field values in `$.VarRef` containers
17
- // to maintain Go's value semantics.
18
- // - A constructor that initializes the `_fields` and allows partial initialization.
19
- // - A `clone` method for creating a deep copy of the struct instance.
20
- // - Methods defined directly on the struct.
21
- // - Wrapper methods for promoted fields and methods from embedded structs,
22
- // ensuring correct access and behavior.
23
- func (c *GoToTSCompiler) WriteStructTypeSpec(a *ast.TypeSpec, t *ast.StructType) error {
24
- isInsideFunction := false
25
- if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
26
- isInsideFunction = nodeInfo.IsInsideFunction
27
- }
28
- if !isInsideFunction {
29
- c.tsw.WriteLiterally("export ")
30
- }
31
- c.tsw.WriteLiterally("class ")
32
- if err := c.WriteValueExpr(a.Name); err != nil {
33
- return err
34
- }
35
-
36
- // Write type parameters if present (for generics)
37
- if a.TypeParams != nil {
38
- c.WriteTypeParameters(a.TypeParams)
39
- }
40
-
41
- c.tsw.WriteLiterally(" ")
42
- c.tsw.WriteLine("{")
43
- c.tsw.Indent(1)
44
-
45
- className := sanitizeIdentifier(a.Name.Name)
46
-
47
- goStructType, ok := c.pkg.TypesInfo.Defs[a.Name].Type().(*types.Named)
48
- if !ok {
49
- return fmt.Errorf("could not get named type for %s", a.Name.Name)
50
- }
51
- underlyingStruct, ok := goStructType.Underlying().(*types.Struct)
52
- if !ok {
53
- return fmt.Errorf("underlying type of %s is not a struct", a.Name.Name)
54
- }
55
-
56
- // Generate getters and setters for each non-embedded field first
57
- for _, field := range t.Fields.List {
58
- if len(field.Names) == 0 { // Skip anonymous/embedded fields here; they are handled below or via promotion
59
- continue
60
- }
61
- for _, name := range field.Names {
62
- fieldName := name.Name
63
- // Skip underscore fields
64
- if fieldName == "_" {
65
- continue
66
- }
67
- fieldType := c.pkg.TypesInfo.TypeOf(field.Type)
68
- if fieldType == nil {
69
- fieldType = types.Typ[types.Invalid]
70
- }
71
- c.writeGetterSetter(fieldName, fieldType, field.Doc, field.Comment, field.Type)
72
- }
73
- }
74
-
75
- // Generate getters and setters for EMBEDDED struct fields themselves
76
- for field := range underlyingStruct.Fields() {
77
- if field.Anonymous() {
78
- fieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
79
- c.writeGetterSetter(fieldKeyName, field.Type(), nil, nil, nil)
80
- }
81
- }
82
-
83
- // Create a mapping from field names to AST types for preserving qualified names
84
- fieldASTTypes := make(map[string]ast.Expr)
85
- for _, field := range t.Fields.List {
86
- if len(field.Names) > 0 {
87
- for _, name := range field.Names {
88
- fieldASTTypes[name.Name] = field.Type
89
- }
90
- }
91
- }
92
-
93
- // Define the _fields property type
94
- c.tsw.WriteLiterally("public _fields: {")
95
- c.tsw.Indent(1)
96
- c.tsw.WriteLine("")
97
-
98
- for field := range underlyingStruct.Fields() {
99
- var fieldKeyName string
100
- if field.Anonymous() {
101
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
102
- } else {
103
- fieldKeyName = field.Name()
104
- }
105
- // Skip underscore fields
106
- if fieldKeyName == "_" {
107
- continue
108
- }
109
-
110
- // Use AST-based type string when available, fall back to types-based
111
- // Note: getASTTypeString already includes "null |" for interface types
112
- astType := fieldASTTypes[fieldKeyName]
113
- fieldTsType := c.getASTTypeString(astType, field.Type())
114
-
115
- c.tsw.WriteLinef("%s: $.VarRef<%s>;", fieldKeyName, fieldTsType)
116
- }
117
- c.tsw.Indent(-1)
118
- c.tsw.WriteLine("}")
119
-
120
- // Generate the flattened type string for the constructor init parameter
121
- flattenedInitType := c.generateFlattenedInitTypeString(goStructType, fieldASTTypes)
122
-
123
- c.tsw.WriteLine("")
124
- c.tsw.WriteLinef("constructor(init?: Partial<%s>) {", flattenedInitType)
125
- c.tsw.Indent(1)
126
- c.tsw.WriteLiterally("this._fields = {")
127
-
128
- numFields := underlyingStruct.NumFields()
129
- if numFields != 0 {
130
- c.tsw.WriteLine("")
131
- c.tsw.Indent(1)
132
-
133
- firstFieldWritten := false
134
- for i := range numFields {
135
- field := underlyingStruct.Field(i)
136
- fieldType := field.Type()
137
- var fieldKeyName string
138
- if field.Anonymous() {
139
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
140
- } else {
141
- fieldKeyName = field.Name()
142
- }
143
-
144
- // Skip underscore fields
145
- if fieldKeyName == "_" {
146
- continue
147
- }
148
-
149
- if firstFieldWritten {
150
- c.tsw.WriteLine(",")
151
- }
152
-
153
- c.writeVarRefedFieldInitializer(fieldKeyName, fieldType, field.Anonymous(), fieldASTTypes[fieldKeyName])
154
- firstFieldWritten = true
155
- }
156
- if firstFieldWritten {
157
- c.tsw.WriteLine("")
158
- }
159
- c.tsw.Indent(-1)
160
- }
161
- c.tsw.WriteLine("}")
162
-
163
- c.tsw.Indent(-1)
164
- c.tsw.WriteLine("}")
165
- c.tsw.WriteLine("")
166
-
167
- // Generate the clone method
168
- var cloneReturnType strings.Builder
169
- cloneReturnType.WriteString(className)
170
- if a.TypeParams != nil && len(a.TypeParams.List) > 0 {
171
- cloneReturnType.WriteString("<")
172
- first := true
173
- for _, field := range a.TypeParams.List {
174
- for _, name := range field.Names {
175
- if !first {
176
- cloneReturnType.WriteString(", ")
177
- }
178
- first = false
179
- cloneReturnType.WriteString(name.Name)
180
- }
181
- }
182
- cloneReturnType.WriteString(">")
183
- }
184
-
185
- c.tsw.WriteLinef("public clone(): %s {", cloneReturnType.String())
186
- c.tsw.Indent(1)
187
- c.tsw.WriteLinef("const cloned = new %s()", cloneReturnType.String())
188
- c.tsw.WriteLine("cloned._fields = {")
189
- c.tsw.Indent(1)
190
-
191
- firstFieldWritten := false
192
- for i := range numFields {
193
- field := underlyingStruct.Field(i)
194
- fieldType := field.Type()
195
- var fieldKeyName string
196
- if field.Anonymous() {
197
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
198
- } else {
199
- fieldKeyName = field.Name()
200
- }
201
-
202
- // Skip underscore fields
203
- if fieldKeyName == "_" {
204
- continue
205
- }
206
-
207
- if firstFieldWritten {
208
- c.tsw.WriteLine(",")
209
- }
210
-
211
- c.writeClonedFieldInitializer(fieldKeyName, fieldType, field.Anonymous())
212
- firstFieldWritten = true
213
- }
214
- if firstFieldWritten {
215
- c.tsw.WriteLine("")
216
- }
217
-
218
- c.tsw.Indent(-1)
219
- c.tsw.WriteLine("}")
220
- c.tsw.WriteLine("return cloned")
221
- c.tsw.Indent(-1)
222
- c.tsw.WriteLine("}")
223
-
224
- // Methods for this struct (direct methods)
225
- for _, fileSyntax := range c.pkg.Syntax {
226
- for _, decl := range fileSyntax.Decls {
227
- funcDecl, isFunc := decl.(*ast.FuncDecl)
228
- if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
229
- continue
230
- }
231
- recvField := funcDecl.Recv.List[0]
232
- recvType := recvField.Type
233
- if starExpr, ok := recvType.(*ast.StarExpr); ok {
234
- recvType = starExpr.X
235
- }
236
-
237
- // Check for both simple identifiers (Pair) and generic types (Pair[T])
238
- var recvTypeName string
239
- if ident, ok := recvType.(*ast.Ident); ok {
240
- recvTypeName = sanitizeIdentifier(ident.Name)
241
- } else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
242
- if ident, ok := indexExpr.X.(*ast.Ident); ok {
243
- recvTypeName = sanitizeIdentifier(ident.Name)
244
- }
245
- }
246
-
247
- if recvTypeName == className {
248
- c.tsw.WriteLine("")
249
- if err := c.WriteFuncDeclAsMethod(funcDecl); err != nil {
250
- return err
251
- }
252
- }
253
- }
254
- }
255
-
256
- // Generate getters/setters and wrapper methods for PROMOTED fields/methods from embedded structs
257
- seenPromotedFields := make(map[string]bool)
258
- directMethods := make(map[string]bool)
259
- // Populate directMethods (methods defined directly on this struct type)
260
- for method := range goStructType.Methods() {
261
- sig := method.Type().(*types.Signature)
262
- if sig.Recv() != nil {
263
- recvType := sig.Recv().Type()
264
- if namedRecv, ok := recvType.(*types.Named); ok && namedRecv.Obj() == goStructType.Obj() {
265
- directMethods[method.Name()] = true
266
- } else if ptrRecv, ok := recvType.(*types.Pointer); ok {
267
- if namedElem, ok := ptrRecv.Elem().(*types.Named); ok && namedElem.Obj() == goStructType.Obj() {
268
- directMethods[method.Name()] = true
269
- }
270
- }
271
- }
272
- }
273
-
274
- for field := range underlyingStruct.Fields() {
275
- if !field.Anonymous() {
276
- continue
277
- }
278
-
279
- embeddedFieldType := field.Type()
280
- embeddedFieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
281
-
282
- // Skip if not a named type (required for proper embedding promotion)
283
- trueEmbeddedType := embeddedFieldType
284
- if ptr, isPtr := trueEmbeddedType.(*types.Pointer); isPtr {
285
- trueEmbeddedType = ptr.Elem()
286
- }
287
- if _, isNamed := trueEmbeddedType.(*types.Named); !isNamed {
288
- continue
289
- }
290
-
291
- // Promoted fields
292
- if namedEmbedded, ok := trueEmbeddedType.(*types.Named); ok {
293
- if underlyingEmbeddedStruct, ok := namedEmbedded.Underlying().(*types.Struct); ok {
294
- for promotedField := range underlyingEmbeddedStruct.Fields() {
295
- if !promotedField.Exported() && promotedField.Pkg() != c.pkg.Types {
296
- continue
297
- }
298
- promotedFieldName := promotedField.Name()
299
- if seenPromotedFields[promotedFieldName] {
300
- continue
301
- }
302
- // Check for conflicts with outer struct's own fields or other promoted fields
303
- conflict := false
304
- for field := range underlyingStruct.Fields() {
305
- if !field.Anonymous() && field.Name() == promotedFieldName {
306
- conflict = true
307
- break
308
- }
309
- }
310
- if conflict {
311
- continue
312
- }
313
-
314
- seenPromotedFields[promotedFieldName] = true
315
- tsPromotedFieldType := c.getTypeString(promotedField.Type())
316
- c.tsw.WriteLine("")
317
- c.tsw.WriteLinef("public get %s(): %s {", promotedFieldName, tsPromotedFieldType)
318
- c.tsw.Indent(1)
319
- // Check if the embedded type is an interface and add null assertion
320
- embeddedFieldTypeUnderlying := embeddedFieldType
321
- if ptr, isPtr := embeddedFieldTypeUnderlying.(*types.Pointer); isPtr {
322
- embeddedFieldTypeUnderlying = ptr.Elem()
323
- }
324
- if named, isNamed := embeddedFieldTypeUnderlying.(*types.Named); isNamed {
325
- embeddedFieldTypeUnderlying = named.Underlying()
326
- }
327
- if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
328
- c.tsw.WriteLinef("return this.%s!.%s", embeddedFieldKeyName, promotedFieldName)
329
- } else {
330
- c.tsw.WriteLinef("return this.%s.%s", embeddedFieldKeyName, promotedFieldName)
331
- }
332
- c.tsw.Indent(-1)
333
- c.tsw.WriteLine("}")
334
- c.tsw.WriteLinef("public set %s(value: %s) {", promotedFieldName, tsPromotedFieldType)
335
- c.tsw.Indent(1)
336
- if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
337
- c.tsw.WriteLinef("this.%s!.%s = value", embeddedFieldKeyName, promotedFieldName)
338
- } else {
339
- c.tsw.WriteLinef("this.%s.%s = value", embeddedFieldKeyName, promotedFieldName)
340
- }
341
- c.tsw.Indent(-1)
342
- c.tsw.WriteLine("}")
343
- }
344
- }
345
- }
346
-
347
- // Promoted methods
348
- // Use pointer to embedded type to get both value and pointer receiver methods
349
- // This matches Go's behavior where embedding T promotes both T and *T methods
350
- // Exception: For interfaces, use the interface directly as pointer-to-interface has no methods
351
- methodSetType := embeddedFieldType
352
- if _, isPtr := embeddedFieldType.(*types.Pointer); !isPtr {
353
- if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); !isInterface {
354
- methodSetType = types.NewPointer(embeddedFieldType)
355
- }
356
- }
357
- embeddedMethodSet := types.NewMethodSet(methodSetType)
358
- for methodSelection := range embeddedMethodSet.Methods() {
359
- method := methodSelection.Obj().(*types.Func)
360
- methodName := method.Name()
361
-
362
- // Skip if it's not a promoted method (indirect) or if it's shadowed by a direct method or an already processed promoted method
363
- if len(methodSelection.Index()) == 1 && !directMethods[methodName] && !seenPromotedFields[methodName] {
364
- // Check for conflict with outer struct's own fields
365
- conflictWithField := false
366
- for field := range underlyingStruct.Fields() {
367
- if !field.Anonymous() && field.Name() == methodName {
368
- conflictWithField = true
369
- break
370
- }
371
- }
372
- if conflictWithField {
373
- continue
374
- }
375
-
376
- seenPromotedFields[methodName] = true // Mark as handled to avoid duplicates from other embeddings
377
- sig := method.Type().(*types.Signature)
378
- c.tsw.WriteLine("")
379
- c.tsw.WriteLiterally("public ")
380
- c.tsw.WriteLiterally(methodName)
381
- c.tsw.WriteLiterally("(")
382
- params := sig.Params()
383
- paramNames := make([]string, params.Len())
384
- for j := 0; j < params.Len(); j++ {
385
- param := params.At(j)
386
- paramName := param.Name()
387
- if paramName == "" || paramName == "_" {
388
- paramName = fmt.Sprintf("_p%d", j)
389
- }
390
- paramNames[j] = paramName
391
- if j > 0 {
392
- c.tsw.WriteLiterally(", ")
393
- }
394
- c.tsw.WriteLiterally(paramName)
395
- c.tsw.WriteLiterally(": ")
396
- c.WriteGoType(param.Type(), GoTypeContextGeneral)
397
- }
398
- c.tsw.WriteLiterally(")")
399
- results := sig.Results()
400
- if results.Len() > 0 {
401
- c.tsw.WriteLiterally(": ")
402
- if results.Len() == 1 {
403
- c.WriteGoType(results.At(0).Type(), GoTypeContextFunctionReturn)
404
- } else {
405
- c.tsw.WriteLiterally("[")
406
- for j := 0; j < results.Len(); j++ {
407
- if j > 0 {
408
- c.tsw.WriteLiterally(", ")
409
- }
410
- c.WriteGoType(results.At(j).Type(), GoTypeContextFunctionReturn)
411
- }
412
- c.tsw.WriteLiterally("]")
413
- }
414
- } else {
415
- c.tsw.WriteLiterally(": void")
416
- }
417
- c.tsw.WriteLine(" {")
418
- c.tsw.Indent(1)
419
- if results.Len() > 0 {
420
- c.tsw.WriteLiterally("return ")
421
- }
422
-
423
- assertionPrefix := "this.%s"
424
- if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); isInterface {
425
- assertionPrefix = "this.%s!"
426
- }
427
- c.tsw.WriteLiterallyf(assertionPrefix+".%s(%s)", embeddedFieldKeyName, methodName, strings.Join(paramNames, ", "))
428
-
429
- c.tsw.WriteLine("")
430
- c.tsw.Indent(-1)
431
- c.tsw.WriteLine("}")
432
- }
433
- }
434
- }
435
-
436
- // Add code to register the type with the runtime type system
437
- c.tsw.WriteLine("")
438
- c.tsw.WriteLinef("// Register this type with the runtime type system")
439
-
440
- // Build full package path name for registration
441
- structName := className
442
- pkgPath := c.pkg.Types.Path()
443
- pkgName := c.pkg.Types.Name()
444
- if pkgPath != "" && pkgName != "main" {
445
- structName = pkgPath + "." + className
446
- } else if pkgName == "main" {
447
- structName = "main." + className
448
- }
449
-
450
- c.tsw.WriteLinef("static __typeInfo = $.registerStructType(")
451
- c.tsw.WriteLinef(" '%s',", structName)
452
- c.tsw.WriteLinef(" new %s(),", className)
453
- c.tsw.WriteLiterally(" [")
454
- // Collect methods for the struct type
455
- var structMethods []*types.Func
456
- for method := range goStructType.Methods() {
457
- // Ensure it's a method directly on this type (not promoted here, promotion handled separately)
458
- // Check if receiver is *T or T where T is goStructType
459
- sig := method.Type().(*types.Signature)
460
- recv := sig.Recv().Type()
461
- if ptr, ok := recv.(*types.Pointer); ok {
462
- recv = ptr.Elem()
463
- }
464
- if namedRecv, ok := recv.(*types.Named); ok && namedRecv.Obj() == goStructType.Obj() {
465
- structMethods = append(structMethods, method)
466
- }
467
- }
468
- c.writeMethodSignatures(structMethods)
469
- c.tsw.WriteLiterally("],")
470
- c.tsw.WriteLine("")
471
-
472
- c.tsw.WriteLinef(" %s,", className)
473
- // Add field type information for type assertions
474
- c.tsw.WriteLiterally(" {")
475
- firstField := true
476
- for i := 0; i < underlyingStruct.NumFields(); i++ {
477
- field := underlyingStruct.Field(i)
478
- var fieldKeyName string
479
- if field.Anonymous() {
480
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
481
- } else {
482
- fieldKeyName = field.Name()
483
- }
484
- // Skip underscore fields
485
- if fieldKeyName == "_" {
486
- continue
487
- }
488
- if !firstField {
489
- c.tsw.WriteLiterally(", ")
490
- }
491
- firstField = false
492
- c.tsw.WriteLiterallyf("%q: ", fieldKeyName)
493
-
494
- // Get the struct tag for this field
495
- tag := underlyingStruct.Tag(i)
496
- if tag != "" {
497
- // Write field info with tag as StructFieldInfo object
498
- c.tsw.WriteLiterally("{ type: ")
499
- c.writeTypeInfoObject(field.Type())
500
- c.tsw.WriteLiterallyf(", tag: %q }", tag)
501
- } else {
502
- // No tag, write type info directly for backwards compatibility
503
- c.writeTypeInfoObject(field.Type())
504
- }
505
- }
506
- c.tsw.WriteLiterally("}")
507
- c.tsw.WriteLine("")
508
- c.tsw.WriteLinef(");")
509
-
510
- c.tsw.Indent(-1)
511
- c.tsw.WriteLine("}")
512
- return nil
513
- }
514
-
515
- // WriteNamedStructTypeSpec generates a TypeScript class for a named type whose
516
- // underlying type is another named struct. The emitted class copies the field
517
- // layout without inheriting the underlying named type's prototype methods.
518
- func (c *GoToTSCompiler) WriteNamedStructTypeSpec(a *ast.TypeSpec, named *types.Named) error {
519
- isInsideFunction := false
520
- if nodeInfo := c.analysis.NodeData[a]; nodeInfo != nil {
521
- isInsideFunction = nodeInfo.IsInsideFunction
522
- }
523
- if !isInsideFunction {
524
- c.tsw.WriteLiterally("export ")
525
- }
526
- c.tsw.WriteLiterally("class ")
527
- if err := c.WriteValueExpr(a.Name); err != nil {
528
- return err
529
- }
530
-
531
- if a.TypeParams != nil {
532
- c.WriteTypeParameters(a.TypeParams)
533
- }
534
-
535
- c.tsw.WriteLiterally(" ")
536
- c.tsw.WriteLine("{")
537
- c.tsw.Indent(1)
538
-
539
- className := sanitizeIdentifier(a.Name.Name)
540
- underlyingStruct, ok := named.Underlying().(*types.Struct)
541
- if !ok {
542
- return fmt.Errorf("underlying type of %s is not a struct", a.Name.Name)
543
- }
544
-
545
- underlyingType := c.pkg.TypesInfo.TypeOf(a.Type)
546
- underlyingInitType := "{}"
547
- if underlyingNamed, ok := underlyingType.(*types.Named); ok {
548
- underlyingInitType = c.generateFlattenedInitTypeString(underlyingNamed, nil)
549
- }
550
- underlyingTypeName := c.getASTTypeString(a.Type, underlyingType)
551
-
552
- for i := 0; i < underlyingStruct.NumFields(); i++ {
553
- field := underlyingStruct.Field(i)
554
- if field.Anonymous() {
555
- continue
556
- }
557
- if !field.Exported() && field.Pkg() != c.pkg.Types {
558
- continue
559
- }
560
- c.writeGetterSetter(field.Name(), field.Type(), nil, nil, nil)
561
- }
562
-
563
- for field := range underlyingStruct.Fields() {
564
- if field.Anonymous() {
565
- fieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
566
- c.writeGetterSetter(fieldKeyName, field.Type(), nil, nil, nil)
567
- }
568
- }
569
-
570
- c.tsw.WriteLiterally("public _fields: {")
571
- c.tsw.Indent(1)
572
- c.tsw.WriteLine("")
573
- for i := 0; i < underlyingStruct.NumFields(); i++ {
574
- field := underlyingStruct.Field(i)
575
- fieldKeyName := field.Name()
576
- if field.Anonymous() {
577
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
578
- }
579
- if fieldKeyName == "_" {
580
- continue
581
- }
582
- c.tsw.WriteLinef("%s: $.VarRef<%s>;", fieldKeyName, c.getTypeString(field.Type()))
583
- }
584
- c.tsw.Indent(-1)
585
- c.tsw.WriteLine("}")
586
- c.tsw.WriteLine("")
587
-
588
- c.tsw.WriteLinef("constructor(init?: Partial<%s>) {", underlyingInitType)
589
- c.tsw.Indent(1)
590
- c.tsw.WriteLinef("const base = new %s(init)", underlyingTypeName)
591
- c.tsw.WriteLine("this._fields = base._fields")
592
- c.tsw.Indent(-1)
593
- c.tsw.WriteLine("}")
594
- c.tsw.WriteLine("")
595
-
596
- var cloneReturnType strings.Builder
597
- cloneReturnType.WriteString(className)
598
- if a.TypeParams != nil && len(a.TypeParams.List) > 0 {
599
- cloneReturnType.WriteString("<")
600
- first := true
601
- for _, field := range a.TypeParams.List {
602
- for _, name := range field.Names {
603
- if !first {
604
- cloneReturnType.WriteString(", ")
605
- }
606
- first = false
607
- cloneReturnType.WriteString(name.Name)
608
- }
609
- }
610
- cloneReturnType.WriteString(">")
611
- }
612
-
613
- c.tsw.WriteLinef("public clone(): %s {", cloneReturnType.String())
614
- c.tsw.Indent(1)
615
- c.tsw.WriteLinef("const cloned = new %s()", cloneReturnType.String())
616
- c.tsw.WriteLine("cloned._fields = {")
617
- c.tsw.Indent(1)
618
-
619
- firstFieldWritten := false
620
- for i := 0; i < underlyingStruct.NumFields(); i++ {
621
- field := underlyingStruct.Field(i)
622
- fieldType := field.Type()
623
- fieldKeyName := field.Name()
624
- if field.Anonymous() {
625
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
626
- }
627
- if fieldKeyName == "_" {
628
- continue
629
- }
630
-
631
- if firstFieldWritten {
632
- c.tsw.WriteLine(",")
633
- }
634
- c.writeClonedFieldInitializer(fieldKeyName, fieldType, field.Anonymous())
635
- firstFieldWritten = true
636
- }
637
- if firstFieldWritten {
638
- c.tsw.WriteLine("")
639
- }
640
-
641
- c.tsw.Indent(-1)
642
- c.tsw.WriteLine("}")
643
- c.tsw.WriteLine("return cloned")
644
- c.tsw.Indent(-1)
645
- c.tsw.WriteLine("}")
646
-
647
- for _, fileSyntax := range c.pkg.Syntax {
648
- for _, decl := range fileSyntax.Decls {
649
- funcDecl, isFunc := decl.(*ast.FuncDecl)
650
- if !isFunc || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
651
- continue
652
- }
653
- recvType := funcDecl.Recv.List[0].Type
654
- if starExpr, ok := recvType.(*ast.StarExpr); ok {
655
- recvType = starExpr.X
656
- }
657
-
658
- var recvTypeName string
659
- if ident, ok := recvType.(*ast.Ident); ok {
660
- recvTypeName = sanitizeIdentifier(ident.Name)
661
- } else if indexExpr, ok := recvType.(*ast.IndexExpr); ok {
662
- if ident, ok := indexExpr.X.(*ast.Ident); ok {
663
- recvTypeName = sanitizeIdentifier(ident.Name)
664
- }
665
- }
666
-
667
- if recvTypeName == className {
668
- c.tsw.WriteLine("")
669
- if err := c.WriteFuncDeclAsMethod(funcDecl); err != nil {
670
- return err
671
- }
672
- }
673
- }
674
- }
675
-
676
- seenPromotedFields := make(map[string]bool)
677
- directMethods := make(map[string]bool)
678
- for method := range named.Methods() {
679
- sig := method.Type().(*types.Signature)
680
- if sig.Recv() != nil {
681
- recvType := sig.Recv().Type()
682
- if namedRecv, ok := recvType.(*types.Named); ok && namedRecv.Obj() == named.Obj() {
683
- directMethods[method.Name()] = true
684
- } else if ptrRecv, ok := recvType.(*types.Pointer); ok {
685
- if namedElem, ok := ptrRecv.Elem().(*types.Named); ok && namedElem.Obj() == named.Obj() {
686
- directMethods[method.Name()] = true
687
- }
688
- }
689
- }
690
- }
691
-
692
- for field := range underlyingStruct.Fields() {
693
- if !field.Anonymous() {
694
- continue
695
- }
696
-
697
- embeddedFieldType := field.Type()
698
- embeddedFieldKeyName := c.getEmbeddedFieldKeyName(field.Type())
699
-
700
- trueEmbeddedType := embeddedFieldType
701
- if ptr, isPtr := trueEmbeddedType.(*types.Pointer); isPtr {
702
- trueEmbeddedType = ptr.Elem()
703
- }
704
- if _, isNamed := trueEmbeddedType.(*types.Named); !isNamed {
705
- continue
706
- }
707
-
708
- if namedEmbedded, ok := trueEmbeddedType.(*types.Named); ok {
709
- if underlyingEmbeddedStruct, ok := namedEmbedded.Underlying().(*types.Struct); ok {
710
- for promotedField := range underlyingEmbeddedStruct.Fields() {
711
- if !promotedField.Exported() && promotedField.Pkg() != c.pkg.Types {
712
- continue
713
- }
714
- promotedFieldName := promotedField.Name()
715
- if seenPromotedFields[promotedFieldName] {
716
- continue
717
- }
718
- conflict := false
719
- for field := range underlyingStruct.Fields() {
720
- if !field.Anonymous() && field.Name() == promotedFieldName {
721
- conflict = true
722
- break
723
- }
724
- }
725
- if conflict {
726
- continue
727
- }
728
-
729
- seenPromotedFields[promotedFieldName] = true
730
- tsPromotedFieldType := c.getTypeString(promotedField.Type())
731
- c.tsw.WriteLine("")
732
- c.tsw.WriteLinef("public get %s(): %s {", promotedFieldName, tsPromotedFieldType)
733
- c.tsw.Indent(1)
734
- embeddedFieldTypeUnderlying := embeddedFieldType
735
- if ptr, isPtr := embeddedFieldTypeUnderlying.(*types.Pointer); isPtr {
736
- embeddedFieldTypeUnderlying = ptr.Elem()
737
- }
738
- if named, isNamed := embeddedFieldTypeUnderlying.(*types.Named); isNamed {
739
- embeddedFieldTypeUnderlying = named.Underlying()
740
- }
741
- if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
742
- c.tsw.WriteLinef("return this.%s!.%s", embeddedFieldKeyName, promotedFieldName)
743
- } else {
744
- c.tsw.WriteLinef("return this.%s.%s", embeddedFieldKeyName, promotedFieldName)
745
- }
746
- c.tsw.Indent(-1)
747
- c.tsw.WriteLine("}")
748
- c.tsw.WriteLinef("public set %s(value: %s) {", promotedFieldName, tsPromotedFieldType)
749
- c.tsw.Indent(1)
750
- if _, isInterface := embeddedFieldTypeUnderlying.(*types.Interface); isInterface {
751
- c.tsw.WriteLinef("this.%s!.%s = value", embeddedFieldKeyName, promotedFieldName)
752
- } else {
753
- c.tsw.WriteLinef("this.%s.%s = value", embeddedFieldKeyName, promotedFieldName)
754
- }
755
- c.tsw.Indent(-1)
756
- c.tsw.WriteLine("}")
757
- }
758
- }
759
- }
760
-
761
- methodSetType := embeddedFieldType
762
- if _, isPtr := embeddedFieldType.(*types.Pointer); !isPtr {
763
- if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); !isInterface {
764
- methodSetType = types.NewPointer(embeddedFieldType)
765
- }
766
- }
767
- embeddedMethodSet := types.NewMethodSet(methodSetType)
768
- for methodSelection := range embeddedMethodSet.Methods() {
769
- method := methodSelection.Obj().(*types.Func)
770
- methodName := method.Name()
771
-
772
- if len(methodSelection.Index()) == 1 && !directMethods[methodName] && !seenPromotedFields[methodName] {
773
- conflictWithField := false
774
- for field := range underlyingStruct.Fields() {
775
- if !field.Anonymous() && field.Name() == methodName {
776
- conflictWithField = true
777
- break
778
- }
779
- }
780
- if conflictWithField {
781
- continue
782
- }
783
-
784
- seenPromotedFields[methodName] = true
785
- sig := method.Type().(*types.Signature)
786
- c.tsw.WriteLine("")
787
- c.tsw.WriteLiterally("public ")
788
- c.tsw.WriteLiterally(methodName)
789
- c.tsw.WriteLiterally("(")
790
- params := sig.Params()
791
- paramNames := make([]string, params.Len())
792
- for j := 0; j < params.Len(); j++ {
793
- param := params.At(j)
794
- paramName := param.Name()
795
- if paramName == "" || paramName == "_" {
796
- paramName = fmt.Sprintf("_p%d", j)
797
- }
798
- paramNames[j] = paramName
799
- if j > 0 {
800
- c.tsw.WriteLiterally(", ")
801
- }
802
- c.tsw.WriteLiterally(paramName)
803
- c.tsw.WriteLiterally(": ")
804
- c.WriteGoType(param.Type(), GoTypeContextGeneral)
805
- }
806
- c.tsw.WriteLiterally(")")
807
- results := sig.Results()
808
- if results.Len() > 0 {
809
- c.tsw.WriteLiterally(": ")
810
- if results.Len() == 1 {
811
- c.WriteGoType(results.At(0).Type(), GoTypeContextFunctionReturn)
812
- } else {
813
- c.tsw.WriteLiterally("[")
814
- for j := 0; j < results.Len(); j++ {
815
- if j > 0 {
816
- c.tsw.WriteLiterally(", ")
817
- }
818
- c.WriteGoType(results.At(j).Type(), GoTypeContextFunctionReturn)
819
- }
820
- c.tsw.WriteLiterally("]")
821
- }
822
- } else {
823
- c.tsw.WriteLiterally(": void")
824
- }
825
- c.tsw.WriteLine(" {")
826
- c.tsw.Indent(1)
827
- if results.Len() > 0 {
828
- c.tsw.WriteLiterally("return ")
829
- }
830
-
831
- assertionPrefix := "this.%s"
832
- if _, isInterface := embeddedFieldType.Underlying().(*types.Interface); isInterface {
833
- assertionPrefix = "this.%s!"
834
- }
835
- c.tsw.WriteLiterallyf(assertionPrefix+".%s(%s)", embeddedFieldKeyName, methodName, strings.Join(paramNames, ", "))
836
-
837
- c.tsw.WriteLine("")
838
- c.tsw.Indent(-1)
839
- c.tsw.WriteLine("}")
840
- }
841
- }
842
- }
843
-
844
- c.tsw.WriteLine("")
845
- c.tsw.WriteLine("// Register this type with the runtime type system")
846
-
847
- structName := className
848
- pkgPath := c.pkg.Types.Path()
849
- pkgName := c.pkg.Types.Name()
850
- if pkgPath != "" && pkgName != "main" {
851
- structName = pkgPath + "." + className
852
- } else if pkgName == "main" {
853
- structName = "main." + className
854
- }
855
-
856
- c.tsw.WriteLine("static __typeInfo = $.registerStructType(")
857
- c.tsw.WriteLinef(" %q,", structName)
858
- c.tsw.WriteLinef(" new %s(),", className)
859
- c.tsw.WriteLiterally(" [")
860
-
861
- var structMethods []*types.Func
862
- for method := range named.Methods() {
863
- sig := method.Type().(*types.Signature)
864
- recv := sig.Recv().Type()
865
- if ptr, ok := recv.(*types.Pointer); ok {
866
- recv = ptr.Elem()
867
- }
868
- if namedRecv, ok := recv.(*types.Named); ok && namedRecv.Obj() == named.Obj() {
869
- structMethods = append(structMethods, method)
870
- }
871
- }
872
- c.writeMethodSignatures(structMethods)
873
- c.tsw.WriteLiterally("],")
874
- c.tsw.WriteLine("")
875
-
876
- c.tsw.WriteLinef(" %s,", className)
877
- c.tsw.WriteLiterally(" {")
878
- firstField := true
879
- for i := 0; i < underlyingStruct.NumFields(); i++ {
880
- field := underlyingStruct.Field(i)
881
- fieldKeyName := field.Name()
882
- if field.Anonymous() {
883
- fieldKeyName = c.getEmbeddedFieldKeyName(field.Type())
884
- }
885
- if fieldKeyName == "_" {
886
- continue
887
- }
888
- if !firstField {
889
- c.tsw.WriteLiterally(", ")
890
- }
891
- firstField = false
892
- c.tsw.WriteLiterallyf("%q: ", fieldKeyName)
893
-
894
- tag := underlyingStruct.Tag(i)
895
- if tag != "" {
896
- c.tsw.WriteLiterally("{ type: ")
897
- c.writeTypeInfoObject(field.Type())
898
- c.tsw.WriteLiterallyf(", tag: %q }", tag)
899
- } else {
900
- c.writeTypeInfoObject(field.Type())
901
- }
902
- }
903
- c.tsw.WriteLiterally("}")
904
- c.tsw.WriteLine("")
905
- c.tsw.WriteLine(");")
906
-
907
- c.tsw.Indent(-1)
908
- c.tsw.WriteLine("}")
909
- return nil
910
- }
911
-
912
- // generateFlattenedInitTypeString generates a TypeScript type string for the
913
- // initialization object passed to a Go struct's constructor (`_init` method in TypeScript).
914
- // The generated type is a `Partial`-like structure, `"{ Field1?: Type1, Field2?: Type2, ... }"`,
915
- // including all direct and promoted fields of the `structType`.
916
- // - It iterates through the direct fields of the `structType`. Exported fields
917
- // are included with their TypeScript types (obtained via `WriteGoType`).
918
- // - For anonymous (embedded) fields, it generates a type like `EmbeddedName?: ConstructorParameters<typeof EmbeddedName>[0]`,
919
- // allowing initialization of the embedded struct's fields directly within the outer struct's initializer.
920
- // - It then uses `types.NewMethodSet` and checks for `types.Var` objects that are fields
921
- // to find promoted fields from embedded structs, adding them to the type string if not already present.
922
- //
923
- // The resulting string is sorted by field name for deterministic output and represents
924
- // the shape of the object expected by the struct's TypeScript constructor.
925
- func (c *GoToTSCompiler) generateFlattenedInitTypeString(structType *types.Named, fieldASTTypes map[string]ast.Expr) string {
926
- if structType == nil {
927
- return "{}"
928
- }
929
-
930
- // Use a map to collect unique field names and their types
931
- fieldMap := make(map[string]string)
932
- embeddedTypeMap := make(map[string]string) // Stores TS type string for embedded struct initializers
933
-
934
- underlying, ok := structType.Underlying().(*types.Struct)
935
- if !ok {
936
- return "{}"
937
- }
938
-
939
- // First add the direct fields and track embedded types
940
- for field := range underlying.Fields() {
941
- fieldName := field.Name()
942
-
943
- // Skip underscore fields
944
- if fieldName == "_" {
945
- continue
946
- }
947
-
948
- if !field.Exported() && field.Pkg() != c.pkg.Types {
949
- continue
950
- }
951
-
952
- if field.Anonymous() {
953
- fieldType := field.Type()
954
- if ptr, ok := fieldType.(*types.Pointer); ok {
955
- fieldType = ptr.Elem()
956
- }
957
-
958
- if _, ok := fieldType.(*types.Named); ok {
959
- // Check if the embedded type is an interface
960
- if _, isInterface := fieldType.Underlying().(*types.Interface); isInterface {
961
- // For embedded interfaces, use the full qualified interface type
962
- embeddedTypeMap[c.getEmbeddedFieldKeyName(field.Type())] = c.getTypeString(field.Type())
963
- } else {
964
- // For embedded structs, use ConstructorParameters for field-based initialization
965
- // Use getTypeString to get the qualified type name (e.g., bytes.Buffer not just Buffer)
966
- qualifiedTypeName := c.getTypeString(fieldType)
967
- embeddedTypeMap[c.getEmbeddedFieldKeyName(field.Type())] = fmt.Sprintf("Partial<ConstructorParameters<typeof %s>[0]>", qualifiedTypeName)
968
- }
969
- }
970
- continue
971
- }
972
- fieldMap[fieldName] = c.getASTTypeString(fieldASTTypes[fieldName], field.Type())
973
- }
974
-
975
- // Promoted fields (handled by Go's embedding, init should use direct/embedded names)
976
- // The current logic for `generateFlattenedInitTypeString` seems to focus on top-level
977
- // settable properties in the constructor. Promoted fields are accessed via `this.promotedField`,
978
- // not typically set directly in `init?` unless the embedded struct itself is named in `init?`.
979
-
980
- // Add embedded types to the field map (these are the names of the embedded structs themselves)
981
- maps.Copy(fieldMap, embeddedTypeMap)
982
-
983
- var fieldNames []string
984
- for name := range fieldMap {
985
- fieldNames = append(fieldNames, name)
986
- }
987
- slices.Sort(fieldNames)
988
-
989
- var fieldDefs []string
990
- for _, fieldName := range fieldNames {
991
- fieldDefs = append(fieldDefs, fmt.Sprintf("%s?: %s", fieldName, fieldMap[fieldName]))
992
- }
993
-
994
- return "{" + strings.Join(fieldDefs, ", ") + "}"
995
- }