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
package/compiler/decl.go DELETED
@@ -1,801 +0,0 @@
1
- package compiler
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/token"
7
- "go/types"
8
- "slices"
9
- "strings"
10
- )
11
-
12
- // linknameInfo holds parsed //go:linkname directive information.
13
- type linknameInfo struct {
14
- targetPkg string // target package path (e.g., "github.com/example/package")
15
- targetName string // target symbol name (e.g., "CanHaveDecorators")
16
- }
17
-
18
- // parseLinknameDirective checks if a doc comment contains a //go:linkname directive
19
- // and returns the parsed information if found.
20
- func parseLinknameDirective(doc *ast.CommentGroup) *linknameInfo {
21
- if doc == nil {
22
- return nil
23
- }
24
- for _, comment := range doc.List {
25
- text := strings.TrimSpace(comment.Text)
26
- if strings.HasPrefix(text, "//go:linkname ") {
27
- // Format: //go:linkname localname importpath.name
28
- parts := strings.Fields(text)
29
- if len(parts) >= 3 {
30
- target := parts[2]
31
- // Split target into package path and symbol name
32
- lastDot := strings.LastIndex(target, ".")
33
- if lastDot > 0 {
34
- return &linknameInfo{
35
- targetPkg: target[:lastDot],
36
- targetName: target[lastDot+1:],
37
- }
38
- }
39
- }
40
- }
41
- }
42
- return nil
43
- }
44
-
45
- // WriteDecls iterates through a slice of Go top-level declarations (`ast.Decl`)
46
- // and translates each one into its TypeScript equivalent.
47
- // It distinguishes between:
48
- // - Function declarations (`ast.FuncDecl`):
49
- // - If it's a regular function (no receiver), it delegates to `WriteFuncDeclAsFunction`.
50
- // - Methods (with receivers) are handled within `WriteTypeSpec` when their
51
- // associated struct/type is defined, so they are skipped here.
52
- // - General declarations (`ast.GenDecl`), which can contain imports, constants,
53
- // variables, or type definitions: It iterates through `d.Specs` and calls
54
- // `WriteSpec` for each specification.
55
- //
56
- // Type declarations are sorted by dependencies to ensure referenced types are
57
- // defined before types that reference them, avoiding initialization order issues.
58
- // A newline is added after each processed declaration or spec group for readability.
59
- // Unknown declaration types result in a printed diagnostic message.
60
- func (c *GoToTSCompiler) WriteDecls(decls []ast.Decl) error {
61
- // Separate type declarations from other declarations for dependency sorting
62
- var typeSpecs []*ast.TypeSpec
63
- var varSpecs []*ast.ValueSpec
64
- var otherDecls []ast.Decl
65
- var otherSpecs []ast.Spec
66
-
67
- for _, decl := range decls {
68
- switch d := decl.(type) {
69
- case *ast.FuncDecl:
70
- // Only handle top-level functions here. Methods are handled within WriteTypeSpec.
71
- if d.Recv == nil {
72
- otherDecls = append(otherDecls, d)
73
- }
74
- case *ast.GenDecl:
75
- for _, spec := range d.Specs {
76
- if typeSpec, ok := spec.(*ast.TypeSpec); ok {
77
- typeSpecs = append(typeSpecs, typeSpec)
78
- } else if varSpec, ok := spec.(*ast.ValueSpec); ok && d.Tok == token.VAR {
79
- varSpecs = append(varSpecs, varSpec)
80
- } else {
81
- otherSpecs = append(otherSpecs, spec)
82
- }
83
- }
84
- default:
85
- otherDecls = append(otherDecls, d)
86
- }
87
- }
88
-
89
- // Sort type declarations by dependencies
90
- sortedTypeSpecs, err := c.sortTypeSpecsByDependencies(typeSpecs)
91
- if err != nil {
92
- // Surface the error instead of silently falling back
93
- return fmt.Errorf("circular dependency detected sorting type declarations: %w", err)
94
- }
95
-
96
- // Sort variable declarations by type dependencies
97
- sortedVarSpecs, err := c.sortVarSpecsByTypeDependencies(varSpecs, typeSpecs)
98
- if err != nil {
99
- return fmt.Errorf("failed to sort variable declarations: %w", err)
100
- }
101
-
102
- // Write non-type, non-var declarations first (imports, constants)
103
- for _, spec := range otherSpecs {
104
- if err := c.WriteSpec(spec); err != nil {
105
- return err
106
- }
107
- c.tsw.WriteLine("") // Add space after spec
108
- }
109
-
110
- // Write sorted type declarations
111
- for _, typeSpec := range sortedTypeSpecs {
112
- if err := c.WriteSpec(typeSpec); err != nil {
113
- return err
114
- }
115
- c.tsw.WriteLine("") // Add space after spec
116
- }
117
-
118
- // Write sorted variable declarations
119
- for _, varSpec := range sortedVarSpecs {
120
- if err := c.WriteSpec(varSpec); err != nil {
121
- return err
122
- }
123
- c.tsw.WriteLine("") // Add space after spec
124
- }
125
-
126
- // Write function declarations last
127
- for _, decl := range otherDecls {
128
- switch d := decl.(type) {
129
- case *ast.FuncDecl:
130
- if err := c.WriteFuncDeclAsFunction(d); err != nil {
131
- return err
132
- }
133
- c.tsw.WriteLine("") // Add space after function
134
- default:
135
- return fmt.Errorf("unknown decl: %#v", decl)
136
- }
137
- }
138
-
139
- return nil
140
- }
141
-
142
- // sortTypeSpecsByDependencies performs a topological sort of type specifications
143
- // based on their dependencies to ensure referenced types are defined before
144
- // types that reference them.
145
- func (c *GoToTSCompiler) sortTypeSpecsByDependencies(typeSpecs []*ast.TypeSpec) ([]*ast.TypeSpec, error) {
146
- if len(typeSpecs) <= 1 {
147
- return typeSpecs, nil
148
- }
149
-
150
- // Build dependency graph
151
- dependencies := make(map[string][]string) // typeName -> list of types it depends on
152
- typeSpecMap := make(map[string]*ast.TypeSpec)
153
-
154
- // First pass: collect all type names
155
- for _, typeSpec := range typeSpecs {
156
- typeName := typeSpec.Name.Name
157
- typeSpecMap[typeName] = typeSpec
158
- dependencies[typeName] = []string{}
159
- }
160
-
161
- // Second pass: analyze dependencies
162
- for _, typeSpec := range typeSpecs {
163
- typeName := typeSpec.Name.Name
164
- deps := c.extractTypeDependencies(typeSpec.Type, typeSpecMap)
165
- dependencies[typeName] = deps
166
- }
167
-
168
- // Perform topological sort
169
- sorted, err := c.topologicalSort(dependencies)
170
- if err != nil {
171
- return nil, err
172
- }
173
-
174
- // Build result in sorted order
175
- var result []*ast.TypeSpec
176
- for _, typeName := range sorted {
177
- if typeSpec, exists := typeSpecMap[typeName]; exists {
178
- result = append(result, typeSpec)
179
- }
180
- }
181
-
182
- return result, nil
183
- }
184
-
185
- // extractTypeDependencies extracts only the dependencies that cause TypeScript initialization order issues.
186
- // These are dependencies where the constructor of one type directly instantiates another type.
187
- //
188
- // TRUE dependencies (cause initialization issues):
189
- // - Direct struct fields (non-pointer): type A struct { b B } -> A constructor calls new B()
190
- // - Embedded struct fields: type A struct { B } -> A constructor calls new B()
191
- // - Direct type aliases: type A B -> A directly wraps B
192
- // - Array/slice of structs: type A []B -> needs B for default values
193
- //
194
- // FALSE dependencies (don't cause initialization issues):
195
- // - Pointer fields: type A struct { b *B } -> just stores reference, no constructor call
196
- // - Interface fields: type A struct { b SomeInterface } -> stores interface, no concrete instantiation
197
- // - Map types: type A map[K]V -> map initialized empty, no constructor calls
198
- // - Array/slice of pointers: type A []*B -> array of pointers, no constructor calls
199
- func (c *GoToTSCompiler) extractTypeDependencies(typeExpr ast.Expr, typeSpecMap map[string]*ast.TypeSpec) []string {
200
- var deps []string
201
-
202
- switch t := typeExpr.(type) {
203
- case *ast.Ident:
204
- // Direct type reference (e.g., type MyType OtherType)
205
- if _, isLocalType := typeSpecMap[t.Name]; isLocalType {
206
- deps = append(deps, t.Name)
207
- }
208
-
209
- case *ast.StructType:
210
- // Struct type - check field types, but be more selective
211
- if t.Fields != nil {
212
- for _, field := range t.Fields.List {
213
- fieldDeps := c.extractStructFieldDependencies(field.Type, typeSpecMap)
214
- deps = append(deps, fieldDeps...)
215
- }
216
- }
217
-
218
- case *ast.ArrayType:
219
- // Array/slice types don't create initialization dependencies
220
- // Slices are reference types (initialized to null/empty), and arrays of structs
221
- // don't require the element type constructor at declaration time.
222
- // This allows circular references like: type A struct { BB []B }; type B struct { AA []A }
223
-
224
- case *ast.StarExpr:
225
- // Pointer types don't create initialization dependencies
226
- // The pointed-to type doesn't need to be initialized when creating a pointer field
227
-
228
- case *ast.MapType:
229
- // Map types don't create initialization dependencies
230
- // Maps are initialized empty, no constructor calls needed
231
-
232
- case *ast.InterfaceType:
233
- // Interface types don't create initialization dependencies
234
-
235
- case *ast.FuncType:
236
- // Function types don't create initialization dependencies
237
-
238
- case *ast.SelectorExpr:
239
- // External package types don't create local dependencies
240
-
241
- // Add other type expressions as needed
242
- }
243
-
244
- // Sort dependencies for deterministic output
245
- slices.Sort(deps)
246
- return deps
247
- }
248
-
249
- // extractStructFieldDependencies extracts dependencies from struct field types
250
- func (c *GoToTSCompiler) extractStructFieldDependencies(fieldType ast.Expr, typeSpecMap map[string]*ast.TypeSpec) []string {
251
- var deps []string
252
-
253
- switch t := fieldType.(type) {
254
- case *ast.Ident:
255
- // Direct field type: struct { b B } - this requires B to be initialized
256
- if _, isLocalType := typeSpecMap[t.Name]; isLocalType {
257
- deps = append(deps, t.Name)
258
- }
259
-
260
- case *ast.StarExpr:
261
- // Pointer field: struct { b *B } - this doesn't require B initialization
262
- // Pointers are just references, no constructor call needed
263
-
264
- case *ast.ArrayType:
265
- // Array/slice fields don't create initialization dependencies
266
- // Slices are reference types (initialized to null/empty), and arrays of structs
267
- // don't require the element type constructor at declaration time.
268
- // This allows circular references like: type A struct { BB []B }; type B struct { AA []A }
269
-
270
- case *ast.MapType:
271
- // Map field: struct { b map[K]V } - maps don't require initialization dependencies
272
-
273
- case *ast.InterfaceType:
274
- // Interface field: struct { b SomeInterface } - no concrete type dependency
275
-
276
- case *ast.FuncType:
277
- // Function field: struct { b func() } - no dependency
278
-
279
- // Handle other field types as needed
280
- }
281
-
282
- return deps
283
- }
284
-
285
- // sortVarSpecsByTypeDependencies sorts variable declarations based on their value dependencies
286
- // to ensure that variables are initialized in the correct order (respecting JavaScript's TDZ).
287
- // For example: var StdEncoding = NewEncoding(...) must come before var RawStdEncoding = StdEncoding.WithPadding(...)
288
- func (c *GoToTSCompiler) sortVarSpecsByTypeDependencies(varSpecs []*ast.ValueSpec, typeSpecs []*ast.TypeSpec) ([]*ast.ValueSpec, error) {
289
- if len(varSpecs) <= 1 {
290
- return varSpecs, nil
291
- }
292
-
293
- // Build a map of variable names to their specs
294
- varSpecMap := make(map[string]*ast.ValueSpec)
295
- varNames := []string{}
296
- for _, varSpec := range varSpecs {
297
- if len(varSpec.Names) > 0 {
298
- name := varSpec.Names[0].Name
299
- varSpecMap[name] = varSpec
300
- varNames = append(varNames, name)
301
- }
302
- }
303
-
304
- // Build dependency graph: varName -> list of variables it depends on
305
- dependencies := make(map[string][]string)
306
- for _, name := range varNames {
307
- dependencies[name] = []string{}
308
- }
309
-
310
- // Extract value dependencies from initializer expressions
311
- for _, varSpec := range varSpecs {
312
- if len(varSpec.Names) == 0 {
313
- continue
314
- }
315
- varName := varSpec.Names[0].Name
316
-
317
- // Check initializer expressions for variable references
318
- for _, value := range varSpec.Values {
319
- deps := c.extractVarDependencies(value, varSpecMap)
320
- dependencies[varName] = append(dependencies[varName], deps...)
321
- }
322
- }
323
-
324
- // Perform topological sort
325
- sorted, err := c.topologicalSort(dependencies)
326
- if err != nil {
327
- return nil, err
328
- }
329
-
330
- // Build result in sorted order
331
- result := make([]*ast.ValueSpec, 0, len(varSpecs))
332
- for _, varName := range sorted {
333
- if spec, exists := varSpecMap[varName]; exists {
334
- result = append(result, spec)
335
- }
336
- }
337
-
338
- return result, nil
339
- }
340
-
341
- // extractVarDependencies extracts variable dependencies from an initializer expression.
342
- // It returns a list of variable names that the expression depends on.
343
- func (c *GoToTSCompiler) extractVarDependencies(expr ast.Expr, varSpecMap map[string]*ast.ValueSpec) []string {
344
- var deps []string
345
- seen := make(map[string]bool)
346
-
347
- ast.Inspect(expr, func(n ast.Node) bool {
348
- if ident, ok := n.(*ast.Ident); ok {
349
- // Check if this identifier refers to a package-level variable
350
- if _, isVar := varSpecMap[ident.Name]; isVar {
351
- if !seen[ident.Name] {
352
- deps = append(deps, ident.Name)
353
- seen[ident.Name] = true
354
- }
355
- }
356
- }
357
- return true
358
- })
359
-
360
- return deps
361
- }
362
-
363
- // topologicalSort performs a topological sort of the dependency graph
364
- func (c *GoToTSCompiler) topologicalSort(dependencies map[string][]string) ([]string, error) {
365
- // Kahn's algorithm for topological sorting with deterministic ordering
366
- inDegree := make(map[string]int)
367
- graph := make(map[string][]string)
368
-
369
- // Initialize in-degree counts and reverse graph
370
- for node := range dependencies {
371
- inDegree[node] = 0
372
- graph[node] = []string{}
373
- }
374
-
375
- // Build reverse graph and count in-degrees
376
- for node, deps := range dependencies {
377
- // Sort dependencies for consistent output
378
- sortedDeps := make([]string, len(deps))
379
- copy(sortedDeps, deps)
380
- slices.Sort(sortedDeps)
381
-
382
- for _, dep := range sortedDeps {
383
- if _, exists := inDegree[dep]; exists {
384
- graph[dep] = append(graph[dep], node)
385
- inDegree[node]++
386
- }
387
- }
388
- }
389
-
390
- // Sort neighbors in graph for consistency
391
- for node := range graph {
392
- slices.Sort(graph[node])
393
- }
394
-
395
- // Find nodes with no incoming edges and sort them
396
- var queue []string
397
- for node, degree := range inDegree {
398
- if degree == 0 {
399
- queue = append(queue, node)
400
- }
401
- }
402
- slices.Sort(queue) // Sort initial queue for deterministic output
403
-
404
- var result []string
405
-
406
- for len(queue) > 0 {
407
- // Remove node from queue (already sorted)
408
- current := queue[0]
409
- queue = queue[1:]
410
- result = append(result, current)
411
-
412
- // Collect new zero-degree nodes
413
- var newZeroNodes []string
414
- for _, neighbor := range graph[current] {
415
- inDegree[neighbor]--
416
- if inDegree[neighbor] == 0 {
417
- newZeroNodes = append(newZeroNodes, neighbor)
418
- }
419
- }
420
-
421
- // Sort new zero-degree nodes and add to queue
422
- slices.Sort(newZeroNodes)
423
- queue = append(queue, newZeroNodes...)
424
- }
425
-
426
- // Check for cycles
427
- if len(result) != len(dependencies) {
428
- // Find the remaining nodes to help debug the circular dependency
429
- processed := make(map[string]bool)
430
- for _, name := range result {
431
- processed[name] = true
432
- }
433
-
434
- var remaining []string
435
- for name := range dependencies {
436
- if !processed[name] {
437
- remaining = append(remaining, name)
438
- }
439
- }
440
- slices.Sort(remaining)
441
-
442
- return nil, fmt.Errorf("circular dependency detected in type declarations. Remaining types: %v", remaining)
443
- }
444
-
445
- return result, nil
446
- }
447
-
448
- // WriteFuncDeclAsFunction translates a Go function declaration (`ast.FuncDecl`)
449
- // that does not have a receiver (i.e., it's a regular function, not a method)
450
- // into a TypeScript function.
451
- // - Go documentation comments (`decl.Doc`) are preserved.
452
- // - If the Go function is exported (name starts with an uppercase letter) or is
453
- // the `main` function, the `export` keyword is added to the TypeScript output.
454
- // - If the `Analysis` data indicates the function is asynchronous, the `async`
455
- // keyword is prepended.
456
- // - The function signature (parameters and return type) is translated using `WriteFuncType`,
457
- // passing the `isAsync` status.
458
- // - The function body (`decl.Body`) is translated using `WriteStmt`.
459
- //
460
- // This function specifically handles top-level functions; methods are generated
461
- // by `WriteFuncDeclAsMethod` within the context of their type definition.
462
- func (c *GoToTSCompiler) WriteFuncDeclAsFunction(decl *ast.FuncDecl) error {
463
- if decl.Recv != nil {
464
- // This function should not be called for methods.
465
- // Methods are handled by WriteFuncDeclAsMethod within WriteTypeSpec.
466
- return nil
467
- }
468
-
469
- // Check for //go:linkname directive on functions without a body
470
- if linkInfo := parseLinknameDirective(decl.Doc); linkInfo != nil && decl.Body == nil {
471
- // This is a linkname function - generate a re-export with type annotation
472
- return c.writeLinknameFunction(decl, linkInfo)
473
- }
474
-
475
- if decl.Doc != nil {
476
- c.WriteDoc(decl.Doc)
477
- }
478
-
479
- // Export all functions for intra-package visibility
480
- // This allows other files in the same package to import functions
481
- c.tsw.WriteLiterally("export ")
482
-
483
- // Check if this function is async using the analysis data
484
- var isAsync bool
485
- if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
486
- isAsync = c.analysis.IsAsyncFunc(obj)
487
- }
488
-
489
- // Always make main function async (only in main package)
490
- if decl.Name.Name == "main" && c.pkg.Name == "main" {
491
- isAsync = true
492
- }
493
-
494
- if isAsync {
495
- c.tsw.WriteLiterally("async ")
496
- }
497
-
498
- c.tsw.WriteLiterally("function ")
499
- if err := c.WriteValueExpr(decl.Name); err != nil { // Function name is a value identifier
500
- return fmt.Errorf("failed to write function name: %w", err)
501
- }
502
-
503
- // Write type parameters if present
504
- if decl.Type.TypeParams != nil {
505
- c.WriteTypeParameters(decl.Type.TypeParams)
506
- }
507
-
508
- // WriteFuncType needs to be aware if the function is async
509
- c.WriteFuncType(decl.Type, isAsync) // Write signature (params, return type)
510
- c.tsw.WriteLiterally(" ")
511
-
512
- if c.hasNamedReturns(decl.Type.Results) {
513
- c.tsw.WriteLine("{")
514
- c.tsw.Indent(1)
515
-
516
- // Declare named return variables and initialize them to their zero values
517
- if err := c.writeNamedReturnDeclarations(decl.Type.Results); err != nil {
518
- return fmt.Errorf("failed to write named return declarations: %w", err)
519
- }
520
- }
521
-
522
- if err := c.WriteStmt(decl.Body); err != nil {
523
- return fmt.Errorf("failed to write function body: %w", err)
524
- }
525
-
526
- if c.hasNamedReturns(decl.Type.Results) {
527
- c.tsw.Indent(-1)
528
- c.tsw.WriteLine("}")
529
- }
530
-
531
- return nil
532
- }
533
-
534
- // writeLinknameFunction generates a TypeScript const re-export for a //go:linkname function.
535
- // It generates: export const LocalName: (params) => ReturnType = alias.TargetName
536
- //
537
- // Unlike Go's //go:linkname, which does not perform type checking between the
538
- // local declaration and the target symbol, the generated TypeScript code includes an
539
- // explicit function type annotation. This means the TypeScript compiler will enforce
540
- // that the declared parameter and return types match the actual target function type.
541
- // Any mismatch will result in a TypeScript compilation error.
542
- func (c *GoToTSCompiler) writeLinknameFunction(decl *ast.FuncDecl, info *linknameInfo) error {
543
- // Find the import alias for the target package
544
- alias := c.findImportAlias(info.targetPkg)
545
- if alias == "" {
546
- // Package not imported, write a comment and fall back to empty function
547
- c.tsw.WriteLinef("//go:linkname target %s not found in imports", info.targetPkg)
548
- c.tsw.WriteLiterally("export function ")
549
- c.tsw.WriteLiterally(c.sanitizeIdentifier(decl.Name.Name))
550
- c.WriteFuncType(decl.Type, false)
551
- c.tsw.WriteLine(" {}")
552
- return nil
553
- }
554
-
555
- // Generate: export const LocalName: (params) => ReturnType = alias.TargetName
556
- c.tsw.WriteLiterally("export const ")
557
- c.tsw.WriteLiterally(c.sanitizeIdentifier(decl.Name.Name))
558
- c.tsw.WriteLiterally(": ")
559
-
560
- // Write the function type as an arrow function type
561
- c.WriteFuncTypeAsArrow(decl.Type)
562
-
563
- c.tsw.WriteLiterally(" = ")
564
- c.tsw.WriteLiterally(alias)
565
- c.tsw.WriteLiterally(".")
566
- c.tsw.WriteLiterally(info.targetName)
567
- c.tsw.WriteLine("")
568
-
569
- return nil
570
- }
571
-
572
- // findImportAlias finds the import alias used for a Go package path in the current file.
573
- // Returns empty string if the package is not imported.
574
- func (c *GoToTSCompiler) findImportAlias(pkgPath string) string {
575
- // The importPath in analysis.Imports is stored as the TypeScript path (e.g., @goscript/pkg/path)
576
- // We need to convert the Go package path to match
577
- tsPath := translateGoImportPathToTypescriptModulePath(pkgPath)
578
-
579
- for alias, imp := range c.analysis.Imports {
580
- if imp.importPath == tsPath {
581
- return alias
582
- }
583
- }
584
- return ""
585
- }
586
-
587
- // WriteFuncDeclAsMethod translates a Go function declaration (`ast.FuncDecl`)
588
- // that has a receiver (i.e., it's a method) into a TypeScript class method.
589
- // - It preserves Go documentation comments (`decl.Doc`).
590
- // - The method is declared as `public`.
591
- // - If the `Analysis` data indicates the method is asynchronous, the `async`
592
- // keyword is prepended.
593
- // - The method name retains its original Go casing.
594
- // - Parameters and return types are translated using `WriteFieldList` and
595
- // `WriteTypeExpr`, respectively. Async methods have their return types
596
- // wrapped in `Promise<>`.
597
- // - The method body is translated. If the Go receiver has a name (e.g., `(s *MyStruct)`),
598
- // a `const receiverName = this;` binding is generated at the start of the
599
- // TypeScript method body to make `this` available via the Go receiver's name.
600
- // If the method body requires deferred cleanup (`NeedsDefer`), the appropriate
601
- // `using __defer = new $.DisposableStack()` (or `AsyncDisposableStack`)
602
- // is also generated.
603
- //
604
- // This function assumes it is called only for `FuncDecl` nodes that are methods.
605
- func (c *GoToTSCompiler) WriteFuncDeclAsMethod(decl *ast.FuncDecl) error {
606
- _, err := c.writeMethodSignature(decl)
607
- if err != nil {
608
- return err
609
- }
610
-
611
- return c.writeMethodBodyWithReceiverBinding(decl, "this")
612
- }
613
-
614
- // writeNamedReturnDeclarations generates TypeScript variable declarations for named return parameters.
615
- // It declares each named return variable with its appropriate type and zero value.
616
- func (c *GoToTSCompiler) writeNamedReturnDeclarations(results *ast.FieldList) error {
617
- if results == nil {
618
- return nil
619
- }
620
-
621
- for _, field := range results.List {
622
- for _, name := range field.Names {
623
- c.tsw.WriteLiterallyf("let %s: ", c.sanitizeIdentifier(name.Name))
624
- c.WriteTypeExpr(field.Type)
625
- c.tsw.WriteLiterally(" = ")
626
- c.WriteZeroValueForType(c.pkg.TypesInfo.TypeOf(field.Type))
627
- c.tsw.WriteLine("")
628
- }
629
- }
630
- return nil
631
- }
632
-
633
- // hasNamedReturns checks if a function type has any named return parameters.
634
- func (c *GoToTSCompiler) hasNamedReturns(results *ast.FieldList) bool {
635
- if results == nil {
636
- return false
637
- }
638
-
639
- for _, field := range results.List {
640
- if len(field.Names) > 0 {
641
- return true
642
- }
643
- }
644
- return false
645
- }
646
-
647
- // writeMethodSignature writes the TypeScript method signature including async, public modifiers, name, parameters, and return type
648
- func (c *GoToTSCompiler) writeMethodSignature(decl *ast.FuncDecl) (bool, error) {
649
- if decl.Doc != nil {
650
- c.WriteDoc(decl.Doc)
651
- }
652
-
653
- // Determine if method is async
654
- var isAsync bool
655
- if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
656
- isAsync = c.analysis.IsAsyncFunc(obj)
657
-
658
- // Check if this method must be async due to interface constraints
659
- if !isAsync && decl.Recv != nil && len(decl.Recv.List) > 0 {
660
- // Get the receiver type
661
- receiverType := decl.Recv.List[0].Type
662
- if starExpr, ok := receiverType.(*ast.StarExpr); ok {
663
- receiverType = starExpr.X
664
- }
665
-
666
- if ident, ok := receiverType.(*ast.Ident); ok {
667
- // Get the named type for this receiver
668
- if receiverObj := c.pkg.TypesInfo.Uses[ident]; receiverObj != nil {
669
- if namedType, ok := receiverObj.Type().(*types.Named); ok {
670
- // Check if this method must be async due to interface constraints
671
- if c.analysis.MustBeAsyncDueToInterface(namedType, decl.Name.Name) {
672
- isAsync = true
673
- }
674
- }
675
- }
676
- }
677
- }
678
- }
679
-
680
- // Methods are typically public in the TS output
681
- c.tsw.WriteLiterally("public ")
682
-
683
- // Add async modifier if needed
684
- if isAsync {
685
- c.tsw.WriteLiterally("async ")
686
- }
687
-
688
- // Keep original Go casing for method names
689
- if err := c.WriteValueExpr(decl.Name); err != nil { // Method name is a value identifier
690
- return isAsync, err
691
- }
692
-
693
- // Write signature (parameters and return type)
694
- funcType := decl.Type
695
- c.tsw.WriteLiterally("(")
696
- if funcType.Params != nil {
697
- c.WriteFieldList(funcType.Params, true) // true = arguments
698
- }
699
- c.tsw.WriteLiterally(")")
700
-
701
- // Handle return type
702
- if funcType.Results != nil && len(funcType.Results.List) > 0 {
703
- c.tsw.WriteLiterally(": ")
704
- if isAsync {
705
- c.tsw.WriteLiterally("Promise<")
706
- }
707
- if len(funcType.Results.List) == 1 {
708
- // Single return value
709
- resultType := funcType.Results.List[0].Type
710
- c.WriteTypeExpr(resultType)
711
- } else {
712
- // Multiple return values -> tuple type
713
- c.tsw.WriteLiterally("[")
714
- first := true
715
- for _, field := range funcType.Results.List {
716
- // Each field may represent multiple return values (e.g., "a, b int")
717
- count := len(field.Names)
718
- if count == 0 {
719
- count = 1 // Unnamed return value
720
- }
721
- for j := 0; j < count; j++ {
722
- if !first {
723
- c.tsw.WriteLiterally(", ")
724
- }
725
- first = false
726
- c.WriteTypeExpr(field.Type)
727
- }
728
- }
729
- c.tsw.WriteLiterally("]")
730
- }
731
- if isAsync {
732
- c.tsw.WriteLiterally(">")
733
- }
734
- } else {
735
- // No return value -> void
736
- if isAsync {
737
- c.tsw.WriteLiterally(": Promise<void>")
738
- } else {
739
- c.tsw.WriteLiterally(": void")
740
- }
741
- }
742
-
743
- c.tsw.WriteLiterally(" ")
744
- return isAsync, nil
745
- }
746
-
747
- // writeMethodBodyWithReceiverBinding writes the method body with optional receiver binding
748
- // receiverTarget should be "this" for struct methods or "this._value" for named type methods
749
- func (c *GoToTSCompiler) writeMethodBodyWithReceiverBinding(decl *ast.FuncDecl, receiverTarget string) error {
750
- // Bind receiver name conditionally
751
- if recvField := decl.Recv.List[0]; len(recvField.Names) > 0 {
752
- recvName := recvField.Names[0].Name
753
- if recvName != "_" {
754
- // Check if receiver is actually used
755
- var needsReceiverBinding bool
756
- if obj := c.pkg.TypesInfo.Defs[decl.Name]; obj != nil {
757
- needsReceiverBinding = c.analysis.IsReceiverUsed(obj)
758
- }
759
-
760
- c.tsw.WriteLine("{")
761
- c.tsw.Indent(1)
762
-
763
- if needsReceiverBinding {
764
- // Sanitize the receiver name to avoid conflicts with TypeScript reserved words
765
- sanitizedRecvName := c.sanitizeIdentifier(recvName)
766
- c.tsw.WriteLinef("const %s = %s", sanitizedRecvName, receiverTarget)
767
- }
768
-
769
- // Add using statement if needed
770
- if c.analysis.NeedsDefer(decl.Body) {
771
- if c.analysis.IsInAsyncFunction(decl) {
772
- c.tsw.WriteLine("await using __defer = new $.AsyncDisposableStack();")
773
- } else {
774
- c.tsw.WriteLine("using __defer = new $.DisposableStack();")
775
- }
776
- }
777
-
778
- // Declare named return variables and initialize them to their zero values
779
- if err := c.writeNamedReturnDeclarations(decl.Type.Results); err != nil {
780
- return fmt.Errorf("failed to write named return declarations: %w", err)
781
- }
782
-
783
- // write method body without outer braces
784
- for _, stmt := range decl.Body.List {
785
- if err := c.WriteStmt(stmt); err != nil {
786
- return fmt.Errorf("failed to write statement in function body: %w", err)
787
- }
788
- }
789
- c.tsw.Indent(-1)
790
- c.tsw.WriteLine("}")
791
-
792
- return nil
793
- }
794
- }
795
- // no named receiver, write whole body
796
- if err := c.WriteStmt(decl.Body); err != nil {
797
- return fmt.Errorf("failed to write function body: %w", err)
798
- }
799
-
800
- return nil
801
- }